Sync inav to Gitea
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,3 @@
|
||||
# This middleware library is unavailable in this repository
|
||||
|
||||
In this repository, this middleware library **along with** the projects (demos, applications, and examples) using it, are **not available**. Please refer to the [README.md](../../../README.md#some-middleware-libraries-and-projects-are-unavailable-in-this-repository) file at the root of this repository for further details.
|
||||
+2955
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_address.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network address management functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_ADDRESS_H
|
||||
#define NET_ADDRESS_H
|
||||
|
||||
#include "string.h"
|
||||
#include <stdlib.h>
|
||||
#include "net_types.h"
|
||||
|
||||
#define NET_ZERO(a) (void) memset(&a,0,sizeof(a))
|
||||
#define NET_EQUAL(a,b) (memcmp(&(a),&(b),sizeof(a))==0)
|
||||
#define NET_DIFF(a,b) (memcmp(&(a),&(b),sizeof(a))!=0)
|
||||
#define NET_COPY(a,b) (void) memcpy(&a,&b,sizeof(a))
|
||||
|
||||
#ifdef NET_USE_LWIP_DEFINITIONS
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/inet.h"
|
||||
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
typedef struct sockaddr_in net_sockaddr_in_t;
|
||||
typedef struct sockaddr_in6 net_sockaddr_in6_t;
|
||||
typedef struct sockaddr net_sockaddr_t;
|
||||
typedef ip_addr_t net_ip_addr_t;
|
||||
typedef in_addr_t net_in_addr_t;
|
||||
|
||||
|
||||
#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
|
||||
(sin)->sin_len = (uint8_t) sizeof(struct sockaddr_in); \
|
||||
(sin)->sin_family = AF_INET; \
|
||||
(sin)->sin_port = lwip_htons((port)); \
|
||||
inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \
|
||||
(void) memset((void*)(sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
|
||||
|
||||
|
||||
#define NET_IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
|
||||
IP4ADDR_PORT_TO_SOCKADDR(( struct sockaddr_in*)( void*)(sockaddr), ipaddr, port)
|
||||
|
||||
|
||||
#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \
|
||||
inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \
|
||||
(port) = lwip_ntohs((sin)->sin_port); }while(0)
|
||||
|
||||
#define NET_SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \
|
||||
SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port)
|
||||
|
||||
|
||||
|
||||
#define NET_IP_ADDR_CMP ip_addr_cmp
|
||||
#define NET_IP_ADDR_ISANY_VAL ip_addr_isany_val
|
||||
#define NET_IP_ADDR_COPY ip_addr_copy
|
||||
#define NET_HTONL htonl
|
||||
#define NET_NTOHL ntohl
|
||||
#define NET_HTONS htons
|
||||
#define NET_NTOHS ntohs
|
||||
#define NET_NTOA_R ipaddr_ntoa_r
|
||||
#define NET_NTOA ipaddr_ntoa
|
||||
#define NET_ATON ip4addr_aton
|
||||
#define NET_ATON_R ipaddr_addr
|
||||
#define NET_IPADDR4_INIT(u32val) { u32val }
|
||||
#define NET_IPADDR4_INIT_BYTES(a,b,c,d) NET_IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
|
||||
|
||||
|
||||
#else /* NET_USE_LWIP_DEFINTIONS */
|
||||
|
||||
|
||||
#define NET_IP_ADDR_CMP(addr1, addr2) ((addr1)->addr == (addr2)->addr)
|
||||
#define NET_IP_ADDR_COPY(dest, src) ((dest).addr = (src).addr)
|
||||
/** Safely copy one IP address to another (src may be NULL) */
|
||||
#define NET_IP_ADDR_SET(dest, src) ((dest)->addr = \
|
||||
((src) == NULL ? 0 : \
|
||||
(src)->addr))
|
||||
/** Set complete address to zero */
|
||||
#define NET_IP_ADDR_SET_ZERO(ipaddr) ((ipaddr)->addr = 0U)
|
||||
#define NET_IP_ADDR_ISANY_VAL(addr1) ((addr1).addr == 0U)
|
||||
|
||||
#define NET_SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) do { \
|
||||
(ipaddr)->addr = (sockaddr)->sin_addr.s_addr;\
|
||||
(port) = NET_NTOHS((sockaddr)->sin_port); }while(0)
|
||||
|
||||
#define NET_IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \
|
||||
(sin)->sin_len = (uint8_t) sizeof(net_sockaddr_in_t); \
|
||||
(sin)->sin_family = NET_AF_INET; \
|
||||
(sin)->sin_port = NET_HTONS((port)); \
|
||||
(sin)->sin_addr.s_addr = (ipaddr)->addr;\
|
||||
memset((void*)(sin)->sin_zero, 0, NET_SIN_ZERO_LEN); }while(0)
|
||||
|
||||
#define NET_IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \
|
||||
NET_IP4ADDR_PORT_TO_SOCKADDR(( net_sockaddr_in_t*)( void*)(sockaddr), ipaddr, port)
|
||||
|
||||
|
||||
#define NET_HTONL(A) ((((uint32_t)(A) & 0xff000000U) >> 24) | \
|
||||
(((uint32_t)(A) & 0x00ff0000U) >> 8) | \
|
||||
(((uint32_t)(A) & 0x0000ff00U) << 8) | \
|
||||
(((uint32_t)(A) & 0x000000ffU) << 24))
|
||||
|
||||
#define NET_NTOHL NET_HTONL
|
||||
|
||||
#define NET_HTONS(A) ((((uint16_t)(A) & 0xff00U) >> 8U) | \
|
||||
(((uint16_t)(A) & 0x00ffU) << 8U))
|
||||
#define NET_NTOHS NET_HTONS
|
||||
|
||||
|
||||
#define NET_NTOA net_ntoa
|
||||
#define NET_NTOA_R net_ntoa_r
|
||||
#define NET_ATON net_aton
|
||||
#define NET_ATON_R net_aton_r
|
||||
|
||||
|
||||
#define NET_NULL_IP_ADDR 0U
|
||||
|
||||
#define NET_PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
|
||||
(((x) & 0x0000ff00UL) << 8) | \
|
||||
(((x) & 0x00ff0000UL) >> 8) | \
|
||||
(((x) & 0xff000000UL) >> 24))
|
||||
|
||||
|
||||
#define NET_ASLWIP_MAKEU32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
|
||||
((uint32_t)((b) & 0xff) << 16) | \
|
||||
((uint32_t)((c) & 0xff) << 8) | \
|
||||
(uint32_t)((d) & 0xff))
|
||||
|
||||
|
||||
#define NET_IPADDR4_INIT(u32val) { u32val }
|
||||
#define NET_IPADDR4_INIT_BYTES(a,b,c,d) NET_IPADDR4_INIT(NET_PP_HTONL(NET_ASLWIP_MAKEU32(a,b,c,d)))
|
||||
|
||||
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
|
||||
#define inet_addr_to_ip4addr(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 ip4_addr_t are an u32_t effectively! */
|
||||
#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*\
|
||||
)&((source_inaddr)->s_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)
|
||||
|
||||
/* generic socket address structure to support IPV6 and IPV4 */
|
||||
/* size is 16 bytes and is aligned on LWIP definition to ease integration */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t addr;
|
||||
} net_ip4_addr_t;
|
||||
|
||||
typedef struct net_in_addr
|
||||
{
|
||||
uint32_t s_addr;
|
||||
} net_in_addr_t;
|
||||
|
||||
/* Only IPv4 is managed */
|
||||
typedef net_ip4_addr_t net_ip_addr_t;
|
||||
|
||||
typedef struct net_sockaddr
|
||||
{
|
||||
uint8_t sa_len;
|
||||
uint8_t sa_family;
|
||||
char_t sa_data[14];
|
||||
} net_sockaddr_t;
|
||||
|
||||
/* IPV4 address , with 8 stuffing byte */
|
||||
#define NET_SIN_ZERO_LEN 8
|
||||
typedef struct net_sockaddr_in
|
||||
{
|
||||
uint8_t sin_len;
|
||||
uint8_t sin_family;
|
||||
uint16_t sin_port;
|
||||
net_in_addr_t sin_addr;
|
||||
char_t sin_zero[NET_SIN_ZERO_LEN];
|
||||
} net_sockaddr_in_t;
|
||||
|
||||
char_t *net_ntoa(const net_ip_addr_t *addr);
|
||||
char_t *net_ntoa_r(const net_ip_addr_t *addr, char_t *buf, int32_t buflen);
|
||||
int32_t net_aton_r(const char_t *cp);
|
||||
int32_t net_aton(const char_t *cp, net_ip_addr_t *addr);
|
||||
|
||||
|
||||
#endif /* NET_USE_LWIP_DEFINTIONS */
|
||||
|
||||
|
||||
#define S_ADDR(a) (a).s_addr
|
||||
|
||||
typedef net_sockaddr_in_t sockaddr_in_t;
|
||||
#if NET_USE_IPV6
|
||||
typedef net_sockaddr_in6_t sockaddr_in6_t;
|
||||
#endif /* NET_USE_IPV6 */
|
||||
typedef net_sockaddr_t sockaddr_t;
|
||||
|
||||
/** MAC address. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mac[6];
|
||||
} macaddr_t;
|
||||
|
||||
|
||||
|
||||
void net_set_port(net_sockaddr_t *addr, uint16_t port);
|
||||
uint16_t net_get_port(net_sockaddr_t *addr);
|
||||
net_ip_addr_t net_get_ip_addr(net_sockaddr_t *addr);
|
||||
typedef struct net_if_handle_s net_if_handle_t;
|
||||
#endif /* NET_ADDRESS_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_buffers.h
|
||||
* @author MCD Application Team
|
||||
* @brief Defines buffer allocation functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef NET_BUFFERS_H
|
||||
#define NET_BUFFERS_H
|
||||
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
#define NET_BUF_ALLOC(n) (net_buf_t*)pbuf_alloc(PBUF_RAW, n, PBUF_POOL)
|
||||
#define NET_BUF_REF_ALLOC() (net_buf_t*)pbuf_alloc(PBUF_RAW, 0, PBUF_REF);
|
||||
#define NET_BUF_FREE(p) pbuf_free((struct pbuf*)p);
|
||||
#define NET_BUF_REF(p) pbuf_ref((struct pbuf*)p);
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
#endif /* NET_BUFFERS_H */
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_cellular.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network Cellular class.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef NET_CELLULAR_H
|
||||
#define NET_CELLULAR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef NET_CELLULAR_CREDENTIAL_V2
|
||||
|
||||
/* SIM socket type */
|
||||
#define NET_SIM_SLOT_MODEM_SOCKET 0 /* Modem Socket SIM Slot */
|
||||
#define NET_SIM_SLOT_MODEM_EMBEDDED_SIM 1 /* Modem Embedded SIM Slot */
|
||||
#define NET_CELLULAR_MAX_SUPPORTED_SLOT 2 /* Number max of supported SIM slot */
|
||||
#define NET_CELLULAR_DEFAULT_SIM_SLOT NET_SIM_SLOT_MODEM_SOCKET /* Default SIM Slot */
|
||||
|
||||
typedef char_t net_sim_slot_type_t ;
|
||||
|
||||
/* SIM Slot parameters */
|
||||
typedef struct net_cellular_sim_slot_s
|
||||
{
|
||||
net_sim_slot_type_t sim_slot_type; /* sim slot type */
|
||||
char_t *apn; /* APN (string) */
|
||||
char_t cid; /* CID (1-9) */
|
||||
char_t *username; /* username: empty string => no username */
|
||||
char_t *password; /* password (used only is username is defined) */
|
||||
} net_cellular_sim_slot_t;
|
||||
|
||||
/* Credential configuration */
|
||||
typedef struct net_cellular_credentials_s
|
||||
{
|
||||
uint8_t sim_socket_nb; /* number of sim slot used */
|
||||
net_cellular_sim_slot_t sim_slot[NET_CELLULAR_MAX_SUPPORTED_SLOT]; /* sim slot parameters */
|
||||
} net_cellular_credentials_t;
|
||||
|
||||
#else /*NET_CELLULAR_CREDENTIAL_V2 */
|
||||
|
||||
/* Credential configuration */
|
||||
typedef struct net_cellular_credentials_s
|
||||
{
|
||||
const char_t *apn;
|
||||
const char_t *username;
|
||||
const char_t *password;
|
||||
bool_t use_internal_sim;
|
||||
} net_cellular_credentials_t;
|
||||
|
||||
#endif /* NET_CELLULAR_CREDENTIAL_V2 */
|
||||
|
||||
|
||||
/* Network radio results */
|
||||
typedef struct net_cellular_radio_results_s
|
||||
{
|
||||
int8_t signal_level_db;
|
||||
} net_cellular_radio_results_t;
|
||||
|
||||
/* network extension for Cellular class interface */
|
||||
int32_t net_cellular_set_credentials(net_if_handle_t *pnetif, const net_cellular_credentials_t *credentials);
|
||||
int32_t net_cellular_get_radio_results(net_if_handle_t *pnetif, net_cellular_radio_results_t *results);
|
||||
/* Declaration of cellular network interface constructor */
|
||||
int32_t cellular_net_driver(net_if_handle_t *pnetif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CELLULAR_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_class_extension.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network class extensions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_CLASS_EXTENSION_H
|
||||
#define NET_CLASS_EXTENSION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct net_if_wifi_class_extension_s
|
||||
{
|
||||
int32_t (*scan)(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
|
||||
int32_t (*get_scan_results)(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
|
||||
int32_t (*set_credentials)(const net_wifi_credentials_t *cred);
|
||||
int32_t (*get_system_info)(const net_wifi_system_info_t info, void *data);
|
||||
int32_t (*set_param)(const net_wifi_param_t info, void *data);
|
||||
const net_wifi_credentials_t *credentials;
|
||||
net_wifi_mode_t mode;
|
||||
/* Acces Point parameter */
|
||||
uint8_t access_channel;
|
||||
uint8_t max_connections;
|
||||
bool AP_hidden;
|
||||
|
||||
const net_wifi_powersave_t *powersave;
|
||||
void *ifp; /* Interface STA or AP handler */
|
||||
} net_if_wifi_class_extension_t;
|
||||
|
||||
|
||||
typedef struct net_if_ethernet_class_extension_s
|
||||
{
|
||||
int32_t (*version)(void);
|
||||
} net_if_ethernet_class_extension_t;
|
||||
|
||||
typedef struct net_if_cellular_class_extension_s
|
||||
{
|
||||
int32_t (*get_radio_results)(net_cellular_radio_results_t *results);
|
||||
const net_cellular_credentials_t *credentials;
|
||||
} net_if_cellular_class_extension_t;
|
||||
|
||||
typedef struct net_if_custom_class_extension_s
|
||||
{
|
||||
int32_t (*version)(void);
|
||||
} net_if_custom_class_extension_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* NET_CLASS_EXTENSION_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Configures the network socket APIs.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_CONF_TEMPLATE_H
|
||||
#define NET_CONF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
|
||||
/*cstat -MISRAC2012-Dir-4.4 */
|
||||
|
||||
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include <stdio.h>
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
|
||||
/* Please uncomment if you want socket address defintion from LWIP include file rather than local one */
|
||||
/* This is recommended if network interface uses LWIP to save some code size. This is required if */
|
||||
/* project uses IPv6 */
|
||||
|
||||
/* #define NET_USE_LWIP_DEFINITIONS */
|
||||
|
||||
/* Experimental : Please uncomment if you want to use only control part of network library */
|
||||
/* net_socket api are directly redifined to LWIP ,NET_MBEDTLS_HOST_SUPPORT is not supported with */
|
||||
/* this mode, dedicated to save memory (4K code) */
|
||||
/* #define NET_BYPASS_NET_SOCKET */
|
||||
|
||||
|
||||
/* Please uncomment if secure socket have to be supported and is implemented thanks to MBEDTLS running on MCU */
|
||||
/* #define NET_MBEDTLS_HOST_SUPPORT */
|
||||
|
||||
/* Please uncomment if device supports internally Secure TCP connection */
|
||||
/* #define NET_MBEDTLS_DEVICE_SUPPORT */
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "cmsis_os.h"
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* when using LWIP , size of hostname */
|
||||
#define NET_IP_HOSTNAME_MAX_LEN 32
|
||||
|
||||
#ifndef NET_USE_IPV6
|
||||
#define NET_USE_IPV6 0
|
||||
#endif /* NET_USE_IPV6 */
|
||||
|
||||
#if NET_USE_IPV6 && !defined(NET_USE_LWIP_DEFINTIONS)
|
||||
#error "NET IPV6 required to define NET_USE_LWIP_DEFINTIONS"
|
||||
#endif /* NET_USE_IPV6 */
|
||||
|
||||
|
||||
/* MbedTLS configuration */
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
|
||||
|
||||
#if !defined NET_MBEDTLS_DEBUG_LEVEL
|
||||
#define NET_MBEDTLS_DEBUG_LEVEL 1
|
||||
#endif /* NET_MBEDTLS_DEBUG_LEVEL */
|
||||
|
||||
#if !defined NET_MBEDTLS_CONNECT_TIMEOUT
|
||||
#define NET_MBEDTLS_CONNECT_TIMEOUT 10000U
|
||||
#endif /* NET_MBEDTLS_CONNECT_TIMEOUT */
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#define MBEDTLS_CONFIG_FILE "mbedtls/config.h"
|
||||
#endif /* MBEDTLS_CONFIG_FILE */
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
|
||||
#if !defined(NET_MAX_SOCKETS_NBR)
|
||||
#define NET_MAX_SOCKETS_NBR 5
|
||||
#endif /* NET_MAX_SOCKETS_NBR */
|
||||
|
||||
#define NET_IF_NAME_LEN 128
|
||||
#define NET_DEVICE_NAME_LEN 64
|
||||
#define NET_DEVICE_ID_LEN 64
|
||||
#define NET_DEVICE_VER_LEN 64
|
||||
|
||||
|
||||
#define NET_SOCK_DEFAULT_RECEIVE_TO 60000
|
||||
#define NET_SOCK_DEFAULT_SEND_TO 60000
|
||||
#define NET_UDP_MAX_SEND_BLOCK_TO 1024
|
||||
|
||||
#if !defined(NET_USE_DEFAULT_INTERFACE)
|
||||
#define NET_USE_DEFAULT_INTERFACE 1
|
||||
#endif /* NET_USE_DEFAULT_INTERFACE */
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
|
||||
#if ( osCMSIS < 0x20000U)
|
||||
#define RTOS_SUSPEND if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { (void) vTaskSuspendAll(); }
|
||||
#define RTOS_RESUME if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { (void) xTaskResumeAll(); }
|
||||
#else
|
||||
#define RTOS_SUSPEND (void) osKernelLock()
|
||||
#define RTOS_RESUME (void) osKernelUnlock()
|
||||
#endif /* osCMSIS */
|
||||
|
||||
#else
|
||||
#define RTOS_SUSPEND
|
||||
#define RTOS_RESUME
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
#if !defined(NET_DBG_INFO)
|
||||
#define NET_DBG_INFO(...)
|
||||
/*
|
||||
#define NET_DBG_INFO(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf(__VA_ARGS__); \
|
||||
RTOS_RESUME; \
|
||||
} while (0)
|
||||
*/
|
||||
#endif /* NET_DBG_INFO */
|
||||
|
||||
#if !defined(NET_DBG_ERROR)
|
||||
#define NET_DBG_ERROR(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf("\nERROR: %s:%d ",__FILE__,__LINE__) ;\
|
||||
(void)printf(__VA_ARGS__);\
|
||||
(void)printf("\n"); \
|
||||
RTOS_RESUME; \
|
||||
} while (false)
|
||||
#endif /* NET_DBG_ERROR */
|
||||
|
||||
#if !defined(NET_DBG_PRINT)
|
||||
#define NET_DBG_PRINT(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void)printf("%s:%d ",__FILE__,__LINE__) ;\
|
||||
(void)printf(__VA_ARGS__);\
|
||||
(void)printf("\n"); \
|
||||
RTOS_RESUME; \
|
||||
} while (false)
|
||||
#endif /* NET_DBG_PRINT */
|
||||
|
||||
#if !defined(NET_ASSERT)
|
||||
#define NET_ASSERT(test,...) do { if (!(test)) {\
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf("Assert Failed %s %d :",__FILE__,__LINE__);\
|
||||
(void) printf(__VA_ARGS__);\
|
||||
RTOS_RESUME; \
|
||||
while(true) {}; }\
|
||||
} while (false)
|
||||
#endif /* NET_ASSERT */
|
||||
|
||||
#if !defined(NET_PRINT)
|
||||
#define NET_PRINT(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf(__VA_ARGS__);\
|
||||
(void) printf("\n"); \
|
||||
RTOS_RESUME; \
|
||||
} while (false)
|
||||
#endif /* NET_PRINT */
|
||||
|
||||
#if !defined(NET_PRINT_WO_CR)
|
||||
#define NET_PRINT_WO_CR(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf(__VA_ARGS__);\
|
||||
RTOS_RESUME; \
|
||||
} while (false)
|
||||
#endif /* NET_PRINT_WO_CR */
|
||||
|
||||
#if !defined(NET_WARNING)
|
||||
#define NET_WARNING(...) do { \
|
||||
RTOS_SUSPEND; \
|
||||
(void) printf("Warning %s:%d ",__FILE__,__LINE__) ;\
|
||||
(void) printf(__VA_ARGS__);\
|
||||
(void) printf("\n"); \
|
||||
RTOS_RESUME; \
|
||||
} while (false)
|
||||
#endif /* NET_WARNING */
|
||||
|
||||
|
||||
|
||||
#ifndef NET_PERF_MAXTHREAD
|
||||
#define NET_PERF_MAXTHREAD 10U
|
||||
#endif /* NET_PERF_MAXTHREAD */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_TEMPLATE_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,312 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_connect.h
|
||||
* @author MCD Application Team
|
||||
* @brief Provides the network interface APIs.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONNECT_H
|
||||
#define NET_CONNECT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "net_types.h"
|
||||
#include "net_conf.h"
|
||||
#include "net_mem.h"
|
||||
#include "net_perf.h"
|
||||
#include "net_address.h"
|
||||
#include "net_errors.h"
|
||||
#include "net_wifi.h"
|
||||
#include "net_cellular.h"
|
||||
|
||||
/* flags */
|
||||
|
||||
#define NET_ETHERNET_FLAG_DEFAULT_IF 1
|
||||
|
||||
|
||||
|
||||
/* Socket family */
|
||||
#define NET_AF_INET 2
|
||||
#define NET_AF_UNSPEC 0
|
||||
#define NET_AF_INET6 10
|
||||
#define NET_IPADDR_ANY ((u32_t)0x00000000UL)
|
||||
|
||||
/* Socket types */
|
||||
#define NET_SOCK_STREAM 1
|
||||
#define NET_SOCK_DGRAM 2
|
||||
#define NET_SOCK_RAW 3
|
||||
|
||||
/* Socket protocol */
|
||||
#define NET_IPPROTO_TCP 6
|
||||
#define NET_IPPROTO_ICMP 1
|
||||
#define NET_IPPROTO_UDP 17
|
||||
#define NET_IPPROTO_TCP_TLS 36
|
||||
|
||||
|
||||
#define NET_SHUTDOWN_R 0
|
||||
#define NET_SHUTDOWN_W 1
|
||||
#define NET_SHUTDOWN_RW 2
|
||||
|
||||
#define NET_SOL_SOCKET 0xfff
|
||||
/** @defgroup Socket
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
||||
NET_SO_RCVTIMEO = 0x1006,/**< to set received timeout in ms, option type is an integer value */
|
||||
NET_SO_SNDTIMEO = 0x1005,/**< to set send timeout in ms, option type is an integer value */
|
||||
NET_SO_BINDTODEVICE = 3,/**< to map socket to a specific network interface, no implemented so far , normal bind should make the job */
|
||||
NET_SO_BLOCKING = 4,/**< to set blocking or none blocking mode, option type is an boolean, true means blocking (default value), false non blocking */
|
||||
NET_SO_SECURE = 5,/**< to set a socket a a secure socket, no option argument, setsock option must be done before any connection */
|
||||
NET_SO_TLS_CA_CERT = 7,/**< to pass root ca to secure socket, option type is a pointer to a string , certificat is pem format string */
|
||||
NET_SO_TLS_CA_CRL = 8,/**< to pass revocation certificat list, this is not supported */
|
||||
NET_SO_TLS_DEV_KEY = 9,/**< to pass device key to secure socket, option type is a pointer to a string , key is pem format string */
|
||||
NET_SO_TLS_DEV_CERT = 10,/**< to pass device certificat to secure socket, option type is a pointer to a string , certificat is pem format string */
|
||||
NET_SO_TLS_SERVER_VERIFICATION = 11,/**< to define verification mode for secure socket,option type is a boolean, True to check server name */
|
||||
NET_SO_TLS_SERVER_NAME = 12,/**< to define server name to check again,option type is a point to a null terminated string */
|
||||
NET_SO_TLS_PASSWORD = 13,/**< to define passwd (if any) used to encrypt the device key, option type is pointer to a null terminated string */
|
||||
NET_SO_TLS_CERT_PROF = 14,/**< to set the X509 security profile , option type is pointer to mbedtls_x509_crt_profile structure */
|
||||
}
|
||||
net_socketoption_t;
|
||||
|
||||
|
||||
/** @defgroup Socket
|
||||
* @}
|
||||
*/
|
||||
#define NET_MSG_DONTWAIT 0x08U /* Nonblocking i/o for this operation only */
|
||||
|
||||
typedef struct pbuf net_buf_t;
|
||||
|
||||
|
||||
/**
|
||||
* TOPPP transition are requested by application. "ING" state are transitioning state, meaning that application has required a transition and the transition is ongoing. "ED" states are stable state.
|
||||
*/
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NET_EVENT_STATE_CHANGE,
|
||||
NET_EVENT,
|
||||
NET_EVENT_WIFI,
|
||||
} net_evt_t;
|
||||
|
||||
|
||||
/** @defgroup State
|
||||
* @{
|
||||
* State transition are requested by application. "ING" state are transitioning state, meaning that application has required a transition and the transition is ongoing. "ED" states are stable state.
|
||||
|
||||
*/
|
||||
|
||||
typedef enum enum_state
|
||||
{
|
||||
|
||||
NET_STATE_DEINITIALIZED = 0,
|
||||
NET_STATE_INITIALIZED, /**< basic memory allocation for driver and network interface have been performed */
|
||||
|
||||
NET_STATE_STARTING, /**< Network interface interface is starting, application waits for event from network interface to signal transition is performed to NET_STATE_STARTED */
|
||||
NET_STATE_READY, /**< Network interface interface is started, MAC address can be retrieved */
|
||||
|
||||
NET_STATE_CONNECTING,/**< Network interface interface is connecting */
|
||||
NET_STATE_CONNECTED,/**< Network interface interface is connected, IP address can be retrieved , socket operation can be performed*/
|
||||
|
||||
NET_STATE_STOPPING, /**< Network interface interface is stopping */
|
||||
|
||||
NET_STATE_DISCONNECTING, /**< Network interface interface is disconnecting */
|
||||
NET_STATE_CONNECTION_LOST, /**< Network interface connection is lost , this can be a transient state , it can return to connected state without application specific action*/
|
||||
} net_state_t;
|
||||
|
||||
|
||||
/** @defgroup State
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** Network state events. */
|
||||
typedef enum
|
||||
{
|
||||
NET_EVENT_CMD_INIT = 0,
|
||||
NET_EVENT_CMD_START,
|
||||
NET_EVENT_CMD_CONNECT,
|
||||
NET_EVENT_CMD_DISCONNECT,
|
||||
NET_EVENT_CMD_STOP,
|
||||
NET_EVENT_CMD_DEINIT,
|
||||
NET_EVENT_INTERFACE_INITIALIZED,
|
||||
NET_EVENT_INTERFACE_READY,
|
||||
NET_EVENT_LINK_UP,
|
||||
NET_EVENT_LINK_DOWN,
|
||||
NET_EVENT_IPADDR,
|
||||
} net_state_event_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/** Network events. */
|
||||
typedef enum
|
||||
{
|
||||
NET_EVENT_POWERSAVE_ENABLED = 0,
|
||||
} net_event_t;
|
||||
|
||||
|
||||
|
||||
typedef struct net_if_drv_s net_if_drv_t;
|
||||
typedef struct net_ip_if_s net_ip_if_t;
|
||||
|
||||
typedef void(* net_if_notify_func)(void *context, uint32_t event_class, uint32_t event_id, void *event_data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
net_if_notify_func callback;
|
||||
void *context;
|
||||
} net_event_handler_t;
|
||||
|
||||
struct net_if_handle_s
|
||||
{
|
||||
struct net_if_handle_s *next;
|
||||
net_ip_addr_t ipaddr;
|
||||
net_ip_addr_t gateway;
|
||||
net_ip_addr_t netmask;
|
||||
net_ip_addr_t static_ipaddr;
|
||||
net_ip_addr_t static_gateway;
|
||||
net_ip_addr_t static_netmask;
|
||||
net_ip_addr_t static_dnserver;
|
||||
bool_t dhcp_mode;
|
||||
bool_t dhcp_inform_flag;
|
||||
bool_t dhcp_enabled;
|
||||
bool_t dhcp_release_on_link_lost;
|
||||
char_t DeviceName[NET_DEVICE_NAME_LEN];
|
||||
char_t DeviceID [NET_DEVICE_ID_LEN];
|
||||
char_t DeviceVer [NET_DEVICE_VER_LEN];
|
||||
macaddr_t macaddr;
|
||||
net_state_t state;
|
||||
net_if_drv_t *pdrv;
|
||||
struct netif *netif;
|
||||
const net_event_handler_t *event_handler;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef int32_t(* net_if_driver_init_func)(net_if_handle_t *pnetif);
|
||||
|
||||
|
||||
|
||||
/* network state control functions */
|
||||
int32_t net_if_init(net_if_handle_t *pnetif, net_if_driver_init_func driver_init,
|
||||
const net_event_handler_t *event_handler);
|
||||
int32_t net_if_deinit(net_if_handle_t *pnetif);
|
||||
|
||||
int32_t net_if_start(net_if_handle_t *pnetif);
|
||||
int32_t net_if_stop(net_if_handle_t *pnetif);
|
||||
|
||||
/* network io data receive process, called in main loop */
|
||||
int32_t net_if_yield(net_if_handle_t *pnetif, uint32_t timeout);
|
||||
|
||||
int32_t net_if_connect(net_if_handle_t *pnetif);
|
||||
int32_t net_if_disconnect(net_if_handle_t *pnetif);
|
||||
|
||||
|
||||
int32_t net_if_getState(net_if_handle_t *pnetif, net_state_t *state);
|
||||
int32_t net_if_wait_state(net_if_handle_t *pnetif, net_state_t state, uint32_t timeout);
|
||||
|
||||
/* network event management */
|
||||
void net_if_notify(net_if_handle_t *pnetif, net_evt_t event_class, uint32_t event_if, void *event_data);
|
||||
|
||||
/* network parameter and status functions */
|
||||
int32_t net_if_set_dhcp_mode(net_if_handle_t *pnetif, bool_t mode);
|
||||
int32_t net_if_set_ipaddr(net_if_handle_t *pnetif, net_ip_addr_t ipaddr, net_ip_addr_t gateway, net_ip_addr_t netmask);
|
||||
int32_t net_if_get_mac_address(net_if_handle_t *pnetif, macaddr_t *mac);
|
||||
int32_t net_if_get_ip_address(net_if_handle_t *pnetif, net_ip_addr_t *ip);
|
||||
int32_t net_if_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
|
||||
int32_t net_if_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t reponse[]);
|
||||
|
||||
/* networtk interface power management */
|
||||
int32_t net_if_powersave_enable(net_if_handle_t *pnetif);
|
||||
int32_t net_if_powersave_disable(net_if_handle_t *pnetif);
|
||||
|
||||
#if 0
|
||||
int32_t net_if_sleep(net_if_handle_t *pnetif);
|
||||
int32_t net_if_wakeup(net_if_handle_t *pnetif);
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
|
||||
/* network socket API */
|
||||
#ifdef NET_BYPASS_NET_SOCKET
|
||||
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/etharp.h"
|
||||
/*cstat +MISRAC* +DEFINE-* -CERT-EXP19* */
|
||||
|
||||
#define net_socket lwip_socket
|
||||
#define net_bind lwip_bind
|
||||
#define net_accept lwip_accept
|
||||
#define net_closesocket lwip_close
|
||||
#define net_shutdown lwip_shutdown
|
||||
#define net_setsockopt lwip_setsockopt
|
||||
#define net_getsockopt lwip_getsockopt
|
||||
#define net_connect lwip_connect
|
||||
#define net_listen lwip_listen
|
||||
#define net_send lwip_send
|
||||
#define net_recv lwip_recv
|
||||
#define net_sendto lwip_sendto
|
||||
#define net_recvfrom lwip_recvfrom
|
||||
#define net_getsockname lwip_getsockname
|
||||
#define net_getpeername lwip_getpeeername
|
||||
|
||||
#else
|
||||
|
||||
int32_t net_socket(int32_t Domain, int32_t Type, int32_t Protocol);
|
||||
int32_t net_bind(int32_t sock, net_sockaddr_t *addr, uint32_t addrlen);
|
||||
int32_t net_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
|
||||
int32_t net_closesocket(int32_t sock);
|
||||
int32_t net_shutdown(int32_t sock, int32_t mode);
|
||||
int32_t net_setsockopt(int32_t sock, int32_t level, net_socketoption_t optname, const void *optvalue, uint32_t optlen);
|
||||
int32_t net_getsockopt(int32_t sock, int32_t level, net_socketoption_t optname, void *optvalue, uint32_t *optlen);
|
||||
int32_t net_connect(int32_t sock, net_sockaddr_t *addr, uint32_t addrlen);
|
||||
int32_t net_listen(int32_t sock, int32_t backlog);
|
||||
int32_t net_send(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags);
|
||||
int32_t net_recv(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags);
|
||||
int32_t net_sendto(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags, net_sockaddr_t *to, uint32_t tolen);
|
||||
int32_t net_recvfrom(int32_t sock, uint8_t *buf, uint32_t len, int32_t flags, net_sockaddr_t *from, uint32_t *fromlen);
|
||||
int32_t net_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
int32_t net_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
|
||||
#endif /* NET_BYPASS_NET_SOCKET */
|
||||
|
||||
extern const int32_t net_tls_sizeof_suite_structure;
|
||||
extern const void *net_tls_user_suite0;
|
||||
extern const void *net_tls_user_suite1;
|
||||
extern const void *net_tls_user_suite2;
|
||||
extern const void *net_tls_user_suite3;
|
||||
extern const void *net_tls_user_suite4;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* NET_CONNECT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_core.h
|
||||
* @author MCD Application Team
|
||||
* @brief Provides the network interface driver APIs.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_CORE_H
|
||||
#define NET_CORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "net_state.h"
|
||||
#include "net_wifi.h"
|
||||
#include "net_class_extension.h"
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
/* #include "lwip/err.h" */
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t icmp_ping(net_if_handle_t *netif, net_sockaddr_t *addr, int32_t count, int32_t timeout, int32_t response[]);
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
|
||||
|
||||
|
||||
void net_init_locks(void);
|
||||
void net_destroy_locks(void);
|
||||
|
||||
void net_lock(int32_t idx, uint32_t to);
|
||||
void net_unlock(int32_t idx);
|
||||
|
||||
void net_lock_nochk(int32_t idx, uint32_t to);
|
||||
void net_unlock_nochk(int32_t idx);
|
||||
|
||||
/* OS */
|
||||
#define NET_OS_WAIT_FOREVER 0xffffffffU
|
||||
|
||||
|
||||
#define NET_LOCK_SOCKET_ARRAY NET_MAX_SOCKETS_NBR
|
||||
#define NET_LOCK_NETIF_LIST NET_MAX_SOCKETS_NBR+1
|
||||
#define NET_LOCK_STATE_EVENT NET_MAX_SOCKETS_NBR+2
|
||||
|
||||
#define NET_LOCK_NUMBER (NET_LOCK_STATE_EVENT+1)
|
||||
|
||||
#define LOCK_SOCK(s) net_lock((int32_t)s,NET_OS_WAIT_FOREVER)
|
||||
#define UNLOCK_SOCK(s) net_unlock(s)
|
||||
|
||||
#define LOCK_SOCK_ARRAY() net_lock(NET_LOCK_SOCKET_ARRAY,NET_OS_WAIT_FOREVER)
|
||||
#define UNLOCK_SOCK_ARRAY() net_unlock(NET_LOCK_SOCKET_ARRAY )
|
||||
|
||||
#define LOCK_NETIF_LIST() net_lock(NET_LOCK_NETIF_LIST,NET_OS_WAIT_FOREVER )
|
||||
#define UNLOCK_NETIF_LIST() net_unlock(NET_LOCK_NETIF_LIST )
|
||||
|
||||
#define WAIT_STATE_CHANGE(to) net_lock_nochk(NET_LOCK_STATE_EVENT,to )
|
||||
#define SIGNAL_STATE_CHANGE() net_unlock_nochk(NET_LOCK_STATE_EVENT )
|
||||
|
||||
#else
|
||||
|
||||
#define LOCK_SOCK(s)
|
||||
#define UNLOCK_SOCK(s)
|
||||
#define LOCK_SOCK_ARRAY()
|
||||
#define UNLOCK_SOCK_ARRAY()
|
||||
#define LOCK_NETIF_LIST()
|
||||
#define UNLOCK_NETIF_LIST()
|
||||
#define WAIT_STATE_CHANGE(to) pnetif->pdrv->if_yield(pnetif, 10)
|
||||
#define SIGNAL_STATE_CHANGE()
|
||||
|
||||
|
||||
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NET_INTERFACE_CLASS_WIFI,
|
||||
NET_INTERFACE_CLASS_CELLULAR,
|
||||
NET_INTERFACE_CLASS_ETHERNET,
|
||||
NET_INTERFACE_CLASS_CUSTOM
|
||||
}
|
||||
net_interface_class_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NET_ACCESS_SOCKET,
|
||||
NET_ACCESS_BIND,
|
||||
NET_ACCESS_LISTEN,
|
||||
NET_ACCESS_CONNECT,
|
||||
NET_ACCESS_SEND,
|
||||
NET_ACCESS_SENDTO,
|
||||
NET_ACCESS_RECV,
|
||||
NET_ACCESS_RECVFROM,
|
||||
NET_ACCESS_CLOSE,
|
||||
NET_ACCESS_SETSOCKOPT,
|
||||
}
|
||||
net_access_t;
|
||||
|
||||
struct net_if_drv_s
|
||||
{
|
||||
net_interface_class_t if_class;
|
||||
/* Interface APIs */
|
||||
int32_t (* if_init)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_deinit)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_start)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_stop)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_yield)(net_if_handle_t *pnetif, uint32_t timeout);
|
||||
int32_t (* if_connect)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_disconnect)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_powersave_enable)(net_if_handle_t *pnetif);
|
||||
int32_t (* if_powersave_disable)(net_if_handle_t *pnetif);
|
||||
void *netif;
|
||||
void *context;
|
||||
#ifndef NET_BYPASS_NET_SOCKET
|
||||
/* Socket BSD Like APIs */
|
||||
int32_t (* psocket)(int32_t domain, int32_t type, int32_t protocol);
|
||||
int32_t (* pbind)(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
int32_t (* plisten)(int32_t sock, int32_t backlog);
|
||||
int32_t (* paccept)(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
|
||||
int32_t (* pconnect)(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
int32_t (* psend)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
int32_t (* precv)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
int32_t (* psendto)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to, uint32_t tolen);
|
||||
int32_t (* precvfrom)(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from, uint32_t *flen);
|
||||
int32_t (* psetsockopt)(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
|
||||
int32_t (* pgetsockopt)(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
|
||||
int32_t (* pgetsockname)(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
int32_t (* pgetpeername)(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
int32_t (* pclose)(int32_t sock, bool Clone);
|
||||
int32_t (* pshutdown)(int32_t sock, int32_t mode);
|
||||
#endif /* NET_BYPASS_NET_SOCKET */
|
||||
/* Service */
|
||||
int32_t (* pgethostbyname)(net_if_handle_t *, net_sockaddr_t *addr, char_t *name);
|
||||
int32_t (* pping)(net_if_handle_t *, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t reponse[]);
|
||||
/* class extension */
|
||||
struct
|
||||
{
|
||||
net_if_wifi_class_extension_t *wifi;
|
||||
net_if_ethernet_class_extension_t *ethernet;
|
||||
net_if_cellular_class_extension_t *cellular;
|
||||
net_if_custom_class_extension_t *custom;
|
||||
} extension;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
net_if_handle_t *net_if_find(net_sockaddr_t *addr);
|
||||
net_if_handle_t *netif_check(net_if_handle_t *pnetif);
|
||||
|
||||
|
||||
bool net_access_control(net_if_handle_t *pnetif, net_access_t access, int32_t *l);
|
||||
|
||||
typedef void (*sock_notify_func)(int32_t, int32_t, const uint8_t *, uint32_t);
|
||||
|
||||
typedef struct net_tls_data net_tls_data_t;
|
||||
typedef int32_t net_ulsock_t;
|
||||
|
||||
typedef enum { SOCKET_NOT_ALIVE = 0, SOCKET_ALLOCATED, SOCKET_CONNECTED } socket_state_t;
|
||||
|
||||
|
||||
typedef struct net_socket_s
|
||||
{
|
||||
net_if_handle_t *pnetif;
|
||||
net_ulsock_t ulsocket;
|
||||
socket_state_t status;
|
||||
int32_t domain;
|
||||
int32_t type;
|
||||
int32_t protocol;
|
||||
bool cloneserver;
|
||||
bool connected;
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
bool is_secure;
|
||||
net_tls_data_t *tlsData;
|
||||
bool tls_started;
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
int32_t read_timeout;
|
||||
int32_t write_timeout;
|
||||
bool blocking;
|
||||
int32_t idx;
|
||||
} net_socket_t;
|
||||
|
||||
|
||||
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "net_mbedtls.h"
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* NET_CORE_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_errors.h
|
||||
* @author MCD Application Team
|
||||
* @brief Defines the network interface error codes
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_ERRORS_H
|
||||
#define NET_ERRORS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NET_OK 0 /*!< no error */
|
||||
#define NET_TIMEOUT -1 /*!< Timeout rearched during a blocking operation. */
|
||||
#define NET_ERROR_WOULD_BLOCK -2 /*!< no data is available but call is non-blocking */
|
||||
#define NET_ERROR_UNSUPPORTED -3 /*!< unsupported functionality */
|
||||
#define NET_ERROR_PARAMETER -4 /*!< invalid parameter/configuration */
|
||||
#define NET_ERROR_NO_CONNECTION -5 /*!< not connected to a network */
|
||||
#define NET_ERROR_INVALID_SOCKET -6 /*!< socket invalid */
|
||||
#define NET_ERROR_NO_ADDRESS -7 /*!< IP address is not known */
|
||||
#define NET_ERROR_NO_MEMORY -8 /*!< memory resource not available */
|
||||
#define NET_ERROR_NO_SSID -9 /*!< ssid not found */
|
||||
#define NET_ERROR_DNS_FAILURE -10 /*!< DNS failed to complete successfully */
|
||||
#define NET_ERROR_DHCP_FAILURE -11 /*!< DHCP failed to complete successfully */
|
||||
#define NET_ERROR_AUTH_FAILURE -12 /*!< connection to access point failed */
|
||||
#define NET_ERROR_DEVICE_ERROR -13 /*!< failure interfacing with the network processor */
|
||||
#define NET_ERROR_IN_PROGRESS -14 /*!< operation (eg connect) in progress */
|
||||
#define NET_ERROR_ALREADY -15 /*!< operation (eg connect) already in progress */
|
||||
#define NET_ERROR_IS_CONNECTED -16 /*!< socket is already connected */
|
||||
#define NET_ERROR_INTERFACE_FAILURE -17 /*!< an error in interface level */
|
||||
#define NET_ERROR_DATA -18 /*!< an error in interface level */
|
||||
#define NET_ERROR_SOCKET_FAILURE -19 /*!< an error in interface level */
|
||||
#define NET_ERROR_OUT_OF_SOCKET -20 /*!< no more available socket , open failed */
|
||||
#define NET_ERROR_CLOSE_SOCKET -21 /*!< error while closing socket */
|
||||
#define NET_ERROR_DISCONNECTED -22 /*!< Connection dropped during the operation. */
|
||||
#define NET_ERROR_CREATE_SECURE_SOCKET -23 /*!< failed to create the secure socket */
|
||||
#define NET_ERROR_IS_NOT_SECURE -24 /*!< try to set secure option on a non secure socket */
|
||||
#define NET_ERROR_FRAMEWORK -25 /*!< should never happen */
|
||||
#define NET_ERROR_STATE_TRANSITION -26 /*!< should never happen */
|
||||
#define NET_ERROR_INVALID_STATE_TRANSITION -27 /*!< should never happen */
|
||||
#define NET_ERROR_INVALID_STATE -28 /*!< should never happen */
|
||||
#define NET_ERROR_GENERIC -29 /*!< generic error */
|
||||
#define NET_ERROR_MODULE_INITIALIZATION -30 /*!< module is not able to initialized */
|
||||
#define NET_ERROR_WIFI_CANT_JOIN -31 /*!< wifi module is not able to join */
|
||||
|
||||
|
||||
|
||||
#define NET_ERROR_MBEDTLS_ENTROPY -100/*!<mbedtls enthropy setup failed */
|
||||
#define NET_ERROR_MBEDTLS_CRT_PARSE -101/*!<mbedtls parsing certificat failed */
|
||||
#define NET_ERROR_MBEDTLS_KEY_PARSE -102/*!<mbedtls parsing key failed */
|
||||
#define NET_ERROR_MBEDTLS_SET_HOSTNAME -103/*!<mbedtls cannot setup hostname*/
|
||||
#define NET_ERROR_MBEDTLS_SEED -104/*!<mbedtls seed setup failed */
|
||||
|
||||
#define NET_ERROR_MBEDTLS_REMOTE_AUTH -105/*!<mbedtls remote host could not be authentified */
|
||||
#define NET_ERROR_MBEDTLS_CONFIG -106/*!<mbedtls error in config */
|
||||
#define NET_ERROR_MBEDTLS_SSL_SETUP -107/*!<mbedtls error setting setup */
|
||||
#define NET_ERROR_MBEDTLS_CONNECT -108/*!<mbedtls error while connecting */
|
||||
#define NET_ERROR_MBEDTLS -109/*!<mbedtls error while reading writing data */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* NET_ERRORS_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_internals.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network interface with mbedTLS (if used)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_INTERNALS_H
|
||||
#define NET_INTERNALS_H
|
||||
|
||||
#include "net_core.h"
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "net_mbedtls.h"
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
#endif /* NET_INTERNALS_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ip_ethernet.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network interface on ethernet
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_IP_ETHERNET_H
|
||||
#define NET_IP_ETHERNET_H
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "lwip/netif.h"
|
||||
/*cstat +MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
|
||||
/* Within 'USER CODE' section, code will be kept by default at each generation */
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void net_ethernetif_deinit(void);
|
||||
void net_ethernetif_get_mac_addr(uint8_t *mac_addr);
|
||||
uint8_t net_ethernetif_get_link_status(void);
|
||||
err_t net_ethernetif_init(struct netif *netif);
|
||||
int32_t net_ethernetif_output(void *context, net_buf_t *net_buf);
|
||||
#endif /* NET_IP_ETHERNET_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ip_lwip.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network IP functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_IP_LWIP_H
|
||||
#define NET_IP_LWIP_H
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/etharp.h"
|
||||
/*cstat +MISRAC* +DEFINE-* -CERT-EXP19* */
|
||||
|
||||
|
||||
#define NET_IP_IF_TIMEOUT 1000
|
||||
#define NET_IP_INPUT_QUEUE_TIMEOUT 1000
|
||||
#define NET_IP_INPUT_QUEUE_SIZE 128
|
||||
#define NET_IP_THREAD_SIZE 1024
|
||||
|
||||
#define NET_IP_FLAG_DEFAULT_INTERFACE (1U<<0)
|
||||
#define NET_IP_FLAG_TCPIP_STARTED_EXTERNALLY (1U<<1)
|
||||
|
||||
|
||||
|
||||
void net_ip_init(void);
|
||||
|
||||
int32_t net_ip_add_if(net_if_handle_t *pnetif, err_t (*if_init)(struct netif *netif), uint32_t flag);
|
||||
int32_t net_ip_remove_if(net_if_handle_t *pnetif, err_t (*if_deinit)(struct netif *netif));
|
||||
int32_t net_ip_connect(net_if_handle_t *pnetif);
|
||||
int32_t net_ip_disconnect(net_if_handle_t *pnetif);
|
||||
void net_ip_status_cb(struct netif *netif);
|
||||
void net_ip_link_status(struct netif *netif, uint8_t status);
|
||||
int32_t returncode_lwip2net(int32_t ret);
|
||||
|
||||
|
||||
|
||||
#endif /* NET_IP_LWIP_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_mbedtls.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network TLS functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 MBEDTLS_NET_H
|
||||
#define MBEDTLS_NET_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/certs.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/timing.h"
|
||||
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
struct net_tls_data
|
||||
{
|
||||
const char_t *tls_ca_certs; /**< Socket option. */
|
||||
const char_t *tls_ca_crl; /**< Socket option. */
|
||||
const char_t *tls_dev_cert; /**< Socket option. */
|
||||
const char_t *tls_dev_key; /**< Socket option. */
|
||||
const uint8_t *tls_dev_pwd; /**< Socket option. */
|
||||
size_t tls_dev_pwd_len; /**< Socket option / meta. */
|
||||
bool tls_srv_verification; /**< Socket option. */
|
||||
const char_t *tls_srv_name; /**< Socket option. */
|
||||
/* mbedTLS objects */
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_ssl_config conf;
|
||||
uint32_t flags;
|
||||
mbedtls_x509_crt cacert;
|
||||
mbedtls_x509_crt clicert;
|
||||
mbedtls_pk_context pkey;
|
||||
const mbedtls_x509_crt_profile *tls_cert_prof; /**< Socket option. */
|
||||
} ;
|
||||
|
||||
void net_tls_init(void);
|
||||
void net_tls_destroy(void);
|
||||
|
||||
int32_t net_mbedtls_start(net_socket_t *sockhnd);
|
||||
int32_t net_mbedtls_stop(net_socket_t *sockhnd);
|
||||
int32_t net_mbedtls_sock_recv(net_socket_t *sockhnd, uint8_t *buf, size_t len);
|
||||
int32_t net_mbedtls_sock_send(net_socket_t *sockhnd, const uint8_t *buf, size_t len);
|
||||
bool net_mbedtls_check_tlsdata(net_socket_t *sockhnd);
|
||||
void net_mbedtls_set_read_timeout(net_socket_t *sock);
|
||||
|
||||
|
||||
#endif /* MBEDTLS_NET_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_mem.h
|
||||
* @author MCD Application Team
|
||||
* @brief Memory allocator functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_MEM_H
|
||||
#define NET_MEM_H
|
||||
#include "net_conf.h"
|
||||
#include "net_types.h"
|
||||
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
|
||||
/*cstat -MISRAC2012-Dir-4.4 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef NET_ALLOC_DEBUG
|
||||
|
||||
#if !defined NET_ALLOC_MAX_NODE
|
||||
#define NET_ALLOC_MAX_NODE 50U
|
||||
#endif /* NET_ALLOC_MAX_NODE */
|
||||
|
||||
#if !defined NET_DISPLAY_TAB
|
||||
#define NET_DISPLAY_TAB 4U
|
||||
#endif /* NET_DISPLAY_TAB */
|
||||
|
||||
#if !defined NET_DISPLAY_WIDTH
|
||||
#define NET_DISPLAY_WIDTH 120U
|
||||
#endif /* NET_DISPLAY_WIDTH */
|
||||
|
||||
#if !defined NET_DISPLAY_RESULT_WIDTH
|
||||
#define NET_DISPLAY_RESULT_WIDTH 8U
|
||||
#endif /* NET_DISPLAY_RESULT_WIDTH */
|
||||
|
||||
#if !defined NET_DISPLAY_DIRNAME_LEN
|
||||
#define NET_DISPLAY_DIRNAME_LEN 30U
|
||||
#endif /* NET_DISPLAY_DIRNAME_LEN */
|
||||
|
||||
#if !defined NET_ALLOC_VERBOSE
|
||||
#define NET_ALLOC_VERBOSE 0
|
||||
#endif /* NET_ALLOC_VERBOSE */
|
||||
|
||||
#ifndef NET_LEAKAGE_ARRAY
|
||||
#define NET_LEAKAGE_ARRAY 300U
|
||||
#endif /* NET_LEAKAGE_ARRAY */
|
||||
|
||||
#ifndef NET_ALLOC_BREAK
|
||||
#define NET_ALLOC_BREAK 0xFFFFFFFFU
|
||||
#endif /* NET_ALLOC_BREAK */
|
||||
|
||||
|
||||
#define NET_CALLOC(a,b) net_calloc_debug(a,b,__FILE__,__LINE__)
|
||||
#define NET_REALLOC(a,b) net_realloc_debug(a,b,__FILE__,__LINE__)
|
||||
#define NET_MALLOC(a) net_malloc_debug(a,__FILE__,__LINE__)
|
||||
#define NET_FREE(a) net_free_debug(a)
|
||||
|
||||
|
||||
void *net_calloc_debug(size_t m, size_t n, const char *s, uint32_t line);
|
||||
void *net_malloc_debug(size_t m, const char *s, uint32_t line);
|
||||
void *net_realloc_debug(void *p, size_t size, const char_t *filename, uint32_t line);
|
||||
void net_free_debug(void *p);
|
||||
|
||||
void net_alloc_report(void);
|
||||
|
||||
|
||||
#else /* !NET_ALLOC_DEBUG */
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
#define NET_CALLOC net_calloc
|
||||
#define NET_REALLOC net_realloc
|
||||
#define NET_MALLOC pvPortMalloc
|
||||
#define NET_FREE vPortFree
|
||||
|
||||
void *net_calloc(size_t n, size_t m);
|
||||
void *net_realloc(void *p, size_t m);
|
||||
|
||||
#else
|
||||
#define NET_CALLOC calloc
|
||||
#define NET_REALLOC realloc
|
||||
#define NET_MALLOC malloc
|
||||
#define NET_FREE free
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
#endif /* NET_ALLOC_DEBUG */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_MEM_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_perf.h
|
||||
* @author MCD Application Team
|
||||
* @brief Memory allocator functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 NET_PERF_H
|
||||
#define NET_PERF_H
|
||||
|
||||
/* disable Misra rule to enable doxigen comment , A sectio of code appear to have been commented out */
|
||||
/*cstat -MISRAC2012-Dir-4.4 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "net_conf.h"
|
||||
#include "net_types.h"
|
||||
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
|
||||
#if (osCMSIS < 0x20000U)
|
||||
#define NET_TICK osKernelSysTick
|
||||
#else
|
||||
#define NET_TICK osKernelGetTickCount
|
||||
#endif /* osCMSIS */
|
||||
|
||||
#else
|
||||
#define NET_TICK HAL_GetTick
|
||||
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
|
||||
/*cstat -MISRAC2012-Rule-21.1 */
|
||||
#ifndef __IO
|
||||
#define __IO volatile
|
||||
#endif /* __IO */
|
||||
/*cstat +MISRAC2012-Rule-21.1 */
|
||||
|
||||
#define NET_DWT_CONTROL (*((__IO uint32_t*)0xE0001000U))
|
||||
#define NET_DWT_CYCCNTENA_BIT (1UL<<0U)
|
||||
/*!< DWT Cycle Counter register */
|
||||
#define NET_DWT_CYCCNT (*((__IO uint32_t*)0xE0001004U))
|
||||
/*!< DEMCR: Debug Exception and Monitor Control Register */
|
||||
#define NET_DEMCR (*((__IO uint32_t*)0xE000EDFCU))
|
||||
/*!< Trace enable bit in DEMCR register */
|
||||
#define NET_TRCENA_BIT (1UL<<24U)
|
||||
|
||||
|
||||
static inline uint32_t net_get_cycle(void)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.4 */
|
||||
return NET_DWT_CYCCNT;
|
||||
/*cstat +MISRAC2012-Rule-11.4 */
|
||||
}
|
||||
|
||||
static inline void net_stop_cycle(void)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.4 */
|
||||
NET_DWT_CONTROL &= ~NET_DWT_CYCCNTENA_BIT ;
|
||||
/*cstat +MISRAC2012-Rule-11.4 */
|
||||
}
|
||||
|
||||
static inline void net_start_cycle(void)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.4 */
|
||||
NET_DWT_CONTROL |= NET_DWT_CYCCNTENA_BIT ;
|
||||
/*cstat +MISRAC2012-Rule-11.4 */
|
||||
}
|
||||
|
||||
void net_perf_start(void);
|
||||
void net_perf_report(void);
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
|
||||
#if defined(NET_PERF_TASK) && !defined(NET_FREERTOS_PERF)
|
||||
#warning "To use NET_PERF_TASK please add followings lines to FreeRTOSConfig.h"
|
||||
#warning " void net_perf_task_in(void);"
|
||||
#warning " void net_perf_task_out(void);"
|
||||
#warning " #define NET_FREERTOS_PERF"
|
||||
#warning " #define traceTASK_SWITCHED_IN net_perf_task_in"
|
||||
#warning " #define traceTASK_SWITCHED_OUT net_perf_task_out"
|
||||
#endif /* NET_PERF_TASK */
|
||||
|
||||
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_PERF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_state.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network state management functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_STATE_H
|
||||
#define NET_STATE_H
|
||||
int32_t net_state_manage_event(net_if_handle_t *pnetif, net_state_event_t state_to);
|
||||
void net_state_transition_done(net_if_handle_t *pnetif, net_state_t state_to);
|
||||
|
||||
#endif /* NET_STATE_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_types.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network types definitions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_TYPES_H
|
||||
#define NET_TYPES_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
/*cstat -MISRAC2012-Dir-4.6_b */
|
||||
typedef char char_t;
|
||||
typedef unsigned char uchar_t;
|
||||
/*cstat +MISRAC2012-Dir-4.6_b */
|
||||
|
||||
typedef bool bool_t;
|
||||
|
||||
|
||||
#endif /* NET_TYPES_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_wifi.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the network Wi-Fi class.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef NET_WIFI_H
|
||||
#define NET_WIFI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NET_WIFI_MAC_ADDRESS_SIZE 6
|
||||
#define NET_WIFI_MAX_SSID_SIZE 32
|
||||
#define NET_WEP_ENABLED 0x0001U /**< Flag to enable WEP Security */
|
||||
#define NET_TKIP_ENABLED 0x0002U /**< Flag to enable TKIP Encryption */
|
||||
#define NET_AES_ENABLED 0x0004U /**< Flag to enable AES Encryption */
|
||||
#define NET_SHARED_ENABLED 0x00008000U /**< Flag to enable Shared key Security */
|
||||
#define NET_WPA_SECURITY 0x00200000U /**< Flag to enable WPA Security */
|
||||
#define NET_WPA2_SECURITY 0x00400000U /**< Flag to enable WPA2 Security */
|
||||
#define NET_WPA3_SECURITY 0x01000000U /**< Flag to enable WPA3 PSK Security */
|
||||
|
||||
#define NET_ENTERPRISE_ENABLED 0x02000000U /**< Flag to enable Enterprise Security */
|
||||
#define NET_WPS_ENABLED 0x10000000U /**< Flag to enable WPS Security */
|
||||
#define NET_IBSS_ENABLED 0x20000000U /**< Flag to enable IBSS mode */
|
||||
#define NET_FBT_ENABLED 0x40000000U /**< Flag to enable FBT */
|
||||
|
||||
#define NET_WIFI_SM_OPEN 0U
|
||||
/**< Open security */
|
||||
#define NET_WIFI_SM_WEP_PSK NET_WEP_ENABLED
|
||||
/**< WEP PSK Security with open authentication */
|
||||
#define NET_WIFI_SM_WEP_SHARED (NET_WEP_ENABLED | NET_SHARED_ENABLED)
|
||||
/**< WEP PSK Security with shared authentication */
|
||||
#define NET_WIFI_SM_WPA_TKIP_PSK (NET_WPA_SECURITY | NET_TKIP_ENABLED)
|
||||
/**< WPA PSK Security with TKIP */
|
||||
#define NET_WIFI_SM_WPA_AES_PSK (NET_WPA_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA PSK Security with AES */
|
||||
#define NET_WIFI_SM_WPA_MIXED_PSK (NET_WPA_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
|
||||
/**< WPA PSK Security with AES & TKIP */
|
||||
#define NET_WIFI_SM_WPA2_AES_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA2 PSK Security with AES */
|
||||
#define NET_WIFI_SM_WPA2_WPA_PSK (NET_WPA2_SECURITY | NET_WPA_SECURITY)
|
||||
/**< WPA2 PSK Security with AES */
|
||||
#define NET_WIFI_SM_WPA2_TKIP_PSK (NET_WPA2_SECURITY | NET_TKIP_ENABLED)
|
||||
/**< WPA2 PSK Security with TKIP */
|
||||
#define NET_WIFI_SM_WPA2_MIXED_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
|
||||
/**< WPA2 PSK Security with AES & TKIP */
|
||||
#define NET_WIFI_SM_WPA2_FBT_PSK (NET_WPA2_SECURITY | NET_AES_ENABLED | NET_FBT_ENABLED)
|
||||
/**< WPA2 FBT PSK Security with AES & TKIP */
|
||||
#define NET_WIFI_SM_WPA3_SAE (NET_WPA3_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA3 Security with AES */
|
||||
#define NET_WIFI_SM_WPA3_WPA2_PSK (NET_WPA3_SECURITY | NET_WPA2_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA3 WPA2 PSK Security with AES */
|
||||
|
||||
#define NET_WIFI_SM_WPA_TKIP_ENT (NET_ENTERPRISE_ENABLED | NET_WPA_SECURITY | NET_TKIP_ENABLED)
|
||||
/**< WPA Enterprise Security with TKIP */
|
||||
#define NET_WIFI_SM_WPA_AES_ENT (NET_ENTERPRISE_ENABLED | NET_WPA_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA Enterprise Security with AES */
|
||||
#define NET_WIFI_SM_WPA_MIXED_ENT (NET_ENTERPRISE_ENABLED\
|
||||
| NET_WPA_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
|
||||
/**< WPA Enterprise Security with AES & TKIP */
|
||||
#define NET_WIFI_SM_WPA2_TKIP_ENT (NET_ENTERPRISE_ENABLED | NET_WPA2_SECURITY | NET_TKIP_ENABLED)
|
||||
/**< WPA2 Enterprise Security with TKIP */
|
||||
#define NET_WIFI_SM_WPA2_AES_ENT (NET_ENTERPRISE_ENABLED | NET_WPA2_SECURITY | NET_AES_ENABLED)
|
||||
/**< WPA2 Enterprise Security with AES */
|
||||
#define NET_WIFI_SM_WPA2_MIXED_ENT (NET_ENTERPRISE_ENABLED\
|
||||
| NET_WPA2_SECURITY | NET_AES_ENABLED | NET_TKIP_ENABLED)
|
||||
/**< WPA2 Enterprise Security with AES & TKIP */
|
||||
#define NET_WIFI_SM_WPA2_FBT_ENT (NET_ENTERPRISE_ENABLED\
|
||||
| NET_WPA2_SECURITY | NET_AES_ENABLED | NET_FBT_ENABLED)
|
||||
/**< WPA2 Enterprise Security with AES & FBT */
|
||||
|
||||
#define NET_WIFI_SM_IBSS_OPEN (NET_IBSS_ENABLED)
|
||||
/**< Open security on IBSS ad-hoc network */
|
||||
#define NET_WIFI_SM_WPS_OPEN (NET_WPS_ENABLED)
|
||||
/**< WPS with open security */
|
||||
#define NET_WIFI_SM_WPS_SECURE (NET_WPS_ENABLED | NET_AES_ENABLED)
|
||||
/**< WPS with AES security */
|
||||
#define NET_WIFI_SM_UNKNOWN 0xFFFFFFFFU
|
||||
/**< UNKNOWN security */
|
||||
#define NET_WIFI_SM_AUTO 0xFFFFFFF0U
|
||||
/**< Auto Mode */
|
||||
|
||||
|
||||
/* Wi-Fi events */
|
||||
typedef enum
|
||||
{
|
||||
NET_WIFI_SCAN_RESULTS_READY
|
||||
} net_wifi_event_t;
|
||||
|
||||
|
||||
/* Mode */
|
||||
typedef enum
|
||||
{
|
||||
NET_WIFI_MODE_STA,
|
||||
NET_WIFI_MODE_AP
|
||||
} net_wifi_mode_t;
|
||||
|
||||
/* MAC address */
|
||||
typedef uint8_t net_wifi_mac_t[NET_WIFI_MAC_ADDRESS_SIZE];
|
||||
|
||||
/* SSID , max 32 alpha string chain*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t length; /**< SSID length */
|
||||
uint8_t value[NET_WIFI_MAX_SSID_SIZE]; /**< SSID name (AP name) */
|
||||
} net_wifi_ssid_t;
|
||||
|
||||
|
||||
/* Scan */
|
||||
typedef enum
|
||||
{
|
||||
NET_WIFI_SCAN_PASSIVE,
|
||||
NET_WIFI_SCAN_ACTIVE,
|
||||
NET_WIFI_SCAN_AUTO
|
||||
} net_wifi_scan_mode_t;
|
||||
|
||||
typedef struct net_wifi_scan_bss_s
|
||||
{
|
||||
net_wifi_ssid_t ssid;
|
||||
net_wifi_mac_t bssid;
|
||||
uint32_t security;
|
||||
uint8_t channel;
|
||||
uint8_t country[4]; /* one more char for null terminated string */
|
||||
int8_t rssi;
|
||||
} net_wifi_scan_bss_t;
|
||||
#if 0
|
||||
typedef struct net_wifi_scan_results_s
|
||||
{
|
||||
uint16_t number;
|
||||
net_wifi_scan_bss_t *bss;
|
||||
} net_wifi_scan_results_t;
|
||||
#else
|
||||
typedef net_wifi_scan_bss_t net_wifi_scan_results_t;
|
||||
#endif /* old definiton */
|
||||
|
||||
/* Param */
|
||||
typedef enum
|
||||
{
|
||||
NET_WIFI_MODE,
|
||||
} net_wifi_param_t;
|
||||
|
||||
/* System info */
|
||||
typedef enum
|
||||
{
|
||||
NET_WIFI_SCAN_RESULTS_NUMBER,
|
||||
} net_wifi_system_info_t;
|
||||
|
||||
/* Credential configuration */
|
||||
typedef struct net_wifi_credentials_s
|
||||
{
|
||||
const char_t *ssid;
|
||||
const char_t *psk;
|
||||
int32_t security_mode;
|
||||
} net_wifi_credentials_t;
|
||||
|
||||
/* Powersave */
|
||||
typedef enum
|
||||
{
|
||||
WIFI_POWERSAVE_ACTIVE,
|
||||
WIFI_POWERSAVE_LIGHT_SLEEP,
|
||||
WIFI_POWERSAVE_DEEP_SLEEP
|
||||
}
|
||||
net_wifi_powersave_t;
|
||||
|
||||
const char_t *net_wifi_security_to_string(uint32_t sec);
|
||||
uint32_t net_wifi_string_to_security(char *sec);
|
||||
|
||||
int32_t net_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
|
||||
|
||||
int32_t net_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
|
||||
int32_t net_wifi_set_credentials(net_if_handle_t *pnetif, const net_wifi_credentials_t *credentials);
|
||||
int32_t net_wifi_set_access_mode(net_if_handle_t *pnetif, net_wifi_mode_t mode);
|
||||
int32_t net_wifi_set_access_channel(net_if_handle_t *pnetif, uint8_t channel);
|
||||
int32_t net_wifi_set_powersave(net_if_handle_t *pnetif, const net_wifi_powersave_t *powersave);
|
||||
int32_t net_wifi_set_param(net_if_handle_t *pnetif, const net_wifi_param_t param, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_WIFI_H */
|
||||
@@ -0,0 +1 @@
|
||||
STM32 Network Library Framework
|
||||
@@ -0,0 +1,370 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Release Notes for STM32 Network Library</title>
|
||||
<style type="text/css">
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="_htmresc/mini-st.css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
<link rel="icon" type="image/x-icon" href="_htmresc/favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<p>::: {.row} ::: {.col-sm-12 .col-lg-4}</p>
|
||||
<div class="card fluid">
|
||||
<div class="sectione dark">
|
||||
<center>
|
||||
<h1 id="release-notes-for-stm32-network-library"><small>Release Notes for</small> <mark>STM32 Network Library</mark></h1>
|
||||
<p>Copyright © 2019 STMicroelectronics<br />
|
||||
Microcontrollers Division - Application Team</p>
|
||||
<a href="https://www.st.com" class="logo"><img src="_htmresc/st_logo.png" alt="ST logo" /></a>
|
||||
</center>
|
||||
</div>
|
||||
</div>
|
||||
<h1 id="license">License</h1>
|
||||
<p>Licensed under ST license SLA0044 (the “License”). You may not use this package except in compliance with the License.</p>
|
||||
<p>You may obtain a copy of the License at: <a href="http://www.st.com/software_license_agreement_liberty_v2">SLA0044 Software license agreement</a>.</p>
|
||||
<h1 id="purpose">Purpose</h1>
|
||||
<p>The <mark>STM32 Network Library</mark> is a middleware providing network services on STM32 devices. It provides a socket API (BSD like style) with support of secure or non secure connection and an API to control the lifecycle of the network adapters.</p>
|
||||
<p>Three classes of network adapters are supported WIFI, Ethernet and Cellular. Different WIFI modules are supported from third party vendors.</p>
|
||||
<h1 id="documentation">Documentation</h1>
|
||||
<p><a href="./NetworkLib.chm">Doxygen documentation</a> :::</p>
|
||||
<div class="col-sm-12 col-lg-8">
|
||||
<h1 id="update-history">Update History</h1>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section8" checked aria-hidden="false"> <label for="collapse-section8" aria-hidden="true">V2.1.0 / 2020-Mai-04</label>
|
||||
<div>
|
||||
<h2 id="main-changes">Main changes</h2>
|
||||
<h3 id="network-library-core">Network library core</h3>
|
||||
<ul>
|
||||
<li>Improve performance monitoring primitives adding Thread display support</li>
|
||||
<li>Improve Memory debug primitive</li>
|
||||
<li>Add Node Tree display for dynamic memory allocation</li>
|
||||
</ul>
|
||||
<h3 id="mxchip-wifi-network-interface">MXCHIP WIFI Network interface</h3>
|
||||
<ul>
|
||||
<li>Add support of UART interrupt module</li>
|
||||
</ul>
|
||||
<h3 id="bug-fixes">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Fix uninitialized variable for all WIFI network interface to force default to AP mode when connecting</li>
|
||||
<li>Fix memory leakage for MXCHIP network interface</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.27.1</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
<li>STM32H743I-EVAL (with Ethernet interface)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:</li>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-lg-8">
|
||||
<h1 id="update-history-1">Update History</h1>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section7" checked aria-hidden="false"> <label for="collapse-section7" aria-hidden="true">V2.0.0 / 2020-April-08</label>
|
||||
<div>
|
||||
<h2 id="main-changes-1">Main changes</h2>
|
||||
<h3 id="network-library-core-1">Network library core</h3>
|
||||
<ul>
|
||||
<li>Prepare support of IPv6 addresses, making code independent from network address definition</li>
|
||||
<li>Clean up template of configuration file to allow application to overwrite default definition</li>
|
||||
<li>Add performance monitoring primitives</li>
|
||||
<li>Add memory allocation primitive to track leakage</li>
|
||||
<li>Add yield feature for specific network interface</li>
|
||||
</ul>
|
||||
<h3 id="wifi-generic-support">WIFI generic support</h3>
|
||||
<ul>
|
||||
<li>Add WIFI Access point support, with needed new API (set_channel, set mode )</li>
|
||||
<li>Update state machine management to support AP and STA connection</li>
|
||||
<li>Add support of concurrent interface, for instance an AP running in parallel with a STA</li>
|
||||
<li>Extend list of supported security mode</li>
|
||||
</ul>
|
||||
<h3 id="cellular-network-interface">Cellular Network interface</h3>
|
||||
<ul>
|
||||
<li>Add compatibility until XCube Cellular package 1.5.0</li>
|
||||
</ul>
|
||||
<h3 id="cypress-wifi-network-interface">Cypress WIFI Network interface</h3>
|
||||
<ul>
|
||||
<li>Add support of Access Point mode</li>
|
||||
</ul>
|
||||
<h3 id="mxchip-wifi-network-interface-1">MXCHIP WIFI Network interface</h3>
|
||||
<ul>
|
||||
<li>Newly supported WIFI module</li>
|
||||
<li>Add support of UART and SPI based module</li>
|
||||
<li>Add templates files</li>
|
||||
</ul>
|
||||
<h3 id="inventek-wifi-network-interface">Inventek WIFI network interface</h3>
|
||||
<ul>
|
||||
<li>Add support of net_getpeername and net_getsocketinfo API</li>
|
||||
</ul>
|
||||
<h3 id="bug-fixes-1">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Fix memory leakage for Cypress WHD based devices</li>
|
||||
<li>Fix memory leakage for secure socket (based on MbedTLS )</li>
|
||||
<li>Fix timeout definition for Cellular devices on connection</li>
|
||||
<li>Fix state machine on deinitialization transition</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-1">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.27.1</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-1">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
<li>STM32H743I-EVAL (with Ethernet interface)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-1">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:</li>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section6" aria-hidden="true"> <label for="collapse-section6" aria-hidden="true">V1.1.0 / 2019-November-27</label>
|
||||
<div>
|
||||
<h2 id="main-changes-2">Main changes</h2>
|
||||
<ul>
|
||||
<li>Add support for WIFI-WHD devices, create a new network interface</li>
|
||||
<li>Add support of ethernet on H7 device (STM32H743I-EVAL board)</li>
|
||||
<li>Restructure code regarding LWIP based network interface</li>
|
||||
<li>lwip related initialisation is moved to net_conf.c</li>
|
||||
<li>Compliant with ST-Quality standard
|
||||
<ul>
|
||||
<li>Pass MISRA check list</li>
|
||||
<li>Pass CodeSonar test<br />
|
||||
</li>
|
||||
<li>Enforce ST coding style rules</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<h3 id="bug-fixes-2">Bug fixes</h3>
|
||||
<h2 id="development-toolchains-and-compilers-2">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-2">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
<li>STM32H743I-EVAL (with Ethernet interface)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-2">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:
|
||||
<ul>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section5" aria-hidden="true"> <label for="collapse-section5" aria-hidden="true">V1.0.5 / 2019-October-8</label>
|
||||
<div>
|
||||
<h2 id="main-changes-3">Main changes</h2>
|
||||
<ul>
|
||||
<li>Add support for CMSIS-OS2</li>
|
||||
</ul>
|
||||
<h3 id="bug-fixes-3">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Fix cellular network interface, required to used firmware version >= BG96MAR02A08M1G.</li>
|
||||
<li>Fix message order on notification</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-3">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-3">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-3">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:
|
||||
<ul>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section4" aria-hidden="true"> <label for="collapse-section4" aria-hidden="true">V1.0.4 / 2019-August-1</label>
|
||||
<div>
|
||||
<h2 id="main-changes-4">Main changes</h2>
|
||||
<ul>
|
||||
<li>Renamed STM32 Connectivity library as STM32 Network library</li>
|
||||
<li>Re-implement State management of network interface ,renamed states from INITIALIZED to READY , suppress some unused states</li>
|
||||
<li>Add and test support of embedded Inventek WIFI TLS socket</li>
|
||||
<li>Run MISRA checks</li>
|
||||
</ul>
|
||||
<h3 id="bug-fixes-4">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Ethernet template: properly clear the “Receive buffer unavailable status” in case of RX descriptor underflow.</li>
|
||||
<li>Fix missing semaphore on net_wait API</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-4">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-4">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-4">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:
|
||||
<ul>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section3" aria-hidden="true"> <label for="collapse-section3" aria-hidden="true">V1.0.3 / 2019-july-05</label>
|
||||
<div>
|
||||
<h2 id="main-changes-5">Main changes</h2>
|
||||
<h3 id="bug-fixes-5">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Run Astyle checks</li>
|
||||
<li>Add doxygen doc generation</li>
|
||||
<li>Fix issue on F769 Ethernet interface , avoid blocking thread on alloc failure from LWIP pool</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-5">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-5">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-5">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:
|
||||
<ul>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section2" aria-hidden="true"> <label for="collapse-section2" aria-hidden="true">V1.0.2 / 2019-june-07</label>
|
||||
<div>
|
||||
<h2 id="main-changes-6">Main changes</h2>
|
||||
<h3 id="bug-fixes-6">Bug fixes</h3>
|
||||
<ul>
|
||||
<li>Ethernet template: properly clear the “Receive buffer unavailable status” in case of RX descriptor underflow.</li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-6">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.32.3.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-6">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-6">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02:
|
||||
<ul>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse">
|
||||
<input type="checkbox" id="collapse-section1" aria-hidden="true"> <label for="collapse-section1" aria-hidden="true">V1.0.0 / 2019-april-26</label>
|
||||
<div>
|
||||
<h2 id="initial-version">Initial version</h2>
|
||||
<ul>
|
||||
<li>Features supported:
|
||||
<ul>
|
||||
<li>BSD socket like API</li>
|
||||
<li>Network interface control API (init, start, stop, …)</li>
|
||||
<li>TCP and UPD protocols</li>
|
||||
<li>Client and server connections</li>
|
||||
<li>DNS and ping services</li>
|
||||
<li>Secure socket on top of mbedTLS</li>
|
||||
<li>RTOS and bare metal applications are supported</li>
|
||||
<li>IPv4 address only is supported (IPv6 will be available in a future version)</li>
|
||||
<li>Wi-Fi, Ethernet and cellular connectivities</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<h2 id="development-toolchains-and-compilers-7">Development Toolchains and Compilers</h2>
|
||||
<ul>
|
||||
<li>IAR Embedded Workbench for ARM (EWARM). Version 8.30.1.</li>
|
||||
<li>Keil Microcontroller Development Kit (MDK-ARM) Version 5.26.</li>
|
||||
<li>System Workbench for STM32. Version 2.8.1.</li>
|
||||
</ul>
|
||||
<h2 id="supported-devices-and-boards-7">Supported Devices and Boards</h2>
|
||||
<ul>
|
||||
<li>B-L475E-IOT01A board (MB1297 rev D).</li>
|
||||
<li>32F413HDISCOVERY board (MB1274 rev B).</li>
|
||||
<li>32F769IDISCOVERY board (MB1225 rev B).</li>
|
||||
<li>P-L496G-CELL02 board package including the 32L496G-Discovery board (MB1261 rev B) and the Cellular Add-on board based on BG96 4G Modem (MB1329 rev B)</li>
|
||||
</ul>
|
||||
<h2 id="known-limitations-7">Known Limitations</h2>
|
||||
<ul>
|
||||
<li>Cellular on P-L496G-CELL02
|
||||
<ul>
|
||||
<li>UDP sockets are not supported</li>
|
||||
<li>Server sockets are not supported</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="sticky">
|
||||
For complete documentation on <mark>STM32</mark> microcontrollers please visit <a href="http://www.st.com/stm32" class="uri">http://www.st.com/stm32</a>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,319 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_address.c
|
||||
* @author MCD Application Team
|
||||
* @brief Implements network address conversion routines
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
|
||||
#define NET_IN_RANGE(c, lo, up) (((c) >= (lo)) && ((c) <= (up)))
|
||||
#define NET_IS_PRINT(c) (NET_IN_RANGE(c, 0x20, 0x7f))
|
||||
#define NET_ISDIGIT(c) (NET_IN_RANGE(c, '0', '9'))
|
||||
#define NET_ISXDIGIT(c) (NET_ISDIGIT(c) || NET_IN_RANGE(c, 'a', 'f') || NET_IN_RANGE(c, 'A', 'F'))
|
||||
#define NET_ISLOWER(c) (NET_IN_RANGE(c, 'a', 'z'))
|
||||
#define NET_ISSPACE(c) (((c) == ' ')\
|
||||
|| ((c) == '\f') || ((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == '\v'))
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
#if !defined(NET_USE_LWIP_DEFINITIONS)
|
||||
char_t *net_ntoa_r(const net_ip_addr_t *addr, char_t *buf, int32_t buflen)
|
||||
{
|
||||
uint32_t NET_S_ADDR;
|
||||
uint8_t val;
|
||||
char_t inv[3];
|
||||
uint8_t *ap;
|
||||
uint8_t rem;
|
||||
uint8_t i;
|
||||
int32_t len = 0;
|
||||
char_t *buf_ret;
|
||||
|
||||
NET_S_ADDR = addr->addr;
|
||||
|
||||
ap = (uint8_t *)&NET_S_ADDR;
|
||||
for (uint8_t n = 0; n < (uint8_t) 4; n++)
|
||||
{
|
||||
i = 0;
|
||||
val = ap[n];
|
||||
do
|
||||
{
|
||||
rem = val % 10U;
|
||||
val /= 10U;
|
||||
inv[i] = (char_t)'0' + rem;
|
||||
i++;
|
||||
} while (val != 0U);
|
||||
|
||||
while (i != 0U)
|
||||
{
|
||||
i--;
|
||||
if (len < buflen)
|
||||
{
|
||||
buf[len] = inv[i];
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((n < 3U) && (len < buflen))
|
||||
{
|
||||
buf[len] = (char_t) '.';
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < buflen)
|
||||
{
|
||||
buf[len] = (char_t) '\0';
|
||||
buf_ret = buf;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_ret = NULL;
|
||||
}
|
||||
|
||||
return buf_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
char_t *net_ntoa(const net_ip_addr_t *addr)
|
||||
{
|
||||
static char_t str[16];
|
||||
return net_ntoa_r(addr, str, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
int32_t net_aton(const char_t *ptr, net_ip_addr_t *addr)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
uint32_t base;
|
||||
char_t c0;
|
||||
const char_t *cp = ptr;
|
||||
uint32_t parts[4];
|
||||
uint32_t *pp = parts;
|
||||
int32_t ret = 1;
|
||||
int32_t done;
|
||||
|
||||
c0 = *cp;
|
||||
done = 0;
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, 1-9=decimal.
|
||||
*/
|
||||
if (done == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NET_ISDIGIT(c0))
|
||||
{
|
||||
ret = 0;
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = 0;
|
||||
base = 10;
|
||||
if (c0 == '0')
|
||||
{
|
||||
++cp;
|
||||
c0 = (char_t) * cp;
|
||||
if ((c0 == (char_t) 'x') || (c0 == (char_t) 'X'))
|
||||
{
|
||||
base = 16;
|
||||
++cp;
|
||||
c0 = (char_t) * cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (NET_ISDIGIT(c0))
|
||||
{
|
||||
val = (val * base) + (uint32_t)c0 - (uint32_t) '0';
|
||||
++cp;
|
||||
c0 = (char_t) * cp;
|
||||
}
|
||||
else if ((base == 16U) && NET_ISXDIGIT(c0))
|
||||
{
|
||||
val = (val << 4) | ((uint32_t)c0 + 10U - (uint32_t)(NET_ISLOWER(c0) ? 'a' : 'A'));
|
||||
++cp;
|
||||
c0 = (char_t) * cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c0 == '.')
|
||||
{
|
||||
/*
|
||||
* 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))
|
||||
{
|
||||
ret = 0;
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pp = val;
|
||||
pp++;
|
||||
++cp;
|
||||
c0 = (char_t) * cp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if ((c0 != (char_t)'\0') && (NET_ISSPACE((c0)) == false))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
{
|
||||
switch (pp - parts + 1)
|
||||
{
|
||||
|
||||
case 0:
|
||||
ret = 0; /* initial nondigit */
|
||||
break;
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffffUL)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffffU)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xffU)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1)
|
||||
{
|
||||
if (addr != NULL)
|
||||
{
|
||||
addr->addr = NET_HTONL(val);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
int32_t net_aton_r(const char_t *cp)
|
||||
{
|
||||
net_ip_addr_t val;
|
||||
int32_t ret;
|
||||
val.addr = 0;
|
||||
if (net_aton(cp, &val) != 0)
|
||||
{
|
||||
ret = (int32_t) val.addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif /* NET_USE_LWIP_DEFINITIONS */
|
||||
|
||||
|
||||
uint16_t net_get_port(net_sockaddr_t *addr)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.3 -MISRAC2012-Rule-11.8 */
|
||||
return (NET_NTOHS(((net_sockaddr_in_t *)addr)->sin_port));
|
||||
/*cstat +MISRAC2012-Rule-11.3 +MISRAC2012-Rule-11.8 +MISRAC2012-Rule-10.8 Cast */
|
||||
}
|
||||
void net_set_port(net_sockaddr_t *addr, uint16_t port)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.3 Cast */
|
||||
((net_sockaddr_in_t *)addr)->sin_port = NET_HTONS(port);
|
||||
/*cstat +MISRAC2012-Rule-11.3 Cast */
|
||||
}
|
||||
|
||||
net_ip_addr_t net_get_ip_addr(net_sockaddr_t *addr)
|
||||
{
|
||||
net_ip_addr_t ipaddr;
|
||||
uint32_t addrv;
|
||||
/*cstat -MISRAC2012-Rule-11.3 Cast */
|
||||
addrv = ((net_sockaddr_in_t *)addr)->sin_addr.s_addr;
|
||||
/*cstat +MISRAC2012-Rule-11.3 Cast */
|
||||
NET_COPY(ipaddr, addrv);
|
||||
return ipaddr;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,431 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_class_extension.c
|
||||
* @author MCD Application Team
|
||||
* @brief Specific class interface function implementation
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#define MATCH(a,b) (a & (b) == (b))
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convert wifi security enum value to string
|
||||
* @param sec is an unsigned integer
|
||||
* @retval a constant string , for instance "Open" or "WPA2-AES"
|
||||
*/
|
||||
const char_t *net_wifi_security_to_string(uint32_t sec)
|
||||
{
|
||||
const char_t *s;
|
||||
if (sec == NET_WIFI_SM_OPEN)
|
||||
{
|
||||
s = "Open";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WEP_SHARED)
|
||||
{
|
||||
s = "WEP-shared";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA_TKIP_PSK)
|
||||
{
|
||||
s = "WPA-TKIP";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA_MIXED_PSK)
|
||||
{
|
||||
s = "WPA-Mixed";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_AES_PSK)
|
||||
{
|
||||
s = "WPA2-AES";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_TKIP_PSK)
|
||||
{
|
||||
s = "WPA2-TKIP";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_MIXED_PSK)
|
||||
{
|
||||
s = "WPA2_Mixed";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_FBT_PSK)
|
||||
{
|
||||
s = "WPA2-FBT";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA3_SAE)
|
||||
{
|
||||
s = "WPA3";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA3_WPA2_PSK)
|
||||
{
|
||||
s = "WPA3-WPA2";
|
||||
}
|
||||
|
||||
else if (sec == NET_WIFI_SM_WPA_TKIP_ENT)
|
||||
{
|
||||
s = "WPA-TKIP-Ent";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA_AES_ENT)
|
||||
{
|
||||
s = "WPA-AES-Ent";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_TKIP_ENT)
|
||||
{
|
||||
s = "WPA2-TKIP-Ent";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_AES_ENT)
|
||||
{
|
||||
s = "WPA2-AES-Ent";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_MIXED_ENT)
|
||||
{
|
||||
s = "WPA2-Mixed-Ent";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPA2_FBT_ENT)
|
||||
{
|
||||
s = "WPA-FBT-Ent";
|
||||
}
|
||||
|
||||
else if (sec == NET_WIFI_SM_IBSS_OPEN)
|
||||
{
|
||||
s = "IBS";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPS_OPEN)
|
||||
{
|
||||
s = "WPS";
|
||||
}
|
||||
else if (sec == NET_WIFI_SM_WPS_SECURE)
|
||||
{
|
||||
s = "WPS-AES";
|
||||
}
|
||||
else
|
||||
{
|
||||
s = "unknown";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a string to a security enum value
|
||||
* @param sec is a pointer to a string
|
||||
*/
|
||||
uint32_t net_wifi_string_to_security(char_t *sec)
|
||||
{
|
||||
uint32_t ret = NET_WIFI_SM_UNKNOWN;
|
||||
if (strcmp(sec, "Open") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_OPEN;
|
||||
}
|
||||
if (strcmp(sec, "WEP-shared") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WEP_SHARED;
|
||||
}
|
||||
if (strcmp(sec, "WPA-TKIP") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA_TKIP_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA-Mixed") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA_MIXED_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-AES") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_AES_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-TKIP") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_TKIP_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-Mixed") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_MIXED_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-DBT") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_FBT_PSK;
|
||||
}
|
||||
if (strcmp(sec, "WPA3") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA3_SAE;
|
||||
}
|
||||
if (strcmp(sec, "WPA3-WPA2") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA3_WPA2_PSK;
|
||||
}
|
||||
|
||||
if (strcmp(sec, "WPA-TKIP-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA_TKIP_ENT;
|
||||
}
|
||||
if (strcmp(sec, "WPA-AES-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA_AES_ENT;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-TKIP-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_TKIP_ENT;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-AES-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_AES_ENT;
|
||||
}
|
||||
if (strcmp(sec, "WPA2-Mixed-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_MIXED_ENT;
|
||||
}
|
||||
if (strcmp(sec, "WPA-FBT-Ent") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPA2_FBT_ENT;
|
||||
}
|
||||
if (strcmp(sec, "IBS") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_IBSS_OPEN;
|
||||
}
|
||||
if (strcmp(sec, "WPS") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPS_OPEN;
|
||||
}
|
||||
if (strcmp(sec, "WPS-AES") == 0)
|
||||
{
|
||||
ret = NET_WIFI_SM_WPS_SECURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief start a wifi scan operation
|
||||
* @param pnetif_in is a pointer to an allocated network interface structure
|
||||
* @param mode is an enum to specify type of scan mode to be performed
|
||||
* @param ssid is a pointer to a string, when not null, scan searches only this ssid
|
||||
* @retval return the number of found access point , max value is "number".
|
||||
* This function is a synchronous function.
|
||||
*/
|
||||
|
||||
int32_t net_wifi_scan(net_if_handle_t *pnetif_in, net_wifi_scan_mode_t mode, char_t *ssid)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_scan function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnetif->pdrv->extension.wifi->scan(pnetif, mode, ssid) != NET_OK)
|
||||
{
|
||||
NET_DBG_ERROR("Error when executing net_wifi_scan function\n");
|
||||
ret = NET_ERROR_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the result of scan operation , once event has been recevied
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param results is a pointer to an allocated array of net_wifi_scan_results_t
|
||||
* @param number is unsigned integer , size of the array 'results'
|
||||
* @retval return the number of found access point , max value is "number".
|
||||
*/
|
||||
int32_t net_wifi_get_scan_results(net_if_handle_t *pnetif_in, net_wifi_scan_results_t *results, uint8_t number)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_scan function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = pnetif->pdrv->extension.wifi->get_scan_results(pnetif, results, number);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the credential of a wifi interface, can be AP or STA credentials
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param credentials a pointer to a const allocated structure which contain credentials values (ssid , passwd)
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_wifi_set_credentials(net_if_handle_t *pnetif, const net_wifi_credentials_t *credentials)
|
||||
{
|
||||
pnetif->pdrv->extension.wifi->credentials = credentials;
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the acess mode for a wifi interface: AP or STA mode
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_wifi_set_access_mode(net_if_handle_t *pnetif, net_wifi_mode_t mode)
|
||||
{
|
||||
pnetif->pdrv->extension.wifi->mode = mode;
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the wifi channel to used for an AP
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param channel is an unsigned 8 bit integer
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_wifi_set_access_channel(net_if_handle_t *pnetif, uint8_t channel)
|
||||
{
|
||||
pnetif->pdrv->extension.wifi->access_channel = channel;
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set wifi power save mode
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param powersave is a pointer to an allocated structute to define the powersave mode
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_wifi_set_powersave(net_if_handle_t *pnetif_in, const net_wifi_powersave_t *powersave)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
net_if_handle_t *pnetif;
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_set_powersave function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
pnetif->pdrv->extension.wifi->powersave = powersave;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set wifi extension parameter
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param param is an enum value to specify which parameter to set
|
||||
* @param data is a pointer to an allocated opaque structure to specify the parameter value
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
|
||||
int32_t net_wifi_set_param(net_if_handle_t *pnetif, const net_wifi_param_t param, void *data)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_WIFI)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_wifi_set_param function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = pnetif->pdrv->extension.wifi->set_param(param, data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief set the credential of a cellular interface
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param credentials a pointer to a const allocated structure which contains credentials values (ssid , passwd)
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
|
||||
int32_t net_cellular_set_credentials(net_if_handle_t *pnetif_in, const net_cellular_credentials_t *credentials)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_CELLULAR)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_cellular_get_radio_results function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
pnetif->pdrv->extension.cellular->credentials = credentials;
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get cellular radio information
|
||||
* @param pnetif_is a pointer to an allocated network interface structure
|
||||
* @param reults is a pointer to an allocated net_cellular_radio_results_t structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_cellular_get_radio_results(net_if_handle_t *pnetif_in, net_cellular_radio_results_t *results)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
net_if_handle_t *pnetif;
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnetif->pdrv->if_class != NET_INTERFACE_CLASS_CELLULAR)
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect class interface when calling net_cellular_get_radio_results function\n");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = pnetif->pdrv->extension.cellular->get_radio_results(results);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,569 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_core.c
|
||||
* @author MCD Application Team
|
||||
* @brief Network interface core implementation
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
static void netif_add_to_list(net_if_handle_t *pnetif);
|
||||
static void netif_remove_from_list(net_if_handle_t *pnetif);
|
||||
static net_if_handle_t *net_if_list = NULL;
|
||||
|
||||
#ifndef __IO
|
||||
/*cstat -MISRAC2012-Rule-21.1 */
|
||||
#define __IO volatile
|
||||
/*cstat +MISRAC2012-Rule-21.1 */
|
||||
#endif /* IO */
|
||||
|
||||
static void netif_add_to_list(net_if_handle_t *pnetif)
|
||||
{
|
||||
LOCK_NETIF_LIST();
|
||||
if (net_if_list == NULL)
|
||||
{
|
||||
net_if_list = pnetif;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*add it to end of the list*/
|
||||
net_if_handle_t *plastnetif;
|
||||
plastnetif = net_if_list;
|
||||
while (plastnetif->next != NULL)
|
||||
{
|
||||
plastnetif = plastnetif->next;
|
||||
}
|
||||
plastnetif->next = pnetif;
|
||||
}
|
||||
UNLOCK_NETIF_LIST();
|
||||
}
|
||||
|
||||
|
||||
static void netif_remove_from_list(net_if_handle_t *pnetif)
|
||||
{
|
||||
net_if_handle_t *pnetif_prev;
|
||||
LOCK_NETIF_LIST();
|
||||
|
||||
if (net_if_list == pnetif)
|
||||
{
|
||||
net_if_list = net_if_list->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pnetif_prev = net_if_list; pnetif_prev->next != NULL; pnetif_prev = pnetif_prev->next)
|
||||
{
|
||||
if (pnetif_prev->next == pnetif)
|
||||
{
|
||||
pnetif_prev->next = pnetif->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UNLOCK_NETIF_LIST();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
net_if_handle_t *net_if_find(net_sockaddr_t *addr)
|
||||
{
|
||||
net_if_handle_t *ptr;
|
||||
net_ip_addr_t ipaddr;
|
||||
net_ip_addr_t ipaddr_zero;
|
||||
|
||||
NET_ZERO(ipaddr_zero);
|
||||
NET_ZERO(ipaddr);
|
||||
if (addr != NULL)
|
||||
{
|
||||
ipaddr = net_get_ip_addr(addr);
|
||||
|
||||
}
|
||||
LOCK_NETIF_LIST();
|
||||
|
||||
ptr = net_if_list;
|
||||
|
||||
if (NET_DIFF(ipaddr, ipaddr_zero) != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (NET_EQUAL(ptr->ipaddr, ipaddr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
} while (ptr != NULL);
|
||||
}
|
||||
UNLOCK_NETIF_LIST();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
net_if_handle_t *netif_check(net_if_handle_t *pnetif_in)
|
||||
{
|
||||
net_if_handle_t *pnetif = pnetif_in;
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
/* get default interface*/
|
||||
pnetif = net_if_find(NULL);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("No network interface defined");
|
||||
}
|
||||
}
|
||||
return pnetif;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Wait for state transtion
|
||||
* @param pnetif a pointer to the selected network interface
|
||||
* @param state the expected state
|
||||
* @param timeout max time to wait in ms for the transition
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
extern uint32_t HAL_GetTick(void);
|
||||
|
||||
int32_t net_if_wait_state(net_if_handle_t *pnetif, net_state_t state, uint32_t timeout)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
__IO net_state_t *p;
|
||||
p = &pnetif->state;
|
||||
|
||||
uint32_t start_time = HAL_GetTick();
|
||||
while (*p != state)
|
||||
{
|
||||
if (HAL_GetTick() >= (start_time + timeout))
|
||||
{
|
||||
ret = NET_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
WAIT_STATE_CHANGE(timeout);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void net_if_notify(net_if_handle_t *pnetif, net_evt_t event_class, uint32_t event_id, void *event_data)
|
||||
{
|
||||
/* call the user Handler first ,FIXME , first or not , race between wait state transition and user handler */
|
||||
if ((NULL != pnetif->event_handler) && (NULL != pnetif->event_handler->callback))
|
||||
{
|
||||
pnetif->event_handler->callback(pnetif->event_handler->context, event_class, event_id, event_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
static int32_t net_initialized = 0;
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
/** @defgroup State State Management Network Framework
|
||||
* Application uses this set of function to control the network interface state.
|
||||
* Normal state flow is init => start => connect.
|
||||
* Socket interface can be used when connected state is reached.Network interface is connected and got an IP address.
|
||||
* To finish, flow is disconnect,stop,deinit. All connection are closed and allocated resources are freed.
|
||||
* State transition are asynchronous but could be implemented in a synchronous way depending on the selected
|
||||
* network interface. Once a transition is requested,the net_wait_state primitive should be used to wait
|
||||
* for transition to occur.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Perform network interface initialization
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param driver_init a pointer to a function which define the driver to use
|
||||
* @param event_handler a calback function to manage event from network framework
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
* This function is a synchronous function.
|
||||
*/
|
||||
int32_t net_if_init(net_if_handle_t *pnetif_in, net_if_driver_init_func driver_init,
|
||||
const net_event_handler_t *event_handler)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif = pnetif_in;
|
||||
#ifdef NET_USE_RTOS
|
||||
if (net_initialized == 0)
|
||||
{
|
||||
net_init_locks();
|
||||
net_initialized = 1;
|
||||
}
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
pnetif->event_handler = event_handler;
|
||||
pnetif->state = NET_STATE_INITIALIZED;
|
||||
netif_add_to_list(pnetif);
|
||||
ret = (*driver_init)(pnetif);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot be initialized.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform network interface de-initialization
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_deinit(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_CMD_DEINIT);
|
||||
pnetif->state = NET_STATE_DEINITIALIZED;
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
netif_remove_from_list(pnetif);
|
||||
}
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
if (net_initialized == 1)
|
||||
{
|
||||
net_destroy_locks();
|
||||
net_initialized = 0;
|
||||
}
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* @brief Start network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_start(net_if_handle_t *pnetif)
|
||||
{
|
||||
return net_state_manage_event(pnetif, NET_EVENT_CMD_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_stop(net_if_handle_t *pnetif)
|
||||
{
|
||||
return net_state_manage_event(pnetif, NET_EVENT_CMD_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* @brief Yield data from network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_yield(net_if_handle_t *pnetif_in, uint32_t timeout)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
net_if_handle_t *pnetif;
|
||||
net_state_t state;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
(void) net_if_getState(pnetif, &state);
|
||||
|
||||
if (state == NET_STATE_CONNECTED)
|
||||
{
|
||||
if (NULL != pnetif->pdrv->if_yield)
|
||||
{
|
||||
ret = pnetif->pdrv->if_yield(pnetif, timeout);
|
||||
}
|
||||
if (ret != NET_OK)
|
||||
{
|
||||
NET_DBG_ERROR("Interface yield failed!!!");
|
||||
ret = NET_ERROR_STATE_TRANSITION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Incorrect requested State transition");
|
||||
ret = NET_ERROR_INVALID_STATE_TRANSITION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* @brief Connect network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
return net_state_manage_event(pnetif, NET_EVENT_CMD_CONNECT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* @brief Disconnect network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
return net_state_manage_event(pnetif, NET_EVENT_CMD_DISCONNECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get network interface state
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param state a pointer to a net_state_t enum
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_getState(net_if_handle_t *pnetif_in, net_state_t *state)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
*state = pnetif->state;
|
||||
ret = NET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @defgroup State
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable power save mode
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_powersave_enable(net_if_handle_t *pnetif_in)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
if (pnetif->state == NET_STATE_CONNECTED)
|
||||
{
|
||||
ret = pnetif->pdrv->if_powersave_enable(pnetif);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Power-save cannot be enabled when the device is not connected");
|
||||
ret = NET_ERROR_INVALID_STATE_TRANSITION;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @defgroup GetAndSet Get and Set Network Interface information
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief get MAC address
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param mac a pointer to an allocated macaddr_t structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_get_mac_address(net_if_handle_t *pnetif_in, macaddr_t *mac)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
if (NET_STATE_DEINITIALIZED != pnetif->state)
|
||||
{
|
||||
(void) memcpy(mac, &pnetif->macaddr, sizeof(macaddr_t));
|
||||
ret = NET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
NET_DBG_ERROR("Interface not yet initialized or in error state");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get IP address
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param ip a pointer to an allocated net_ip_addr_t structure
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_get_ip_address(net_if_handle_t *pnetif_in, net_ip_addr_t *ip)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
if (pnetif->state == NET_STATE_CONNECTED)
|
||||
{
|
||||
*ip = pnetif->ipaddr;
|
||||
ret = NET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Can get ipaddr for un connected network interface");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief get host by name
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param name is a pointer to the hostname string
|
||||
* @param addr is a pointer to the structure net_sockaddr_t
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_gethostbyname(net_if_handle_t *pnetif_in, net_sockaddr_t *addr, char_t *name)
|
||||
{
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
ret = pnetif->pdrv->pgethostbyname(pnetif, addr, name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ping a remote machine
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param addr is a pointer to the socketaddr of the remote host
|
||||
* @param count is an integer, number of iteration to ping the remote machine
|
||||
* @param delay is an integer, maximum delay in millisecond to wait for remote answer
|
||||
* @param response is an array of <count> integer, containing the time to get response for each iteration.
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_ping(net_if_handle_t *pnetif_in, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t response[])
|
||||
{
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
ret = pnetif->pdrv->pping(pnetif, addr, count, delay, response);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enable or disable dhcp mode
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param mode is a boolean , true to activate DHCP
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_set_dhcp_mode(net_if_handle_t *pnetif_in, bool mode)
|
||||
{
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
pnetif->dhcp_mode = mode;
|
||||
ret = NET_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setting ipaddr , gateway and netmask forcurrent network interface
|
||||
* @param pnetif a pointer to an allocated network interface structure
|
||||
* @param ipaddr is a pointer to and net_ip_addr_t structure used as ip address
|
||||
* @param gateway is a pointer to the net_ip_addr_t structure used as gateway address
|
||||
* @param netmask is a pointer to the net_ip_addr_t structure used as the netmask
|
||||
* @retval 0 in case of success, an error code otherwise
|
||||
*/
|
||||
int32_t net_if_set_ipaddr(net_if_handle_t *pnetif_in, net_ip_addr_t ipaddr,
|
||||
net_ip_addr_t gateway, net_ip_addr_t netmask)
|
||||
{
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
pnetif->static_ipaddr = ipaddr;
|
||||
pnetif->static_gateway = gateway;
|
||||
pnetif->static_netmask = netmask;
|
||||
ret = NET_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** @defgroup GetAndSet
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -0,0 +1,819 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_os.c
|
||||
* @author MCD Application Team
|
||||
* @brief OS needed functions implementation
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
|
||||
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#endif /* osCMSIS */
|
||||
|
||||
extern void *pxCurrentTCB;
|
||||
|
||||
|
||||
static osSemaphoreId net_mutex[NET_LOCK_NUMBER];
|
||||
|
||||
void net_init_locks(void)
|
||||
{
|
||||
#if (osCMSIS < 0x20000U)
|
||||
static osSemaphoreDef_t mutex_def[NET_LOCK_NUMBER] = {0};
|
||||
#endif /* osCMSIS */
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
net_tls_init();
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
for (int32_t i = 0; i < NET_LOCK_NUMBER; i++)
|
||||
{
|
||||
#if (osCMSIS < 0x20000U)
|
||||
net_mutex[i] = osSemaphoreCreate(&mutex_def[i], 1);
|
||||
#else
|
||||
net_mutex[i] = osSemaphoreNew(1, 1, NULL);
|
||||
|
||||
#endif /* osCMSIS */
|
||||
NET_ASSERT(net_mutex[i] > 0, "Failed on mutex creation");
|
||||
}
|
||||
}
|
||||
|
||||
void net_destroy_locks(void)
|
||||
{
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
net_tls_destroy();
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
for (int32_t i = 0; i < NET_LOCK_NUMBER; i++)
|
||||
{
|
||||
(void)osSemaphoreDelete(net_mutex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void net_lock(int32_t sock, uint32_t timeout_in)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t timeout = timeout_in;
|
||||
if (timeout == NET_OS_WAIT_FOREVER)
|
||||
{
|
||||
/*MISRA issue so hand coded osWaitForever*/
|
||||
timeout = 0xffffffffU;
|
||||
}
|
||||
ret = (int32_t) OSSEMAPHOREWAIT(net_mutex[sock], timeout);
|
||||
NET_ASSERT(ret == 0, "Failed locking mutex");
|
||||
}
|
||||
|
||||
void net_unlock(int32_t sock)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = (int32_t) osSemaphoreRelease(net_mutex[sock]);
|
||||
NET_ASSERT(ret == 0, "Failed unlocking mutex");
|
||||
}
|
||||
|
||||
void net_lock_nochk(int32_t sock, uint32_t timeout_in)
|
||||
{
|
||||
uint32_t timeout = timeout_in;
|
||||
if (timeout == NET_OS_WAIT_FOREVER)
|
||||
{
|
||||
/* MISRA issue so hand coded t osWaitForever*/
|
||||
timeout = 0xffffffffU;
|
||||
}
|
||||
(void) OSSEMAPHOREWAIT(net_mutex[sock], timeout);
|
||||
}
|
||||
|
||||
void net_unlock_nochk(int32_t sock)
|
||||
{
|
||||
(void) osSemaphoreRelease(net_mutex[sock]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(NET_ALLOC_DEBUG)
|
||||
|
||||
/*cstat -MISRAC2012-Rule-21.2 */
|
||||
void *net_calloc(size_t n, size_t m)
|
||||
{
|
||||
void *p;
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
p = pvPortMalloc(n * m);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (p != NULL)
|
||||
{
|
||||
(void) memset(p, 0, n * m);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *net_realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if (size != (size_t) 0)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
ret = pvPortMalloc(size);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (ret == NULL)
|
||||
{
|
||||
/* to avoid erroneous MISRA detection */
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size != (size_t) 0)
|
||||
{
|
||||
void *new_ptr;
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
new_ptr = pvPortMalloc(size);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (new_ptr != NULL)
|
||||
{
|
||||
(void) memcpy(new_ptr, ptr, size);
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
vPortFree(ptr);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
ret = new_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
vPortFree(ptr);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !NET_ALLOC_DEBUG */
|
||||
|
||||
/* below function are not supposed to be used , all malloc /free should be mapped to NET_MALLOC/NET_FREE macros */
|
||||
/* if not the case , it means that some mapping are missing */
|
||||
/* Using directly the malloc/free prevent to track orginal locatino of memory leakages */
|
||||
|
||||
/*cstat -MISRAC2012-Rule-21.2 */
|
||||
|
||||
void *realloc(void *p, size_t n)
|
||||
{
|
||||
return NET_REALLOC(p, n);
|
||||
}
|
||||
|
||||
void *calloc(size_t n, size_t m)
|
||||
{
|
||||
return NET_CALLOC(n, m);
|
||||
}
|
||||
|
||||
|
||||
void *malloc(size_t n)
|
||||
{
|
||||
return NET_MALLOC(n);
|
||||
}
|
||||
|
||||
void free(void *p)
|
||||
{
|
||||
NET_FREE(p);
|
||||
}
|
||||
/*cstat +MISRAC2012-Rule-21.2 */
|
||||
|
||||
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef NET_ALLOC_DEBUG
|
||||
|
||||
|
||||
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
|
||||
#define NET_DISPLAY_RESULT_COLUMN (NET_DISPLAY_WIDTH-((2U*NET_DISPLAY_RESULT_WIDTH)+1U))
|
||||
|
||||
typedef struct net_alloc_node_s
|
||||
{
|
||||
const char_t *name;
|
||||
uint32_t namelen;
|
||||
struct net_alloc_node_s *down;
|
||||
struct net_alloc_node_s *up;
|
||||
struct net_alloc_node_s *neighbour;
|
||||
uint32_t current_alloc;
|
||||
uint32_t max_total_alloc;
|
||||
}
|
||||
net_alloc_node_t;
|
||||
|
||||
|
||||
static net_alloc_node_t node[NET_ALLOC_MAX_NODE + 1];
|
||||
static net_alloc_node_t *root_node;
|
||||
static uint32_t max_node;
|
||||
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
|
||||
typedef struct net_debug_alloc
|
||||
{
|
||||
const char_t *filename;
|
||||
uint16_t line;
|
||||
uint16_t iter;
|
||||
uint32_t size;
|
||||
void *p;
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
net_alloc_node_t *node;
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
} net_debug_alloc_t;
|
||||
|
||||
static uint32_t current_alloc = 0;
|
||||
static uint32_t max_total_alloc = 0;
|
||||
|
||||
static uint32_t iteralloc = 0;
|
||||
static uint32_t iterfree = 0;
|
||||
static uint32_t max_alive_alloc = 0;
|
||||
static net_debug_alloc_t allocated_info[NET_LEAKAGE_ARRAY];
|
||||
|
||||
|
||||
void *net_calloc_debug(size_t n, size_t msize, const char_t *filename, uint32_t line)
|
||||
{
|
||||
/*cstat -MISRAC2012-Dir-4.12 */
|
||||
void *p = net_malloc_debug(n * msize, filename, line);
|
||||
/*cstat +MISRAC2012-Dir-4.12 */
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
(void) memset(p, 0, n * msize);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *net_realloc_debug(void *p, size_t size, const char_t *filename, uint32_t line)
|
||||
{
|
||||
void *ret;
|
||||
if (p == NULL)
|
||||
{
|
||||
if (size != (size_t) 0)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
ret = net_malloc_debug(size, filename, line);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (ret == NULL)
|
||||
{
|
||||
/* to avoid erroneous MISRA detection */
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size != (size_t) 0)
|
||||
{
|
||||
void *new_ptr;
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
new_ptr = net_malloc_debug(size, filename, line);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (new_ptr != NULL)
|
||||
{
|
||||
(void) memcpy(new_ptr, p, size);
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
net_free_debug(p);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
ret = new_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
net_free_debug(p);
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
|
||||
static uint32_t getdirlen(const char_t *filename_in)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
const char_t *filename = filename_in;
|
||||
|
||||
if (*filename != '\0')
|
||||
{
|
||||
|
||||
if (*filename == '\\')
|
||||
{
|
||||
len = 1;
|
||||
filename++;
|
||||
}
|
||||
|
||||
if ((filename[0] == 'C') && (filename[1] == ':') && (filename[2] == '\\'))
|
||||
{
|
||||
len = 3;
|
||||
filename++;
|
||||
filename++;
|
||||
filename++;
|
||||
}
|
||||
|
||||
while ((*filename != '\0') && (*filename != '\\'))
|
||||
{
|
||||
len++;
|
||||
filename++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static net_alloc_node_t *get_new_node(const char_t *filename, uint32_t dir_name_len, uint32_t n)
|
||||
{
|
||||
net_alloc_node_t *p = &node[max_node];
|
||||
uint32_t next_dir_name_len = getdirlen(&filename[dir_name_len]);
|
||||
|
||||
max_node++;
|
||||
p->current_alloc = n;
|
||||
p->max_total_alloc = n;
|
||||
p->name = filename;
|
||||
p->namelen = dir_name_len;
|
||||
if (max_node == NET_ALLOC_MAX_NODE)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
(void) printf("ERROR: Please increase NET_ALLOC_MAX_NODE, current value %lu is too low\n", NET_ALLOC_MAX_NODE);
|
||||
}
|
||||
}
|
||||
|
||||
if (next_dir_name_len != 0U)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-17.2_a */
|
||||
p->down = get_new_node(&filename[dir_name_len], next_dir_name_len, n);
|
||||
/*cstat +MISRAC2012-Rule-17.2_a */
|
||||
p->down->up = p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static net_alloc_node_t *net_walk_malloc_node(net_alloc_node_t *root, const char_t *filename, uint32_t n)
|
||||
{
|
||||
net_alloc_node_t *p = root;
|
||||
uint32_t dir_name_len = getdirlen(filename);
|
||||
|
||||
/* search amoung the neighbour (same level tree) */
|
||||
while (NULL != p)
|
||||
{
|
||||
if (strncmp(p->name, filename, dir_name_len) == 0)
|
||||
{
|
||||
/* find a matching neighbour */
|
||||
p->current_alloc += n;
|
||||
if (p->current_alloc > p->max_total_alloc)
|
||||
{
|
||||
p->max_total_alloc = p->current_alloc;
|
||||
}
|
||||
/*printf("ALLOC %s %d %d inc %d\n",filename,p->max_total_alloc,p->current_alloc,n);*/
|
||||
/* Did not reach a leaf so continue down in the tree */
|
||||
if (filename[dir_name_len] != '\0')
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-17.2_a */
|
||||
p = net_walk_malloc_node(p->down, &filename[dir_name_len], n);
|
||||
/*cstat +MISRAC2012-Rule-17.2_a */
|
||||
}
|
||||
break;
|
||||
}
|
||||
p = p->neighbour;
|
||||
}
|
||||
|
||||
if (NULL == p)
|
||||
{
|
||||
/* create a new neighbour and all the associated tree */
|
||||
p = get_new_node(filename, dir_name_len, n);
|
||||
/* add to neighbour list */
|
||||
if (NULL != root)
|
||||
{
|
||||
p->up = root->up;
|
||||
p->neighbour = root->neighbour;
|
||||
root->neighbour = p;
|
||||
}
|
||||
/* but we should return the leaf */
|
||||
while (NULL != p->down)
|
||||
{
|
||||
p = p->down;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void net_walk_free_node(net_alloc_node_t *node_in, uint32_t n)
|
||||
{
|
||||
net_alloc_node_t *node = node_in;
|
||||
while (NULL != node)
|
||||
{
|
||||
node->current_alloc -= n;
|
||||
/*printf("FREE %s %d %d inc %d\n",node->name,node->max_total_alloc,node->current_alloc,n);*/
|
||||
node = node->up;
|
||||
}
|
||||
}
|
||||
|
||||
static net_alloc_node_t *net_malloc_tree_start(net_alloc_node_t *root)
|
||||
{
|
||||
net_alloc_node_t *p = root;
|
||||
|
||||
while (NULL == p->down->neighbour)
|
||||
{
|
||||
p = p->down;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void net_malloc_tree_print(net_alloc_node_t *root, uint32_t level)
|
||||
{
|
||||
net_alloc_node_t *p = root;
|
||||
if (level == 0U)
|
||||
{
|
||||
(void) printf("\n### Dynamic Allocation tree report, uses %lu nodes out of %lu (%lu bytes)\n", max_node,
|
||||
NET_ALLOC_MAX_NODE, max_node * sizeof(net_alloc_node_t));
|
||||
for (uint32_t i = 0U; i < NET_DISPLAY_RESULT_COLUMN; i++)
|
||||
{
|
||||
(void) printf("-");
|
||||
}
|
||||
(void) printf("%*s %*s", NET_DISPLAY_RESULT_WIDTH, "Maximum", NET_DISPLAY_RESULT_WIDTH, "Leakage");
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
while (NULL != p)
|
||||
{
|
||||
{
|
||||
char_t s[100];
|
||||
uint32_t w = level;
|
||||
uint32_t n = NET_DISPLAY_RESULT_COLUMN - ((level + 1U) * NET_DISPLAY_TAB) - NET_DISPLAY_DIRNAME_LEN;
|
||||
(void) strncpy(s, &p->name[1], p->namelen - 1U);
|
||||
s[p->namelen - 1U] = '\0';
|
||||
(void) printf("%*c", NET_DISPLAY_TAB, ' ');
|
||||
while (w != 0U)
|
||||
{
|
||||
w--;
|
||||
(void) printf(".");
|
||||
#if (NET_DISPLAY_TAB>1)
|
||||
(void)printf("%*c", NET_DISPLAY_TAB - 1U, ' ');
|
||||
#endif /* NET_DISPLAY_TAB */
|
||||
}
|
||||
(void) printf("%-*s", NET_DISPLAY_DIRNAME_LEN, s);
|
||||
if ((NULL != p->down) && (p->down->max_total_alloc == p->max_total_alloc)
|
||||
&& (p->down->current_alloc == p->current_alloc))
|
||||
{
|
||||
(void) printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) printf("%*c%*d %*d\n", n, ' ', NET_DISPLAY_RESULT_WIDTH, p->max_total_alloc, NET_DISPLAY_RESULT_WIDTH,
|
||||
p->current_alloc);
|
||||
}
|
||||
}
|
||||
/*cstat -MISRAC2012-Rule-17.2_a */
|
||||
net_malloc_tree_print(p->down, level + 1U);
|
||||
/*cstat +MISRAC2012-Rule-17.2_a */
|
||||
p = p->neighbour;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
|
||||
|
||||
void *net_malloc_debug(size_t n, const char_t *filename, uint32_t line)
|
||||
{
|
||||
|
||||
void *p;
|
||||
uint32_t i;
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
vTaskSuspendAll();
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
if (iteralloc == 0U)
|
||||
{
|
||||
(void) memset(allocated_info, 0, sizeof(allocated_info));
|
||||
current_alloc = 0;
|
||||
max_total_alloc = 0;
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
max_node = 0;
|
||||
root_node = NULL;
|
||||
(void) memset(node, 0, sizeof(node));
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
}
|
||||
|
||||
|
||||
iteralloc++;
|
||||
current_alloc += n;
|
||||
if (current_alloc > max_total_alloc)
|
||||
{
|
||||
max_total_alloc = current_alloc;
|
||||
}
|
||||
/*printf("-ALLOC- Max %d Current %d inc %d\n",max_total_alloc,current_alloc,n);*/
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
p = pvPortMalloc(n);
|
||||
#else
|
||||
/*cstat -MISRAC2012-Dir-4.12 -MISRAC2012-Dir-4.7_b -MISRAC2012-Rule-21.3 */
|
||||
p = malloc(n);
|
||||
/*cstat +MISRAC2012-Dir-4.12 +MISRAC2012-Dir-4.7_b +MISRAC2012-Rule-21.3 */
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
if ((iteralloc - iterfree) > max_alive_alloc)
|
||||
{
|
||||
max_alive_alloc = iteralloc - iterfree;
|
||||
}
|
||||
|
||||
for (i = 0; i < NET_LEAKAGE_ARRAY ; i++)
|
||||
{
|
||||
if (allocated_info[i].p == 0U)
|
||||
{
|
||||
allocated_info[i].p = p ;
|
||||
allocated_info[i].size = n ;
|
||||
allocated_info[i].line = (uint16_t) line ;
|
||||
allocated_info[i].filename = filename;
|
||||
allocated_info[i].iter = (uint16_t) iteralloc;
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
allocated_info[i].node = net_walk_malloc_node(root_node, filename, n);
|
||||
if (NULL == root_node)
|
||||
{
|
||||
root_node = allocated_info[i].node;
|
||||
/* we got the leaf , so move to top */
|
||||
while (NULL != root_node->up)
|
||||
{
|
||||
root_node = root_node->up;
|
||||
}
|
||||
}
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
NET_ASSERT((iteralloc != NET_ALLOC_BREAK), "Reach Allocation break\n");
|
||||
|
||||
NET_ASSERT((i != NET_LEAKAGE_ARRAY), "Too much allocations,Please increase NET_LEAKAGE_ARRAY (%lu)in net_conf.h",
|
||||
NET_LEAKAGE_ARRAY);
|
||||
#if NET_ALLOC_VERBOSE
|
||||
(void) printf("%lu bytes allocated: Allocating size %lu at %s:%lu\n", total_alloc, allocated_info[i].size,
|
||||
allocated_info[i].filename, allocated_info[i].line);
|
||||
#endif /* NET_ALLOC_VERBOSE */
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
(void) xTaskResumeAll();
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void net_free_debug(void *p)
|
||||
{
|
||||
uint32_t i;
|
||||
#ifdef NET_USE_RTOS
|
||||
vPortFree(p);
|
||||
vTaskSuspendAll();
|
||||
#else
|
||||
/*cstat -MISRAC2012-Rule-21.3 */
|
||||
free(p);
|
||||
/*cstat +MISRAC2012-Rule-21.3 */
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
#ifdef NET_FREE_STOP_ON_NULL_POINTER
|
||||
if (NULL == p)
|
||||
{
|
||||
(void) printf("Free function : Freeing a NULL pointer, seriously ?\n");
|
||||
while (1);
|
||||
}
|
||||
#endif /* NET_STOP_ON_FREEING_NULL_POINTER */
|
||||
|
||||
if (NULL != p)
|
||||
{
|
||||
iterfree++;
|
||||
for (i = 0; i < NET_LEAKAGE_ARRAY; i++)
|
||||
{
|
||||
if (allocated_info[i].p == p)
|
||||
{
|
||||
allocated_info[i].p = NULL;
|
||||
current_alloc -= allocated_info[i].size;
|
||||
/*printf("-FREE- Max %d Current %d inc %d\n",max_total_alloc,current_alloc,allocated_info[i].size);*/
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
net_walk_free_node(allocated_info[i].node, allocated_info[i].size);
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
allocated_info[i].size = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NET_LEAKAGE_ARRAY)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-1.3_o -MISRAC2012-Rule-1.3_p -MISRAC2012-Dir-4.7_b -MISRAC2012-Dir-4.13_e -MISRAC2012-Dir-4.13_d */
|
||||
(void) printf("Free function : did not find this segment %p\n", p);
|
||||
/*cstat +MISRAC2012-Rule-1.3_o +MISRAC2012-Rule-1.3_p +MISRAC2012-Dir-4.7_b +MISRAC2012-Dir-4.13_e +MISRAC2012-Dir-4.13_d */
|
||||
while (true) {};
|
||||
}
|
||||
}
|
||||
#ifdef NET_USE_RTOS
|
||||
(void) xTaskResumeAll();
|
||||
#endif /* NET_USE_RTOS */
|
||||
}
|
||||
|
||||
void net_alloc_report(void)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t count = 0;
|
||||
uint32_t leak = 0;
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
vTaskSuspendAll();
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
(void) printf("\n### Net Malloc report: max alloc: %lu bytes, current leakage: %lu bytes, number of allocation: %lu, number of free: %lu, alloc table usage %lu/%lu (%lu) bytes\n\n",
|
||||
max_total_alloc, current_alloc, iteralloc, iterfree, max_alive_alloc, NET_LEAKAGE_ARRAY, sizeof(allocated_info));
|
||||
|
||||
for (i = 0; i < NET_LEAKAGE_ARRAY; i++)
|
||||
{
|
||||
if (allocated_info[i].p != 0)
|
||||
{
|
||||
count++;
|
||||
leak += allocated_info[i].size;
|
||||
(void) printf("\tAllocation number #%lu Not free %p size %lu at %s:%lu\n", allocated_info[i].iter, allocated_info[i].p,
|
||||
allocated_info[i].size, allocated_info[i].filename, allocated_info[i].line);
|
||||
}
|
||||
}
|
||||
(void) printf("\n%lu allocation not freed %lu bytes out of %lu allocated byte\n\n", count, leak, max_total_alloc);
|
||||
|
||||
#ifdef NET_ALLOC_DEBUG_TREE
|
||||
net_malloc_tree_print(net_malloc_tree_start(root_node), 0);
|
||||
#endif /* NET_ALLOC_DEBUG_TREE */
|
||||
(void) printf("\n### Net Malloc end report\n");
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
(void) xTaskResumeAll();
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
}
|
||||
|
||||
#endif /* NET_DEBUG_ALLOC */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct net_perf
|
||||
{
|
||||
uint32_t total;
|
||||
#if defined(NET_USE_RTOS) && defined(NET_PERF_TASK)
|
||||
uint32_t elapsed_cycle[NET_PERF_MAXTHREAD];
|
||||
TaskHandle_t handle[NET_PERF_MAXTHREAD];
|
||||
#endif
|
||||
}
|
||||
perf;
|
||||
|
||||
|
||||
#if defined(NET_PERF_TASK)
|
||||
|
||||
/**
|
||||
* @brief Executed for each context switch in
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
#if !defined(NET_USE_RTOS)
|
||||
#error "NET_USE_RTOS must be defined to use NET_PERF_TASK"
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
void net_perf_task_in(void)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
TaskHandle_t xHandle = xTaskGetCurrentTaskHandle();
|
||||
for (i = 0; i < NET_PERF_MAXTHREAD; i++)
|
||||
{
|
||||
if (NULL == perf.handle[i])
|
||||
{
|
||||
/* new thread */
|
||||
perf.handle[i] = xHandle;
|
||||
}
|
||||
if (xHandle == perf.handle[i])
|
||||
{
|
||||
perf.elapsed_cycle[i] -= net_get_cycle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
NET_ASSERT(NET_PERF_MAXTHREAD != i, "Net perf ,please increase NET_PERF_MAX_THREAD");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Executed for each context switch out
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void net_perf_task_out(void)
|
||||
{
|
||||
uint32_t i;
|
||||
TaskHandle_t xHandle = xTaskGetCurrentTaskHandle();
|
||||
for (i = 0; i < NET_PERF_MAXTHREAD; i++)
|
||||
{
|
||||
if (NULL == perf.handle[i])
|
||||
{
|
||||
/* new thread */
|
||||
perf.handle[i] = xHandle;
|
||||
while (true) { };
|
||||
}
|
||||
if (xHandle == perf.handle[i])
|
||||
{
|
||||
perf.elapsed_cycle[i] += net_get_cycle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
NET_ASSERT(NET_PERF_MAXTHREAD != i, "Net perf ,please increase NET_PERF_MAX_THREAD");
|
||||
}
|
||||
|
||||
static const char_t *GetTaskName(TaskHandle_t xHandle)
|
||||
{
|
||||
TaskStatus_t xTaskDetails;
|
||||
vTaskGetInfo( /* The handle of the task being queried. */
|
||||
xHandle,
|
||||
/* The TaskStatus_t structure to complete with information
|
||||
on xTask. */
|
||||
&xTaskDetails,
|
||||
/* Include the stack high water mark value in the
|
||||
TaskStatus_t structure. */
|
||||
pdTRUE,
|
||||
/* Include the task state in the TaskStatus_t structure. */
|
||||
eInvalid);
|
||||
return (const char_t *)xTaskDetails.pcTaskName;
|
||||
}
|
||||
#endif /* NET_PERF_TASK */
|
||||
|
||||
|
||||
void net_perf_start(void)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.4 */
|
||||
NET_DWT_CONTROL |= NET_DWT_CYCCNTENA_BIT ;
|
||||
NET_DWT_CYCCNT = 0U;
|
||||
/*cstat +MISRAC2012-Rule-11.4 */
|
||||
(void) memset(&perf, 0, sizeof(perf));
|
||||
#if defined(NET_PERF_TASK)
|
||||
net_perf_task_in();
|
||||
#endif /* NET_PERF_TASK */
|
||||
}
|
||||
|
||||
void net_perf_report(void)
|
||||
{
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
#if defined(NET_PERF_TASK)
|
||||
net_perf_task_out();
|
||||
#endif /* NET_PERF_TASK */
|
||||
perf.total += net_get_cycle();
|
||||
(void) printf("\n### Net Performance report CPU Freq %3lu Mhz\n\n", SystemCoreClock / 1000000U);
|
||||
(void) printf("\tTotal %12lu cycles %8lu ms\n", perf.total, perf.total / (SystemCoreClock / 1000U));
|
||||
#if defined(NET_PERF_TASK)
|
||||
uint32_t count = 0;
|
||||
(void) printf("\n");
|
||||
while (perf.handle[count] != 0)
|
||||
{
|
||||
(void) printf("\tthread #%lu %25s : %12lu cycles %7lu ms\n", count, GetTaskName(perf.handle[count]),
|
||||
perf.elapsed_cycle[count], perf.elapsed_cycle[count] / (SystemCoreClock / 1000U));
|
||||
count++;
|
||||
}
|
||||
#endif /* NET_PERF_TASK */
|
||||
(void) printf("\n### Net Performance end report\n\n");
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_state.c
|
||||
* @author MCD Application Team
|
||||
* @brief Management of state machine for network interfaces
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "stdarg.h"
|
||||
#ifdef DEBUGSTATE
|
||||
static const char_t *eventstr[] =
|
||||
{
|
||||
"NET_EVENT_CMD_INIT",
|
||||
"NET_EVENT_CMD_START",
|
||||
"NET_EVENT_CMD_CONNECT",
|
||||
"NET_EVENT_CMD_DISCONNECT",
|
||||
"NET_EVENT_CMD_STOP",
|
||||
"NET_EVENT_CMD_DEINIT",
|
||||
"NET_EVENT_INTERFACE_INITIALIZED",
|
||||
"NET_EVENT_INTERFACE_READY",
|
||||
"NET_EVENT_LINK_UP",
|
||||
"NET_EVENT_LINK_DOWN",
|
||||
"NET_EVENT_IPADDR",
|
||||
};
|
||||
|
||||
|
||||
static const char_t *statestr[] =
|
||||
{
|
||||
"NET_STATE_DEINITIALIZED",
|
||||
"NET_STATE_INITIALIZED",
|
||||
"NET_STATE_STARTING",
|
||||
"NET_STATE_READY",
|
||||
"NET_STATE_CONNECTING",
|
||||
"NET_STATE_CONNECTED",
|
||||
"NET_STATE_STOPPING",
|
||||
"NET_STATE_DISCONNECTING",
|
||||
"NET_STATE_CONNECTION_LOST",
|
||||
};
|
||||
#endif /* DEBUGSTATE */
|
||||
|
||||
static void set_state(net_if_handle_t *pnetif, net_state_t state)
|
||||
{
|
||||
pnetif->state = state;
|
||||
net_if_notify(pnetif, NET_EVENT_STATE_CHANGE, (uint32_t) state, NULL);
|
||||
SIGNAL_STATE_CHANGE();
|
||||
}
|
||||
|
||||
|
||||
static int32_t net_state_initialized(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_CMD_START:
|
||||
set_state(pnetif, NET_STATE_STARTING);
|
||||
ret = pnetif->pdrv->if_start(pnetif);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot be started.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_EVENT_CMD_DEINIT:
|
||||
ret = pnetif->pdrv->if_deinit(pnetif);
|
||||
set_state(pnetif, NET_STATE_DEINITIALIZED);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot be deinitialized.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_starting(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_INTERFACE_READY:
|
||||
set_state(pnetif, NET_STATE_READY);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_ready(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_CMD_CONNECT:
|
||||
set_state(pnetif, NET_STATE_CONNECTING);
|
||||
ret = pnetif->pdrv->if_connect(pnetif);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot connect.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_EVENT_CMD_STOP:
|
||||
set_state(pnetif, NET_STATE_STOPPING);
|
||||
ret = pnetif->pdrv->if_stop(pnetif);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot stop.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_connecting(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_IPADDR:
|
||||
set_state(pnetif, NET_STATE_CONNECTED);
|
||||
break;
|
||||
|
||||
case NET_EVENT_CMD_DISCONNECT:
|
||||
set_state(pnetif, NET_STATE_READY);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_connected(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_CMD_DISCONNECT:
|
||||
set_state(pnetif, NET_STATE_DISCONNECTING);
|
||||
ret = pnetif->pdrv->if_disconnect(pnetif);
|
||||
if (NET_OK != ret)
|
||||
{
|
||||
NET_DBG_ERROR("Interface cannot disconnect.");
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NET_EVENT_LINK_DOWN:
|
||||
set_state(pnetif, NET_STATE_CONNECTION_LOST);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_disconnecting(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_INTERFACE_READY:
|
||||
set_state(pnetif, NET_STATE_READY);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_stopping(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
case NET_EVENT_INTERFACE_INITIALIZED:
|
||||
set_state(pnetif, NET_STATE_INITIALIZED);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_state_connection_lost(net_if_handle_t *pnetif, net_state_event_t event)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
switch (event)
|
||||
{
|
||||
|
||||
case NET_EVENT_LINK_UP:
|
||||
set_state(pnetif, NET_STATE_CONNECTED);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t net_state_manage_event(net_if_handle_t *pnetif_in, net_state_event_t event)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_handle_t *pnetif;
|
||||
|
||||
pnetif = netif_check(pnetif_in);
|
||||
if (pnetif == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("Invalid interface.");
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUGSTATE
|
||||
printf("In state %s , received event %s\n", statestr[pnetif->state], eventstr[event]);
|
||||
#endif /* DEBUGSTATE */
|
||||
switch (pnetif->state)
|
||||
{
|
||||
case NET_STATE_INITIALIZED:
|
||||
ret = net_state_initialized(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_STARTING:
|
||||
ret = net_state_starting(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_READY:
|
||||
ret = net_state_ready(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_CONNECTING:
|
||||
ret = net_state_connecting(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_CONNECTED:
|
||||
ret = net_state_connected(pnetif, event);
|
||||
break;
|
||||
case NET_STATE_DISCONNECTING:
|
||||
ret = net_state_disconnecting(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_CONNECTION_LOST:
|
||||
ret = net_state_connection_lost(pnetif, event);
|
||||
break;
|
||||
|
||||
case NET_STATE_STOPPING:
|
||||
ret = net_state_stopping(pnetif, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = NET_ERROR_INVALID_STATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/C/users/gentit/Doxygen/bin/Release/doxygen.exe doxyconfig
|
||||
File diff suppressed because it is too large
Load Diff
+1443
File diff suppressed because it is too large
Load Diff
+143
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ethernet_driver.c
|
||||
* @author MCD Application Team
|
||||
* @brief Ethernet specific BSD-like socket wrapper
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "net_ip_ethernet.h"
|
||||
#include "net_ip_lwip.h"
|
||||
|
||||
/* global constructor of the ethernet network interface */
|
||||
int32_t ethernet_net_driver(net_if_handle_t *pnetif);
|
||||
|
||||
|
||||
static int32_t net_ethernet_if_init(net_if_handle_t *pnetif);
|
||||
static int32_t net_ethernet_if_deinit(net_if_handle_t *pnetif);
|
||||
static int32_t net_ethernet_if_start(net_if_handle_t *pnetif);
|
||||
static int32_t net_ethernet_if_stop(net_if_handle_t *pnetif);
|
||||
static int32_t net_ethernet_if_connect(net_if_handle_t *pnetif);
|
||||
static int32_t net_ethernet_if_disconnect(net_if_handle_t *pnetif);
|
||||
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
err_t ethernetif_deinit(struct netif *netif);
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
|
||||
int32_t ethernet_net_driver(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
net_ip_init();
|
||||
ret = net_ethernet_if_init(pnetif);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_ethernet_if_init(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
/*cstat -MISRAC2012-Rule-11.5 malloc cast*/
|
||||
net_if_drv_t *pdrv = NET_MALLOC(sizeof(net_if_drv_t));
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
|
||||
if (pdrv != NULL)
|
||||
{
|
||||
pdrv->if_class = NET_INTERFACE_CLASS_ETHERNET;
|
||||
pdrv->if_init = net_ethernet_if_init;
|
||||
pdrv->if_deinit = net_ethernet_if_deinit;
|
||||
pdrv->if_start = net_ethernet_if_start;
|
||||
pdrv->if_stop = net_ethernet_if_stop;
|
||||
pdrv->if_connect = net_ethernet_if_connect;
|
||||
pdrv->if_disconnect = net_ethernet_if_disconnect;
|
||||
pdrv->pping = icmp_ping;
|
||||
pnetif->pdrv = pdrv;
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
ret = NET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for es_wifi_driver class\n");
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t net_ethernet_if_start(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = net_ip_add_if(pnetif, ethernetif_init, NET_ETHERNET_FLAG_DEFAULT_IF);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
(void) strncpy(pnetif->DeviceName, "Ethernet IF", sizeof(pnetif->DeviceName));
|
||||
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
|
||||
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
|
||||
/* set call back , here to not loose first linkup when if_init is performed */
|
||||
netif_set_down(pnetif->netif);
|
||||
netif_set_link_down(pnetif->netif);
|
||||
|
||||
netif_set_status_callback(pnetif->netif, net_ip_status_cb);
|
||||
netif_set_link_callback(pnetif->netif, net_ip_status_cb);
|
||||
netif_set_link_up(pnetif->netif);
|
||||
netif_set_up(pnetif->netif);
|
||||
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_ethernet_if_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = net_ip_connect(pnetif);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_ethernet_if_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
(void) net_ip_disconnect(pnetif);
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_ethernet_if_stop(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
(void) net_ip_remove_if(pnetif, ethernetif_deinit);
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_ethernet_if_deinit(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
NET_FREE(pnetif->pdrv);
|
||||
pnetif->pdrv = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+675
@@ -0,0 +1,675 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ethernet_driver.c
|
||||
* @author MCD Application Team
|
||||
* @brief Ethernet specific BSD-like socket wrapper
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "net_ip_lwip.h"
|
||||
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "whd.h"
|
||||
#include "whd_debug.h"
|
||||
#include "whd_resource_api.h"
|
||||
#include "whd_wifi_api.h"
|
||||
#include "whd_network_types.h"
|
||||
#include "whd_types_int.h"
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
|
||||
#define NET_CYPRESS_MAX_INTERFACE 4
|
||||
|
||||
typedef struct net_cypress_key
|
||||
{
|
||||
void *key;
|
||||
void *value;
|
||||
} net_cypress_key_t;
|
||||
|
||||
static net_cypress_key_t netif2ifp[NET_CYPRESS_MAX_INTERFACE];
|
||||
static uint32_t cypress_alive_interface_count = 0;
|
||||
static whd_driver_t whd_driver;
|
||||
|
||||
/* create and boot WHD driver */
|
||||
cy_rslt_t whd_boot(whd_driver_t *whd_driver);
|
||||
cy_rslt_t whd_powerdown(whd_driver_t *whd_driver);
|
||||
|
||||
|
||||
/* global constructor of the ethernet network interface */
|
||||
int32_t cypress_whd_net_driver(net_if_handle_t *pnetif);
|
||||
|
||||
|
||||
|
||||
static err_t low_level_output(struct netif *netif, struct pbuf *p);
|
||||
static err_t low_level_init(struct netif *netif);
|
||||
static int32_t net_cypress_whd_if_init(net_if_handle_t *pnetif);
|
||||
static int32_t net_cypress_whd_if_deinit(net_if_handle_t *pnetif);
|
||||
static int32_t net_cypress_whd_if_start(net_if_handle_t *pnetif);
|
||||
static int32_t net_cypress_whd_if_stop(net_if_handle_t *pnetif);
|
||||
static int32_t net_cypress_whd_if_connect(net_if_handle_t *pnetif);
|
||||
static int32_t net_cypress_whd_if_disconnect(net_if_handle_t *pnetif);
|
||||
|
||||
static int32_t net_cypress_whd_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
|
||||
static int32_t net_cypress_whd_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int32_t cypress_whd_net_driver(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
/* init lwip library here if not already done by another network interface */
|
||||
net_ip_init();
|
||||
|
||||
ret = net_cypress_whd_if_init(pnetif);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_init(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
net_if_drv_t *pdrv = NET_MALLOC(sizeof(net_if_drv_t));
|
||||
if (pdrv != NULL)
|
||||
{
|
||||
pdrv->if_class = NET_INTERFACE_CLASS_WIFI;
|
||||
pdrv->if_init = net_cypress_whd_if_init;
|
||||
pdrv->if_deinit = net_cypress_whd_if_deinit;
|
||||
pdrv->if_start = net_cypress_whd_if_start;
|
||||
pdrv->if_stop = net_cypress_whd_if_stop;
|
||||
pdrv->if_connect = net_cypress_whd_if_connect;
|
||||
pdrv->if_disconnect = net_cypress_whd_if_disconnect;
|
||||
pdrv->pping = icmp_ping;
|
||||
pnetif->pdrv = pdrv;
|
||||
pdrv->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
|
||||
if (NULL == pdrv->extension.wifi)
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for wifi extension\n");
|
||||
NET_FREE(pdrv);
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) memset(pdrv->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
|
||||
pdrv->extension.wifi->scan = net_cypress_whd_scan;
|
||||
pdrv->extension.wifi->get_scan_results = net_cypress_whd_scan_result;
|
||||
|
||||
if (cypress_alive_interface_count == 0)
|
||||
{
|
||||
/* Boot cypress module and start whd driver for very first interface */
|
||||
if (WHD_SUCCESS != whd_boot(&whd_driver))
|
||||
{
|
||||
NET_DBG_ERROR("can't perform intialization of whd driver and module\n");
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
|
||||
NET_DBG_PRINT("WHD init driver done\n");
|
||||
(void) memset(netif2ifp, 0, sizeof(netif2ifp));
|
||||
|
||||
if (NET_OK == ret)
|
||||
{
|
||||
|
||||
if (WHD_SUCCESS != whd_wifi_on(whd_driver, (whd_interface_t *) &pdrv->extension.wifi->ifp))
|
||||
{
|
||||
NET_DBG_PRINT("Failed when creating WIFI default interface\n");
|
||||
NET_FREE(pdrv->extension.wifi);
|
||||
NET_FREE(pdrv);
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_PRINT("WHD init interface done\n");
|
||||
cypress_alive_interface_count++;
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
whd_mac_t mac_addr = {0xA0, 0xC9, 0xA0, 0X3D, 0x43, 0x41};
|
||||
if (WHD_SUCCESS != whd_add_secondary_interface(whd_driver, &mac_addr, (whd_interface_t *) &pdrv->extension.wifi->ifp))
|
||||
{
|
||||
NET_DBG_PRINT("Failed when creating WIFI default interface\n");
|
||||
NET_FREE(pdrv->extension.wifi);
|
||||
NET_FREE(pdrv);
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_PRINT("WHD init interface done\n");
|
||||
cypress_alive_interface_count++;
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for WHD driver class\n");
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void convert_credential(const net_wifi_credentials_t *credentials, whd_security_t *privacy, whd_ssid_t *myssid)
|
||||
{
|
||||
*privacy = (whd_security_t) credentials->security_mode;
|
||||
strcpy((char *) myssid->value, (char *) credentials->ssid);
|
||||
myssid->length = strlen((char *)myssid->value);
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_start_sta(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
whd_security_t privacy;
|
||||
whd_ssid_t myssid;
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
|
||||
convert_credential(credentials, &privacy, &myssid);
|
||||
|
||||
NET_DBG_PRINT("Joinning ... %s\n", myssid.value);
|
||||
|
||||
ret = whd_wifi_join((whd_interface_t)pnetif->pdrv->extension.wifi->ifp, (whd_ssid_t const *) &myssid, privacy,
|
||||
(uint8_t const *) credentials->psk, strlen(credentials->psk));
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR("can't join %s\n", myssid.value);
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_PRINT("Joined Access point %s\n", myssid.value);
|
||||
ret = net_ip_add_if(pnetif, low_level_init, NET_ETHERNET_FLAG_DEFAULT_IF);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
(void) strncpy(pnetif->DeviceName, "Wlan WHD murata 1LD", sizeof(pnetif->DeviceName));
|
||||
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
|
||||
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
netif_set_link_up(pnetif->netif);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't add interface (netif)\n");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_start_ap(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
whd_security_t privacy;
|
||||
whd_ssid_t myssid;
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
|
||||
NET_DBG_PRINT("Init Access Point ... %s\n", myssid.value);
|
||||
convert_credential(credentials, &privacy, &myssid);
|
||||
|
||||
ret = whd_wifi_init_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp, &myssid, privacy,
|
||||
(uint8_t const *) credentials->psk, strlen(credentials->psk),
|
||||
pnetif->pdrv->extension.wifi->access_channel);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR("can't init access point %s\n", myssid.value);
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = whd_wifi_start_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR("can't start access point %s\n", myssid.value);
|
||||
ret = NET_ERROR_MODULE_INITIALIZATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_PRINT("Start Access point %s\n", myssid.value);
|
||||
ret = net_ip_add_if(pnetif, low_level_init, NET_ETHERNET_FLAG_DEFAULT_IF);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
(void) strncpy(pnetif->DeviceName, "Wlan WHD murata 1LD", sizeof(pnetif->DeviceName));
|
||||
(void) strncpy(pnetif->DeviceID, "Unknown", sizeof(pnetif->DeviceID));
|
||||
(void) strncpy(pnetif->DeviceVer, "Unknown", sizeof(pnetif->DeviceVer));
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
netif_set_link_up(pnetif->netif);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't add interface (netif)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t net_cypress_whd_if_start(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
|
||||
{
|
||||
ret = net_cypress_whd_if_start_sta(pnetif);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = net_cypress_whd_if_start_ap(pnetif);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = net_ip_connect(pnetif);
|
||||
if (ret != NET_OK)
|
||||
{
|
||||
NET_DBG_ERROR("Failed to connect\n");
|
||||
ret = NET_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int32_t net_cypress_whd_if_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = net_ip_disconnect(pnetif);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_stop(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = net_ip_remove_if(pnetif, NULL);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
}
|
||||
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
|
||||
{
|
||||
whd_wifi_leave(pnetif->pdrv->extension.wifi->ifp);
|
||||
}
|
||||
else
|
||||
{
|
||||
whd_wifi_stop_ap((whd_interface_t)pnetif->pdrv->extension.wifi->ifp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t net_cypress_whd_if_deinit(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
uint32_t i;
|
||||
|
||||
/*Switch off Wifi*/
|
||||
whd_wifi_off(pnetif->pdrv->extension.wifi->ifp);
|
||||
|
||||
for (i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
|
||||
{
|
||||
if (netif2ifp[i].key == pnetif->pdrv->extension.wifi->ifp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NET_CYPRESS_MAX_INTERFACE)
|
||||
{
|
||||
WPRINT_WHD_DEBUG(("Couldn't find the interface \n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
netif2ifp[i].key = NULL;
|
||||
netif2ifp[i].value = NULL;
|
||||
|
||||
if (cypress_alive_interface_count == 1)
|
||||
{
|
||||
/*Deletes all the interface and De-init the whd, free whd_driver memory */
|
||||
whd_deinit(pnetif->pdrv->extension.wifi->ifp);
|
||||
whd_powerdown(&whd_driver);
|
||||
|
||||
}
|
||||
cypress_alive_interface_count--;
|
||||
NET_FREE(pnetif->pdrv->extension.wifi);
|
||||
NET_FREE(pnetif->pdrv);
|
||||
pnetif->pdrv = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static err_t low_level_init(struct netif *netif)
|
||||
{
|
||||
err_t ret = ERR_VAL;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
net_if_handle_t *pnetif = netif->state;
|
||||
whd_interface_t ifp = pnetif->pdrv->extension.wifi->ifp;
|
||||
|
||||
/* to retrieve back netif from ifp */
|
||||
for (int32_t i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
|
||||
{
|
||||
if (netif2ifp[i].key == NULL)
|
||||
{
|
||||
netif2ifp[i].key = ifp;
|
||||
netif2ifp[i].value = netif;
|
||||
ret = (err_t) ERR_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
netif->name[0] = 'c';
|
||||
netif->name[1] = 'y';
|
||||
|
||||
/* 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;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
|
||||
|
||||
/* Set MAC hardware address length ( 6)*/
|
||||
netif->hwaddr_len = (u8_t) ETHARP_HWADDR_LEN;
|
||||
|
||||
/* Setup the physical address of this IP instance. */
|
||||
if (whd_wifi_get_mac_address(ifp, (whd_mac_t *) netif->hwaddr) != WHD_SUCCESS)
|
||||
{
|
||||
WPRINT_WHD_DEBUG(("Couldn't get MAC address\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
WPRINT_WHD_DEBUG((" MAC address %x.%x.%x.%x.%x.%x\n", netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2],
|
||||
netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]));
|
||||
|
||||
/* Set Maximum Transfer Unit */
|
||||
netif->mtu = (u16_t) WHD_PAYLOAD_MTU;
|
||||
|
||||
/* Set device capabilities. Don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags = (u8_t)(NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET);
|
||||
|
||||
/* Do whatever else is needed to initialize interface. */
|
||||
#if LWIP_IGMP
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
netif_set_igmp_mac_filter(netif, lwip_igmp_mac_filter);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
/* Register a handler for any address changes and when interface goes up or down*/
|
||||
netif_set_status_callback(netif, net_ip_status_cb);
|
||||
netif_set_link_callback(netif, net_ip_status_cb);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
net_if_handle_t *pnetif = netif->state;
|
||||
whd_interface_t ifp = pnetif->pdrv->extension.wifi->ifp;
|
||||
|
||||
if (whd_wifi_is_ready_to_transceive(ifp) == WHD_SUCCESS)
|
||||
{
|
||||
/* Take a reference to this packet */
|
||||
pbuf_ref(p);
|
||||
#if 0
|
||||
NET_DBG_PRINT("Transmit buffer 1 %x next=%p tot-len=%d len=%d\n", p, p->next, p->tot_len, p->len);
|
||||
#endif /* for debug */
|
||||
LWIP_ASSERT("No chained buffers", ((p->next == NULL) && ((p->tot_len == p->len))));
|
||||
#ifdef NET_PERF
|
||||
stat.whd_send_cycle -= net_get_cycle();
|
||||
#endif /* NET_PERF */
|
||||
whd_network_send_ethernet_data((whd_interface_t) ifp, p);
|
||||
#ifdef NET_PERF
|
||||
/*stat.whd_send_cycle += net_get_cycle();*/
|
||||
#endif /* NET_PERF */
|
||||
LINK_STATS_INC(link.xmit);
|
||||
return (err_t) ERR_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_PRINT("cannot transmit wifi not rdy\n");
|
||||
|
||||
/* Stop lint warning about packet not being freed - it is not being referenced */ /*@-mustfree@*/
|
||||
return (err_t) ERR_INPROGRESS; /* Note that signalling ERR_CLSD or ERR_CONN causes loss of connectivity on a roam */
|
||||
/*@+mustfree@*/
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t cy_callback_tcpip = 0;
|
||||
uint32_t cy_callback = 0;
|
||||
|
||||
/**
|
||||
* 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 p : the incoming ethernet packet
|
||||
*/
|
||||
void cy_network_process_ethernet_data(whd_interface_t interface, whd_buffer_t buff)
|
||||
{
|
||||
|
||||
struct eth_hdr *ethernet_header;
|
||||
struct netif *tmp_netif;
|
||||
u8_t result;
|
||||
uint16_t ethertype;
|
||||
struct pbuf *buffer = (struct pbuf *) buff;
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* points to packet payload, which starts with an Ethernet header */
|
||||
ethernet_header = (struct eth_hdr *) buffer->payload;
|
||||
|
||||
ethertype = lwip_htons(ethernet_header->type);
|
||||
|
||||
#ifdef FILTER
|
||||
if (filter_ethernet_packet_callback != NULL && filter_ethertype == ethertype && filter_interface == interface)
|
||||
{
|
||||
filter_ethernet_packet_callback(buffer->payload, filter_userdata);
|
||||
}
|
||||
#endif /* FILTER */
|
||||
/* Check if this is an 802.1Q VLAN tagged packet */
|
||||
if (ethertype == WHD_ETHERTYPE_8021Q)
|
||||
{
|
||||
/* Need to remove the 4 octet VLAN Tag, by moving src and dest addresses 4 octets to the right,
|
||||
* and then read the actual ethertype. The VLAN ID and priority fields are currently ignored. */
|
||||
uint8_t temp_buffer[ 12 ];
|
||||
memcpy(temp_buffer, buffer->payload, 12);
|
||||
memcpy(((uint8_t *) buffer->payload) + 4, temp_buffer, 12);
|
||||
|
||||
buffer->payload = ((uint8_t *) buffer->payload) + 4;
|
||||
buffer->len = (u16_t)(buffer->len - 4);
|
||||
|
||||
ethernet_header = (struct eth_hdr *) buffer->payload;
|
||||
ethertype = lwip_htons(ethernet_header->type);
|
||||
}
|
||||
#ifdef DEEP_SLEEP
|
||||
if (WHD_DEEP_SLEEP_IS_ENABLED() && (WHD_DEEP_SLEEP_SAVE_PACKETS_NUM != 0))
|
||||
{
|
||||
if (wiced_deep_sleep_save_packet(buffer, interface))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* DEEP_SLEEP */
|
||||
cy_callback++;
|
||||
switch (ethertype)
|
||||
{
|
||||
case WHD_ETHERTYPE_IPv4:
|
||||
case WHD_ETHERTYPE_ARP:
|
||||
#if PPPOE_SUPPORT
|
||||
/* PPPoE packet? */
|
||||
case ETHTYPE_PPPOEDISC:
|
||||
case ETHTYPE_PPPOE:
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
/* Find the netif object matching the provided interface */
|
||||
tmp_netif = NULL;
|
||||
for (int32_t i = 0; i < NET_CYPRESS_MAX_INTERFACE; i++)
|
||||
{
|
||||
if (netif2ifp[i].key == interface)
|
||||
{
|
||||
tmp_netif = netif2ifp[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*NET_DBG_PRINT("Recv %d for netif %x ifp %x\n",buffer->len,tmp_netif,interface);*/
|
||||
|
||||
if (tmp_netif == NULL)
|
||||
{
|
||||
NET_DBG_PRINT("This buffer is not for this interface !\n");
|
||||
|
||||
/* Received a packet for a network interface is not initialised Cannot do anything with packet
|
||||
- just drop it. */
|
||||
result = pbuf_free(buffer);
|
||||
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
|
||||
buffer = NULL;
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
NET_DBG_PRINT("process input packet ethertype %x size %d\n", ethertype, buffer->len);
|
||||
#endif /* debug */
|
||||
|
||||
/* Send to packet to tcpip_thread to process */
|
||||
cy_callback_tcpip++;
|
||||
|
||||
if (tcpip_input(buffer, tmp_netif) != ERR_OK)
|
||||
{
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
|
||||
/* Stop lint warning - packet has not been released in this case */ /*@-usereleased@*/
|
||||
result = pbuf_free(buffer);
|
||||
/*@+usereleased@*/
|
||||
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
|
||||
buffer = NULL;
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
/*FIXME , not supported todays */
|
||||
case WHD_ETHERTYPE_EAPOL:
|
||||
whd_eapol_receive_eapol_packet(buffer, interface);
|
||||
break;
|
||||
#endif /* 0 */
|
||||
default:
|
||||
result = pbuf_free(buffer);
|
||||
LWIP_ASSERT("Failed to release packet buffer", (result != (u8_t)0));
|
||||
buffer = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int32_t net_cypress_whd_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid)
|
||||
{
|
||||
(void) pnetif;
|
||||
(void) mode;
|
||||
(void) ssid;
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
|
||||
static int32_t net_cypress_whd_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *scan_bss, uint8_t number)
|
||||
{
|
||||
int32_t ret = NET_ERROR_GENERIC;
|
||||
whd_sync_scan_result_t *scan_result;
|
||||
|
||||
if ((NULL == scan_bss) || (0 == number))
|
||||
{
|
||||
return NET_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
scan_result = (whd_sync_scan_result_t *)NET_MALLOC(sizeof(whd_sync_scan_result_t) * number);
|
||||
if (NULL == scan_result)
|
||||
{
|
||||
return NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t apcount;
|
||||
whd_sync_scan_result_t *scan_result_info = scan_result;
|
||||
|
||||
memset(scan_result, 0, sizeof(whd_sync_scan_result_t) * number);
|
||||
apcount = whd_wifi_scan_synch((whd_interface_t) pnetif->pdrv->extension.wifi->ifp, scan_result, number);
|
||||
|
||||
for (uint32_t i = 0; i < apcount; i++)
|
||||
{
|
||||
memset(scan_bss, 0, sizeof(net_wifi_scan_bss_t));
|
||||
memcpy(scan_bss->ssid.value, (void *) scan_result_info->SSID.value, scan_result_info->SSID.length);
|
||||
scan_bss->ssid.value[scan_result_info->SSID.length] = 0;
|
||||
scan_bss->ssid.length = scan_result_info->SSID.length;
|
||||
|
||||
scan_bss->security = scan_result_info->security;
|
||||
memcpy(&scan_bss->bssid, scan_result_info->BSSID.octet, NET_WIFI_MAC_ADDRESS_SIZE);
|
||||
scan_bss->rssi = (int8_t)scan_result_info->signal_strength;
|
||||
scan_bss->channel = scan_result_info->channel;
|
||||
memcpy(scan_bss->country, ".CN", 4); /* NOT SUPPORT for MX_WIFI */
|
||||
|
||||
scan_bss++;
|
||||
scan_result_info++;
|
||||
}
|
||||
ret = apcount;
|
||||
}
|
||||
|
||||
free((void *) scan_result);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+1573
File diff suppressed because it is too large
Load Diff
+715
@@ -0,0 +1,715 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_mx_wifi.c
|
||||
* @author MCD Application Team
|
||||
* @brief MXCHIP Wi-Fi specific BSD-like socket wrapper
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*cstat -MISRAC2012-* */
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
/*cstat +MISRAC2012-* */
|
||||
|
||||
#include "mx_wifi.h"
|
||||
|
||||
|
||||
#ifdef MX_WIFI_API_DEBUG
|
||||
#define DEBUG_LOG(M, ...) printf(M, ##__VA_ARGS__);
|
||||
#else
|
||||
#define DEBUG_LOG(M, ...)
|
||||
#endif /* MX_WIFI_API_DEBUG */
|
||||
|
||||
#define MXWIFI_MAX_CHANNEL_NBR 4
|
||||
|
||||
#define WIFI_FREE_SOCKET 0U
|
||||
#define WIFI_ALLOCATED_SOCKET 1U
|
||||
#define WIFI_BIND_SOCKET 2U
|
||||
#define WIFI_SEND_OK 4U
|
||||
#define WIFI_RECV_OK 8U
|
||||
#define WIFI_CONNECTED_SOCKET 16U
|
||||
#define WIFI_STARTED_CLIENT_SOCKET 32U
|
||||
#define WIFI_STARTED_SERVER_SOCKET 64U
|
||||
#define WIFI_CONNECTED_SOCKET_RW (WIFI_CONNECTED_SOCKET | WIFI_SEND_OK | WIFI_RECV_OK)
|
||||
|
||||
#define NET_ARTON(A) ((uint32_t)(((uint32_t)A[3] << 24U) |\
|
||||
((uint32_t)A[2] << 16U) |\
|
||||
((uint32_t)A[1] << 8U) |\
|
||||
((uint32_t)A[0] << 0U)))
|
||||
|
||||
/* Declaration of generic class functions */
|
||||
void HAL_Delay(uint32_t delay);
|
||||
|
||||
int32_t mx_wifi_driver(net_if_handle_t *pnetif);
|
||||
|
||||
static int32_t mx_wifi_if_init(net_if_handle_t *pnetif);
|
||||
static int32_t mx_wifi_if_deinit(net_if_handle_t *pnetif);
|
||||
|
||||
static int32_t mx_wifi_if_start(net_if_handle_t *pnetif);
|
||||
static int32_t mx_wifi_if_stop(net_if_handle_t *pnetif);
|
||||
static int32_t mx_wifi_if_yield(net_if_handle_t *pnetif, uint32_t timeout);
|
||||
|
||||
static int32_t mx_wifi_if_connect(net_if_handle_t *pnetif);
|
||||
static int32_t mx_wifi_if_disconnect(net_if_handle_t *pnetif);
|
||||
|
||||
static int32_t mx_wifi_socket(int32_t domain, int32_t type, int32_t protocol);
|
||||
static int32_t mx_wifi_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
static int32_t mx_wifi_listen(int32_t sock, int32_t backlog);
|
||||
static int32_t mx_wifi_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
|
||||
static int32_t mx_wifi_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
static int32_t mx_wifi_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
static int32_t mx_wifi_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
static int32_t mx_wifi_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
|
||||
uint32_t tolen);
|
||||
static int32_t mx_wifi_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
|
||||
uint32_t *fromlen);
|
||||
static int32_t mx_wifi_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
|
||||
static int32_t mx_wifi_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
|
||||
static int32_t mx_wifi_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
static int32_t mx_wifi_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
static int32_t mx_wifi_close(int32_t sock, bool isaclone);
|
||||
static int32_t mx_wifi_shutdown(int32_t sock, int32_t mode);
|
||||
|
||||
static int32_t mx_wifi_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
|
||||
static int32_t mx_wifi_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay,
|
||||
int32_t response[]);
|
||||
|
||||
/* Declaration and definition of class-specific functions */
|
||||
static int32_t mx_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
|
||||
static int32_t mx_wifi_get_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
|
||||
|
||||
extern int32_t wifi_probe(void **ll_drv_context);
|
||||
extern MX_WIFIObject_t *wifi_obj_get(void);
|
||||
|
||||
/* internal structure to mabage es_wfi socket */
|
||||
typedef struct mxwifi_tls_data_s
|
||||
{
|
||||
char *tls_ca_certs; /**< Socket option. */
|
||||
char *tls_ca_crl; /**< Socket option. */
|
||||
char *tls_dev_cert; /**< Socket option. */
|
||||
char *tls_dev_key; /**< Socket option. */
|
||||
uint8_t *tls_dev_pwd; /**< Socket option. */
|
||||
bool tls_srv_verification; /**< Socket option. */
|
||||
char *tls_srv_name; /**< Socket option. */
|
||||
} mxwifi_tls_data_t;
|
||||
|
||||
|
||||
int32_t mx_wifi_driver(net_if_handle_t *pnetif)
|
||||
{
|
||||
return mx_wifi_if_init(pnetif);
|
||||
}
|
||||
|
||||
int32_t mx_wifi_if_init(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_drv_t *p;
|
||||
void *ptmp;
|
||||
|
||||
ptmp = NET_MALLOC(sizeof(net_if_drv_t));
|
||||
(void)memcpy(&p, &ptmp, sizeof(p));
|
||||
if (p != NULL)
|
||||
{
|
||||
p->if_class = NET_INTERFACE_CLASS_WIFI;
|
||||
|
||||
p->if_init = mx_wifi_if_init;
|
||||
p->if_deinit = mx_wifi_if_deinit;
|
||||
|
||||
p->if_start = mx_wifi_if_start;
|
||||
p->if_stop = mx_wifi_if_stop;
|
||||
p->if_yield = mx_wifi_if_yield;
|
||||
|
||||
p->if_connect = mx_wifi_if_connect;
|
||||
p->if_disconnect = mx_wifi_if_disconnect;
|
||||
|
||||
p->psocket = mx_wifi_socket;
|
||||
p->pbind = mx_wifi_bind;
|
||||
p->plisten = mx_wifi_listen;
|
||||
p->paccept = mx_wifi_accept;
|
||||
p->pconnect = mx_wifi_connect;
|
||||
p->psend = mx_wifi_send;
|
||||
p->precv = mx_wifi_recv;
|
||||
p->psendto = mx_wifi_sendto;
|
||||
p->precvfrom = mx_wifi_recvfrom;
|
||||
p->psetsockopt = mx_wifi_setsockopt;
|
||||
p->pgetsockopt = mx_wifi_getsockopt;
|
||||
p->pgetsockname = mx_wifi_getsockname;
|
||||
p->pgetpeername = mx_wifi_getpeername;
|
||||
p->pclose = mx_wifi_close;
|
||||
p->pshutdown = mx_wifi_shutdown;
|
||||
|
||||
p->pgethostbyname = mx_wifi_gethostbyname;
|
||||
p->pping = mx_wifi_ping;
|
||||
p->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
|
||||
|
||||
if (NULL == p->extension.wifi)
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for mx_wifi_driver class\n");
|
||||
NET_FREE(p);
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) memset(p->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
|
||||
pnetif->dhcp_mode = true;
|
||||
pnetif->pdrv = p;
|
||||
p->extension.wifi->scan = mx_wifi_scan;
|
||||
p->extension.wifi->get_scan_results = mx_wifi_get_scan_result;
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for mx_wifi_driver class\n");
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_if_deinit(net_if_handle_t *pnetif)
|
||||
{
|
||||
NET_FREE(pnetif->pdrv->extension.wifi);
|
||||
pnetif->pdrv->extension.wifi = NULL;
|
||||
NET_FREE(pnetif->pdrv);
|
||||
pnetif->pdrv = NULL;
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int32_t mx_wifi_if_start(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
MX_WIFIObject_t *pMxWifiObj;
|
||||
|
||||
if (wifi_probe(&pnetif->pdrv->context) == NET_OK)
|
||||
{
|
||||
DEBUG_LOG("MX_WIFI IO [OK]\r\n");
|
||||
pMxWifiObj = wifi_obj_get();
|
||||
|
||||
/* wifi module hardware reboot */
|
||||
DEBUG_LOG("MX_WIFI REBOOT(HW) ...\r\n");
|
||||
if (MX_WIFI_STATUS_OK != MX_WIFI_HardResetModule(pMxWifiObj))
|
||||
{
|
||||
ret = NET_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NET_USE_RTOS
|
||||
(void)osDelay(500);
|
||||
#else
|
||||
HAL_Delay(500);
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
/* Init the WiFi module */
|
||||
if (MX_WIFI_STATUS_OK != MX_WIFI_Init(pMxWifiObj))
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("MX_WIFI_Init [OK]\r\n");
|
||||
/* Retrieve the WiFi module information */
|
||||
(void)strncpy(pnetif->DeviceName, (char_t *)pMxWifiObj->SysInfo.Product_Name, NET_DEVICE_NAME_LEN);
|
||||
(void)strncpy(pnetif->DeviceID, (char_t *)pMxWifiObj->SysInfo.Product_ID, NET_DEVICE_ID_LEN);
|
||||
(void)strncpy(pnetif->DeviceVer, (char_t *)pMxWifiObj->SysInfo.FW_Rev, NET_DEVICE_VER_LEN);
|
||||
|
||||
(void)MX_WIFI_GetMACAddress(pMxWifiObj, pnetif->macaddr.mac);
|
||||
|
||||
(void)net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_if_stop(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
if (MX_WIFI_STATUS_OK != MX_WIFI_DeInit(pMxWifiObj))
|
||||
{
|
||||
ret = NET_ERROR_GENERIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
ret = NET_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_if_yield(net_if_handle_t *pnetif, uint32_t timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)pnetif;
|
||||
ret = MX_WIFI_IO_YIELD(pMxWifiObj, timeout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mx_wifi_status_changed(uint8_t cate, uint8_t status, void *arg)
|
||||
{
|
||||
net_if_handle_t *pnetif;
|
||||
uint8_t addr[4];
|
||||
net_state_t net_state;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&pnetif, &arg, sizeof(pnetif));
|
||||
|
||||
if ((uint8_t)MC_STATION == cate)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MC_STA_DOWN:
|
||||
DEBUG_LOG("MC_STA_DOWN\r\n");
|
||||
|
||||
(void) net_if_getState(pnetif, &net_state);
|
||||
if (NET_STATE_CONNECTED == net_state)
|
||||
{
|
||||
(void)net_state_manage_event(pnetif, NET_EVENT_LINK_DOWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
}
|
||||
break;
|
||||
|
||||
case MC_STA_UP:
|
||||
DEBUG_LOG("MC_STA_UP\r\n");
|
||||
(void)net_state_manage_event(pnetif, NET_EVENT_LINK_UP);
|
||||
break;
|
||||
|
||||
case MC_STA_GOT_IP:
|
||||
DEBUG_LOG("MC_STA_GOT_IP\r\n");
|
||||
(void) memcpy(addr, pMxWifiObj->NetSettings.IP_Addr, 4);
|
||||
pnetif->ipaddr.addr = NET_ARTON(pMxWifiObj->NetSettings.IP_Addr);
|
||||
(void) memcpy(addr, pMxWifiObj->NetSettings.IP_Mask, 4);
|
||||
pnetif->netmask.addr = NET_ARTON(pMxWifiObj->NetSettings.IP_Mask);
|
||||
(void) memcpy(addr, pMxWifiObj->NetSettings.Gateway_Addr, 4);
|
||||
pnetif->gateway.addr = NET_ARTON(pMxWifiObj->NetSettings.Gateway_Addr);
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((uint8_t)MC_SOFTAP == cate)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MC_AP_DOWN:
|
||||
DEBUG_LOG("MC_AP_DOWN\r\n");
|
||||
net_if_notify(pnetif, NET_EVENT_STATE_CHANGE, (uint32_t) NET_STATE_CONNECTION_LOST, NULL);
|
||||
break;
|
||||
|
||||
case MC_AP_UP:
|
||||
DEBUG_LOG("MC_AP_UP\r\n");
|
||||
pnetif->ipaddr.addr = pnetif->static_ipaddr.addr;
|
||||
pnetif->gateway.addr = pnetif->static_gateway.addr;
|
||||
pnetif->netmask.addr = pnetif->static_netmask.addr;
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
}
|
||||
|
||||
static MX_WIFI_SecurityType_t convert(int security_mode)
|
||||
{
|
||||
#if 0
|
||||
MX_WIFI_SEC_NONE, /**< Open system. */
|
||||
MX_WIFI_SEC_WEP, /**< Wired Equivalent Privacy. WEP security. */
|
||||
MX_WIFI_SEC_WPA_TKIP, /**< WPA /w TKIP */
|
||||
MX_WIFI_SEC_WPA_AES, /**< WPA /w AES */
|
||||
MX_WIFI_SEC_WPA2_TKIP, /**< WPA2 /w TKIP */
|
||||
MX_WIFI_SEC_WPA2_AES, /**< WPA2 /w AES */
|
||||
MX_WIFI_SEC_WPA2_MIXED, /**< WPA2 /w AES or TKIP */
|
||||
#endif
|
||||
return MX_WIFI_SEC_AUTO;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_if_connect_sta(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFI_SecurityType_t secure_type;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
|
||||
if (false == pnetif->dhcp_mode)
|
||||
{
|
||||
pMxWifiObj->NetSettings.DHCP_IsEnabled = 0;
|
||||
(void)memcpy(pMxWifiObj->NetSettings.IP_Addr, &(pnetif->ipaddr), 4);
|
||||
(void)memcpy(pMxWifiObj->NetSettings.IP_Mask, &(pnetif->netmask), 4);
|
||||
(void)memcpy(pMxWifiObj->NetSettings.Gateway_Addr, &(pnetif->gateway), 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pMxWifiObj->NetSettings.DHCP_IsEnabled = 1;
|
||||
}
|
||||
|
||||
(void)MX_WIFI_RegisterStatusCallback(pMxWifiObj, mx_wifi_status_changed, pnetif);
|
||||
|
||||
secure_type = convert(credentials->security_mode);
|
||||
ret = MX_WIFI_Connect(pMxWifiObj, credentials->ssid, credentials->psk, secure_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define BYTEN(A,n) ((A)>>(8u*(n))) & 0xffu
|
||||
#define BYTE3(A) BYTEN((A),3u)
|
||||
#define BYTE2(A) BYTEN((A),2u)
|
||||
#define BYTE1(A) BYTEN((A),1u)
|
||||
#define BYTE0(A) BYTEN((A),0u)
|
||||
#define ADDR(a) BYTE0(a),BYTE1(a),BYTE2(a),BYTE3(a)
|
||||
|
||||
static int32_t mx_wifi_if_connect_ap(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_ERROR_GENERIC;
|
||||
|
||||
MX_WIFI_APSettings_t ap_cfg;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
|
||||
(void) memset(&ap_cfg, 0, sizeof(ap_cfg));
|
||||
(void) strcpy(ap_cfg.SSID, credentials->ssid);
|
||||
(void) strcpy(ap_cfg.pswd, credentials->psk);
|
||||
|
||||
ap_cfg.channel = pnetif->pdrv->extension.wifi->access_channel;
|
||||
|
||||
(void) sprintf(ap_cfg.ip.localip, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_ipaddr.addr));
|
||||
(void) sprintf(ap_cfg.ip.netmask, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_gateway.addr));
|
||||
(void) sprintf(ap_cfg.ip.gateway, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_netmask.addr));
|
||||
(void) sprintf(ap_cfg.ip.dnserver, "%ld.%ld.%ld.%ld", ADDR(pnetif->static_dnserver.addr));
|
||||
|
||||
(void) MX_WIFI_RegisterStatusCallback(pMxWifiObj, mx_wifi_status_changed, pnetif);
|
||||
|
||||
if (MX_WIFI_STATUS_OK == MX_WIFI_StartAP(pMxWifiObj, &ap_cfg))
|
||||
{
|
||||
ret = NET_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int32_t mx_wifi_if_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
|
||||
{
|
||||
(void)MX_WIFI_Disconnect(pMxWifiObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) MX_WIFI_StopAP(pMxWifiObj);
|
||||
}
|
||||
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int32_t mx_wifi_if_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
if (pnetif->pdrv->extension.wifi->mode == NET_WIFI_MODE_STA)
|
||||
{
|
||||
ret = mx_wifi_if_connect_sta(pnetif);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mx_wifi_if_connect_ap(pnetif);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mx_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char_t *ssid)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
uint32_t len = 0u;
|
||||
|
||||
(void) pnetif;
|
||||
|
||||
if (ssid != NULL)
|
||||
{
|
||||
len = strlen(ssid);
|
||||
}
|
||||
ret = MX_WIFI_Scan(pMxWifiObj, (uint8_t)mode, ssid, (int32_t) len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_get_scan_result(net_if_handle_t *pnetif, net_wifi_scan_results_t *scan_bss_array,
|
||||
uint8_t scan_bss_array_size)
|
||||
{
|
||||
int32_t ret;
|
||||
uint8_t number = scan_bss_array_size;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
mc_wifi_ap_info_t *ap_list_head;
|
||||
net_wifi_scan_results_t *scan_bss = scan_bss_array;
|
||||
|
||||
(void)pnetif;
|
||||
static uint32_t mxsec[] =
|
||||
{
|
||||
NET_WIFI_SM_OPEN,
|
||||
NET_WIFI_SM_WEP_PSK, /**< Wired Equivalent Privacy. WEP security. */
|
||||
NET_WIFI_SM_WPA_TKIP_PSK, /**< WPA /w TKIP */
|
||||
NET_WIFI_SM_WPA_AES_PSK, /**< WPA /w AES */
|
||||
NET_WIFI_SM_WPA2_TKIP_PSK, /**< WPA2 /w TKIP */
|
||||
NET_WIFI_SM_WPA2_AES_PSK, /**< WPA2 /w AES */
|
||||
NET_WIFI_SM_WPA2_MIXED_PSK, /**< WPA2 /w AES or TKIP */
|
||||
};
|
||||
|
||||
if ((NULL == scan_bss_array) || (0u == number))
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create buff for mc_wifi results */
|
||||
void *ptmp = NET_MALLOC(sizeof(mc_wifi_ap_info_t) * number);
|
||||
(void) memcpy(&ap_list_head, &ptmp, sizeof(ap_list_head));
|
||||
|
||||
if (NULL == ap_list_head)
|
||||
{
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
mc_wifi_ap_info_t *ap_info = ap_list_head;
|
||||
|
||||
(void) memset(ap_list_head, 0, sizeof(mc_wifi_ap_info_t) * number);
|
||||
|
||||
/* get real mc_wifi scan results data */
|
||||
number = (uint8_t) MX_WIFI_Get_scan_result(pMxWifiObj, (uint8_t *) ap_info, number);
|
||||
|
||||
for (uint32_t i = 0U; i < number; i++)
|
||||
{
|
||||
(void) memset(scan_bss, 0, sizeof(net_wifi_scan_bss_t));
|
||||
(void) memcpy(scan_bss->ssid.value, ap_info->ssid, NET_WIFI_MAX_SSID_SIZE);
|
||||
scan_bss->ssid.length = (uint8_t) strlen(ap_info->ssid);
|
||||
scan_bss->security = mxsec[ap_info->security];
|
||||
(void) memcpy(&scan_bss->bssid, ap_info->bssid, NET_WIFI_MAC_ADDRESS_SIZE);
|
||||
scan_bss->rssi = (int8_t)ap_info->rssi;
|
||||
scan_bss->channel = ap_info->channel;
|
||||
(void) memcpy(scan_bss->country, ".CN", 4); /* NOT SUPPORT for MX_WIFI */
|
||||
|
||||
scan_bss++;
|
||||
ap_info++;
|
||||
}
|
||||
ret = (int32_t) number;
|
||||
NET_FREE((void *) ap_list_head);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_socket(int32_t domain, int32_t type, int32_t protocol)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_create(pMxWifiObj, domain, type, protocol);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_setsockopt(pMxWifiObj, sock, level, optname, optvalue, (int32_t)optlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_getsockopt(pMxWifiObj, sock, level, optname, optvalue, optlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
|
||||
ret = MX_WIFI_Socket_bind(pMxWifiObj, sock, &mx_addr, (int32_t)addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_listen(int32_t sock, int32_t backlog)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_listen(pMxWifiObj, sock, backlog);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
|
||||
ret = MX_WIFI_Socket_accept(pMxWifiObj, sock, &mx_addr, addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&mx_addr, addr, sizeof(mx_addr));
|
||||
ret = MX_WIFI_Socket_connect(pMxWifiObj, sock, &mx_addr, (int32_t)addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_shutdown(int32_t sock, int32_t mode)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_shutdown(pMxWifiObj, sock, mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_close(int32_t sock, bool isaclone)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)isaclone;
|
||||
ret = MX_WIFI_Socket_close(pMxWifiObj, sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_send(pMxWifiObj, sock, buf, len, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
ret = MX_WIFI_Socket_recv(pMxWifiObj, sock, buf, len, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
|
||||
uint32_t tolen)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&mx_addr, to, sizeof(mx_addr));
|
||||
ret = MX_WIFI_Socket_sendto(pMxWifiObj, sock, buf, len, flags, &mx_addr, (int32_t)tolen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
|
||||
uint32_t *fromlen)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)memcpy(&mx_addr, from, sizeof(mx_addr));
|
||||
ret = MX_WIFI_Socket_recvfrom(pMxWifiObj, sock, buf, len, flags, &mx_addr, fromlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name)
|
||||
{
|
||||
int32_t ret;
|
||||
struct sockaddr mx_addr;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
|
||||
(void)pnetif;
|
||||
ret = MX_WIFI_Socket_gethostbyname(pMxWifiObj, &mx_addr, (char_t *)name);
|
||||
(void)memcpy(addr, &mx_addr, sizeof(mx_addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t mx_wifi_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t delay, int32_t response[])
|
||||
{
|
||||
int32_t ret;
|
||||
MX_WIFIObject_t *pMxWifiObj = wifi_obj_get();
|
||||
net_sockaddr_in_t addr_in;
|
||||
net_ip_addr_t ip_addr;
|
||||
|
||||
(void)pnetif;
|
||||
(void)memcpy(&addr_in, addr, sizeof(addr_in));
|
||||
ip_addr.addr = addr_in.sin_addr.s_addr;
|
||||
ret = MX_WIFI_Socket_ping(pMxWifiObj, (char_t *)net_ntoa(&ip_addr), count, delay, response);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
|
||||
{
|
||||
DEBUG_LOG("mx_wifi_getsockname UNSUPPORTED!");
|
||||
(void)sock;
|
||||
(void)name;
|
||||
(void)namelen;
|
||||
return NET_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static int32_t mx_wifi_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
|
||||
{
|
||||
DEBUG_LOG("mx_wifi_getpeername UNSUPPORTED!");
|
||||
(void)sock;
|
||||
(void)name;
|
||||
(void)namelen;
|
||||
return NET_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
+556
@@ -0,0 +1,556 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_st_wifi.c
|
||||
* @author MCD Application Team
|
||||
* @brief ST Wi-Fi specific BSD-like socket wrapper
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "net_buffers.h"
|
||||
#include "net_wifi.h"
|
||||
#include "net_ip_lwip.h"
|
||||
#include "wifi.h"
|
||||
|
||||
|
||||
#define MAX_MTU 1500
|
||||
/* Wi-Fi Driver */
|
||||
extern wifi_driver_t stw_driver;
|
||||
wifi_driver_t *wifi_driver = &stw_driver;
|
||||
|
||||
int32_t st_wifi_driver(net_if_handle_t *pnetif);
|
||||
|
||||
/* STM32 Network library Framework */
|
||||
static int32_t st_wifi_if_init(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_deinit(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_start(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_stop(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_connect(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_disconnect(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_powersave_enable(net_if_handle_t *pnetif);
|
||||
static int32_t st_wifi_if_powersave_disable(net_if_handle_t *pnetif);
|
||||
|
||||
/*static int32_t st_wifi_if_sleep(net_if_handle_t * pnetif); */
|
||||
/*static int32_t st_wifi_if_wakeup(net_if_handle_t * pnetif); */
|
||||
|
||||
/* Class extension */
|
||||
static int32_t st_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid);
|
||||
static int32_t st_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number);
|
||||
static int32_t st_wifi_get_system_info(net_wifi_system_info_t info, void *data);
|
||||
static int32_t st_wifi_set_param(net_wifi_param_t info, void *data);
|
||||
int32_t st_wifi_event_callback(void *context, wifi_event_t event, void *data);
|
||||
|
||||
static err_t net_wifi_if_init(struct netif *netif);
|
||||
static int32_t st_wifi_transmit(struct netif *netif, net_buf_t *net_buf);
|
||||
/*******************************************************************************
|
||||
Wi-Fi Driver
|
||||
*******************************************************************************/
|
||||
int32_t st_wifi_driver(net_if_handle_t *pnetif)
|
||||
{
|
||||
net_ip_init();
|
||||
return st_wifi_if_init(pnetif);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
STM32 Network library Framework
|
||||
*******************************************************************************/
|
||||
|
||||
/* Init */
|
||||
int32_t st_wifi_if_init(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
net_if_drv_t *p = NET_MALLOC(sizeof(net_if_drv_t));
|
||||
|
||||
if (p)
|
||||
{
|
||||
p->if_class = NET_INTERFACE_CLASS_WIFI;
|
||||
p->if_init = st_wifi_if_init;
|
||||
p->if_deinit = st_wifi_if_deinit;
|
||||
p->if_start = st_wifi_if_start;
|
||||
p->if_stop = st_wifi_if_stop;
|
||||
p->if_connect = st_wifi_if_connect;
|
||||
p->if_disconnect = st_wifi_if_disconnect;
|
||||
p->if_powersave_enable = st_wifi_if_powersave_enable;
|
||||
p->if_powersave_disable = st_wifi_if_powersave_disable;
|
||||
p->pping = icmp_ping;
|
||||
p->extension.wifi = NET_MALLOC(sizeof(net_if_wifi_class_extension_t));
|
||||
if (NULL == p->extension.wifi)
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for st_wifi_driver class\n");
|
||||
NET_FREE(p);
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
pnetif->pdrv = p;
|
||||
(void) memset(p->extension.wifi, 0, sizeof(net_if_wifi_class_extension_t));
|
||||
p->extension.wifi->scan = st_wifi_scan;
|
||||
p->extension.wifi->get_scan_results = st_wifi_get_scan_results;
|
||||
p->extension.wifi->get_system_info = st_wifi_get_system_info;
|
||||
p->extension.wifi->set_param = st_wifi_set_param;
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("can't allocate memory for st_wifi_driver class\n");
|
||||
ret = NET_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (wifi_probe(&pnetif->pdrv->context) == NET_OK)
|
||||
{
|
||||
|
||||
if (wifi_init(wifi_driver, st_wifi_event_callback, NULL, pnetif) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Deinit */
|
||||
int32_t st_wifi_if_deinit(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
if (wifi_deinit(wifi_driver) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_OK;
|
||||
}
|
||||
|
||||
NET_FREE(pnetif->pdrv->extension.wifi);
|
||||
pnetif->pdrv->extension.wifi = NULL;
|
||||
NET_FREE(pnetif->pdrv);
|
||||
pnetif->pdrv = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start */
|
||||
int32_t st_wifi_if_start(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
net_wifi_powersave_t wifi_powersave =
|
||||
{
|
||||
WIFI_POWERSAVE_LIGHT_SLEEP
|
||||
};
|
||||
|
||||
if (wifi_start() != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* STA mode */
|
||||
if (wifi_obj->mode == WIFI_MODE_STA)
|
||||
{
|
||||
/* Retrieve Wi-Fi device information */
|
||||
char device_name[NET_DEVICE_NAME_LEN];
|
||||
wifi_get_system_info(WIFI_SYSINFO_DEVICE_NAME, (void *)device_name);
|
||||
strncpy(pnetif->DeviceName, device_name, NET_DEVICE_NAME_LEN);
|
||||
wifi_get_system_info(WIFI_SYSINFO_WLAN_MAC, pnetif->macaddr.mac);
|
||||
|
||||
/* Set default values */
|
||||
pnetif->pdrv->extension.wifi->powersave = &wifi_powersave;
|
||||
|
||||
}
|
||||
/* AP mode */
|
||||
if (wifi_obj->mode == WIFI_MODE_AP)
|
||||
{
|
||||
#if 0
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
wifi_privacy_t privacy = WIFI_PRIVACY_NONE;
|
||||
|
||||
if (credentials->security_mode & NET_WPA_SECURITY)
|
||||
{
|
||||
privacy = WIFI_PRIVACY_WPA;
|
||||
}
|
||||
if (credentials->security_mode & NET_WPA2_SECURITY)
|
||||
{
|
||||
privacy = WIFI_PRIVACY_WPA;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FIXME */
|
||||
}
|
||||
|
||||
/* Add IP interface */
|
||||
ret = net_ip_add_if(pnetif, net_wifi_if_init, NET_ETHERNET_FLAG_DEFAULT_IF);
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
/*Forcing a UP at that stage , would expect msg from WIFI to trigger it
|
||||
netif_set_link_up(pnetif->netif); */
|
||||
if (wifi_obj->mode == WIFI_MODE_STA)
|
||||
{
|
||||
|
||||
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Stop */
|
||||
int32_t st_wifi_if_stop(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
|
||||
if (wifi_stop() != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_INTERFACE_FAILURE;
|
||||
}
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_INITIALIZED);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Connect */
|
||||
static int32_t st_wifi_if_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
const net_wifi_credentials_t *credentials = pnetif->pdrv->extension.wifi->credentials;
|
||||
|
||||
wifi_privacy_t privacy = WIFI_PRIVACY_NONE;
|
||||
if (credentials->security_mode & NET_WPA_SECURITY)
|
||||
{
|
||||
privacy = WIFI_PRIVACY_WPA;
|
||||
}
|
||||
if (credentials->security_mode & NET_WPA2_SECURITY)
|
||||
{
|
||||
privacy = WIFI_PRIVACY_WPA;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (wifi_connect((char *)credentials->ssid, (char *)credentials->psk, privacy, 0) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = net_ip_connect(pnetif);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disconnect */
|
||||
static int32_t st_wifi_if_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
|
||||
|
||||
if (wifi_disconnect() != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_FRAMEWORK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
|
||||
ret = NET_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Power-save */
|
||||
static int32_t st_wifi_if_powersave_enable(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
wifi_power_mode(*(pnetif->pdrv->extension.wifi->powersave));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t st_wifi_if_powersave_disable(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
wifi_power_mode(WIFI_POWER_MODE_ACTIVE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Class extension
|
||||
*******************************************************************************/
|
||||
|
||||
/* Scan */
|
||||
static int32_t st_wifi_scan(net_if_handle_t *pnetif, net_wifi_scan_mode_t mode, char *ssid)
|
||||
{
|
||||
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
(void) ssid;
|
||||
wifi_scan_t params;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case NET_WIFI_SCAN_PASSIVE:
|
||||
params.mode = WIFI_SCAN_MODE_PASSIVE;
|
||||
break;
|
||||
case NET_WIFI_SCAN_ACTIVE:
|
||||
params.mode = WIFI_SCAN_MODE_ACTIVE;
|
||||
break;
|
||||
case NET_WIFI_SCAN_AUTO:
|
||||
params.mode = WIFI_SCAN_MODE_AUTO;
|
||||
break;
|
||||
default:
|
||||
params.mode = WIFI_SCAN_MODE_AUTO;
|
||||
}
|
||||
|
||||
params.ssid.length = 0;
|
||||
params.channels = 0;
|
||||
|
||||
if (wifi_scan(params) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_GENERIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get scan results */
|
||||
static int32_t st_wifi_get_scan_results(net_if_handle_t *pnetif, net_wifi_scan_results_t *results, uint8_t number)
|
||||
{
|
||||
|
||||
int32_t ret = NET_ERROR_FRAMEWORK;
|
||||
|
||||
uint8_t nb;
|
||||
|
||||
wifi_get_system_info(WIFI_SYSINFO_LAST_SCAN_RESULTS_NUMBER, (void *)&nb);
|
||||
if (nb > number)
|
||||
{
|
||||
nb = number;
|
||||
}
|
||||
|
||||
wifi_scan_results_t res;
|
||||
res.number = nb;
|
||||
res.bss = NET_MALLOC(number * sizeof(wifi_scan_bss_t));
|
||||
|
||||
if (wifi_get_scan_results(&res, nb) == WIFI_STATUS_OK)
|
||||
{
|
||||
for (uint8_t i = 0; i < nb; i++)
|
||||
{
|
||||
results->ssid.length = res.bss[i].ssid.length;
|
||||
memcpy(results->ssid.value, res.bss[i].ssid.value, res.bss[i].ssid.length);
|
||||
memcpy(results->bssid, res.bss[i].bssid, sizeof(wifi_mac_t));
|
||||
results->channel = res.bss[i].channel;
|
||||
memcpy(results->country, res.bss[i].country, 3);
|
||||
results->rssi = res.bss[i].rssi;
|
||||
results++;
|
||||
}
|
||||
ret = nb;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_GENERIC;
|
||||
}
|
||||
NET_FREE((void *)(res.bss));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get system info */
|
||||
static int32_t st_wifi_get_system_info(net_wifi_system_info_t info, void *data)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
wifi_system_info_t wifi_info;
|
||||
|
||||
switch (info)
|
||||
{
|
||||
case NET_WIFI_SCAN_RESULTS_NUMBER:
|
||||
wifi_info = WIFI_SYSINFO_LAST_SCAN_RESULTS_NUMBER;
|
||||
break;
|
||||
default:
|
||||
return NET_ERROR_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wifi_get_system_info(wifi_info, data) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set param */
|
||||
static int32_t st_wifi_set_param(net_wifi_param_t param, void *data)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
wifi_params_t wifi_param;
|
||||
void *wifi_data;
|
||||
switch (param)
|
||||
{
|
||||
case NET_WIFI_MODE:
|
||||
{
|
||||
wifi_param = WIFI_MODE;
|
||||
wifi_data = wifi_os_malloc(1);
|
||||
switch (*(uint8_t *)data)
|
||||
{
|
||||
case NET_WIFI_MODE_STA:
|
||||
*(uint8_t *)wifi_data = WIFI_MODE_STA;
|
||||
break;
|
||||
case NET_WIFI_MODE_AP:
|
||||
*(uint8_t *)wifi_data = WIFI_MODE_AP;
|
||||
break;
|
||||
default:
|
||||
return NET_ERROR_PARAMETER;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NET_ERROR_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wifi_set_param(wifi_param, wifi_data) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_OK;
|
||||
}
|
||||
wifi_os_free(wifi_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Event callback */
|
||||
int32_t st_wifi_event_callback(void *context, wifi_event_t event, void *data)
|
||||
{
|
||||
|
||||
net_if_handle_t *pnetif = context;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case WIFI_EVENT_LINK_DOWN:
|
||||
if (wifi_obj->mode == WIFI_MODE_STA)
|
||||
{
|
||||
netif_set_link_down(pnetif->netif);
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_LINK_UP:
|
||||
if (wifi_obj->mode == WIFI_MODE_STA)
|
||||
{
|
||||
netif_set_link_up(pnetif->netif);
|
||||
}
|
||||
if (wifi_obj->mode == WIFI_MODE_AP)
|
||||
{
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_INTERFACE_READY);
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_SCAN_COMPLETE:
|
||||
net_if_notify(pnetif, NET_EVENT_WIFI, NET_WIFI_SCAN_RESULTS_READY, (void *)data);
|
||||
break;
|
||||
case WIFI_EVENT_POWER_MODE_COMPLETE:
|
||||
net_if_notify(pnetif, NET_EVENT, NET_EVENT_POWERSAVE_ENABLED, (void *)data);
|
||||
break;
|
||||
case WIFI_EVENT_RX_DATA:
|
||||
{
|
||||
wifi_rx_data_t *eth_frame = (wifi_rx_data_t *)data;
|
||||
net_buf_t *buf = NET_BUF_ALLOC(eth_frame->len + sizeof(wifi_eth_t));
|
||||
if (buf == NULL)
|
||||
{
|
||||
wifi_os_delay(1);
|
||||
}
|
||||
wifi_eth_receive((uint8_t *)(buf->payload), data);
|
||||
tcpip_input(buf, pnetif->netif);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static err_t net_wifi_if_init(struct netif *netif)
|
||||
{
|
||||
err_t ret = ERR_OK;
|
||||
|
||||
char *hostname = NET_MALLOC(sizeof(char) * ((uint16_t) NET_IP_HOSTNAME_MAX_LEN + 1U));
|
||||
if (hostname == NULL)
|
||||
{
|
||||
return (err_t) ERR_MEM;
|
||||
}
|
||||
|
||||
(void) snprintf(hostname, NET_IP_HOSTNAME_MAX_LEN + 1, "generic eth if #%d", netif->num);
|
||||
|
||||
netif->hostname = hostname;
|
||||
netif->name[0] = 's';
|
||||
netif->name[1] = 't';
|
||||
|
||||
netif->hwaddr_len = 6;
|
||||
|
||||
netif->mtu = MAX_MTU;
|
||||
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||
netif->output = etharp_output;
|
||||
wifi_get_system_info(WIFI_SYSINFO_WLAN_MAC, netif->hwaddr);
|
||||
|
||||
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
/* set call back , here to not loose first linkup when if_init is performed */
|
||||
netif_set_status_callback(netif, net_ip_status_cb);
|
||||
netif_set_link_callback(netif, net_ip_status_cb);
|
||||
|
||||
/* output to the device */
|
||||
netif->linkoutput = (netif_linkoutput_fn)st_wifi_transmit;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
TCP/IP Library
|
||||
*******************************************************************************/
|
||||
|
||||
/* Transmit */
|
||||
static int32_t st_wifi_transmit(struct netif *netif, net_buf_t *net_buf)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
|
||||
if (wifi_eth_transmit((uint8_t *)(net_buf->payload), (uint16_t)(net_buf->len)) != WIFI_STATUS_OK)
|
||||
{
|
||||
ret = NET_ERROR_DATA;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,530 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ip_lwip.c
|
||||
* @author MCD Application Team
|
||||
* @brief lwIP network interface functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#include "net_ip_lwip.h"
|
||||
#include "net_buffers.h"
|
||||
|
||||
#define YES (u8_t)1
|
||||
#define NO (u8_t)0
|
||||
|
||||
static void link_socket_to_lwip(net_if_drv_t *drv);
|
||||
#ifndef NET_BYPASS_NET_SOCKET
|
||||
static int32_t net_lwip_socket(int32_t domain, int32_t type, int32_t protocol);
|
||||
static int32_t net_lwip_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
static int32_t net_lwip_listen(int32_t sock, int32_t backlog);
|
||||
static int32_t net_lwip_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen);
|
||||
static int32_t net_lwip_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen);
|
||||
static int32_t net_lwip_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
static int32_t net_lwip_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags);
|
||||
static int32_t net_lwip_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
|
||||
uint32_t tolen);
|
||||
static int32_t net_lwip_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
|
||||
uint32_t *fromlen);
|
||||
static int32_t net_lwip_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen);
|
||||
static int32_t net_lwip_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen);
|
||||
static int32_t net_lwip_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
static int32_t net_lwip_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen);
|
||||
static int32_t net_lwip_close(int32_t sock, bool clone);
|
||||
static int32_t net_lwip_shutdown(int32_t sock, int32_t mode);
|
||||
#endif /* NET_BYPASS_NET_SOCKET */
|
||||
|
||||
static int32_t net_lwip_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name);
|
||||
|
||||
#define NETIF_IS_LINK_UP(netif) (((netif)->flags & NETIF_FLAG_LINK_UP)!=0U)
|
||||
/* Manage init of LWIP libraryu as a singleton */
|
||||
void net_ip_init(void)
|
||||
{
|
||||
static bool tcpip_init_done = 0;
|
||||
if (false == tcpip_init_done)
|
||||
{
|
||||
tcpip_init(NULL, NULL);
|
||||
tcpip_init_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add of a new network interface */
|
||||
int32_t net_ip_add_if(net_if_handle_t *pnetif, err_t (*if_init)(struct netif *netif), uint32_t flag)
|
||||
{
|
||||
int32_t ret;
|
||||
struct netif *netif;
|
||||
/*cstat -MISRAC2012-Rule-11.5 Malloc*/
|
||||
netif = (struct netif *)(void *) NET_MALLOC(sizeof(struct netif));
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
if (NULL != netif)
|
||||
{
|
||||
pnetif->netif = netif;
|
||||
(void) memset(netif, 0x00, sizeof(struct netif));
|
||||
netif = netif_add(netif, NULL, NULL, NULL, pnetif, if_init, tcpip_input);
|
||||
if ((flag & NET_IP_FLAG_DEFAULT_INTERFACE) != 0U)
|
||||
{
|
||||
netif_set_default(netif);
|
||||
}
|
||||
|
||||
/* Get MAC hardware address from netif */
|
||||
(void) memcpy(pnetif->macaddr.mac, netif->hwaddr, sizeof(netif->hwaddr));
|
||||
|
||||
/* link current network interface to LWIP library */
|
||||
link_socket_to_lwip(pnetif->pdrv);
|
||||
#if 0 /*FIXME*/
|
||||
#if LWIP_IPV6
|
||||
/* Set the IPv6 linklocal address using our MAC */
|
||||
NET_DBG_PRINT("Setting IPv6 link-local address\n");
|
||||
|
||||
netif_create_ip6_linklocal_address(netif, 1);
|
||||
IP_HANDLE(interface).ip6_autoconfig_enabled = 1;
|
||||
#endif /* LWIP_IPV6 */
|
||||
#endif /* FIXME */
|
||||
ret = NET_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_GENERIC;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ip4_addr_t const *ip4_addr(net_ip_addr_t *ipaddr)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.3 Const casting*/
|
||||
return (ip4_addr_t const *) ipaddr;
|
||||
/*cstat +MISRAC2012-Rule-11.3*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* CONNECTION */
|
||||
int32_t net_ip_connect(net_if_handle_t *pnetif)
|
||||
{
|
||||
int32_t ret;
|
||||
struct netif *netif = (struct netif *)pnetif->netif;
|
||||
|
||||
if (NULL != netif)
|
||||
{
|
||||
if (!pnetif->dhcp_mode && (NET_IP_ADDR_ISANY_VAL(pnetif->static_ipaddr)))
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
netif_set_up(netif);
|
||||
if (pnetif->dhcp_mode)
|
||||
{
|
||||
(void) dhcp_start(netif);
|
||||
}
|
||||
else
|
||||
{
|
||||
netif_set_addr(netif, ip4_addr(&pnetif->static_ipaddr), ip4_addr(&pnetif->static_netmask),
|
||||
ip4_addr(&pnetif->static_gateway));
|
||||
dhcp_inform(netif);
|
||||
}
|
||||
ret = NET_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t net_ip_disconnect(net_if_handle_t *pnetif)
|
||||
{
|
||||
struct netif *netif = pnetif->netif;
|
||||
/*cstat -MISRAC2012-Rule-11.5 LWIP function*/
|
||||
if (netif_dhcp_data(netif) != NULL)
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
{
|
||||
(void) dhcp_release(netif);
|
||||
dhcp_stop(netif);
|
||||
dhcp_cleanup(netif);
|
||||
}
|
||||
else
|
||||
{
|
||||
netif_set_addr(netif, NULL, NULL, NULL);
|
||||
pnetif->dhcp_inform_flag = false;
|
||||
dhcp_inform(netif);
|
||||
}
|
||||
return (int32_t) ERR_OK;
|
||||
}
|
||||
|
||||
int32_t net_ip_remove_if(net_if_handle_t *pnetif, err_t (*if_deinit)(struct netif *netif))
|
||||
{
|
||||
if (pnetif != NULL)
|
||||
{
|
||||
struct netif *netif = pnetif->netif;
|
||||
if (netif != NULL)
|
||||
{
|
||||
netif_set_down(netif);
|
||||
netif_set_link_down(netif);
|
||||
netif_remove(netif);
|
||||
if (NULL != if_deinit)
|
||||
{
|
||||
(*if_deinit)(netif);
|
||||
}
|
||||
NET_FREE(netif);
|
||||
pnetif->netif = NULL;
|
||||
}
|
||||
}
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
void net_ip_status_cb(struct netif *netif)
|
||||
{
|
||||
net_ip_addr_t ipaddr_zero;
|
||||
/*cstat -MISRAC2012-Rule-11.5 casting state pointer by defintion from LWIP */
|
||||
net_if_handle_t *pnetif = (net_if_handle_t *) netif->state;
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
|
||||
NET_ZERO(ipaddr_zero);
|
||||
|
||||
if (pnetif->dhcp_enabled)
|
||||
{
|
||||
/* lost connection */
|
||||
if (NET_DIFF(netif->ip_addr, ipaddr_zero) && (!NETIF_IS_LINK_UP(netif)) && pnetif->dhcp_release_on_link_lost)
|
||||
{
|
||||
NET_DBG_PRINT("Callback lost connection so release connection\n");
|
||||
(void) dhcp_release(netif);
|
||||
(void) dhcp_start(netif);
|
||||
}
|
||||
|
||||
/* up connection , so need to inform other at first time */
|
||||
if (pnetif->dhcp_inform_flag && NETIF_IS_LINK_UP(netif))
|
||||
{
|
||||
NET_DBG_PRINT("Callback get connection\n");
|
||||
dhcp_inform(netif);
|
||||
pnetif->dhcp_inform_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NET_IP_ADDR_CMP(&pnetif->ipaddr, &netif->ip_addr))
|
||||
{
|
||||
NET_IP_ADDR_COPY(pnetif->ipaddr, netif->ip_addr);
|
||||
NET_IP_ADDR_COPY(pnetif->netmask, netif->netmask);
|
||||
NET_IP_ADDR_COPY(pnetif->gateway, netif->gw);
|
||||
/* FIXME for IPV6 support */
|
||||
if (!NET_IP_ADDR_ISANY_VAL(pnetif->ipaddr))
|
||||
{
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_IPADDR);
|
||||
}
|
||||
}
|
||||
|
||||
if (NETIF_IS_LINK_UP(netif))
|
||||
{
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_LINK_UP);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) net_state_manage_event(pnetif, NET_EVENT_LINK_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* UTILITIES */
|
||||
|
||||
void link_socket_to_lwip(net_if_drv_t *drv)
|
||||
{
|
||||
#ifndef NET_BYPASS_NET_SOCKET
|
||||
drv->psocket = net_lwip_socket;
|
||||
drv->pbind = net_lwip_bind;
|
||||
drv->plisten = net_lwip_listen;
|
||||
drv->paccept = net_lwip_accept;
|
||||
drv->pconnect = net_lwip_connect;
|
||||
drv->psend = net_lwip_send;
|
||||
drv->precv = net_lwip_recv;
|
||||
drv->psendto = net_lwip_sendto;
|
||||
drv->precvfrom = net_lwip_recvfrom;
|
||||
drv->psetsockopt = net_lwip_setsockopt;
|
||||
drv->pgetsockopt = net_lwip_getsockopt;
|
||||
drv->pgetsockname = net_lwip_getsockname;
|
||||
drv->pgetpeername = net_lwip_getpeername;
|
||||
drv->pclose = net_lwip_close;
|
||||
drv->pshutdown = net_lwip_shutdown;
|
||||
#endif /* NET_BYPASS_NET_SOCKET */
|
||||
/* Service */
|
||||
drv->pgethostbyname = net_lwip_gethostbyname;
|
||||
}
|
||||
|
||||
|
||||
int32_t returncode_lwip2net(int32_t ret_in)
|
||||
{
|
||||
int32_t ret = ret_in;
|
||||
if (ret_in == -1)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (ret_in == 0)
|
||||
{
|
||||
/* connection close */
|
||||
ret = NET_ERROR_DISCONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do not catch ret valie otherwise */
|
||||
ret = ret_in;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NET_BYPASS_NET_SOCKET
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_socket(int32_t domain, int32_t type, int32_t protocol)
|
||||
{
|
||||
int32_t sock;
|
||||
sock = (int32_t) lwip_socket(domain, type, protocol);
|
||||
return (sock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
|
||||
static struct sockaddr *getsockaddr(const net_sockaddr_t *addr)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.8 const*/
|
||||
return (struct sockaddr *) addr;
|
||||
/*cstat +MISRAC2012-Rule-11.8 const*/
|
||||
|
||||
}
|
||||
|
||||
static int32_t net_lwip_bind(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
|
||||
{
|
||||
int32_t ret = lwip_bind(sock, getsockaddr(addr), addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_listen(int32_t sock, int32_t backlog)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = lwip_listen(sock, backlog);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_accept(int32_t sock, net_sockaddr_t *addr, uint32_t *addrlen)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = lwip_accept(sock, getsockaddr(addr), addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_connect(int32_t sock, const net_sockaddr_t *addr, uint32_t addrlen)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = lwip_connect(sock, getsockaddr(addr), addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_send(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = lwip_send(sock, buf, (uint32_t) len, flags);
|
||||
return returncode_lwip2net(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_recv(int32_t sock, uint8_t *buf, int32_t len, int32_t flags)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = lwip_recv(sock, buf, (uint32_t) len, flags);
|
||||
return returncode_lwip2net(ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_sendto(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *to,
|
||||
uint32_t tolen)
|
||||
{
|
||||
int32_t ret = lwip_sendto(sock, buf, (uint32_t) len, flags, getsockaddr(to), tolen);
|
||||
return returncode_lwip2net(ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_recvfrom(int32_t sock, uint8_t *buf, int32_t len, int32_t flags, net_sockaddr_t *from,
|
||||
uint32_t *fromlen)
|
||||
{
|
||||
int32_t ret = lwip_recvfrom(sock, buf, (uint32_t) len, flags, getsockaddr(from), fromlen);
|
||||
return returncode_lwip2net(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_setsockopt(int32_t sock, int32_t level, int32_t optname, const void *optvalue, uint32_t optlen)
|
||||
{
|
||||
int32_t ret = lwip_setsockopt(sock, level, optname, optvalue, optlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
|
||||
static int32_t net_lwip_getsockopt(int32_t sock, int32_t level, int32_t optname, void *optvalue, uint32_t *optlen)
|
||||
{
|
||||
int32_t ret = lwip_getsockopt(sock, level, optname, optvalue, optlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_getsockname(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
|
||||
{
|
||||
int32_t ret = lwip_getsockname(sock, getsockaddr(name), namelen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_getpeername(int32_t sock, net_sockaddr_t *name, uint32_t *namelen)
|
||||
{
|
||||
int32_t ret = lwip_getpeername(sock, getsockaddr(name), namelen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_close(int32_t sock, bool clone)
|
||||
{
|
||||
(void) clone;
|
||||
int32_t ret = lwip_close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_shutdown(int32_t sock, int32_t mode)
|
||||
{
|
||||
int32_t ret = lwip_shutdown(sock, mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* NET_BYPASS_NET_SOCKET */
|
||||
/**
|
||||
* @brief Function description
|
||||
* @param Params
|
||||
* @retval socket status
|
||||
*/
|
||||
static int32_t net_lwip_gethostbyname(net_if_handle_t *pnetif, net_sockaddr_t *addr, char_t *name)
|
||||
{
|
||||
int32_t ret = NET_ERROR_DNS_FAILURE;
|
||||
struct addrinfo *hostinfo;
|
||||
struct addrinfo hints;
|
||||
|
||||
(void) pnetif;
|
||||
|
||||
if (addr->sa_len < sizeof(net_sockaddr_in_t))
|
||||
{
|
||||
ret = NET_ERROR_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
if (0 == lwip_getaddrinfo((char_t *)name, NULL, &hints, &hostinfo))
|
||||
{
|
||||
if (hostinfo->ai_family == AF_INET)
|
||||
{
|
||||
uint8_t len = addr->sa_len;
|
||||
net_sockaddr_in_t *saddr = (net_sockaddr_in_t *) addr;
|
||||
|
||||
(void) memset(saddr, 0, len);
|
||||
saddr->sin_len = len;
|
||||
saddr->sin_family = NET_AF_INET;
|
||||
(void) memcpy(&saddr->sin_addr, &((net_sockaddr_in_t *)(hostinfo->ai_addr))->sin_addr, 4);
|
||||
ret = NET_OK;
|
||||
}
|
||||
lwip_freeaddrinfo(hostinfo);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,629 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_mbedtls.c
|
||||
* @author MCD Application Team
|
||||
* @brief Network abstraction at transport layer level. mbedTLS implementation.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
#ifdef NET_MBEDTLS_HOST_SUPPORT
|
||||
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#endif /* osCMSIS */
|
||||
|
||||
int32_t mbedtls_rng_raw(void *data, uchar_t *output, size_t len);
|
||||
|
||||
extern struct __RNG_HandleTypeDef hrng;
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void mbedtls_free_resource(net_socket_t *sock);
|
||||
static int32_t mbedtls_net_recv(void *ctx, uchar_t *buf, size_t len, uint32_t timeout);
|
||||
static int32_t mbedtls_net_send(void *ctx, const uchar_t *buf, size_t len);
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
extern void *pxCurrentTCB;
|
||||
|
||||
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
|
||||
|
||||
void mutex_init(mbedtls_threading_mutex_t *mutex);
|
||||
void mutex_free(mbedtls_threading_mutex_t *mutex);
|
||||
int32_t mutex_lock(mbedtls_threading_mutex_t *mutex);
|
||||
int32_t mutex_unlock(mbedtls_threading_mutex_t *mutex);
|
||||
|
||||
void mutex_init(mbedtls_threading_mutex_t *mutex)
|
||||
{
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
mutex->id = osSemaphoreNew(1, 1, NULL);
|
||||
#else
|
||||
mutex->id = osSemaphoreCreate(&mutex->def, 1);
|
||||
#endif /* osCMSIS */
|
||||
}
|
||||
|
||||
void mutex_free(mbedtls_threading_mutex_t *mutex)
|
||||
{
|
||||
(void) osSemaphoreDelete(mutex->id);
|
||||
}
|
||||
|
||||
#define WAITFOREVER 0xFFFFFFFFU /* redefined for MISRA checks */
|
||||
|
||||
int32_t mutex_lock(mbedtls_threading_mutex_t *mutex)
|
||||
{
|
||||
BaseType_t ret;
|
||||
ret = (BaseType_t) OSSEMAPHOREWAIT(mutex->id, WAITFOREVER);
|
||||
return (ret >= 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
int32_t mutex_unlock(mbedtls_threading_mutex_t *mutex)
|
||||
{
|
||||
BaseType_t ret;
|
||||
ret = (BaseType_t) osSemaphoreRelease(mutex->id);
|
||||
return (ret >= 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_THREADING_ALT */
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
void net_tls_init(void)
|
||||
{
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock);
|
||||
#endif /* MBEDTLS_THREADING_ALT */
|
||||
}
|
||||
|
||||
void net_tls_destroy(void)
|
||||
{
|
||||
#ifdef MBEDTLS_THREADING_ALT
|
||||
mbedtls_threading_free_alt();
|
||||
#endif /* MBEDTLS_THREADING_ALT */
|
||||
}
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
bool net_mbedtls_check_tlsdata(net_socket_t *sock)
|
||||
{
|
||||
bool ret = true;
|
||||
void *p;
|
||||
if (NULL == sock->tlsData)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
p = NET_MALLOC(sizeof(net_tls_data_t));
|
||||
/*cstat +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
if (p == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("Error during setting option.\n");
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.5 */
|
||||
sock->tlsData = p;
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
(void) memset(sock->tlsData, 0, sizeof(net_tls_data_t));
|
||||
sock->tlsData->tls_srv_verification = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void DebugPrint(void *ctx,
|
||||
int32_t level,
|
||||
const char_t *file,
|
||||
int32_t line,
|
||||
const char_t *str)
|
||||
|
||||
{
|
||||
/* Unused parameters. */
|
||||
(void)ctx;
|
||||
(void) level;
|
||||
#ifdef NET_USE_RTOS
|
||||
NET_PRINT_WO_CR("%p => %s:%04ld: %s\n", pxCurrentTCB, file, (int32_t) line, str);
|
||||
#else
|
||||
NET_PRINT_WO_CR("%s:%04ld: %s\n", file, (uint32_t) line, str);
|
||||
#endif /* NET_USE_RTOS */
|
||||
}
|
||||
|
||||
|
||||
void net_mbedtls_set_read_timeout(net_socket_t *sock)
|
||||
{
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
if (tlsData != NULL)
|
||||
{
|
||||
mbedtls_ssl_conf_read_timeout(&tlsData->conf, (uint32_t) sock->read_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *net_wrapper_calloc(size_t n, size_t m)
|
||||
{
|
||||
/*cstat -MISRAC2012-Dir-4.12 -MISRAC2012-Rule-21.3 */
|
||||
return NET_CALLOC(n, m);
|
||||
/*cstat +MISRAC2012-Dir-4.12 +MISRAC2012-Rule-21.3 */
|
||||
}
|
||||
|
||||
/*cstat -MISRAC2012-Dir-4.6_b */
|
||||
typedef void (*mbedtls_debug_func_t)(void *, int, const char *, int, const char *);
|
||||
typedef int (*mbedtls_rng_func_t)(void *, unsigned char *, size_t);
|
||||
/*cstat +MISRAC2012-Dir-4.6_b */
|
||||
|
||||
|
||||
static void net_wrapper_free(void *p)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-21.3 */
|
||||
NET_FREE(p);
|
||||
/*cstat +MISRAC2012-Rule-21.3 */
|
||||
}
|
||||
|
||||
uint32_t NET_TICK(void);
|
||||
|
||||
int32_t net_mbedtls_start(net_socket_t *sock)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
uint32_t start_tick;
|
||||
|
||||
(void) mbedtls_platform_set_calloc_free(net_wrapper_calloc, net_wrapper_free);
|
||||
mbedtls_ssl_init(&tlsData->ssl);
|
||||
mbedtls_ssl_config_init(&tlsData->conf);
|
||||
/*cstat -MISRAC2012-Rule-11.1 */
|
||||
mbedtls_ssl_conf_dbg(&tlsData->conf, (mbedtls_debug_func_t) DebugPrint, NULL);
|
||||
/*cstat +MISRAC2012-Rule-11.1 */
|
||||
|
||||
mbedtls_debug_set_threshold(NET_MBEDTLS_DEBUG_LEVEL);
|
||||
mbedtls_x509_crt_init(&tlsData->cacert);
|
||||
if (tlsData->tls_dev_cert != NULL)
|
||||
{
|
||||
mbedtls_x509_crt_init(&tlsData->clicert);
|
||||
}
|
||||
if (tlsData->tls_dev_key != NULL)
|
||||
{
|
||||
mbedtls_pk_init(&tlsData->pkey);
|
||||
}
|
||||
|
||||
/* Root CA */
|
||||
if (tlsData->tls_ca_certs != NULL)
|
||||
{
|
||||
ret = mbedtls_x509_crt_parse(&tlsData->cacert, (uchar_t const *) tlsData->tls_ca_certs,
|
||||
strlen((char_t const *) tlsData->tls_ca_certs) + 1U);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_x509_crt_parse returned 0x%lx while parsing root cert\n", ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_CRT_PARSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*no root so cannot check server identification ?
|
||||
tlsData->tls_srv_verification = */
|
||||
}
|
||||
|
||||
|
||||
/* Client cert. and key */
|
||||
if ((ret == NET_OK) && (tlsData->tls_dev_cert != NULL) && (tlsData->tls_dev_key != NULL))
|
||||
{
|
||||
ret = mbedtls_x509_crt_parse(&tlsData->clicert, (uchar_t const *) tlsData->tls_dev_cert,
|
||||
strlen((char_t const *)tlsData->tls_dev_cert) + 1U);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%lx while parsing device cert\n", -ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_CRT_PARSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = mbedtls_pk_parse_key(&tlsData->pkey, (uchar_t const *)tlsData->tls_dev_key,
|
||||
strlen((char_t const *)tlsData->tls_dev_key) + 1U,
|
||||
(uchar_t const *)tlsData->tls_dev_pwd, tlsData->tls_dev_pwd_len);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%lx while parsing private key\n\n", -ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_KEY_PARSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TLS Connection */
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
ret = mbedtls_ssl_config_defaults(&tlsData->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%lx\n\n", -ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
/* Allow the user to select a TLS profile? */
|
||||
if (tlsData->tls_cert_prof != NULL)
|
||||
{
|
||||
mbedtls_ssl_conf_cert_profile(&tlsData->conf, tlsData->tls_cert_prof);
|
||||
}
|
||||
|
||||
/* Only for debug
|
||||
* mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); */
|
||||
if (tlsData->tls_srv_verification == true)
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
}
|
||||
else
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
}
|
||||
|
||||
/* no verification because no certificat */
|
||||
/*
|
||||
if (tlsData->tls_ca_certs == NULL)
|
||||
{
|
||||
mbedtls_ssl_conf_authmode(&tlsData->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
*/
|
||||
/*cstat -MISRAC2012-Rule-11.1 */
|
||||
mbedtls_ssl_conf_rng(&tlsData->conf, (mbedtls_rng_func_t) mbedtls_rng_raw, &hrng);
|
||||
/*cstat +MISRAC2012-Rule-11.1 */
|
||||
mbedtls_ssl_conf_ca_chain(&tlsData->conf, &tlsData->cacert, NULL);
|
||||
|
||||
if ((tlsData->tls_dev_cert != NULL) && (tlsData->tls_dev_key != NULL))
|
||||
{
|
||||
ret = mbedtls_ssl_conf_own_cert(&tlsData->conf, &tlsData->clicert, &tlsData->pkey);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned -0x%lx\n\n", -ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_CONFIG;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
ret = mbedtls_ssl_setup(&tlsData->ssl, &tlsData->conf);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%lx\n\n", -ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_SSL_SETUP;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret == NET_OK) && (tlsData->tls_srv_name != NULL))
|
||||
{
|
||||
ret = mbedtls_ssl_set_hostname(&tlsData->ssl, (char_t const *)tlsData->tls_srv_name);
|
||||
if (ret != 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %ld\n\n", ret);
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_SET_HOSTNAME;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.1 */
|
||||
mbedtls_ssl_set_bio(&tlsData->ssl, sock, (mbedtls_ssl_send_t *) mbedtls_net_send, NULL,
|
||||
(mbedtls_ssl_recv_timeout_t *) mbedtls_net_recv);
|
||||
/*cstat +MISRAC2012-Rule-11.1 */
|
||||
mbedtls_ssl_conf_read_timeout(&tlsData->conf, (uint32_t)sock->read_timeout);
|
||||
|
||||
|
||||
NET_DBG_INFO("\n\nSSL state connect : %d ", sock->tlsData->ssl.state);
|
||||
|
||||
|
||||
NET_DBG_INFO("\n\nSSL state connect : %d ", sock->tlsData->ssl.state);
|
||||
NET_DBG_INFO(" . Performing the SSL/TLS handshake...");
|
||||
|
||||
ret = mbedtls_ssl_handshake(&tlsData->ssl);
|
||||
start_tick = NET_TICK();
|
||||
while (ret != 0)
|
||||
{
|
||||
uint32_t elapsed_tick = NET_TICK() - start_tick;
|
||||
|
||||
if (elapsed_tick > NET_MBEDTLS_CONNECT_TIMEOUT)
|
||||
{
|
||||
mbedtls_free_resource(sock);
|
||||
ret = NET_ERROR_MBEDTLS_CONNECT;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE))
|
||||
{
|
||||
tlsData->flags = mbedtls_ssl_get_verify_result(&tlsData->ssl);
|
||||
if (tlsData->flags != 0U)
|
||||
{
|
||||
char_t vrfy_buf[512];
|
||||
(void) mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsData->flags);
|
||||
if (tlsData->tls_srv_verification == true)
|
||||
{
|
||||
NET_DBG_ERROR("Server verification:\n%s\n", vrfy_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_INFO("Server verification:\n%s\n", vrfy_buf);
|
||||
}
|
||||
}
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%lx\n", -ret);
|
||||
|
||||
mbedtls_free_resource(sock);
|
||||
ret = (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ? NET_ERROR_MBEDTLS_REMOTE_AUTH : NET_ERROR_MBEDTLS_CONNECT;
|
||||
/*cstat -MISRAC2012-Rule-15.4 */
|
||||
break;
|
||||
/*cstat +MISRAC2012-Rule-15.4 */
|
||||
}
|
||||
ret = mbedtls_ssl_handshake(&tlsData->ssl);
|
||||
}
|
||||
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
int32_t exp;
|
||||
NET_DBG_INFO(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
|
||||
mbedtls_ssl_get_version(&sock->tlsData->ssl),
|
||||
mbedtls_ssl_get_ciphersuite(&sock->tlsData->ssl));
|
||||
|
||||
exp = mbedtls_ssl_get_record_expansion(&tlsData->ssl);
|
||||
if (exp >= 0)
|
||||
{
|
||||
NET_DBG_INFO(" [ Record expansion is %d ]\n", exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_INFO(" [ Record expansion is unknown (compression) ]\n");
|
||||
}
|
||||
|
||||
NET_DBG_INFO(" . Verifying peer X.509 certificate...");
|
||||
|
||||
|
||||
#ifdef NET_DBG_INFO
|
||||
#define NET_CERTIFICATE_DISPLAY_LEN 2048U
|
||||
if (mbedtls_ssl_get_peer_cert(&sock->tlsData->ssl) != NULL)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.5 -MISRAC2012-Rule-21.3 -MISRAC2012-Dir-4.12 */
|
||||
char_t *buf = NET_MALLOC(sizeof(char_t) * NET_CERTIFICATE_DISPLAY_LEN);
|
||||
/*cstat +MISRAC2012-Rule-11.5 +MISRAC2012-Rule-21.3 +MISRAC2012-Dir-4.12 */
|
||||
|
||||
if (buf != NULL)
|
||||
{
|
||||
NET_DBG_INFO(" . Peer certificate information ...\n");
|
||||
(void) mbedtls_x509_crt_info(buf, NET_CERTIFICATE_DISPLAY_LEN - 1U, " ",
|
||||
mbedtls_ssl_get_peer_cert(&sock->tlsData->ssl));
|
||||
NET_DBG_INFO("%s\n", buf);
|
||||
/*cstat -MISRAC2012-Rule-21.3 */
|
||||
NET_FREE(buf);
|
||||
/*cstat +MISRAC2012-Rule-21.3 */
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_INFO(" . Cannot allocate memory to display certificate information ...\n");
|
||||
}
|
||||
}
|
||||
#endif /* NET_DBG_INFO */
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int32_t net_mbedtls_sock_recv(net_socket_t *sock, uint8_t *buf, size_t len)
|
||||
{
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
int32_t ret;
|
||||
|
||||
ret = mbedtls_ssl_read(&tlsData->ssl, buf, len);
|
||||
if (ret <= 0)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
ret = NET_ERROR_DISCONNECTED;
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_TIMEOUT: /* In case a blocking read function was passed through mbedtls_ssl_set_bio() */
|
||||
ret = NET_TIMEOUT;
|
||||
break;
|
||||
|
||||
case MBEDTLS_ERR_SSL_WANT_READ:
|
||||
ret = NET_TIMEOUT;
|
||||
break;
|
||||
|
||||
default:
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_read returned -0x%lx\n\n", -ret);
|
||||
ret = NET_ERROR_MBEDTLS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32_t net_mbedtls_sock_send(net_socket_t *sock, const uint8_t *buf, size_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
#if PERF
|
||||
stat.mbedtls_send_cycle -= net_get_cycle();
|
||||
#endif /* PERF */
|
||||
|
||||
ret = mbedtls_ssl_write(&tlsData->ssl, buf, len);
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = NET_ERROR_DISCONNECTED;
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
NET_DBG_ERROR(" failed\n ! mbedtls_ssl_write returned -0x%lx\n\n", -ret);
|
||||
ret = NET_ERROR_MBEDTLS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ret > 0 nothing to do , MISRA checks */
|
||||
}
|
||||
#if PERF
|
||||
stat.mbedtls_send_cycle += net_get_cycle();
|
||||
#endif /* PERF */
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
int32_t net_mbedtls_stop(net_socket_t *sock)
|
||||
{
|
||||
int32_t ret;
|
||||
/* Closure notification is required by TLS if the session was not already closed by the remote host. */
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
do
|
||||
{
|
||||
ret = mbedtls_ssl_close_notify(&tlsData->ssl);
|
||||
} while ((ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ));
|
||||
|
||||
/* All other negative return values indicate connection needs to be reset.
|
||||
* No further action required since this is disconnect call */
|
||||
|
||||
mbedtls_free_resource(sock);
|
||||
return NET_OK;
|
||||
}
|
||||
|
||||
|
||||
static void mbedtls_free_resource(net_socket_t *sock)
|
||||
{
|
||||
net_tls_data_t *tlsData = sock->tlsData;
|
||||
|
||||
mbedtls_x509_crt_free(&tlsData->clicert);
|
||||
mbedtls_pk_free(&tlsData->pkey);
|
||||
mbedtls_x509_crt_free(&tlsData->cacert);
|
||||
mbedtls_ssl_free(&tlsData->ssl);
|
||||
mbedtls_ssl_config_free(&tlsData->conf);
|
||||
/*cstat -MISRAC2012-Rule-21.3 */
|
||||
NET_FREE(tlsData);
|
||||
/*cstat +MISRAC2012-Rule-21.3 */
|
||||
sock->tlsData = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* received interface implementation.*/
|
||||
static int32_t mbedtls_net_recv(void *ctx, uchar_t *buf, size_t len, uint32_t timeout)
|
||||
{
|
||||
int32_t ret = NET_OK;
|
||||
int32_t flags = 0;
|
||||
/*cstat -MISRAC2012-Rule-11.5 */
|
||||
net_socket_t *pSocket = (net_socket_t *) ctx;
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
|
||||
if (pSocket->read_timeout != (int32_t)timeout)
|
||||
{
|
||||
ret = pSocket->pnetif->pdrv->psetsockopt(pSocket->ulsocket,
|
||||
NET_SOL_SOCKET, NET_SO_RCVTIMEO, &timeout, sizeof(uint32_t));
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
pSocket->read_timeout = (int32_t) timeout;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == NET_OK)
|
||||
{
|
||||
if (pSocket->read_timeout == 0)
|
||||
{
|
||||
flags = (int8_t) NET_MSG_DONTWAIT;
|
||||
}
|
||||
UNLOCK_SOCK(pSocket->idx);
|
||||
ret = pSocket->pnetif->pdrv->precv(pSocket->ulsocket, buf, len, flags);
|
||||
LOCK_SOCK(pSocket->idx);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
ret = MBEDTLS_ERR_SSL_WANT_READ;
|
||||
break;
|
||||
|
||||
case NET_TIMEOUT:
|
||||
/* According to mbedtls headers, MBEDTLS_ERR_SSL_TIMEOUT should be returned. */
|
||||
/* But it saturates the error log with false errors. By contrast, */
|
||||
/* MBEDTLS_ERR_SSL_WANT_READ does not raise any error. */
|
||||
ret = MBEDTLS_ERR_SSL_WANT_READ;
|
||||
break;
|
||||
|
||||
default:
|
||||
NET_DBG_ERROR("mbedtls_net_recv() : error %ld in recv() - requestedLen=%d\n", ret, len);
|
||||
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mbedtls_net_send(void *ctx, const uchar_t *buf, size_t len)
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.5 */
|
||||
net_socket_t *pSocket = (net_socket_t *) ctx;
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
int32_t ret;
|
||||
int32_t flags = 0;
|
||||
|
||||
if (pSocket->write_timeout == 0)
|
||||
{
|
||||
flags = (int8_t) NET_MSG_DONTWAIT;
|
||||
}
|
||||
UNLOCK_SOCK(pSocket->idx);
|
||||
/*cstat -MISRAC2012-Rule-11.8 removing const attribute */
|
||||
ret = pSocket->pnetif->pdrv->psend(pSocket->ulsocket, (uchar_t *) buf, len, flags);
|
||||
/*cstat +MISRAC2012-Rule-11.8 */
|
||||
LOCK_SOCK(pSocket->idx);
|
||||
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("mbedtls_net_send(): error %ld in send() - requestedLen=%d\n", ret, len);
|
||||
|
||||
/* TODO: The underlying layers do not allow to distinguish between
|
||||
* MBEDTLS_ERR_SSL_INTERNAL_ERROR,
|
||||
* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY,
|
||||
* MBEDTLS_ERR_SSL_CONN_EOF.
|
||||
* Most often, the error is due to the closure of the connection by the remote host. */
|
||||
|
||||
ret = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* NET_MBEDTLS_HOST_SUPPORT */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_ping.c
|
||||
* @author MCD Application Team
|
||||
* @brief application to send icmp ping
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "net_connect.h"
|
||||
#include "net_internals.h"
|
||||
/*cstat -MISRAC* -DEFINE-* -CERT-EXP19* */
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/api.h" /* HAL_GetTick() */
|
||||
#include "lwip/ip4.h"
|
||||
/*cstat +MISRAC* +DEFINE-* +CERT-EXP19* */
|
||||
|
||||
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/** ping identifier - must fit on a u16_t */
|
||||
#ifndef PING_ID
|
||||
#define PING_ID 0xAFAF
|
||||
#endif /* PING_ID */
|
||||
|
||||
/** ping additional data size to include in the packet */
|
||||
#ifndef PING_DATA_SIZE
|
||||
#define PING_DATA_SIZE 32
|
||||
#endif /* PING_DATA_SIZE */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static void ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len, uint16_t ping_seq_num)
|
||||
{
|
||||
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 = (uint16_t) lwip_htons(ping_seq_num);
|
||||
|
||||
/* fill the additional data buffer with some data */
|
||||
for (i = 0; i < data_len; i++)
|
||||
{
|
||||
((char_t *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char_t)i;
|
||||
}
|
||||
/* Ping data are sent in RAM mode , so LWIP is not computing the checksum by SW */
|
||||
#ifndef CHECKSUM_BY_HARDWARE
|
||||
iecho->chksum = inet_chksum(iecho, len);
|
||||
#endif /* CHECKSUM_BY_HARDWARE */
|
||||
}
|
||||
|
||||
uint32_t sys_now(void);
|
||||
|
||||
|
||||
#define NET_IPH_HL(hdr) ((hdr)->_v_hl & 0x0fU)
|
||||
|
||||
int32_t icmp_ping(net_if_handle_t *pnetif, net_sockaddr_t *addr, int32_t count, int32_t timeout, int32_t response[])
|
||||
{
|
||||
int32_t sock;
|
||||
int32_t ret = 0;
|
||||
uint32_t ping_start_time;
|
||||
net_sockaddr_t from;
|
||||
uint32_t fromlen;
|
||||
int32_t len;
|
||||
static int32_t ping_seq_num = 1;
|
||||
char_t buf[64] = "";
|
||||
struct ip_hdr *iphdr;
|
||||
struct icmp_echo_hdr *iecho, *pecho = NULL;
|
||||
size_t ping_size = sizeof(struct icmp_echo_hdr) + (uint32_t) PING_DATA_SIZE;
|
||||
u16_t seqnum;
|
||||
(void) pnetif;
|
||||
sock = net_socket(NET_AF_INET, NET_SOCK_RAW, NET_IPPROTO_ICMP);
|
||||
if (sock < 0)
|
||||
{
|
||||
NET_DBG_ERROR("ping: socket fail\r\n");
|
||||
ret = -1;
|
||||
}
|
||||
else if (net_setsockopt(sock, NET_SOL_SOCKET, NET_SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
|
||||
{
|
||||
NET_DBG_ERROR("ping: setsockopt() fail\r\n");
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*cstat -MISRAC2012-Rule-11.5 Malloc */
|
||||
pecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
|
||||
/*cstat +MISRAC2012-Rule-11.5 */
|
||||
|
||||
if (pecho == NULL)
|
||||
{
|
||||
NET_DBG_ERROR("ping_client_process : message alloc fails\r\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
addr->sa_family = NET_AF_INET;
|
||||
net_set_port(addr, 0U);
|
||||
|
||||
for (int32_t i = 0; i < count; i++)
|
||||
{
|
||||
response[i] = -1;
|
||||
/* add useless test for MISRA on pecho */
|
||||
if (pecho != NULL)
|
||||
{
|
||||
ping_prepare_echo(pecho, (uint16_t) ping_size, (uint16_t) ping_seq_num);
|
||||
}
|
||||
|
||||
if (net_sendto(sock, (uint8_t *)pecho, (int32_t) ping_size, 0, addr, (int32_t) sizeof(net_sockaddr_t)) < 0)
|
||||
{
|
||||
NET_DBG_INFO("ping_client_process : send fail\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ping_start_time = sys_now();
|
||||
do
|
||||
{
|
||||
|
||||
len = net_recvfrom(sock, (uint8_t *)buf, (int32_t) ping_size, 0, &from, &fromlen);
|
||||
if (len >= (int32_t)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
|
||||
{
|
||||
|
||||
/*cstat -MISRAC2012-Rule-11.3 Cast */
|
||||
iphdr = (struct ip_hdr *)buf;
|
||||
iecho = (struct icmp_echo_hdr *)(buf + ((NET_IPH_HL(iphdr)) * 4U));
|
||||
/*cstat +MISRAC2012-Rule-11.3 Cast */
|
||||
seqnum = lwip_htons((uint16_t) ping_seq_num);
|
||||
if ((iecho->id == (uint16_t)PING_ID) && (iecho->seqno == seqnum))
|
||||
{
|
||||
if (ICMPH_TYPE(iecho) == (uint8_t) ICMP_ER)
|
||||
{
|
||||
uint32_t delta;
|
||||
ret = 0;
|
||||
delta = sys_now() - ping_start_time;
|
||||
response[i] = (int32_t) delta;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NET_DBG_ERROR("ICMP Other Response received \r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t now = sys_now();
|
||||
NET_DBG_ERROR("no data start %ld : %lu .. %lu\r\n", len, ping_start_time, now);
|
||||
}
|
||||
} while (sys_now() < (ping_start_time + (uint32_t) timeout));
|
||||
ping_seq_num++;
|
||||
}
|
||||
if (pecho != NULL)
|
||||
{
|
||||
mem_free(pecho);
|
||||
}
|
||||
(void) net_closesocket(sock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.c
|
||||
* @author MCD Application Team
|
||||
* @brief Implement cellular_probe() called to initialize the Cellular low level driver
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "net_connect.h"
|
||||
|
||||
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
int32_t cellular_probe(void **ll_drv_context);
|
||||
|
||||
|
||||
int32_t cellular_probe(void **ll_drv_context)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef GENERATOR_AWS_CLOUD
|
||||
#include "mbedtls/x509_crt.h"
|
||||
|
||||
/*
|
||||
* Amazon Profile
|
||||
*/
|
||||
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
|
||||
{
|
||||
/* Only SHA-256 and 384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
|
||||
/* Only ECDSA */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* Only NIST P-256 and P-384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
|
||||
#else
|
||||
0,
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
2048
|
||||
};
|
||||
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
|
||||
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
|
||||
|
||||
#endif /* GENERATOR_AWS_CLOUD */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the configuration for net
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONF_H
|
||||
#define NET_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MDM_SIM_SELECT_0_Pin GPIO_PIN_2
|
||||
#define MDM_SIM_SELECT_0_GPIO_Port GPIOC
|
||||
|
||||
#define MDM_SIM_SELECT_1_Pin GPIO_PIN_3
|
||||
#define MDM_SIM_SELECT_1_GPIO_Port GPIOI
|
||||
|
||||
#define MDM_SIM_CLK_Pin GPIO_PIN_4
|
||||
#define MDM_SIM_CLK_GPIO_Port GPIOA
|
||||
|
||||
#define MDM_SIM_DATA_Pin GPIO_PIN_12
|
||||
#define MDM_SIM_DATA_GPIO_Port GPIOB
|
||||
|
||||
#define MDM_SIM_RST_Pin GPIO_PIN_7
|
||||
#define MDM_SIM_RST_GPIO_Port GPIOC
|
||||
|
||||
#define MDM_PWR_EN_Pin GPIO_PIN_3
|
||||
#define MDM_PWR_EN_GPIO_Port GPIOD
|
||||
|
||||
#define MDM_DTR_Pin GPIO_PIN_0
|
||||
#define MDM_DTR_GPIO_Port GPIOA
|
||||
|
||||
#define MDM_RST_Pin GPIO_PIN_2
|
||||
#define MDM_RST_GPIO_Port GPIOB
|
||||
|
||||
#define USART1_TX_Pin GPIO_PIN_6
|
||||
#define USART1_TX_GPIO_Port GPIOB
|
||||
|
||||
#define UART1_RX_Pin GPIO_PIN_10
|
||||
#define UART1_RX_GPIO_Port GPIOG
|
||||
|
||||
#define UART1_CTS_Pin GPIO_PIN_11
|
||||
#define UART1_CTS_GPIO_Port GPIOG
|
||||
|
||||
#define UART1_RTS_Pin GPIO_PIN_12
|
||||
#define UART1_RTS_GPIO_Port GPIOG
|
||||
|
||||
|
||||
#define NET_USE_RTOS
|
||||
|
||||
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#define NET_MBEDTLS_HOST_SUPPORT
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
#include "net_conf_template.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+834
@@ -0,0 +1,834 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file es_wifi_io.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file implements the IO operations to deal with the es-wifi
|
||||
* module. It mainly Inits and Deinits the SPI interface. Send and
|
||||
* receive data over it.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 ------------------------------------------------------------------*/
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY)
|
||||
#include "stm32f4xx_hal.h"
|
||||
#define DATA_READY_IRQ EXTI15_10_IRQn
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY */
|
||||
|
||||
#if defined(TARGET_B_L475E_IOT01)
|
||||
#include "stm32l4xx_hal.h"
|
||||
#define DATA_READY_IRQ EXTI1_IRQn
|
||||
#endif /* TARGET_B_L475E_IOT01 */
|
||||
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
#include "stm32h7xx_hal.h"
|
||||
#define DATA_READY_IRQ EXTI9_5_IRQn
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
|
||||
#include <core_cm4.h>
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
#include <core_cm7.h>
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
#include <string.h>
|
||||
#include "es_wifi.h"
|
||||
#include "es_wifi_conf.h"
|
||||
#include "net_conf.h"
|
||||
#ifdef GENERATOR_AWS_CLOUD
|
||||
#include "mbedtls/x509_crt.h"
|
||||
#endif /* GENERATOR_AWS_CLOUD */
|
||||
|
||||
/* Global variables --------------------------------------------------------*/
|
||||
SPI_HandleTypeDef hspi;
|
||||
|
||||
/* Function definitions --------------------------------------------------------*/
|
||||
static void SPI_WIFI_MspInit(SPI_HandleTypeDef *hspi);
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY)
|
||||
#define WIFI_RESET_MODULE() do{\
|
||||
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_RESET);\
|
||||
HAL_Delay(10);\
|
||||
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_SET);\
|
||||
HAL_Delay(500);\
|
||||
}while(0);
|
||||
|
||||
|
||||
#define WIFI_ENABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOG, GPIO_PIN_11, GPIO_PIN_RESET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_DISABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOG, GPIO_PIN_11, GPIO_PIN_SET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_12) == GPIO_PIN_SET)
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY */
|
||||
|
||||
#if defined(TARGET_B_L475E_IOT01)
|
||||
#define WIFI_RESET_MODULE() do{\
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);\
|
||||
HAL_Delay(10);\
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);\
|
||||
HAL_Delay(500);\
|
||||
}while(0);
|
||||
|
||||
|
||||
#define WIFI_ENABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOE, GPIO_PIN_0, GPIO_PIN_RESET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_DISABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOE, GPIO_PIN_0, GPIO_PIN_SET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_1) == GPIO_PIN_SET)
|
||||
#endif /* TARGET_B_L475E_IOT01 */
|
||||
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
#define WIFI_RESET_MODULE() do{\
|
||||
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_RESET);\
|
||||
HAL_Delay(10);\
|
||||
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_1, GPIO_PIN_SET);\
|
||||
HAL_Delay(500);\
|
||||
}while(0);
|
||||
|
||||
|
||||
#define WIFI_ENABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_RESET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_DISABLE_NSS() do{ \
|
||||
HAL_GPIO_WritePin( GPIOA, GPIO_PIN_11, GPIO_PIN_SET );\
|
||||
}while(0);
|
||||
|
||||
#define WIFI_IS_CMDDATA_READY() (HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_5) == GPIO_PIN_SET)
|
||||
|
||||
#define SPI_INTERFACE_PRIO 0
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static int32_t __IO spi_rx_event = 0;
|
||||
static int32_t __IO spi_tx_event = 0;
|
||||
static int32_t __IO cmddata_rdy_rising_event = 0;
|
||||
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
osMutexId es_wifi_mutex;
|
||||
osMutexDef(es_wifi_mutex);
|
||||
|
||||
static osMutexId spi_mutex;
|
||||
osMutexDef(spi_mutex);
|
||||
|
||||
static osSemaphoreId spi_rx_sem;
|
||||
osSemaphoreDef(spi_rx_sem);
|
||||
|
||||
static osSemaphoreId spi_tx_sem;
|
||||
osSemaphoreDef(spi_tx_sem);
|
||||
|
||||
static osSemaphoreId cmddata_rdy_rising_sem;
|
||||
osSemaphoreDef(cmddata_rdy_rising_sem);
|
||||
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static int32_t wait_cmddata_rdy_high(int32_t timeout);
|
||||
static int32_t wait_cmddata_rdy_rising_event(int32_t timeout);
|
||||
static int32_t wait_spi_tx_event(int32_t timeout);
|
||||
static int32_t wait_spi_rx_event(int32_t timeout);
|
||||
static void SPI_WIFI_DelayUs(uint32_t);
|
||||
static int8_t SPI_WIFI_DeInit(void);
|
||||
static int8_t SPI_WIFI_Init(uint16_t mode);
|
||||
static int8_t SPI_WIFI_ResetModule(void);
|
||||
static int16_t SPI_WIFI_ReceiveData(uint8_t *pData, uint16_t len, uint32_t timeout);
|
||||
static int16_t SPI_WIFI_SendData(uint8_t *pData, uint16_t len, uint32_t timeout);
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
#ifdef GENERATOR_AWS_CLOUD
|
||||
/*
|
||||
* Amazon Profile
|
||||
*/
|
||||
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
|
||||
{
|
||||
/* Only SHA-256 and 384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
|
||||
/* Only ECDSA */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* Only NIST P-256 and P-384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
|
||||
#else
|
||||
0,
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
2048
|
||||
};
|
||||
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
|
||||
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
|
||||
#endif /* GENERATOR_AWS_CLOUD */
|
||||
|
||||
|
||||
int32_t wifi_probe(void **ll_drv_context);
|
||||
|
||||
ES_WIFIObject_t EsWifiObj;
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
COM Driver Interface (SPI)
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Initialize SPI MSP
|
||||
* @param hspi: SPI handle
|
||||
* @retval None
|
||||
*/
|
||||
static void SPI_WIFI_MspInit(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_Init;
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY)
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||
|
||||
/* configure Wake up pin */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
|
||||
GPIO_Init.Pin = GPIO_PIN_15;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_Init);
|
||||
|
||||
/* configure Data ready pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_12;
|
||||
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_Init);
|
||||
|
||||
/* configure Reset pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_1;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_Init.Alternate = 0;
|
||||
HAL_GPIO_Init(GPIOH, &GPIO_Init);
|
||||
|
||||
/* configure SPI NSS pin pin */
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_11, GPIO_PIN_SET);
|
||||
GPIO_Init.Pin = GPIO_PIN_11;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_Init);
|
||||
|
||||
/* configure SPI CLK pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_12;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF7_SPI3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_Init);
|
||||
|
||||
/* configure SPI MOSI pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_5;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_Init);
|
||||
|
||||
/* configure SPI MISO pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_4;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_PULLUP;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_Init);
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY */
|
||||
|
||||
#if defined(TARGET_B_L475E_IOT01)
|
||||
__HAL_RCC_SPI3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
/* configure Wake up pin */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
|
||||
GPIO_Init.Pin = GPIO_PIN_13;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_Init);
|
||||
|
||||
/* configure Data ready pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_1;
|
||||
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_Init);
|
||||
|
||||
/* configure Reset pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_8;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_Init.Alternate = 0;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_Init);
|
||||
|
||||
/* configure SPI NSS pin pin */
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_SET);
|
||||
GPIO_Init.Pin = GPIO_PIN_0;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_Init);
|
||||
|
||||
/* configure SPI CLK pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_10;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_Init);
|
||||
|
||||
/* configure SPI MOSI pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_12;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_Init);
|
||||
|
||||
/* configure SPI MISO pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_11;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_PULLUP;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF6_SPI3;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_Init);
|
||||
#endif /* TARGET_B_L475E_IOT01 */
|
||||
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
__HAL_RCC_SPI2_FORCE_RESET();
|
||||
__HAL_RCC_SPI2_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
|
||||
/* configure Wake up pin */
|
||||
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_2, GPIO_PIN_RESET);
|
||||
GPIO_Init.Pin = GPIO_PIN_2;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
HAL_GPIO_Init(GPIOI, &GPIO_Init);
|
||||
|
||||
/* configure Data ready pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_5;
|
||||
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOI, &GPIO_Init);
|
||||
|
||||
/* configure Reset pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_1;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_Init.Alternate = GPIO_AF5_SPI2;
|
||||
HAL_GPIO_Init(GPIOI, &GPIO_Init);
|
||||
|
||||
/* configure SPI NSS pin pin */
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
|
||||
GPIO_Init.Pin = GPIO_PIN_11;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_Init);
|
||||
|
||||
/* configure SPI CLK pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_12;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_Init.Alternate = GPIO_AF5_SPI2;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_Init);
|
||||
|
||||
/* configure SPI MOSI pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_3;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_Init.Alternate = GPIO_AF5_SPI2;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_Init);
|
||||
|
||||
/* configure SPI MISO pin */
|
||||
GPIO_Init.Pin = GPIO_PIN_2;
|
||||
GPIO_Init.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_Init.Pull = GPIO_PULLUP;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_Init.Alternate = GPIO_AF5_SPI2;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_Init);
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
}
|
||||
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
|
||||
/**
|
||||
* @brief Initialize the SPI3
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
/**
|
||||
* @brief Initialize the SPI2
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
static int8_t SPI_WIFI_Init(uint16_t mode)
|
||||
{
|
||||
int8_t rc = 0;
|
||||
|
||||
if (mode == ES_WIFI_INIT)
|
||||
{
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
|
||||
hspi.Instance = SPI3;
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
hspi.Instance = SPI2;
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
SPI_WIFI_MspInit(&hspi);
|
||||
|
||||
hspi.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi.Init.DataSize = SPI_DATASIZE_16BIT;
|
||||
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; /* 80/8= 10MHz (Inventek WIFI module supports up to 20MHz)*/
|
||||
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi.Init.CRCPolynomial = 0;
|
||||
|
||||
if (HAL_SPI_Init(&hspi) != HAL_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Enable Interrupt for Data Ready pin , GPIO_PIN1 */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)DATA_READY_IRQ, SPI_INTERFACE_PRIO, 0x00);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)DATA_READY_IRQ);
|
||||
|
||||
/* Enable Interrupt for SPI tx and rx */
|
||||
#if defined(TARGET_STM32F413H_DISCOVERY) || defined(TARGET_B_L475E_IOT01)
|
||||
HAL_NVIC_SetPriority((IRQn_Type)SPI3_IRQn, SPI_INTERFACE_PRIO, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)SPI3_IRQn);
|
||||
#endif /* TARGET_STM32F413H_DISCOVERY || TARGET_B_L475E_IOT01 */
|
||||
#if defined(TARGET_STM32H7B3I_DISCOVERY)
|
||||
HAL_NVIC_SetPriority((IRQn_Type)SPI2_IRQn, SPI_INTERFACE_PRIO, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)SPI2_IRQn);
|
||||
#endif /* TARGET_STM32H7B3I_DISCOVERY */
|
||||
|
||||
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
cmddata_rdy_rising_event = 0;
|
||||
es_wifi_mutex = osMutexCreate(osMutex(es_wifi_mutex));
|
||||
spi_mutex = osMutexCreate(osMutex(spi_mutex));
|
||||
spi_rx_sem = osSemaphoreCreate(osSemaphore(spi_rx_sem), 1);
|
||||
spi_tx_sem = osSemaphoreCreate(osSemaphore(spi_tx_sem), 1);
|
||||
cmddata_rdy_rising_sem = osSemaphoreCreate(osSemaphore(cmddata_rdy_rising_sem), 1);
|
||||
/* take semaphore */
|
||||
SEM_WAIT(cmddata_rdy_rising_sem, 1);
|
||||
SEM_WAIT(spi_rx_sem, 1);
|
||||
SEM_WAIT(spi_tx_sem, 1);
|
||||
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
/* first call used for calibration */
|
||||
SPI_WIFI_DelayUs(10);
|
||||
}
|
||||
|
||||
rc = SPI_WIFI_ResetModule();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int8_t SPI_WIFI_ResetModule(void)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint8_t Prompt[6];
|
||||
uint8_t count = 0;
|
||||
HAL_StatusTypeDef Status;
|
||||
|
||||
WIFI_RESET_MODULE();
|
||||
WIFI_ENABLE_NSS();
|
||||
SPI_WIFI_DelayUs(15);
|
||||
|
||||
while (WIFI_IS_CMDDATA_READY())
|
||||
{
|
||||
Status = HAL_SPI_Receive(&hspi, &Prompt[count], 1, 0xFFFF);
|
||||
count += 2;
|
||||
if (((HAL_GetTick() - tickstart) > 0xFFFF) || (Status != HAL_OK))
|
||||
{
|
||||
WIFI_DISABLE_NSS();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
WIFI_DISABLE_NSS();
|
||||
if ((Prompt[0] != 0x15) || (Prompt[1] != 0x15) || (Prompt[2] != '\r') ||
|
||||
(Prompt[3] != '\n') || (Prompt[4] != '>') || (Prompt[5] != ' '))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the SPI
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static int8_t SPI_WIFI_DeInit(void)
|
||||
{
|
||||
HAL_SPI_DeInit(&hspi);
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
osMutexDelete(spi_mutex);
|
||||
osMutexDelete(es_wifi_mutex);
|
||||
osSemaphoreDelete(spi_tx_sem);
|
||||
osSemaphoreDelete(spi_rx_sem);
|
||||
osSemaphoreDelete(cmddata_rdy_rising_sem);
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Receive wifi Data from SPI
|
||||
* @param pdata : pointer to data
|
||||
* @param len : Data length
|
||||
* @param timeout : send timeout in mS
|
||||
* @retval Length of received data (payload)
|
||||
*/
|
||||
|
||||
int32_t wait_cmddata_rdy_high(int32_t timeout)
|
||||
{
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (WIFI_IS_CMDDATA_READY() == 0)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t wait_cmddata_rdy_rising_event(int32_t timeout)
|
||||
{
|
||||
#ifdef SEM_WAIT
|
||||
return SEM_WAIT(cmddata_rdy_rising_sem, timeout);
|
||||
#else
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (cmddata_rdy_rising_event == 1)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif /* SEM_WAIT */
|
||||
}
|
||||
|
||||
int32_t wait_spi_rx_event(int32_t timeout)
|
||||
{
|
||||
#ifdef SEM_WAIT
|
||||
return SEM_WAIT(spi_rx_sem, timeout);
|
||||
#else
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (spi_rx_event == 1)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif /* SEM_WAIT */
|
||||
}
|
||||
|
||||
int32_t wait_spi_tx_event(int32_t timeout)
|
||||
{
|
||||
#ifdef SEM_WAIT
|
||||
return SEM_WAIT(spi_tx_sem, timeout);
|
||||
#else
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (spi_tx_event == 1)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif /* SEM_WAIT */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int16_t SPI_WIFI_ReceiveData(uint8_t *pData, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
int16_t length = 0;
|
||||
uint8_t tmp[2];
|
||||
|
||||
WIFI_DISABLE_NSS();
|
||||
UNLOCK_SPI();
|
||||
SPI_WIFI_DelayUs(3);
|
||||
|
||||
|
||||
if (wait_cmddata_rdy_rising_event(timeout) < 0)
|
||||
{
|
||||
return ES_WIFI_ERROR_WAITING_DRDY_FALLING;
|
||||
}
|
||||
|
||||
LOCK_SPI();
|
||||
WIFI_ENABLE_NSS();
|
||||
SPI_WIFI_DelayUs(15);
|
||||
while (WIFI_IS_CMDDATA_READY())
|
||||
{
|
||||
if ((length < len) || (!len))
|
||||
{
|
||||
spi_rx_event = 1;
|
||||
if (HAL_SPI_Receive_IT(&hspi, tmp, 1) != HAL_OK)
|
||||
{
|
||||
WIFI_DISABLE_NSS();
|
||||
UNLOCK_SPI();
|
||||
return ES_WIFI_ERROR_SPI_FAILED;
|
||||
}
|
||||
|
||||
wait_spi_rx_event(timeout);
|
||||
|
||||
pData[0] = tmp[0];
|
||||
pData[1] = tmp[1];
|
||||
length += 2;
|
||||
pData += 2;
|
||||
|
||||
if (length >= ES_WIFI_DATA_SIZE)
|
||||
{
|
||||
WIFI_DISABLE_NSS();
|
||||
SPI_WIFI_ResetModule();
|
||||
UNLOCK_SPI();
|
||||
return ES_WIFI_ERROR_STUFFING_FOREVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
WIFI_DISABLE_NSS();
|
||||
UNLOCK_SPI();
|
||||
return length;
|
||||
}
|
||||
/**
|
||||
* @brief Send wifi Data thru SPI
|
||||
* @param pdata : pointer to data
|
||||
* @param len : Data length
|
||||
* @param timeout : send timeout in mS
|
||||
* @retval Length of sent data
|
||||
*/
|
||||
int16_t SPI_WIFI_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
uint8_t Padding[2];
|
||||
|
||||
if (wait_cmddata_rdy_high(timeout) < 0)
|
||||
{
|
||||
return ES_WIFI_ERROR_SPI_FAILED;
|
||||
}
|
||||
|
||||
/* arm to detect rising event */
|
||||
cmddata_rdy_rising_event = 1;
|
||||
LOCK_SPI();
|
||||
WIFI_ENABLE_NSS();
|
||||
SPI_WIFI_DelayUs(15);
|
||||
if (len > 1)
|
||||
{
|
||||
spi_tx_event = 1;
|
||||
if (HAL_SPI_Transmit_IT(&hspi, (uint8_t *)pdata, len / 2) != HAL_OK)
|
||||
{
|
||||
WIFI_DISABLE_NSS();
|
||||
UNLOCK_SPI();
|
||||
return ES_WIFI_ERROR_SPI_FAILED;
|
||||
}
|
||||
wait_spi_tx_event(timeout);
|
||||
}
|
||||
|
||||
if (len & 1)
|
||||
{
|
||||
Padding[0] = pdata[len - 1];
|
||||
Padding[1] = '\n';
|
||||
|
||||
spi_tx_event = 1;
|
||||
if (HAL_SPI_Transmit_IT(&hspi, Padding, 1) != HAL_OK)
|
||||
{
|
||||
WIFI_DISABLE_NSS();
|
||||
UNLOCK_SPI();
|
||||
return ES_WIFI_ERROR_SPI_FAILED;
|
||||
}
|
||||
wait_spi_tx_event(timeout);
|
||||
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delay
|
||||
* @param Delay in us
|
||||
* @retval None
|
||||
*/
|
||||
void SPI_WIFI_DelayUs(uint32_t n)
|
||||
{
|
||||
__IO uint32_t ct = 0;
|
||||
uint32_t loop_per_us = 0;
|
||||
static uint32_t cycle_per_loop = 0;
|
||||
|
||||
/* calibration happen on first call for a duration of 1 ms * nbcycle per loop */
|
||||
/* 10 cycle for STM32L4 */
|
||||
if (cycle_per_loop == 0)
|
||||
{
|
||||
uint32_t cycle_per_ms = (SystemCoreClock / 1000UL);
|
||||
uint32_t tick = 0;
|
||||
ct = cycle_per_ms;
|
||||
tick = HAL_GetTick();
|
||||
while (ct)
|
||||
{
|
||||
ct--;
|
||||
}
|
||||
cycle_per_loop = HAL_GetTick() - tick;
|
||||
if (cycle_per_loop == 0)
|
||||
{
|
||||
cycle_per_loop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
loop_per_us = SystemCoreClock / 1000000UL / cycle_per_loop;
|
||||
ct = n * loop_per_us;
|
||||
while (ct)
|
||||
{
|
||||
ct--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Transfer completed callback.
|
||||
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
|
||||
* the configuration information for SPI module.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
if (spi_rx_event)
|
||||
{
|
||||
SEM_SIGNAL(spi_rx_sem);
|
||||
spi_rx_event = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Transfer completed callback.
|
||||
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
|
||||
* the configuration information for SPI module.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
if (spi_tx_event)
|
||||
{
|
||||
SEM_SIGNAL(spi_tx_sem);
|
||||
spi_tx_event = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interrupt handler for Data RDY signal
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SPI_WIFI_ISR(void)
|
||||
{
|
||||
if (cmddata_rdy_rising_event == 1)
|
||||
{
|
||||
SEM_SIGNAL(cmddata_rdy_rising_sem);
|
||||
cmddata_rdy_rising_event = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief probe function to register wifi to Network library framework
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
int32_t wifi_probe(void **ll_drv_context)
|
||||
{
|
||||
if (ES_WIFI_RegisterBusIO(&EsWifiObj,
|
||||
SPI_WIFI_Init,
|
||||
SPI_WIFI_DeInit,
|
||||
HAL_Delay,
|
||||
SPI_WIFI_SendData,
|
||||
SPI_WIFI_ReceiveData) == 0)
|
||||
{
|
||||
*ll_drv_context = &EsWifiObj;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the configuration for net
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONF_H
|
||||
#define NET_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#define NET_MBEDTLS_HOST_SUPPORT
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
|
||||
#include "net_conf_template.h"
|
||||
|
||||
/* to use Inventek Wifi native TLS */
|
||||
#if 0
|
||||
#undef NET_MBEDTLS_HOST_SUPPORT
|
||||
#define NET_MBEDTLS_WIFI_MODULE_SUPPORT
|
||||
#endif /* 9 */
|
||||
int32_t wifi_probe(void **ll_drv_obj);
|
||||
void SPI_WIFI_ISR(void);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+709
@@ -0,0 +1,709 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file LwIP/LwIP_TCP_Echo_Client/Src/ethernetif.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file implements Ethernet network interface drivers for lwIP
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 "stm32h7xx_hal.h"
|
||||
#include "stm32h7xx_ll_utils.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "ethernetif.h"
|
||||
#include "net_connect.h"
|
||||
#include "net_buffers.h"
|
||||
#define GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#ifdef NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS
|
||||
#include "mbedtls/sha256.h"
|
||||
#endif /* NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS */
|
||||
|
||||
#include "../Components/lan8742/lan8742.h"
|
||||
#include <string.h>
|
||||
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
void ethernetif_input(struct netif *netif);
|
||||
void ethernet_link_check_state(struct netif *netif);
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#endif /* osCMSIS */
|
||||
|
||||
|
||||
|
||||
/* Network interface name */
|
||||
#define IFNAME0 's'
|
||||
#define IFNAME1 't'
|
||||
|
||||
#define ETH_RX_BUFFER_SIZE (1536UL)
|
||||
|
||||
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
|
||||
|
||||
/* Stack size of the interface thread */
|
||||
#define INTERFACE_THREAD_STACK_SIZE 1024
|
||||
#define TIME_WAITING_FOR_INPUT ( 250 ) /*( portMAX_DELAY )*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/*
|
||||
@Note: This interface is implemented to operate in zero-copy mode only:
|
||||
- Rx buffers are allocated statically and passed directly to the LwIP stack
|
||||
they will return back to DMA after been processed by the stack.
|
||||
- Tx Buffers will be allocated from LwIP stack memory heap,
|
||||
then passed to ETH HAL driver.
|
||||
|
||||
@Notes:
|
||||
1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4,
|
||||
to customize it please redefine ETH_RX_DESC_CNT in stm32xxxx_hal_conf.h
|
||||
1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4,
|
||||
to customize it please redefine ETH_TX_DESC_CNT in stm32xxxx_hal_conf.h
|
||||
|
||||
2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT
|
||||
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
|
||||
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
|
||||
#pragma location=0x30040000
|
||||
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
||||
#pragma location=0x30040060
|
||||
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
||||
#pragma location=0x30040200
|
||||
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */
|
||||
|
||||
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
|
||||
|
||||
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef
|
||||
DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
||||
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef
|
||||
DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
||||
__attribute__((section(".RxArraySection"))) uint8_t
|
||||
Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
|
||||
|
||||
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
||||
|
||||
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((
|
||||
section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
|
||||
|
||||
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT
|
||||
__attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
|
||||
|
||||
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((
|
||||
section(".RxArraySection"))); /* Ethernet Receive Buffers */
|
||||
|
||||
#endif /* __ICCARM__ */
|
||||
|
||||
/* Semaphore to signal incoming packets */
|
||||
static osSemaphoreId s_xSemaphore = NULL;
|
||||
static osThreadId ethernetif_thread_handle = NULL;
|
||||
static void ethernetif_task(void *context);
|
||||
|
||||
#if (osCMSIS >= 0x20000U )
|
||||
static const osThreadAttr_t attr =
|
||||
{
|
||||
.name = "EthIf",
|
||||
.priority = osPriorityHigh,
|
||||
. stack_size = INTERFACE_THREAD_STACK_SIZE
|
||||
};
|
||||
#endif /* osCMSIS */
|
||||
|
||||
|
||||
ETH_HandleTypeDef EthHandle;
|
||||
ETH_TxPacketConfig TxConfig;
|
||||
|
||||
lan8742_Object_t LAN8742;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
u32_t sys_now(void);
|
||||
void pbuf_free_custom(struct pbuf *p);
|
||||
|
||||
int32_t ETH_PHY_IO_Init(void);
|
||||
int32_t ETH_PHY_IO_DeInit(void);
|
||||
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
|
||||
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
|
||||
int32_t ETH_PHY_IO_GetTick(void);
|
||||
|
||||
|
||||
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
|
||||
ETH_PHY_IO_DeInit,
|
||||
ETH_PHY_IO_WriteReg,
|
||||
ETH_PHY_IO_ReadReg,
|
||||
ETH_PHY_IO_GetTick
|
||||
};
|
||||
|
||||
LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool");
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/*******************************************************************************
|
||||
LL Driver Interface ( LwIP stack --> ETH)
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief 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)
|
||||
{
|
||||
uint32_t idx = 0;
|
||||
uint8_t macaddress[6] = {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
|
||||
/* Generate an MCU-unique MAC address */
|
||||
#ifdef NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS
|
||||
#define HASH_OUTPUT_LENGTH 32
|
||||
|
||||
unsigned char output[HASH_OUTPUT_LENGTH];
|
||||
uint32_t UID[3];
|
||||
/* Generate a hash digest from the unique CPU ID */
|
||||
UID[0] = LL_GetUID_Word0();
|
||||
UID[1] = LL_GetUID_Word1();
|
||||
UID[2] = LL_GetUID_Word2();
|
||||
|
||||
/* Hash with mbedTLS */
|
||||
int32_t hash_success = 0;
|
||||
mbedtls_sha256_context sha_context;
|
||||
mbedtls_sha256_init(&sha_context);
|
||||
|
||||
if (0 == mbedtls_sha256_starts_ret(&sha_context, 0))
|
||||
{
|
||||
if (0 == mbedtls_sha256_update_ret(&sha_context, (const unsigned char *) UID, sizeof(UID)))
|
||||
{
|
||||
if (0 == mbedtls_sha256_finish_ret(&sha_context, output))
|
||||
{
|
||||
hash_success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbedtls_sha256_free(&sha_context);
|
||||
|
||||
while (hash_success == 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* Copy the 3 first bytes of the digest to the second half of the MAC address. */
|
||||
memcpy(&macaddress[3], output, 3);
|
||||
|
||||
#endif /* NET_ETHERNET_MAC_GENERATION_FROM_MBEDTLS */
|
||||
EthHandle.Instance = ETH;
|
||||
EthHandle.Init.MACAddr = macaddress;
|
||||
EthHandle.Init.MediaInterface = HAL_ETH_RMII_MODE;
|
||||
EthHandle.Init.RxDesc = DMARxDscrTab;
|
||||
EthHandle.Init.TxDesc = DMATxDscrTab;
|
||||
EthHandle.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;
|
||||
|
||||
/* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
|
||||
HAL_ETH_Init(&EthHandle);
|
||||
|
||||
/* set MAC hardware address length */
|
||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
|
||||
/* set MAC hardware address */
|
||||
for (uint32_t i = 0; i < sizeof(macaddress) / sizeof(uint8_t); i++)
|
||||
{
|
||||
netif->hwaddr[i] = macaddress[i];
|
||||
}
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = ETH_MAX_PAYLOAD;
|
||||
|
||||
/* device capabilities */
|
||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||
|
||||
for (idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
|
||||
{
|
||||
HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
|
||||
}
|
||||
|
||||
/* Initialize the RX POOL */
|
||||
LWIP_MEMPOOL_INIT(RX_POOL);
|
||||
|
||||
/* Set Tx packet config common parameters */
|
||||
memset(&TxConfig, 0, sizeof(ETH_TxPacketConfig));
|
||||
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
|
||||
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
|
||||
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
|
||||
|
||||
/* Set PHY IO functions */
|
||||
LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
|
||||
|
||||
/* Initialize the LAN8742 ETH PHY */
|
||||
LAN8742_Init(&LAN8742);
|
||||
|
||||
ethernet_link_check_state(netif);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
uint32_t framelen = 0;
|
||||
struct pbuf *q;
|
||||
err_t errval = ERR_OK;
|
||||
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
|
||||
|
||||
memset(Txbuffer, 0, ETH_TX_DESC_CNT * sizeof(ETH_BufferTypeDef));
|
||||
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
if (i >= ETH_TX_DESC_CNT)
|
||||
{
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
Txbuffer[i].buffer = q->payload;
|
||||
Txbuffer[i].len = q->len;
|
||||
framelen += q->len;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
Txbuffer[i - 1].next = &Txbuffer[i];
|
||||
}
|
||||
|
||||
if (q->next == NULL)
|
||||
{
|
||||
Txbuffer[i].next = NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
TxConfig.Length = framelen;
|
||||
TxConfig.TxBuffer = Txbuffer;
|
||||
|
||||
HAL_ETH_Transmit(&EthHandle, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
|
||||
|
||||
return errval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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 pbuf *p = NULL;
|
||||
ETH_BufferTypeDef RxBuff;
|
||||
uint32_t framelength = 0;
|
||||
struct pbuf_custom *custom_pbuf;
|
||||
|
||||
if (HAL_ETH_IsRxDataAvailable(&EthHandle))
|
||||
{
|
||||
HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff);
|
||||
HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
|
||||
|
||||
/* Build Rx descriptor to be ready for next data reception */
|
||||
HAL_ETH_BuildRxDescriptors(&EthHandle);
|
||||
|
||||
/* Invalidate data cache for ETH Rx Buffers */
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff.buffer, framelength);
|
||||
|
||||
custom_pbuf = (struct pbuf_custom *)LWIP_MEMPOOL_ALLOC(RX_POOL);
|
||||
custom_pbuf->custom_free_function = pbuf_free_custom;
|
||||
|
||||
p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff.buffer, ETH_RX_BUFFER_SIZE);
|
||||
|
||||
return p;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 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)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
netif->hostname = "lwip";
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
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;
|
||||
|
||||
/* initialize the hardware */
|
||||
low_level_init(netif);
|
||||
|
||||
|
||||
/* create a semaphore used for informing ethernetif of frame reception */
|
||||
/* ethernet link list is 4 buffers, set semaphore size to 4 to not miss */
|
||||
/* interrupt (1 is not working ) */
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
s_xSemaphore = osSemaphoreNew(4, 4, NULL);
|
||||
#else
|
||||
osSemaphoreDef(SEM);
|
||||
s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM), 4);
|
||||
#endif /* osCMSIS */
|
||||
|
||||
/* create the task that handles the received data */
|
||||
#if (osCMSIS < 0x20000U )
|
||||
|
||||
osThreadDef(EthIf, (os_pthread) ethernetif_task, osPriorityHigh, 0, INTERFACE_THREAD_STACK_SIZE);
|
||||
ethernetif_thread_handle = osThreadCreate(osThread(EthIf), netif);
|
||||
#else
|
||||
ethernetif_thread_handle = osThreadNew((osThreadFunc_t)ethernetif_task, netif, &attr);
|
||||
#endif /* osCMSIS */
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
err_t ethernetif_deinit(struct netif *netif)
|
||||
{
|
||||
/* join will be welcome first ? */
|
||||
(void) osThreadTerminate(ethernetif_thread_handle);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Custom Rx pbuf free callback
|
||||
* @param pbuf: pbuf to be freed
|
||||
* @retval None
|
||||
*/
|
||||
void pbuf_free_custom(struct pbuf *p)
|
||||
{
|
||||
struct pbuf_custom *custom_pbuf = (struct pbuf_custom *)p;
|
||||
/* Invalidate data cache: lwIP and/or application may have written into buffer */
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)p->payload, p->tot_len);
|
||||
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the current time in milliseconds
|
||||
* when LWIP_TIMERS == 1 and NO_SYS == 1
|
||||
* @param None
|
||||
* @retval Current Time value
|
||||
*/
|
||||
u32_t sys_now(void)
|
||||
{
|
||||
return HAL_GetTick();
|
||||
}
|
||||
/*******************************************************************************
|
||||
Ethernet MSP Routines
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the ETH MSP.
|
||||
* @param heth: ETH handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* Ethernett MSP init: RMII Mode
|
||||
|
||||
RX_CLK --------------> PA1
|
||||
TXD0 --------------> PB12
|
||||
TXD1 --------------> PB13
|
||||
RXD0 --------------> PC4
|
||||
RXD1 --------------> PC5
|
||||
TX_EN --------------> PB11
|
||||
RX_DV --------------> PA7
|
||||
|
||||
MDC --------------> PC1
|
||||
MDIO --------------> PA2
|
||||
|
||||
*/
|
||||
|
||||
/* Enable GPIOs clocks */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
|
||||
/* Configure PA1, PA2 , PA7 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL ;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Configure PG11, PG12 and PG13 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
|
||||
/* Configure PC1, PC4 and PC5 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* Enable the Ethernet global Interrupt */
|
||||
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
|
||||
HAL_NVIC_EnableIRQ(ETH_IRQn);
|
||||
|
||||
/* Enable Ethernet clocks */
|
||||
__HAL_RCC_ETH1MAC_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1TX_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1RX_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ethernet Rx Transfer completed callback
|
||||
* @param heth: ETH handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
|
||||
{
|
||||
osSemaphoreRelease(s_xSemaphore);
|
||||
}
|
||||
/*******************************************************************************
|
||||
PHI IO Functions
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the MDIO interface GPIO and clocks.
|
||||
* @param None
|
||||
* @retval 0 if OK, -1 if ERROR
|
||||
*/
|
||||
int32_t ETH_PHY_IO_Init(void)
|
||||
{
|
||||
/* We assume that MDIO GPIO configuration is already done
|
||||
in the ETH_MspInit() else it should be done here
|
||||
*/
|
||||
|
||||
/* Configure the MDIO Clock */
|
||||
HAL_ETH_SetMDIOClockRange(&EthHandle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-Initializes the MDIO interface .
|
||||
* @param None
|
||||
* @retval 0 if OK, -1 if ERROR
|
||||
*/
|
||||
int32_t ETH_PHY_IO_DeInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a PHY register through the MDIO interface.
|
||||
* @param DevAddr: PHY port address
|
||||
* @param RegAddr: PHY register address
|
||||
* @param pRegVal: pointer to hold the register value
|
||||
* @retval 0 if OK -1 if Error
|
||||
*/
|
||||
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
|
||||
{
|
||||
if (HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a value to a PHY register through the MDIO interface.
|
||||
* @param DevAddr: PHY port address
|
||||
* @param RegAddr: PHY register address
|
||||
* @param RegVal: Value to be written
|
||||
* @retval 0 if OK -1 if Error
|
||||
*/
|
||||
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
|
||||
{
|
||||
if (HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the time in millisecons used for internal PHY driver process.
|
||||
* @retval Time value
|
||||
*/
|
||||
int32_t ETH_PHY_IO_GetTick(void)
|
||||
{
|
||||
return HAL_GetTick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @retval None
|
||||
*/
|
||||
void ethernet_link_check_state(struct netif *netif)
|
||||
{
|
||||
ETH_MACConfigTypeDef MACConf;
|
||||
uint32_t PHYLinkState;
|
||||
uint32_t linkchanged = 0;
|
||||
uint32_t speed = 0;
|
||||
uint32_t duplex = 0;
|
||||
|
||||
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
|
||||
|
||||
if (netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
|
||||
{
|
||||
HAL_ETH_Stop_IT(&EthHandle);
|
||||
netif_set_down(netif);
|
||||
netif_set_link_down(netif);
|
||||
}
|
||||
else if (!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
|
||||
{
|
||||
switch (PHYLinkState)
|
||||
{
|
||||
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
|
||||
duplex = ETH_FULLDUPLEX_MODE;
|
||||
speed = ETH_SPEED_100M;
|
||||
linkchanged = 1;
|
||||
break;
|
||||
case LAN8742_STATUS_100MBITS_HALFDUPLEX:
|
||||
duplex = ETH_HALFDUPLEX_MODE;
|
||||
speed = ETH_SPEED_100M;
|
||||
linkchanged = 1;
|
||||
break;
|
||||
case LAN8742_STATUS_10MBITS_FULLDUPLEX:
|
||||
duplex = ETH_FULLDUPLEX_MODE;
|
||||
speed = ETH_SPEED_10M;
|
||||
linkchanged = 1;
|
||||
break;
|
||||
case LAN8742_STATUS_10MBITS_HALFDUPLEX:
|
||||
duplex = ETH_HALFDUPLEX_MODE;
|
||||
speed = ETH_SPEED_10M;
|
||||
linkchanged = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (linkchanged)
|
||||
{
|
||||
/* Get MAC Config MAC */
|
||||
HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
|
||||
MACConf.DuplexMode = duplex;
|
||||
MACConf.Speed = speed;
|
||||
HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
|
||||
HAL_ETH_Start_IT(&EthHandle);
|
||||
netif_set_up(netif);
|
||||
netif_set_link_up(netif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ethernetif_low_get_link_status(void)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint32_t PHYLinkState;
|
||||
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
|
||||
if (PHYLinkState > LAN8742_STATUS_LINK_DOWN)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void ethernetif_task(void *context)
|
||||
{
|
||||
struct netif *netif = context;
|
||||
int32_t semaphore_retval;
|
||||
static uint8_t link_status = 0;
|
||||
|
||||
if (link_status)
|
||||
{
|
||||
netif_set_link_up(netif);
|
||||
}
|
||||
else netif_set_link_down(netif);
|
||||
for (;;)
|
||||
{
|
||||
semaphore_retval = OSSEMAPHOREWAIT(s_xSemaphore, TIME_WAITING_FOR_INPUT);
|
||||
|
||||
if (ethernetif_low_get_link_status() != link_status)
|
||||
{
|
||||
link_status = 1U - link_status;
|
||||
if (link_status)
|
||||
{
|
||||
netif_set_link_up(netif);
|
||||
}
|
||||
else netif_set_link_down(netif);
|
||||
}
|
||||
if (semaphore_retval == (int32_t) osOK)
|
||||
{
|
||||
struct pbuf *p;
|
||||
/* move received packet into a new pbuf */
|
||||
p = low_level_input(netif);
|
||||
/* no packet could be read, silently ignore this */
|
||||
if (p)
|
||||
{
|
||||
err_t err;
|
||||
/* entry point to the LwIP stack */
|
||||
err = netif->input(p, netif);
|
||||
if (err != ERR_OK)
|
||||
{
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the configuration for net
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONF_H
|
||||
#define NET_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
void ethernetif_low_init(void (*event_callback)(void), void (*buffer_output_callback)(uint8_t *));
|
||||
void ethernetif_low_deinit(void);
|
||||
|
||||
int16_t ethernetif_low_inputsize(void);
|
||||
int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
|
||||
int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
|
||||
|
||||
void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
|
||||
uint8_t ethernetif_low_get_link_status(void);
|
||||
|
||||
#define NET_USE_RTOS
|
||||
#define ETHERNET_MAC_GENERATION_FROM_SHA256
|
||||
|
||||
|
||||
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#define USE_TINY_DTLS
|
||||
#else
|
||||
#define NET_MBEDTLS_HOST_SUPPORT
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
#include "net_conf_template.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+835
@@ -0,0 +1,835 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file Ethernetif.c
|
||||
* @author MCD Application Team
|
||||
* @brief Implement functions called to initialize the Ethernet low level driver
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 ------------------------------------------------------------------*/
|
||||
#ifdef STM32F429xx
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "stm32f4xx_ll_utils.h"
|
||||
#endif /* STM32F429xx */
|
||||
#ifdef STM32F769xx
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "stm32f7xx_ll_utils.h"
|
||||
#endif /* STM32F769xx */
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "net_connect.h"
|
||||
#include "net_buffers.h"
|
||||
|
||||
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#define USED_TINY_DTLS
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
/* Use a tinydtls hash function to generate an 'MCU-unique' MAC address */
|
||||
#ifdef ETHERNET_MAC_GENERATION_FROM_SHA256
|
||||
|
||||
#ifdef USED_TINY_DTLS
|
||||
#include "sha2/sha2.h"
|
||||
#ifndef WITH_SHA256
|
||||
#error "WITH_SHA256 must be enabled in the tinydtls configuration file"
|
||||
#endif /* WITH_SHA256 */
|
||||
#define HASH_OUTPUT_LENGTH DTLS_SHA256_DIGEST_STRING_LENGTH
|
||||
#else /* USED_TINY_DTLS */
|
||||
#include "mbedtls/sha256.h"
|
||||
#define HASH_OUTPUT_LENGTH 32
|
||||
#endif /* USED_TINY_DTLS */
|
||||
#endif /* ETHERNET_MAC_GENERATION_FROM_SHA256 */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
err_t ethernetif_init(struct netif *netif);
|
||||
void ethernetif_deinit(struct netif *netif);
|
||||
|
||||
|
||||
#define MAX_MTU 1500
|
||||
|
||||
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#endif /* osCMSIS */
|
||||
|
||||
/* The time to block waiting for input. */
|
||||
#define TIME_WAITING_FOR_INPUT ( 250 ) /*( portMAX_DELAY )*/
|
||||
|
||||
/* Stack size of the interface thread */
|
||||
#define INTERFACE_THREAD_STACK_SIZE 1024
|
||||
|
||||
/* buffer management list */
|
||||
#define BUFFER_LIST_SIZE 10
|
||||
#define CIRCULAR_INC(a) (a)++;if ((a)==BUFFER_LIST_SIZE) {(a)=0;}
|
||||
|
||||
|
||||
|
||||
/* Within 'USER CODE' section, code will be kept by default at each generation */
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* Private function ---------------------------------------------------------*/
|
||||
static void ethernetif_low_init(void);
|
||||
static void ethernetif_low_deinit(void);
|
||||
static void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
|
||||
static uint8_t ethernetif_low_get_link_status(void);
|
||||
static int16_t ethernetif_low_inputsize(void);
|
||||
static int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
|
||||
static int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
|
||||
|
||||
static int32_t ethernetif_output(void *context, net_buf_t *netbuf);
|
||||
|
||||
static void ethernetif_low_errhandle(void);
|
||||
|
||||
static void ethernetif_task(void *context);
|
||||
static void ethernetif_write_done(void);
|
||||
|
||||
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static uint8_t MACAddr[6];
|
||||
|
||||
/* Semaphore to signal incoming packets */
|
||||
static osSemaphoreId s_xSemaphore = NULL;
|
||||
static osThreadId ethernetif_thread_handle = NULL;
|
||||
|
||||
|
||||
|
||||
static __IO int32_t free_buffer_index;
|
||||
static int32_t write_buffer_index;
|
||||
static int32_t busy_buffer_index;
|
||||
static net_buf_t *sent_write_buffer[BUFFER_LIST_SIZE];
|
||||
|
||||
|
||||
|
||||
/* Global Ethernet handle */
|
||||
ETH_HandleTypeDef EthHandle;
|
||||
#ifdef DATA_CACHE_ENABLED
|
||||
#ifdef USE_CACHED_ETH_BUFFERS
|
||||
#define SECTION_ETHERNET_BUFFERS ".ram_cache"
|
||||
#else
|
||||
#define SECTION_ETHERNET_BUFFERS ".sram2_non_cached_normal"
|
||||
#endif /* USE_CACHED_ETH_BUFFERS */
|
||||
#else
|
||||
#define SECTION_ETHERNET_BUFFERS ".ram"
|
||||
#endif /* DATA_CACHE_ENABLED */
|
||||
#if defined ( __ICCARM__ )
|
||||
|
||||
#pragma data_alignment = 4
|
||||
#pragma location = ".sram2_non_cached_device"
|
||||
static ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB];/* Ethernet Rx MA Descriptor */
|
||||
|
||||
#pragma data_alignment = 4
|
||||
#pragma location = ".sram2_non_cached_device"
|
||||
static ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB];/* Ethernet Tx DMA Descriptor */
|
||||
|
||||
#pragma data_alignment = 4
|
||||
#pragma location = SECTION_ETHERNET_BUFFERS
|
||||
static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; /* Ethernet Receive Buffer */
|
||||
|
||||
#pragma data_alignment = 4
|
||||
#pragma location = SECTION_ETHERNET_BUFFERS
|
||||
static uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; /* Ethernet Transmit Buffer */
|
||||
|
||||
#elif defined(__CC_ARM)
|
||||
ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((section(".sram2_non_cached_device"),
|
||||
zero_init)); /* Ethernet Rx DMA Descriptor */
|
||||
ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((section(".sram2_non_cached_device"),
|
||||
zero_init)); /* Ethernet Tx DMA Descriptor */
|
||||
uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((section(".sram2_non_cached_normal"),
|
||||
zero_init)); /* Ethernet Receive Buffer */
|
||||
uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((section(".sram2_non_cached_normal"),
|
||||
zero_init)); /* Ethernet Transmit Buffer */
|
||||
#elif defined (__GNUC__)
|
||||
/* Ethernet Rx MA Descriptor */
|
||||
ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB] __attribute__((
|
||||
section(".sram2_non_cached_device")));
|
||||
/* Ethernet Tx DMA Descriptor */
|
||||
ETH_DMADescTypeDef DMATxDscrTab[ETH_TXBUFNB] __attribute__((
|
||||
section(".sram2_non_cached_device")));
|
||||
/* Ethernet Received Buffer */
|
||||
uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((
|
||||
section(".sram2_non_cached_normal")));
|
||||
/* Ethernet Transmit Buffer */
|
||||
uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((
|
||||
section(".sram2_non_cached_normal")));
|
||||
#endif /* __CC_ARM */
|
||||
|
||||
|
||||
|
||||
void HAL_ETH_MspInit(ETH_HandleTypeDef *EthHandle)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* Enable GPIOs clocks */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
|
||||
/* Ethernet pins configuration ************************************************/
|
||||
/*
|
||||
RMII_REF_CLK ----------------------> PA1
|
||||
RMII_MDIO -------------------------> PA2
|
||||
RMII_MDC --------------------------> PC1
|
||||
RMII_MII_CRS_DV -------------------> PA7
|
||||
RMII_MII_RXD0 ---------------------> PC4
|
||||
RMII_MII_RXD1 ---------------------> PC5
|
||||
RMII_MII_RXER ---------------------> PG2
|
||||
RMII_MII_TX_EN --------------------> PG11
|
||||
RMII_MII_TXD0 ---------------------> PG13
|
||||
RMII_MII_TXD1 ---------------------> PG14
|
||||
*/
|
||||
#ifdef STM32F429xx
|
||||
GPIO_InitStructure.Pin = RMII_MDC_Pin | RMII_RXD0_Pin | RMII_RXD1_Pin;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = RMII_REF_CLK_Pin | RMII_MDIO_Pin | RMII_CRS_DV_Pin;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = RMII_TXD1_Pin;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = RMII_TX_EN_Pin | RMII_TXD0_Pin;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
#endif /* STM32F429xx */
|
||||
|
||||
#ifdef STM32F769xx
|
||||
/* Configure PA1, PA2 and PA7 */
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Configure PC1, PC4 and PC5 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* Configure PG2, PG11, PG13 and PG14 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
#endif /* STM32F769xx */
|
||||
/* Enable the Ethernet global Interrupt */
|
||||
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
|
||||
HAL_NVIC_EnableIRQ(ETH_IRQn);
|
||||
|
||||
/* Enable ETHERNET clock */
|
||||
__HAL_RCC_ETH_CLK_ENABLE();
|
||||
}
|
||||
|
||||
|
||||
void HAL_ETH_MspDeInit(ETH_HandleTypeDef *ethHandle)
|
||||
{
|
||||
if (ethHandle->Instance == ETH)
|
||||
{
|
||||
/* USER CODE BEGIN ETH_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END ETH_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_ETH_CLK_DISABLE();
|
||||
|
||||
/**ETH GPIO Configuration
|
||||
PC1 ------> ETH_MDC
|
||||
PA1 ------> ETH_REF_CLK
|
||||
PA2 ------> ETH_MDIO
|
||||
PA7 ------> ETH_CRS_DV
|
||||
PC4 ------> ETH_RXD0
|
||||
PC5 ------> ETH_RXD1
|
||||
PB13 ------> ETH_TXD1
|
||||
PG11 ------> ETH_TX_EN
|
||||
PG13 ------> ETH_TXD0
|
||||
*/
|
||||
#if 0
|
||||
HAL_GPIO_DeInit(GPIOC, RMII_MDC_Pin | RMII_RXD0_Pin | RMII_RXD1_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOA, RMII_REF_CLK_Pin | RMII_MDIO_Pin | RMII_CRS_DV_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(RMII_TXD1_GPIO_Port, RMII_TXD1_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOG, RMII_TX_EN_Pin | RMII_TXD0_Pin);
|
||||
|
||||
/* Peripheral interrupt Deinit*/
|
||||
HAL_NVIC_DisableIRQ(ETH_IRQn);
|
||||
#endif /* 0 */
|
||||
/* USER CODE BEGIN ETH_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END ETH_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ethernet Rx Transfer completed callback
|
||||
* @param EthHandle: ETH handle
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *EthHandle)
|
||||
{
|
||||
(void) osSemaphoreRelease(s_xSemaphore);
|
||||
}
|
||||
|
||||
void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *EthHandle)
|
||||
{
|
||||
if (__HAL_ETH_DMA_GET_FLAG(EthHandle, ETH_DMASR_RBUS))
|
||||
{
|
||||
/* The Receive Buffer Unavailable interrupt is cleared by the Ethernet HAL handler before the
|
||||
Ethernet task is scheduled.
|
||||
Temporarily mask it so that the Ethernet task is scheduled before a new IT is trigged.
|
||||
*/
|
||||
__HAL_ETH_DMA_DISABLE_IT(EthHandle, ETH_DMA_IT_RBU);
|
||||
}
|
||||
}
|
||||
|
||||
static void ethernetif_low_init(void)
|
||||
{
|
||||
#ifdef PHY_ISFR
|
||||
uint32_t regvalue;
|
||||
#endif /* PHY_ISFR */
|
||||
|
||||
/* Init ETH */
|
||||
EthHandle.Instance = ETH;
|
||||
EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
|
||||
EthHandle.Init.PhyAddress = LAN8742A_PHY_ADDRESS;
|
||||
MACAddr[0] = 0x00;
|
||||
MACAddr[1] = 0x80;
|
||||
MACAddr[2] = 0xE1;
|
||||
MACAddr[3] = 0x00;
|
||||
MACAddr[4] = 0x00;
|
||||
MACAddr[5] = 0x01;
|
||||
|
||||
/* Generate an MCU-unique MAC address */
|
||||
#ifdef ETHERNET_MAC_GENERATION_FROM_SHA256
|
||||
|
||||
unsigned char output[HASH_OUTPUT_LENGTH];
|
||||
uint32_t UID[3];
|
||||
/* Generate a hash digest from the unique CPU ID */
|
||||
UID[0] = LL_GetUID_Word0();
|
||||
UID[1] = LL_GetUID_Word1();
|
||||
UID[2] = LL_GetUID_Word2();
|
||||
|
||||
|
||||
#ifdef USE_TINY_DTLS
|
||||
/* Hash with tinydtls */
|
||||
dtls_sha256_data((uint8_t *) UID, sizeof(UID), (char *) output);
|
||||
#else /* USED_TINY_DTLS */
|
||||
|
||||
/* Hash with mbedTLS */
|
||||
int32_t hash_success = 0;
|
||||
mbedtls_sha256_context sha_context;
|
||||
mbedtls_sha256_init(&sha_context);
|
||||
|
||||
if (0 == mbedtls_sha256_starts_ret(&sha_context, 0))
|
||||
{
|
||||
if (0 == mbedtls_sha256_update_ret(&sha_context, (const unsigned char *) UID, sizeof(UID)))
|
||||
{
|
||||
if (0 == mbedtls_sha256_finish_ret(&sha_context, output))
|
||||
{
|
||||
hash_success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbedtls_sha256_free(&sha_context);
|
||||
|
||||
while (hash_success == 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
#endif /* USE_TINY_DTLS */
|
||||
/* Copy the 3 first bytes of the digest to the second half of the MAC address. */
|
||||
memcpy(&MACAddr[3], output, 3);
|
||||
|
||||
#endif /* ETHERNET_MAC_GENERATION_FROM_SHA256 */
|
||||
|
||||
|
||||
EthHandle.Init.MACAddr = &MACAddr[0];
|
||||
EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE;
|
||||
#ifdef CHECKSUM_BY_HARDWARE
|
||||
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
|
||||
#else
|
||||
EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
|
||||
#endif /* CHECKSUM_BY_HARDWARE */
|
||||
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
|
||||
EthHandle.Init.Speed = ETH_SPEED_100M;
|
||||
EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
|
||||
EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
|
||||
|
||||
HAL_ETH_Init(&EthHandle);
|
||||
|
||||
/* Enable both the transmission and the read buffer underflow interrupts. */
|
||||
__HAL_ETH_DMA_ENABLE_IT(&EthHandle, ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T | ETH_DMA_IT_AIS | ETH_DMA_IT_RBU);
|
||||
|
||||
/* Initialize Tx Descriptors list: Chain Mode */
|
||||
HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, 0, ETH_TXBUFNB);
|
||||
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
|
||||
{
|
||||
DMATxDscrTab[i].Buffer1Addr = 0;
|
||||
}
|
||||
/* Initialize Rx Descriptors list: Chain Mode */
|
||||
HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
|
||||
|
||||
/* Enable MAC and DMA transmission and reception */
|
||||
HAL_ETH_Start(&EthHandle);
|
||||
|
||||
/* USER CODE BEGIN PHY_PRE_CONFIG */
|
||||
|
||||
/* USER CODE END PHY_PRE_CONFIG */
|
||||
|
||||
#ifdef PHY_ISFR
|
||||
/* Read Register Configuration */
|
||||
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, ®value);
|
||||
regvalue |= (PHY_ISFR_INT4);
|
||||
|
||||
/* Enable Interrupt on change of link status */
|
||||
HAL_ETH_WritePHYRegister(&EthHandle, PHY_ISFR, regvalue);
|
||||
|
||||
/* Read Register Configuration */
|
||||
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, ®value);
|
||||
#endif /* PHY_ISFR */
|
||||
/* USER CODE BEGIN PHY_POST_CONFIG */
|
||||
|
||||
/* USER CODE END PHY_POST_CONFIG */
|
||||
|
||||
}
|
||||
|
||||
static void ethernetif_low_deinit(void)
|
||||
{
|
||||
#ifdef PHY_ISFR
|
||||
uint32_t regvalue;
|
||||
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, ®value);
|
||||
regvalue &= (~PHY_ISFR_INT4);
|
||||
HAL_ETH_WritePHYRegister(&EthHandle, PHY_ISFR, regvalue);
|
||||
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_ISFR, ®value);
|
||||
#endif /* PHY_ISFR */
|
||||
|
||||
HAL_ETH_Stop(&EthHandle);
|
||||
memset(&EthHandle, 0x00, sizeof(EthHandle));
|
||||
memset(MACAddr, 0x00, 6);
|
||||
|
||||
|
||||
/* return pending buffers */
|
||||
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
|
||||
{
|
||||
if ((DMATxDscrTab[i].Buffer1Addr != 0))
|
||||
{
|
||||
ethernetif_write_done();
|
||||
DMATxDscrTab[i].Buffer1Addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t ethernetif_low_inputsize(void)
|
||||
{
|
||||
if (HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK)
|
||||
{
|
||||
ethernetif_low_errhandle();
|
||||
return -1;
|
||||
}
|
||||
return EthHandle.RxFrameInfos.length;
|
||||
}
|
||||
|
||||
static int16_t ethernetif_low_input(uint8_t *payload, uint16_t len)
|
||||
{
|
||||
__IO ETH_DMADescTypeDef *dmarxdesc;
|
||||
uint32_t rlen = 0;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len" variable. */
|
||||
rlen = EthHandle.RxFrameInfos.length;
|
||||
dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc;
|
||||
|
||||
if ((payload == NULL) || (len < rlen))
|
||||
{
|
||||
NET_DBG_INFO("LwIP pool is full or buffer is too small. Dropping an Ethernet RX frame of size %lu.\n", rlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(DATA_CACHE_ENABLE) && defined(USE_CACHED_ETH_BUFFERS)
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)dmarxdesc->Buffer1Addr, rlen);
|
||||
#endif /* USE_CACHED_ETH_BUFFERS */
|
||||
memcpy(payload, (uint8_t *) dmarxdesc->Buffer1Addr, rlen);
|
||||
}
|
||||
|
||||
/* Clear Segment_Count */
|
||||
NET_ASSERT(EthHandle.RxFrameInfos.SegCount == 1, " multiple segments only 1 supported\n");
|
||||
|
||||
EthHandle.RxFrameInfos.SegCount = 0;
|
||||
dmarxdesc->Status |= ETH_DMARXDESC_OWN;
|
||||
|
||||
/* ETH_DMA_IT_R and ETH_DMA_IT_RBU may be raised simultaneously.
|
||||
Run the error handling.
|
||||
*/
|
||||
ethernetif_low_errhandle();
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
|
||||
static void ethernetif_low_errhandle(void)
|
||||
{
|
||||
if (__HAL_ETH_DMA_GET_FLAG(&EthHandle, ETH_DMASR_RBUS))
|
||||
{
|
||||
NET_DBG_INFO("DMA underflow\n");
|
||||
/* Re-enable the Receive Buffer Unavailable interrupt */
|
||||
__HAL_ETH_DMA_ENABLE_IT(&EthHandle, ETH_DMA_IT_RBU);
|
||||
|
||||
/* Clear RBUS ETHERNET DMA flag */
|
||||
__HAL_ETH_DMA_CLEAR_FLAG(&EthHandle, ETH_DMASR_RBUS);
|
||||
|
||||
/* Resume DMA reception */
|
||||
EthHandle.Instance->DMARPDR = 0;
|
||||
|
||||
/* The ETH_DMA_IT_R interrupt is not raised when restarting after a Receive Buffer Unavailable.
|
||||
Poll again.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t ethernetif_low_output(uint8_t *payload, uint16_t len)
|
||||
{
|
||||
int16_t errval = 0;
|
||||
__IO ETH_DMADescTypeDef *DmaTxDesc = EthHandle.TxDesc;
|
||||
|
||||
/* NET_DBG_PRINT ("ethernetif_low_output %d\n",len); */
|
||||
|
||||
/* Count number of buffer that have been sent */
|
||||
for (int32_t i = 0; i < ETH_TXBUFNB; i++)
|
||||
{
|
||||
if ((DMATxDscrTab[i].Buffer1Addr != 0) && !(DMATxDscrTab[i].Status & ETH_DMATXDESC_OWN))
|
||||
{
|
||||
CIRCULAR_INC(free_buffer_index);
|
||||
DMATxDscrTab[i].Buffer1Addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
|
||||
{
|
||||
errval = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
DmaTxDesc->Buffer1Addr = (uint32_t) payload;
|
||||
|
||||
#if defined(DATA_CACHE_ENABLE) && defined(USE_CACHED_ETH_BUFFERS)
|
||||
SCB_CleanDCache_by_Addr(((uint32_t *)DmaTxDesc->Buffer1Addr), len + 32);
|
||||
#endif /* Cache Buffers */
|
||||
/* Prepare transmit descriptors to give to DMA */
|
||||
if (HAL_ETH_TransmitFrame(&EthHandle, len))
|
||||
{
|
||||
errval = -1;
|
||||
}
|
||||
|
||||
|
||||
error:
|
||||
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
|
||||
if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
|
||||
{
|
||||
/* Clear TUS ETHERNET DMA flag */
|
||||
EthHandle.Instance->DMASR = ETH_DMASR_TUS;
|
||||
|
||||
/* Resume DMA transmission*/
|
||||
EthHandle.Instance->DMATPDR = 0;
|
||||
}
|
||||
return errval;
|
||||
}
|
||||
|
||||
|
||||
static void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in)
|
||||
{
|
||||
MACAddr_in[0] = MACAddr[0];
|
||||
MACAddr_in[1] = MACAddr[1];
|
||||
MACAddr_in[2] = MACAddr[2];
|
||||
MACAddr_in[3] = MACAddr[3];
|
||||
MACAddr_in[4] = MACAddr[4];
|
||||
MACAddr_in[5] = MACAddr[5];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t ethernetif_low_get_link_status(void)
|
||||
{
|
||||
uint32_t phyreg;
|
||||
HAL_ETH_ReadPHYRegister(&EthHandle, PHY_BSR, &phyreg);
|
||||
return (uint8_t)((phyreg & PHY_LINKED_STATUS) > 0);
|
||||
}
|
||||
|
||||
|
||||
static int32_t ethernetif_output(void *context, net_buf_t *netbuf)
|
||||
{
|
||||
int32_t ret;
|
||||
uint16_t len = 0u;
|
||||
int32_t nb = 0;
|
||||
net_buf_t *q;
|
||||
|
||||
/* release returned buffers */
|
||||
while (busy_buffer_index != free_buffer_index)
|
||||
{
|
||||
CIRCULAR_INC(busy_buffer_index);
|
||||
(void) NET_BUF_FREE(sent_write_buffer[busy_buffer_index]);
|
||||
sent_write_buffer[busy_buffer_index] = 0;
|
||||
}
|
||||
|
||||
for (q = netbuf; q != NULL ; q = q->next)
|
||||
{
|
||||
len += q->len;
|
||||
nb++;
|
||||
}
|
||||
|
||||
if (nb == 1)
|
||||
{
|
||||
NET_BUF_REF(netbuf);
|
||||
CIRCULAR_INC(write_buffer_index);
|
||||
sent_write_buffer[write_buffer_index] = netbuf;
|
||||
ret = ethernetif_low_output(netbuf->payload, netbuf->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
net_buf_t *p;
|
||||
p = NET_BUF_ALLOC(len);
|
||||
if (p != NULL)
|
||||
{
|
||||
uint8_t *pp = p->payload;
|
||||
for (q = netbuf; q != NULL ; q = q->next)
|
||||
{
|
||||
(void) memcpy(pp, q->payload, q->len);
|
||||
pp = &pp[q->len];
|
||||
}
|
||||
p->len = (uint16_t) len;
|
||||
CIRCULAR_INC(write_buffer_index);
|
||||
sent_write_buffer[write_buffer_index] = p;
|
||||
ret = ethernetif_low_output(p->payload, p->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (true) {};
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ethernetif_write_done(void)
|
||||
{
|
||||
CIRCULAR_INC(free_buffer_index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ethernetif_task(void *context)
|
||||
{
|
||||
struct netif *netif = context;
|
||||
int32_t semaphore_retval;
|
||||
net_buf_t *netbuf;
|
||||
uint8_t *payload;
|
||||
int16_t len;
|
||||
static uint8_t link_status = 0;
|
||||
|
||||
if (link_status)
|
||||
{
|
||||
netif_set_link_up(netif);
|
||||
}
|
||||
else netif_set_link_down(netif);
|
||||
for (;;)
|
||||
{
|
||||
semaphore_retval = OSSEMAPHOREWAIT(s_xSemaphore, TIME_WAITING_FOR_INPUT);
|
||||
|
||||
if (ethernetif_low_get_link_status() != link_status)
|
||||
{
|
||||
link_status = 1U - link_status;
|
||||
if (link_status)
|
||||
{
|
||||
netif_set_link_up(netif);
|
||||
}
|
||||
else netif_set_link_down(netif);
|
||||
}
|
||||
if (semaphore_retval == (int32_t) osOK)
|
||||
{
|
||||
/*NET_DBG_PRINT ("Wakeup Input data\n");*/
|
||||
|
||||
while ((len = ethernetif_low_inputsize()) > 0)
|
||||
{
|
||||
payload = NULL;
|
||||
netbuf = NET_BUF_ALLOC((uint16_t)len);
|
||||
if (netbuf != NULL)
|
||||
{
|
||||
payload = netbuf->payload;
|
||||
}
|
||||
if (ethernetif_low_input(payload, (uint16_t) len) > 0)
|
||||
{
|
||||
tcpip_input(netbuf, netif);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if (osCMSIS >= 0x20000U )
|
||||
static const osThreadAttr_t attr =
|
||||
{
|
||||
.name = "EthIf",
|
||||
.priority = osPriorityHigh,
|
||||
. stack_size = INTERFACE_THREAD_STACK_SIZE
|
||||
};
|
||||
#endif /* osCMSIS */
|
||||
|
||||
|
||||
|
||||
|
||||
err_t ethernetif_init(struct netif *netif)
|
||||
{
|
||||
err_t ret = ERR_OK;
|
||||
|
||||
char *hostname = NET_MALLOC(sizeof(char) * ((uint16_t) NET_IP_HOSTNAME_MAX_LEN + 1U));
|
||||
if (hostname == NULL)
|
||||
{
|
||||
return (err_t) ERR_MEM;
|
||||
}
|
||||
|
||||
(void) snprintf(hostname, NET_IP_HOSTNAME_MAX_LEN + 1, "generic eth if #%d", netif->num);
|
||||
|
||||
netif->hostname = hostname;
|
||||
netif->name[0] = 's';
|
||||
netif->name[1] = 't';
|
||||
|
||||
netif->hwaddr_len = 6;
|
||||
|
||||
netif->mtu = MAX_MTU;
|
||||
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||
netif->output = etharp_output;
|
||||
|
||||
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
|
||||
/* output to the device */
|
||||
netif->linkoutput = (netif_linkoutput_fn)ethernetif_output;
|
||||
|
||||
|
||||
free_buffer_index = 0;
|
||||
write_buffer_index = 0;
|
||||
busy_buffer_index = 0;
|
||||
(void) memset(sent_write_buffer, 0, sizeof(sent_write_buffer));
|
||||
|
||||
/* create a semaphore used for informing ethernetif of frame reception */
|
||||
/* ethernet link list is 4 buffers, set semaphore size to 4 to not miss */
|
||||
/* interrupt (1 is not working ) */
|
||||
#if (osCMSIS >= 0x20000U)
|
||||
s_xSemaphore = osSemaphoreNew(4, 4, NULL);
|
||||
#else
|
||||
osSemaphoreDef(SEM);
|
||||
s_xSemaphore = osSemaphoreCreate(osSemaphore(SEM), 4);
|
||||
#endif /* osCMSIS */
|
||||
|
||||
ethernetif_low_init();
|
||||
ethernetif_low_get_mac_addr(netif->hwaddr);
|
||||
|
||||
/* create the task that handles the ETH_MAC */
|
||||
#if (osCMSIS < 0x20000U )
|
||||
|
||||
osThreadDef(EthIf, (os_pthread) ethernetif_task, osPriorityHigh, 0, INTERFACE_THREAD_STACK_SIZE);
|
||||
ethernetif_thread_handle = osThreadCreate(osThread(EthIf), netif);
|
||||
#else
|
||||
ethernetif_thread_handle = osThreadNew((osThreadFunc_t)ethernetif_task, netif, &attr);
|
||||
#endif /* osCMSIS */
|
||||
|
||||
/* USER CODE BEGIN LOW_LEVEL_INIT */
|
||||
|
||||
/* USER CODE END LOW_LEVEL_INIT */
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ethernetif_deinit(struct netif *netif)
|
||||
{
|
||||
|
||||
while (busy_buffer_index != free_buffer_index)
|
||||
{
|
||||
CIRCULAR_INC(busy_buffer_index);
|
||||
(void) NET_BUF_FREE(sent_write_buffer[busy_buffer_index]);
|
||||
sent_write_buffer[busy_buffer_index] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (netif->hostname)
|
||||
{
|
||||
NET_FREE((void *) netif->hostname);
|
||||
netif->hostname = 0;
|
||||
}
|
||||
|
||||
(void) osThreadTerminate(ethernetif_thread_handle);
|
||||
ethernetif_thread_handle = NULL;
|
||||
|
||||
(void) osSemaphoreDelete(s_xSemaphore);
|
||||
s_xSemaphore = NULL;
|
||||
|
||||
ethernetif_low_deinit();
|
||||
}
|
||||
|
||||
#ifdef GENERATOR_AWS_CLOUD
|
||||
#include "mbedtls/x509_crt.h"
|
||||
|
||||
/*
|
||||
* Amazon Profile
|
||||
*/
|
||||
const mbedtls_x509_crt_profile mbedtls_x509_crt_amazon_suite =
|
||||
{
|
||||
/* Only SHA-256 and 384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
|
||||
/* Only ECDSA */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_RSA) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY) | /* */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA),
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* Only NIST P-256 and P-384 */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
|
||||
#else
|
||||
0,
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
2048
|
||||
};
|
||||
const int32_t net_tls_sizeof_suite_structure = sizeof(mbedtls_x509_crt_profile);
|
||||
const void *net_tls_user_suite0 = (void *) &mbedtls_x509_crt_amazon_suite;
|
||||
|
||||
#endif /* GENERATOR_AWS_CLOUD */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the configuration for net
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONF_H
|
||||
#define NET_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define NET_USE_RTOS
|
||||
#define NET_USE_HARDWARE_CHKSUM
|
||||
#define ETHERNET_MAC_GENERATION_FROM_SHA256
|
||||
|
||||
|
||||
#ifdef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
#define USE_TINY_DTLS
|
||||
#else
|
||||
#define NET_MBEDTLS_HOST_SUPPORT
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
|
||||
#include "net_conf_template.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+488
@@ -0,0 +1,488 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mx_wifi_io.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file implements the IO operations to deal with the mx_wifi
|
||||
* module. It mainly Inits and Deinits the SPI/UART interface. Send and
|
||||
* receive data over it.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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 ------------------------------------------------------------------*/
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include <main.h>
|
||||
#include <string.h>
|
||||
#include "net_conf.h"
|
||||
#include "mx_wifi.h"
|
||||
#if (MX_WIFI_USE_SPI == 1)
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#if (osCMSIS < 0x20000U )
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#endif /* osCMSIS */
|
||||
|
||||
#define SPI_READ (0xBE)
|
||||
#define SPI_WRITE (0xEF)
|
||||
|
||||
|
||||
#define MX_WIFI_RESET_MODULE() do{\
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_RESET);\
|
||||
HAL_Delay(10);\
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);\
|
||||
HAL_Delay(10);\
|
||||
}while(0);
|
||||
|
||||
|
||||
#define MX_WIFI_SPI_CS_ENABLE() do{ \
|
||||
HAL_GPIO_WritePin( MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_RESET );\
|
||||
}while(0);
|
||||
|
||||
#define MX_WIFI_SPI_CS_DISABLE() do{ \
|
||||
HAL_GPIO_WritePin( MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_SET );\
|
||||
}while(0);
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static MX_WIFIObject_t MxWifiObj;
|
||||
static __IO int32_t spi_slave_notify_event = 0;
|
||||
static __IO int32_t spi_slave_flow_event = 0;
|
||||
|
||||
#if MX_WIFI_USE_CMSIS_OS
|
||||
osSemaphoreId slave_notify_sem;
|
||||
osSemaphoreDef(slave_notify_sem);
|
||||
|
||||
osSemaphoreId slave_flow_sem;
|
||||
osSemaphoreDef(slave_flow_sem);
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
|
||||
|
||||
/* Global variables --------------------------------------------------------*/
|
||||
SPI_HandleTypeDef hspi_mx;
|
||||
DMA_HandleTypeDef hdma_spi_mxc_tx;
|
||||
DMA_HandleTypeDef hdma_spi_mxc_rx;
|
||||
|
||||
MX_WIFIObject_t *wifi_obj_get(void);
|
||||
|
||||
|
||||
|
||||
static void MX_WIFI_IO_DELAY(uint32_t ms)
|
||||
{
|
||||
#if MX_WIFI_USE_CMSIS_OS
|
||||
osDelay(ms);
|
||||
#else
|
||||
HAL_Delay(ms);
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
}
|
||||
|
||||
MX_WIFIObject_t *wifi_obj_get(void)
|
||||
{
|
||||
return &MxWifiObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function for WIFI reset IO
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_WIFI_RESET_IO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_Init;
|
||||
|
||||
MX_WIFI_RESET_IO_CLK_ENABLE();
|
||||
|
||||
/* configure Reset pin PA4 */
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);
|
||||
GPIO_Init.Pin = MX_WIFI_RESET_IO_PIN;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(MX_WIFI_RESET_IO_PORT, &GPIO_Init);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the flow, notify and software CS IO for SPI
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_WIFI_SPI_IO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_Init;
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
MX_WIFI_SPI_IO_FLOW_CLK_ENABLE();
|
||||
MX_WIFI_SPI_IO_NOTIFY_CLK_ENABLE();
|
||||
MX_WIFI_SPI_SW_CS_CLK_ENABLE();
|
||||
|
||||
/* configure slave data notify pin */
|
||||
GPIO_Init.Pin = MX_WIFI_SPI_IO_NOTIFY_PIN;
|
||||
GPIO_Init.Mode = GPIO_MODE_IT_RISING_FALLING;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(MX_WIFI_SPI_IO_NOTIFY_PORT, &GPIO_Init);
|
||||
|
||||
/* configure slave flow control pin */
|
||||
GPIO_Init.Pin = MX_WIFI_SPI_IO_FLOW_PIN;
|
||||
GPIO_Init.Mode = GPIO_MODE_IT_RISING_FALLING;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(MX_WIFI_SPI_IO_FLOW_PORT, &GPIO_Init);
|
||||
|
||||
/* Enable Interrupt for slave flow control pin , PA3 */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)MX_WIFI_SPI_IO_FLOW_IRQ, SPI_INTERFACE_IO_PRIO, 0x00);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)MX_WIFI_SPI_IO_FLOW_IRQ);
|
||||
|
||||
/* Enable Interrupt for slave Data Ready pin , PB0 */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)MX_WIFI_SPI_IO_NOTIFY_IRQ, SPI_INTERFACE_IO_PRIO, 0x00);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)MX_WIFI_SPI_IO_NOTIFY_IRQ);
|
||||
|
||||
/* SPI soft-NSS */
|
||||
HAL_GPIO_WritePin(MX_WIFI_SPI_SW_CS_PORT, MX_WIFI_SPI_SW_CS_PIN, GPIO_PIN_RESET);
|
||||
GPIO_Init.Pin = MX_WIFI_SPI_SW_CS_PIN;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(MX_WIFI_SPI_SW_CS_PORT, &GPIO_Init);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI1 hardware
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_SPI_Init(void)
|
||||
{
|
||||
/* SPI1 parameter configuration*/
|
||||
hspi_mx.Instance = SPI1;
|
||||
hspi_mx.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi_mx.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi_mx.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi_mx.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi_mx.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi_mx.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi_mx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
hspi_mx.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi_mx.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi_mx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi_mx.Init.CRCPolynomial = 7;
|
||||
hspi_mx.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
|
||||
hspi_mx.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
|
||||
if (HAL_SPI_Init(&hspi_mx) != HAL_OK)
|
||||
{
|
||||
/*Error_Handler();*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static int8_t MX_WIFI_SPI_Init(uint16_t mode)
|
||||
{
|
||||
int8_t rc = 0;
|
||||
|
||||
MX_WIFI_RESET_IO_Init();
|
||||
|
||||
if (MX_WIFI_RESET == mode)
|
||||
{
|
||||
MX_WIFI_RESET_MODULE();
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
MX_WIFI_SPI_IO_Init();
|
||||
MX_SPI_Init();
|
||||
|
||||
#if MX_WIFI_USE_CMSIS_OS
|
||||
#if (osCMSIS < 0x20000U )
|
||||
slave_notify_sem = osSemaphoreCreate(osSemaphore(slave_notify_sem), 1);
|
||||
slave_flow_sem = osSemaphoreCreate(osSemaphore(slave_flow_sem), 1);
|
||||
#else
|
||||
slave_notify_sem = osSemaphoreNew(1, 1, NULL);
|
||||
slave_flow_sem = osSemaphoreNew(1, 1, NULL);
|
||||
|
||||
#endif /* osCMSIS < 0x20000U*/
|
||||
/* take semaphore */
|
||||
OSSEMAPHOREWAIT(slave_notify_sem, 1);
|
||||
OSSEMAPHOREWAIT(slave_flow_sem, 1);
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the SPI
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static int8_t MX_WIFI_SPI_DeInit(void)
|
||||
{
|
||||
HAL_SPI_DeInit(&hspi_mx);
|
||||
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
osSemaphoreDelete(slave_notify_sem);
|
||||
osSemaphoreDelete(slave_flow_sem);
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI read/write cmd byte
|
||||
*/
|
||||
static int32_t wait_wifi_notify_event(int32_t timeout)
|
||||
{
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
if (osOK != OSSEMAPHOREWAIT(slave_notify_sem, timeout))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (0 == spi_slave_notify_event)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
spi_slave_notify_event = 0;
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t wait_wifi_idle(int32_t timeout)
|
||||
{
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
if (osOK != OSSEMAPHOREWAIT(slave_flow_sem, timeout))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
int32_t tickstart = HAL_GetTick();
|
||||
while (0 == spi_slave_flow_event)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > timeout)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
spi_slave_flow_event = 0;
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Interrupt handler for Data RDY signal
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SPI_WIFI_ISR(uint16_t isr_source)
|
||||
{
|
||||
if (MX_WIFI_SPI_IO_NOTIFY_PIN == isr_source)
|
||||
{
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
osSemaphoreRelease(slave_notify_sem);
|
||||
#else
|
||||
spi_slave_notify_event = 1;
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
}
|
||||
else if (MX_WIFI_SPI_IO_FLOW_PIN == isr_source)
|
||||
{
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
osSemaphoreRelease(slave_flow_sem);
|
||||
#else
|
||||
spi_slave_flow_event = 1;
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Recv wifi Data thru SPI
|
||||
* @param pdata : pointer to data
|
||||
* @param len : Data length
|
||||
* @param timeout : send timeout in mS
|
||||
* @retval Length of recved data
|
||||
*/
|
||||
int16_t MX_WIFI_SPI_ReceiveData(uint8_t *pdata, uint16_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int16_t rc = -1;
|
||||
uint8_t type = SPI_READ;
|
||||
uint16_t read_len = 0;
|
||||
|
||||
MX_WIFI_SPI_CS_ENABLE();
|
||||
|
||||
if (wait_wifi_notify_event(timeout_ms) < 0)
|
||||
{
|
||||
/*DEBUG_LOG("DEBUG: spi recv: wait wifi data timeout.\r\n");*/
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (HAL_SPI_Transmit(&hspi_mx, &type, 1, 5) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: send READ(1) error !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms + 10) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: wait READ ack timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
DEBUG_LOG("spi READ cmd ok.\r\n");
|
||||
|
||||
if (HAL_SPI_Receive(&hspi_mx, (uint8_t *)&read_len, 2, 10) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: recv READ_LEN(2) error !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms + 10) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: wait READ len ack timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
read_len = (read_len > len) ? len : read_len;
|
||||
DEBUG_LOG("spi READ len(%d) ok.\r\n", read_len);
|
||||
|
||||
if (HAL_SPI_Receive(&hspi_mx, pdata, read_len, 200) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: recv DATA(%d) error !\r\n", read_len);
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms + 100) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi recv: wait DATA ack timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
DEBUG_LOG("spi READ data(%d) ok.\r\n", read_len);
|
||||
rc = read_len;
|
||||
|
||||
error_exit:
|
||||
MX_WIFI_SPI_CS_DISABLE();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send wifi Data thru SPI
|
||||
* @param pdata : pointer to data
|
||||
* @param len : Data length
|
||||
* @param timeout : send timeout in mS
|
||||
* @retval Length of sent data
|
||||
*/
|
||||
static int16_t MX_WIFI_SPI_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout_ms)
|
||||
{
|
||||
int16_t rc = -1;
|
||||
uint8_t type = SPI_WRITE;
|
||||
uint16_t send_len = len;
|
||||
|
||||
MX_WIFI_SPI_CS_ENABLE();
|
||||
|
||||
#ifdef WIFI_USE_CMSIS_OS
|
||||
OSSEMAPHOREWAIT(slave_flow_sem, 1);
|
||||
OSSEMAPHOREWAIT(slave_notify_sem, 1);
|
||||
#else
|
||||
spi_slave_notify_event = 0;
|
||||
spi_slave_flow_event = 0;
|
||||
#endif /* WIFI_USE_CMSIS_OS */
|
||||
|
||||
if (HAL_SPI_Transmit(&hspi_mx, (uint8_t *)&type, 1, 5) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: send WRITE(1) error !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: wait WRITE ACK timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
DEBUG_LOG("spi WRITE cmd ok.\r\n");
|
||||
|
||||
if (HAL_SPI_Transmit(&hspi_mx, (uint8_t *)&send_len, 2, 10) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: send WRITE_LEN(2) error !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: wait WRITE_LEN ACK timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
DEBUG_LOG("spi WRITE len(%d) ok.\r\n", send_len);
|
||||
|
||||
if (HAL_SPI_Transmit(&hspi_mx, pdata, send_len, 200) != HAL_OK)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: send DATA(%d) error !\r\n", send_len);
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
if (wait_wifi_idle(timeout_ms + 100) < 0)
|
||||
{
|
||||
DEBUG_LOG("** ERROR: spi send: wait DATA ACK timeout !\r\n");
|
||||
rc = MX_WIFI_STATUS_IO_ERROR;
|
||||
goto error_exit;
|
||||
}
|
||||
DEBUG_LOG("spi WRITE data(%d) ok.\r\n", send_len);
|
||||
rc = send_len;
|
||||
|
||||
error_exit:
|
||||
MX_WIFI_SPI_CS_DISABLE();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief probe function to register wifi to connectivity framwotk
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
int32_t wifi_probe(void **ll_drv_context)
|
||||
{
|
||||
if (MX_WIFI_RegisterBusIO(&MxWifiObj,
|
||||
MX_WIFI_SPI_Init,
|
||||
MX_WIFI_SPI_DeInit,
|
||||
MX_WIFI_IO_DELAY,
|
||||
MX_WIFI_SPI_SendData,
|
||||
MX_WIFI_SPI_ReceiveData) == 0)
|
||||
{
|
||||
*ll_drv_context = &MxWifiObj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* (MX_WIFI_USE_SPI == 1) */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mx_wifi_io.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file implements the IO operations to deal with the mx_wifi
|
||||
* module. It mainly Inits and Deinits the UART interface. Send and
|
||||
* receive data over it.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* this file can be copy and renamed as net_conf.c or use directly from its
|
||||
* orginal location STM32_Network_lib/templates. There is no need to chnage it.
|
||||
*
|
||||
* It performs the connection between the mxchip BSP driver and the UART
|
||||
*
|
||||
* Expectaction is that UART pins labels are defined in main.h (when using
|
||||
* CUbeMX) or in net_conf.h.
|
||||
*
|
||||
* function HAL_UART_MspInit(UART_HandleTypeDef* huart) in file
|
||||
* stm32xxxx_hal_msp.c must performed the init of the selected UART interface
|
||||
* This function can be manualy written or generated by cubeMX
|
||||
*
|
||||
* UART parameter init is done in this file in a redundant way from
|
||||
* the HAL_UART_MspInit function.CubeMX user does not have to know the exact
|
||||
* configuratino of the UART , but only the pin out connections.
|
||||
*
|
||||
* When interrupt are used (NET_USE_RTOS) , the function MXchip_UART_RxCpltCallback
|
||||
* must be called from HAL_UART_RxCpltCallback located in main.c. A dedicated
|
||||
* IRQHandler must be added to the file stm32xxx_it.C to call the HAL_UART_IRQHandler
|
||||
*
|
||||
* the function MX_WIFI_RESET_IO_Initconfigure the reset pins. It should be generated by
|
||||
* CubeMX et being located in main.c
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
#include <main.h>
|
||||
#include <string.h>
|
||||
#include "net_conf.h"
|
||||
#include "mx_wifi.h"
|
||||
#if (MX_WIFI_USE_SPI == 0)
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#if (osCMSIS < 0x20000U )
|
||||
#define OSSEMAPHOREWAIT osSemaphoreWait
|
||||
#else
|
||||
#define OSSEMAPHOREWAIT osSemaphoreAcquire
|
||||
#endif /* osCMSIS */
|
||||
|
||||
|
||||
#define MX_WIFI_RESET_MODULE() do{\
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_RESET);\
|
||||
HAL_Delay(10);\
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);\
|
||||
HAL_Delay(10);\
|
||||
}while(0);
|
||||
|
||||
#if MX_WIFI_USE_UART_INTERRUPT
|
||||
#define RING_BUFFER_SIZE (MX_WIFI_DATA_SIZE + 500)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t data[RING_BUFFER_SIZE];
|
||||
__IO uint16_t tail;
|
||||
__IO uint16_t head;
|
||||
} RingBuffer_t;
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
|
||||
MX_WIFIObject_t *wifi_obj_get(void);
|
||||
|
||||
|
||||
|
||||
UART_HandleTypeDef mx_uart;
|
||||
static MX_WIFIObject_t MxWifiObj;
|
||||
#if MX_WIFI_USE_UART_INTERRUPT
|
||||
__IO RingBuffer_t WiFiRxBuffer;
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
#ifdef NET_USE_RTOS
|
||||
osSemaphoreId wifi_uart_rx_sem;
|
||||
osSemaphoreDef(wifi_uart_rx_sem);
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
MX_WIFIObject_t *wifi_obj_get(void)
|
||||
{
|
||||
return &MxWifiObj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void MX_WIFI_IO_DELAY(uint32_t ms)
|
||||
{
|
||||
#if MX_WIFI_USE_CMSIS_OS
|
||||
osDelay(ms);
|
||||
#else
|
||||
HAL_Delay(ms);
|
||||
#endif /* MX_WIFI_USE_CMSIS_OS */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function for WIFI reset IO
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_WIFI_RESET_IO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_Init;
|
||||
|
||||
MX_WIFI_RESET_IO_CLK_ENABLE();
|
||||
|
||||
/* configure Reset pin for Mxchip */
|
||||
HAL_GPIO_WritePin(MX_WIFI_RESET_IO_PORT, MX_WIFI_RESET_IO_PIN, GPIO_PIN_SET);
|
||||
GPIO_Init.Pin = MX_WIFI_RESET_IO_PIN;
|
||||
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_Init.Pull = GPIO_NOPULL;
|
||||
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(MX_WIFI_RESET_IO_PORT, &GPIO_Init);
|
||||
}
|
||||
|
||||
#ifdef NET_MXCHIP_LOCAL_MSP
|
||||
/**
|
||||
* @brief UART MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
if (huart->Instance == USARTmxc)
|
||||
{
|
||||
/*##-1- Enable peripherals and GPIO Clocks #################################*/
|
||||
/* Enable GPIO TX/RX clock */
|
||||
USARTmxc_TX_GPIO_CLK_ENABLE();
|
||||
USARTmxc_RX_GPIO_CLK_ENABLE();
|
||||
|
||||
/* Enable USARTx clock */
|
||||
USARTmxc_CLK_ENABLE();
|
||||
|
||||
|
||||
/*##-2- Configure peripheral GPIO ##########################################*/
|
||||
/* UART TX GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = USARTmxc_TX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = USARTmxc_TX_AF;
|
||||
|
||||
HAL_GPIO_Init(USARTmxc_TX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* UART RX GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = USARTmxc_RX_PIN;
|
||||
GPIO_InitStruct.Alternate = USARTmxc_RX_AF;
|
||||
|
||||
HAL_GPIO_Init(USARTmxc_RX_GPIO_PORT, &GPIO_InitStruct);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == USARTmxc)
|
||||
{
|
||||
USARTmxc_FORCE_RESET();
|
||||
USARTmxc_RELEASE_RESET();
|
||||
|
||||
USARTmxc_CLK_DISABLE();
|
||||
|
||||
/*##-2- Disable peripherals and GPIO Clocks ################################*/
|
||||
/* Configure UART Tx as alternate function */
|
||||
HAL_GPIO_DeInit(USARTmxc_TX_GPIO_PORT, USARTmxc_TX_PIN);
|
||||
/* Configure UART Rx as alternate function */
|
||||
HAL_GPIO_DeInit(USARTmxc_RX_GPIO_PORT, USARTmxc_RX_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NET_MXCHIP_LOCAL_MSP */
|
||||
|
||||
/**
|
||||
* @brief Initialize the UART
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static int8_t MX_WIFI_UART_Init(uint16_t mode)
|
||||
{
|
||||
int8_t rc = 0;
|
||||
|
||||
MX_WIFI_RESET_IO_Init();
|
||||
|
||||
if (MX_WIFI_RESET == mode)
|
||||
{
|
||||
MX_WIFI_RESET_MODULE();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Configurate the UART to correct speed */
|
||||
mx_uart.Instance = USARTmxc;
|
||||
mx_uart.Init.BaudRate = MX_WIFI_UART_BAUDRATE;
|
||||
mx_uart.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
mx_uart.Init.StopBits = UART_STOPBITS_1;
|
||||
mx_uart.Init.Parity = UART_PARITY_NONE;
|
||||
mx_uart.Init.Mode = UART_MODE_TX_RX;
|
||||
mx_uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
mx_uart.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
mx_uart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
#ifdef UART_PRESCALER_DIV1
|
||||
mx_uart.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
#endif /* UART_PRESCALER_DIV1 */
|
||||
mx_uart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
if (HAL_UART_Init(&mx_uart) != HAL_OK)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
#if MX_WIFI_USE_UART_INTERRUPT
|
||||
WiFiRxBuffer.head = 0;
|
||||
WiFiRxBuffer.tail = 0;
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
#if (osCMSIS < 0x20000U )
|
||||
wifi_uart_rx_sem = osSemaphoreCreate(osSemaphore(wifi_uart_rx_sem), 1);
|
||||
#else
|
||||
wifi_uart_rx_sem = osSemaphoreNew(1, 1, NULL);
|
||||
#endif /* osCMSIS */
|
||||
OSSEMAPHOREWAIT(wifi_uart_rx_sem, 1);
|
||||
HAL_NVIC_SetPriority(UARTmxc_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 0);
|
||||
#else
|
||||
HAL_NVIC_SetPriority(UARTmxc_IRQn, 16, 0);
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
HAL_NVIC_EnableIRQ(UARTmxc_IRQn);
|
||||
#if MX_WIFI_USE_UART_INTERRUPT
|
||||
HAL_UART_Receive_IT(&mx_uart, (uint8_t *)&WiFiRxBuffer.data[WiFiRxBuffer.tail], 1);
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the UART
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static int8_t MX_WIFI_UART_DeInit(void)
|
||||
{
|
||||
int8_t rc = 0;
|
||||
|
||||
if (HAL_UART_DeInit(&mx_uart) != HAL_OK)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
#ifdef NET_USE_RTOS
|
||||
osSemaphoreDelete(wifi_uart_rx_sem);
|
||||
#endif /* NET_USE_RTOS */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#if MX_WIFI_USE_UART_INTERRUPT
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Rx Callback when new data is received on the UART.
|
||||
* @param UartHandle: Uart handle receiving the data.
|
||||
* @retval None.
|
||||
*/
|
||||
void MXchip_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle);
|
||||
void MXchip_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
|
||||
{
|
||||
uint32_t tail;
|
||||
/* WIFI UART */
|
||||
/* If ring buffer end is reached reset tail pointer to start of buffer */
|
||||
if (++WiFiRxBuffer.tail >= RING_BUFFER_SIZE)
|
||||
{
|
||||
WiFiRxBuffer.tail = 0;
|
||||
}
|
||||
|
||||
/* ringbuffer full, overlap head */
|
||||
tail = WiFiRxBuffer.tail;
|
||||
if (tail == WiFiRxBuffer.head)
|
||||
{
|
||||
WiFiRxBuffer.head++;
|
||||
}
|
||||
// fired next reception
|
||||
HAL_UART_Receive_IT(UartHandle, (uint8_t *)&WiFiRxBuffer.data[WiFiRxBuffer.tail], 1);
|
||||
|
||||
#ifdef NET_USE_RTOS
|
||||
osSemaphoreRelease(wifi_uart_rx_sem);
|
||||
#endif /* NET_USE_RTOS */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
|
||||
/**
|
||||
* @brief Send wifi Data thru UART
|
||||
* @param pdata : pointer to data
|
||||
* @param len : Data length
|
||||
* @param timeout : send timeout in mS
|
||||
* @retval Length of sent data
|
||||
*/
|
||||
static int16_t MX_WIFI_UART_SendData(uint8_t *pdata, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
int16_t rc = 0;
|
||||
|
||||
if (HAL_UART_Transmit(&mx_uart, pdata, len, timeout) != HAL_OK)
|
||||
{
|
||||
return MX_WIFI_STATUS_IO_ERROR;
|
||||
}
|
||||
rc = len;
|
||||
/*DEBUG_LOG("MX_WIFI_TX: %d bytes, [%.*s]\r\n", len, len, pdata);*/
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int16_t MX_WIFI_UART_ReceiveData(uint8_t *pdata, uint16_t request_len, uint32_t timeout)
|
||||
{
|
||||
int16_t len = 0;
|
||||
|
||||
#if MX_WIFI_USE_UART_INTERRUPT==0
|
||||
len = request_len;
|
||||
if (HAL_UART_Receive(&mx_uart, pdata, len, timeout) != HAL_OK)
|
||||
{
|
||||
return MX_WIFI_STATUS_IO_ERROR;
|
||||
}
|
||||
/*DEBUG_LOG("MX_WIFI_RX: %d bytes, [%.*s]\r\n", len, len, pdata);*/
|
||||
#else
|
||||
int32_t tail;
|
||||
#ifdef NET_USE_RTOS
|
||||
OSSEMAPHOREWAIT(wifi_uart_rx_sem, 1);
|
||||
#endif /* NET_USE_RTOS */
|
||||
tail = WiFiRxBuffer.tail;
|
||||
len = ((RING_BUFFER_SIZE + tail - WiFiRxBuffer.head) % RING_BUFFER_SIZE);
|
||||
if (len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > request_len)
|
||||
{
|
||||
len = request_len;
|
||||
}
|
||||
|
||||
/*copy from buffer */
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
*pdata++ = WiFiRxBuffer.data[WiFiRxBuffer.head++];
|
||||
if (WiFiRxBuffer.head >= RING_BUFFER_SIZE)
|
||||
{
|
||||
/* wrap */
|
||||
WiFiRxBuffer.head = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MX_WIFI_USE_UART_INTERRUPT */
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief probe function to register wifi to connectivity framwotk
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
int32_t wifi_probe(void **ll_drv_context)
|
||||
{
|
||||
if (MX_WIFI_RegisterBusIO(&MxWifiObj,
|
||||
MX_WIFI_UART_Init,
|
||||
MX_WIFI_UART_DeInit,
|
||||
MX_WIFI_IO_DELAY,
|
||||
MX_WIFI_UART_SendData,
|
||||
MX_WIFI_UART_ReceiveData) == 0)
|
||||
{
|
||||
*ll_drv_context = &MxWifiObj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#endif /* MX_WIFI_USE_SPI */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file net_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the configuration for net
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NET_CONF_H
|
||||
#define NET_CONF_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*#define NET_MBEDTLS_HOST_SUPPORT*/
|
||||
#define NET_DBG_INFO(...)
|
||||
#define NET_DBG_ERROR(...)
|
||||
#define NET_DBG_PRINT(...)
|
||||
#define NET_ASSERT(a,b) do { } while((a)==false)
|
||||
#define NET_PRINT(...)
|
||||
#define NET_PRINT_WO_CR(...)
|
||||
#define NET_WARNING(...)
|
||||
|
||||
#define NET_USE_LWIP_DEFINITIONS
|
||||
#define NET_ALLOC_BREAK 0xFFFFFFFFU
|
||||
/*#define NET_ALLOC_DEBUG*/
|
||||
#define NET_BYPASS_NET_SOCKET
|
||||
#include <stdint.h>
|
||||
void ethernetif_low_init(void (*event_callback)(void), void (*buffer_output_callback)(uint8_t *));
|
||||
void ethernetif_low_deinit(void);
|
||||
|
||||
int16_t ethernetif_low_inputsize(void);
|
||||
int16_t ethernetif_low_input(uint8_t *payload, uint16_t len);
|
||||
int16_t ethernetif_low_output(uint8_t *payload, uint16_t len);
|
||||
|
||||
void ethernetif_low_get_mac_addr(uint8_t *MACAddr_in);
|
||||
uint8_t ethernetif_low_get_link_status(void);
|
||||
|
||||
#define NET_USE_RTOS
|
||||
|
||||
#ifndef GENERATOR_WAKAAMACLIENT_CLOUD
|
||||
/*#define NET_MBEDTLS_HOST_SUPPORT*/
|
||||
#endif /* GENERATOR_WAKAAMACLIENT_CLOUD */
|
||||
|
||||
/*cstat -MISRAC2012-Rule-20.1 */
|
||||
#include "net_conf_template.h"
|
||||
/*cstat +MISRAC2012-Rule-20.1 */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_audio.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_audio.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_AUDIO_H
|
||||
#define __USB_AUDIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_AUDIO
|
||||
* @brief This file is the Header file for usbd_audio.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef USBD_AUDIO_FREQ
|
||||
/* AUDIO Class Config */
|
||||
#define USBD_AUDIO_FREQ 48000U
|
||||
#endif /* USBD_AUDIO_FREQ */
|
||||
|
||||
#ifndef USBD_MAX_NUM_INTERFACES
|
||||
#define USBD_MAX_NUM_INTERFACES 1U
|
||||
#endif /* USBD_AUDIO_FREQ */
|
||||
|
||||
#ifndef AUDIO_HS_BINTERVAL
|
||||
#define AUDIO_HS_BINTERVAL 0x01U
|
||||
#endif /* AUDIO_HS_BINTERVAL */
|
||||
|
||||
#ifndef AUDIO_FS_BINTERVAL
|
||||
#define AUDIO_FS_BINTERVAL 0x01U
|
||||
#endif /* AUDIO_FS_BINTERVAL */
|
||||
|
||||
#ifndef AUDIO_OUT_EP
|
||||
#define AUDIO_OUT_EP 0x01U
|
||||
#endif /* AUDIO_OUT_EP */
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ 0x6DU
|
||||
#define AUDIO_INTERFACE_DESC_SIZE 0x09U
|
||||
#define USB_AUDIO_DESC_SIZ 0x09U
|
||||
#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09U
|
||||
#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07U
|
||||
|
||||
#define AUDIO_DESCRIPTOR_TYPE 0x21U
|
||||
#define USB_DEVICE_CLASS_AUDIO 0x01U
|
||||
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01U
|
||||
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02U
|
||||
#define AUDIO_PROTOCOL_UNDEFINED 0x00U
|
||||
#define AUDIO_STREAMING_GENERAL 0x01U
|
||||
#define AUDIO_STREAMING_FORMAT_TYPE 0x02U
|
||||
|
||||
/* Audio Descriptor Types */
|
||||
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24U
|
||||
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25U
|
||||
|
||||
/* Audio Control Interface Descriptor Subtypes */
|
||||
#define AUDIO_CONTROL_HEADER 0x01U
|
||||
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U
|
||||
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U
|
||||
#define AUDIO_CONTROL_FEATURE_UNIT 0x06U
|
||||
|
||||
#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0CU
|
||||
#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09U
|
||||
#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07U
|
||||
|
||||
#define AUDIO_CONTROL_MUTE 0x0001U
|
||||
|
||||
#define AUDIO_FORMAT_TYPE_I 0x01U
|
||||
#define AUDIO_FORMAT_TYPE_III 0x03U
|
||||
|
||||
#define AUDIO_ENDPOINT_GENERAL 0x01U
|
||||
|
||||
#define AUDIO_REQ_GET_CUR 0x81U
|
||||
#define AUDIO_REQ_SET_CUR 0x01U
|
||||
|
||||
#define AUDIO_OUT_STREAMING_CTRL 0x02U
|
||||
|
||||
#define AUDIO_OUT_TC 0x01U
|
||||
#define AUDIO_IN_TC 0x02U
|
||||
|
||||
|
||||
#define AUDIO_OUT_PACKET (uint16_t)(((USBD_AUDIO_FREQ * 2U * 2U) / 1000U))
|
||||
#define AUDIO_DEFAULT_VOLUME 70U
|
||||
|
||||
/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
|
||||
that it is an even number and higher than 3 */
|
||||
#define AUDIO_OUT_PACKET_NUM 80U
|
||||
/* Total size of the audio transfer buffer */
|
||||
#define AUDIO_TOTAL_BUF_SIZE ((uint16_t)(AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM))
|
||||
|
||||
/* Audio Commands enumeration */
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_CMD_START = 1,
|
||||
AUDIO_CMD_PLAY,
|
||||
AUDIO_CMD_STOP,
|
||||
} AUDIO_CMD_TypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_OFFSET_NONE = 0,
|
||||
AUDIO_OFFSET_HALF,
|
||||
AUDIO_OFFSET_FULL,
|
||||
AUDIO_OFFSET_UNKNOWN,
|
||||
} AUDIO_OffsetTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t data[USB_MAX_EP0_SIZE];
|
||||
uint8_t len;
|
||||
uint8_t unit;
|
||||
} USBD_AUDIO_ControlTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t alt_setting;
|
||||
uint8_t buffer[AUDIO_TOTAL_BUF_SIZE];
|
||||
AUDIO_OffsetTypeDef offset;
|
||||
uint8_t rd_enable;
|
||||
uint16_t rd_ptr;
|
||||
uint16_t wr_ptr;
|
||||
USBD_AUDIO_ControlTypeDef control;
|
||||
} USBD_AUDIO_HandleTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int8_t (*Init)(uint32_t AudioFreq, uint32_t Volume, uint32_t options);
|
||||
int8_t (*DeInit)(uint32_t options);
|
||||
int8_t (*AudioCmd)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
|
||||
int8_t (*VolumeCtl)(uint8_t vol);
|
||||
int8_t (*MuteCtl)(uint8_t cmd);
|
||||
int8_t (*PeriodicTC)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
|
||||
int8_t (*GetState)(void);
|
||||
} USBD_AUDIO_ItfTypeDef;
|
||||
|
||||
/*
|
||||
* Audio Class specification release 1.0
|
||||
*/
|
||||
|
||||
/* Table 4-2: Class-Specific AC Interface Header Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint16_t bcdADC;
|
||||
uint16_t wTotalLength;
|
||||
uint8_t bInCollection;
|
||||
uint8_t baInterfaceNr;
|
||||
} __PACKED USBD_SpeakerIfDescTypeDef;
|
||||
|
||||
/* Table 4-3: Input Terminal Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bTerminalID;
|
||||
uint16_t wTerminalType;
|
||||
uint8_t bAssocTerminal;
|
||||
uint8_t bNrChannels;
|
||||
uint16_t wChannelConfig;
|
||||
uint8_t iChannelNames;
|
||||
uint8_t iTerminal;
|
||||
} __PACKED USBD_SpeakerInDescTypeDef;
|
||||
|
||||
/* USB Speaker Audio Feature Unit Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bUnitID;
|
||||
uint8_t bSourceID;
|
||||
uint8_t bControlSize;
|
||||
uint16_t bmaControls;
|
||||
uint8_t iTerminal;
|
||||
} __PACKED USBD_SpeakerFeatureDescTypeDef;
|
||||
|
||||
/* Table 4-4: Output Terminal Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bTerminalID;
|
||||
uint16_t wTerminalType;
|
||||
uint8_t bAssocTerminal;
|
||||
uint8_t bSourceID;
|
||||
uint8_t iTerminal;
|
||||
} __PACKED USBD_SpeakerOutDescTypeDef;
|
||||
|
||||
/* Table 4-19: Class-Specific AS Interface Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bTerminalLink;
|
||||
uint8_t bDelay;
|
||||
uint16_t wFormatTag;
|
||||
} __PACKED USBD_SpeakerStreamIfDescTypeDef;
|
||||
|
||||
/* USB Speaker Audio Type III Format Interface Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bFormatType;
|
||||
uint8_t bNrChannels;
|
||||
uint8_t bSubFrameSize;
|
||||
uint8_t bBitResolution;
|
||||
uint8_t bSamFreqType;
|
||||
uint8_t tSamFreq2;
|
||||
uint8_t tSamFreq1;
|
||||
uint8_t tSamFreq0;
|
||||
} USBD_SpeakerIIIFormatIfDescTypeDef;
|
||||
|
||||
/* Table 4-17: Standard AC Interrupt Endpoint Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint8_t bInterval;
|
||||
uint8_t bRefresh;
|
||||
uint8_t bSynchAddress;
|
||||
} __PACKED USBD_SpeakerEndDescTypeDef;
|
||||
|
||||
/* Table 4-21: Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptor;
|
||||
uint8_t bmAttributes;
|
||||
uint8_t bLockDelayUnits;
|
||||
uint16_t wLockDelay;
|
||||
} __PACKED USBD_SpeakerEndStDescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_AUDIO;
|
||||
#define USBD_AUDIO_CLASS &USBD_AUDIO
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_AUDIO_ItfTypeDef *fops);
|
||||
|
||||
void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_AUDIO_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_audio_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for usbd_audio_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_AUDIO_IF_TEMPLATE_H
|
||||
#define __USBD_AUDIO_IF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_audio.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_AUDIO_IF_TEMPLATE_H */
|
||||
+980
@@ -0,0 +1,980 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_audio.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the Audio core functions.
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* AUDIO Class Description
|
||||
* ===================================================================
|
||||
* This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
|
||||
* Audio Devices V1.0 Mar 18, 98".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Device descriptor management
|
||||
* - Configuration descriptor management
|
||||
* - Standard AC Interface Descriptor management
|
||||
* - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
|
||||
* - 1 Audio Streaming Endpoint
|
||||
* - 1 Audio Terminal Input (1 channel)
|
||||
* - Audio Class-Specific AC Interfaces
|
||||
* - Audio Class-Specific AS Interfaces
|
||||
* - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
|
||||
* - Audio Feature Unit (limited to Mute control)
|
||||
* - Audio Synchronization type: Asynchronous
|
||||
* - Single fixed audio sampling rate (configurable in usbd_conf.h file)
|
||||
* The current audio class version supports the following audio features:
|
||||
* - Pulse Coded Modulation (PCM) format
|
||||
* - sampling rate: 48KHz.
|
||||
* - Bit resolution: 16
|
||||
* - Number of channels: 2
|
||||
* - No volume control
|
||||
* - Mute/Unmute capability
|
||||
* - Asynchronous Endpoints
|
||||
*
|
||||
* @note In HS mode and when the DMA is used, all variables and data structures
|
||||
* dealing with the DMA during the transaction process should be 32-bit aligned.
|
||||
*
|
||||
*
|
||||
* @endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_audio.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_audio.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define AUDIO_SAMPLE_FREQ(frq) \
|
||||
(uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
|
||||
|
||||
#define AUDIO_PACKET_SZE(frq) \
|
||||
(uint8_t)(((frq * 2U * 2U) / 1000U) & 0xFFU), (uint8_t)((((frq * 2U * 2U) / 1000U) >> 8) & 0xFFU)
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
#define AUDIO_PACKET_SZE_WORD(frq) (uint32_t)((((frq) * 2U * 2U)/1000U))
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
|
||||
static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req);
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev);
|
||||
static uint8_t USBD_AUDIO_EP0_TxReady(USBD_HandleTypeDef *pdev);
|
||||
static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev);
|
||||
|
||||
static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_ClassTypeDef USBD_AUDIO =
|
||||
{
|
||||
USBD_AUDIO_Init,
|
||||
USBD_AUDIO_DeInit,
|
||||
USBD_AUDIO_Setup,
|
||||
USBD_AUDIO_EP0_TxReady,
|
||||
USBD_AUDIO_EP0_RxReady,
|
||||
USBD_AUDIO_DataIn,
|
||||
USBD_AUDIO_DataOut,
|
||||
USBD_AUDIO_SOF,
|
||||
USBD_AUDIO_IsoINIncomplete,
|
||||
USBD_AUDIO_IsoOutIncomplete,
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
USBD_AUDIO_GetCfgDesc,
|
||||
USBD_AUDIO_GetCfgDesc,
|
||||
USBD_AUDIO_GetCfgDesc,
|
||||
USBD_AUDIO_GetDeviceQualifierDesc,
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB AUDIO device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
/* Configuration 1 */
|
||||
0x09, /* bLength */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */
|
||||
LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength */
|
||||
HIBYTE(USB_AUDIO_CONFIG_DESC_SIZ),
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
/* 09 byte*/
|
||||
|
||||
/* USB Speaker Standard interface descriptor */
|
||||
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
/* 09 byte*/
|
||||
|
||||
/* USB Speaker Class-specific AC Interface Descriptor */
|
||||
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
|
||||
0x00, /* 1.00 */ /* bcdADC */
|
||||
0x01,
|
||||
0x27, /* wTotalLength */
|
||||
0x00,
|
||||
0x01, /* bInCollection */
|
||||
0x01, /* baInterfaceNr */
|
||||
/* 09 byte*/
|
||||
|
||||
/* USB Speaker Input Terminal Descriptor */
|
||||
AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x01, /* bTerminalID */
|
||||
0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */
|
||||
0x01,
|
||||
0x00, /* bAssocTerminal */
|
||||
0x01, /* bNrChannels */
|
||||
0x00, /* wChannelConfig 0x0000 Mono */
|
||||
0x00,
|
||||
0x00, /* iChannelNames */
|
||||
0x00, /* iTerminal */
|
||||
/* 12 byte*/
|
||||
|
||||
/* USB Speaker Audio Feature Unit Descriptor */
|
||||
0x09, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
|
||||
AUDIO_OUT_STREAMING_CTRL, /* bUnitID */
|
||||
0x01, /* bSourceID */
|
||||
0x01, /* bControlSize */
|
||||
AUDIO_CONTROL_MUTE, /* bmaControls(0) */
|
||||
0, /* bmaControls(1) */
|
||||
0x00, /* iTerminal */
|
||||
/* 09 byte */
|
||||
|
||||
/* USB Speaker Output Terminal Descriptor */
|
||||
0x09, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
|
||||
0x03, /* bTerminalID */
|
||||
0x01, /* wTerminalType 0x0301 */
|
||||
0x03,
|
||||
0x00, /* bAssocTerminal */
|
||||
0x02, /* bSourceID */
|
||||
0x00, /* iTerminal */
|
||||
/* 09 byte */
|
||||
|
||||
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */
|
||||
/* Interface 1, Alternate Setting 0 */
|
||||
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
/* 09 byte*/
|
||||
|
||||
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
|
||||
/* Interface 1, Alternate Setting 1 */
|
||||
AUDIO_INTERFACE_DESC_SIZE, /* bLength */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
/* 09 byte*/
|
||||
|
||||
/* USB Speaker Audio Streaming Interface Descriptor */
|
||||
AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
|
||||
0x01, /* bTerminalLink */
|
||||
0x01, /* bDelay */
|
||||
0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001 */
|
||||
0x00,
|
||||
/* 07 byte*/
|
||||
|
||||
/* USB Speaker Audio Type III Format Interface Descriptor */
|
||||
0x0B, /* bLength */
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */
|
||||
0x02, /* bNrChannels */
|
||||
0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
|
||||
16, /* bBitResolution (16-bits per sample) */
|
||||
0x01, /* bSamFreqType only one frequency supported */
|
||||
AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */
|
||||
/* 11 byte*/
|
||||
|
||||
/* Endpoint 1 - Standard Descriptor */
|
||||
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */
|
||||
AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint */
|
||||
USBD_EP_TYPE_ISOC, /* bmAttributes */
|
||||
AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
|
||||
AUDIO_FS_BINTERVAL, /* bInterval */
|
||||
0x00, /* bRefresh */
|
||||
0x00, /* bSynchAddress */
|
||||
/* 09 byte*/
|
||||
|
||||
/* Endpoint - Audio Streaming Descriptor */
|
||||
AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
|
||||
0x00, /* bmAttributes */
|
||||
0x00, /* bLockDelayUnits */
|
||||
0x00, /* wLockDelay */
|
||||
0x00,
|
||||
/* 07 byte*/
|
||||
} ;
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_AUDIO_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,
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
static uint8_t AUDIOOutEpAdd = AUDIO_OUT_EP;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_Init
|
||||
* Initialize the AUDIO interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
|
||||
/* Allocate Audio structure */
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef));
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)haudio;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
|
||||
}
|
||||
else /* LOW and FULL-speed endpoints */
|
||||
{
|
||||
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = AUDIO_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, AUDIOOutEpAdd, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET);
|
||||
pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
haudio->alt_setting = 0U;
|
||||
haudio->offset = AUDIO_OFFSET_UNKNOWN;
|
||||
haudio->wr_ptr = 0U;
|
||||
haudio->rd_ptr = 0U;
|
||||
haudio->rd_enable = 0U;
|
||||
|
||||
/* Initialize the Audio output Hardware layer */
|
||||
if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(USBD_AUDIO_FREQ,
|
||||
AUDIO_DEFAULT_VOLUME,
|
||||
0U) != 0U)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
/* Prepare Out endpoint to receive 1st packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd, haudio->buffer,
|
||||
AUDIO_OUT_PACKET);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_Init
|
||||
* DeInitialize the AUDIO layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_CloseEP(pdev, AUDIOOutEpAdd);
|
||||
pdev->ep_out[AUDIOOutEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_out[AUDIOOutEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* DeInit physical Interface components */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
|
||||
{
|
||||
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(0U);
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_Setup
|
||||
* Handle the AUDIO specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
uint16_t len;
|
||||
uint8_t *pbuf;
|
||||
uint16_t status_info = 0U;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case AUDIO_REQ_GET_CUR:
|
||||
AUDIO_REQ_GetCurrent(pdev, req);
|
||||
break;
|
||||
|
||||
case AUDIO_REQ_SET_CUR:
|
||||
AUDIO_REQ_SetCurrent(pdev, req);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
|
||||
{
|
||||
pbuf = (uint8_t *)USBD_AUDIO_GetAudioHeaderDesc(pdev->pConfDesc);
|
||||
if (pbuf != NULL)
|
||||
{
|
||||
len = MIN(USB_AUDIO_DESC_SIZ, req->wLength);
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES)
|
||||
{
|
||||
haudio->alt_setting = (uint8_t)(req->wValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the error management function (command will be NAKed */
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_AUDIO_GetCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_AUDIO_GetCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_AUDIO_CfgDesc);
|
||||
|
||||
return USBD_AUDIO_CfgDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @brief USBD_AUDIO_DataIn
|
||||
* handle data IN Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
/* Only OUT data are processed */
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_EP0_RxReady
|
||||
* handle EP0 Rx Ready event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (haudio->control.cmd == AUDIO_REQ_SET_CUR)
|
||||
{
|
||||
/* In this driver, to simplify code, only SET_CUR request is managed */
|
||||
|
||||
if (haudio->control.unit == AUDIO_OUT_STREAMING_CTRL)
|
||||
{
|
||||
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->MuteCtl(haudio->control.data[0]);
|
||||
haudio->control.cmd = 0U;
|
||||
haudio->control.len = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_AUDIO_EP0_TxReady
|
||||
* handle EP0 TRx Ready event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_EP0_TxReady(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
|
||||
/* Only OUT control data are processed */
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_AUDIO_SOF
|
||||
* handle SOF event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_SOF
|
||||
* handle SOF event
|
||||
* @param pdev: device instance
|
||||
* @param offset: audio offset
|
||||
* @retval status
|
||||
*/
|
||||
void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
uint32_t BufferSize = AUDIO_TOTAL_BUF_SIZE / 2U;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
haudio->offset = offset;
|
||||
|
||||
if (haudio->rd_enable == 1U)
|
||||
{
|
||||
haudio->rd_ptr += (uint16_t)BufferSize;
|
||||
|
||||
if (haudio->rd_ptr == AUDIO_TOTAL_BUF_SIZE)
|
||||
{
|
||||
/* roll back */
|
||||
haudio->rd_ptr = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
if (haudio->rd_ptr > haudio->wr_ptr)
|
||||
{
|
||||
if ((haudio->rd_ptr - haudio->wr_ptr) < AUDIO_OUT_PACKET)
|
||||
{
|
||||
BufferSize += 4U;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((haudio->rd_ptr - haudio->wr_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET))
|
||||
{
|
||||
BufferSize -= 4U;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET)
|
||||
{
|
||||
BufferSize -= 4U;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET))
|
||||
{
|
||||
BufferSize += 4U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (haudio->offset == AUDIO_OFFSET_FULL)
|
||||
{
|
||||
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0],
|
||||
BufferSize, AUDIO_CMD_PLAY);
|
||||
haudio->offset = AUDIO_OFFSET_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_IsoINIncomplete
|
||||
* handle data ISO IN Incomplete event
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_AUDIO_IsoOutIncomplete
|
||||
* handle data ISO OUT Incomplete event
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
/* Prepare Out endpoint to receive next audio packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, epnum,
|
||||
&haudio->buffer[haudio->wr_ptr],
|
||||
AUDIO_OUT_PACKET);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_AUDIO_DataOut
|
||||
* handle data OUT Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
uint16_t PacketSize;
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
AUDIOOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_ISOC, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (epnum == AUDIOOutEpAdd)
|
||||
{
|
||||
/* Get received data packet length */
|
||||
PacketSize = (uint16_t)USBD_LL_GetRxDataSize(pdev, epnum);
|
||||
|
||||
/* Packet received Callback */
|
||||
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->PeriodicTC(&haudio->buffer[haudio->wr_ptr],
|
||||
PacketSize, AUDIO_OUT_TC);
|
||||
|
||||
/* Increment the Buffer pointer or roll it back when all buffers are full */
|
||||
haudio->wr_ptr += PacketSize;
|
||||
|
||||
if (haudio->wr_ptr >= AUDIO_TOTAL_BUF_SIZE)
|
||||
{
|
||||
/* All buffers are full: roll back */
|
||||
haudio->wr_ptr = 0U;
|
||||
|
||||
if (haudio->offset == AUDIO_OFFSET_UNKNOWN)
|
||||
{
|
||||
((USBD_AUDIO_ItfTypeDef *)pdev->pUserData[pdev->classId])->AudioCmd(&haudio->buffer[0],
|
||||
AUDIO_TOTAL_BUF_SIZE / 2U,
|
||||
AUDIO_CMD_START);
|
||||
haudio->offset = AUDIO_OFFSET_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (haudio->rd_enable == 0U)
|
||||
{
|
||||
if (haudio->wr_ptr == (AUDIO_TOTAL_BUF_SIZE / 2U))
|
||||
{
|
||||
haudio->rd_enable = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare Out endpoint to receive next audio packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, AUDIOOutEpAdd,
|
||||
&haudio->buffer[haudio->wr_ptr],
|
||||
AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AUDIO_Req_GetCurrent
|
||||
* Handles the GET_CUR Audio control request.
|
||||
* @param pdev: device instance
|
||||
* @param req: setup class request
|
||||
* @retval status
|
||||
*/
|
||||
static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
(void)USBD_memset(haudio->control.data, 0, USB_MAX_EP0_SIZE);
|
||||
|
||||
/* Send the current mute state */
|
||||
(void)USBD_CtlSendData(pdev, haudio->control.data,
|
||||
MIN(req->wLength, USB_MAX_EP0_SIZE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AUDIO_Req_SetCurrent
|
||||
* Handles the SET_CUR Audio control request.
|
||||
* @param pdev: device instance
|
||||
* @param req: setup class request
|
||||
* @retval status
|
||||
*/
|
||||
static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_AUDIO_HandleTypeDef *haudio;
|
||||
haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (haudio == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->wLength != 0U)
|
||||
{
|
||||
haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */
|
||||
haudio->control.len = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); /* Set the request data length */
|
||||
haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */
|
||||
|
||||
/* Prepare the reception of the buffer over EP0 */
|
||||
(void)USBD_CtlPrepareRx(pdev, haudio->control.data, haudio->control.len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_AUDIO_DeviceQualifierDesc);
|
||||
|
||||
return USBD_AUDIO_DeviceQualifierDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @brief USBD_AUDIO_RegisterInterface
|
||||
* @param pdev: device instance
|
||||
* @param fops: Audio interface callback
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_AUDIO_ItfTypeDef *fops)
|
||||
{
|
||||
if (fops == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_AUDIO_GetEpPcktSze
|
||||
* @param pdev: device instance (reserved for future use)
|
||||
* @param If: Interface number (reserved for future use)
|
||||
* @param Ep: Endpoint number (reserved for future use)
|
||||
* @retval status
|
||||
*/
|
||||
uint32_t USBD_AUDIO_GetEpPcktSze(USBD_HandleTypeDef *pdev, uint8_t If, uint8_t Ep)
|
||||
{
|
||||
uint32_t mps;
|
||||
|
||||
UNUSED(pdev);
|
||||
UNUSED(If);
|
||||
UNUSED(Ep);
|
||||
|
||||
mps = AUDIO_PACKET_SZE_WORD(USBD_AUDIO_FREQ);
|
||||
|
||||
/* Return the wMaxPacketSize value in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
|
||||
return mps;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @brief USBD_AUDIO_GetAudioHeaderDesc
|
||||
* This function return the Audio descriptor
|
||||
* @param pdev: device instance
|
||||
* @param pConfDesc: pointer to Bos descriptor
|
||||
* @retval pointer to the Audio AC Header descriptor
|
||||
*/
|
||||
static void *USBD_AUDIO_GetAudioHeaderDesc(uint8_t *pConfDesc)
|
||||
{
|
||||
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
|
||||
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
|
||||
uint8_t *pAudioDesc = NULL;
|
||||
uint16_t ptr;
|
||||
|
||||
if (desc->wTotalLength > desc->bLength)
|
||||
{
|
||||
ptr = desc->bLength;
|
||||
|
||||
while (ptr < desc->wTotalLength)
|
||||
{
|
||||
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
if ((pdesc->bDescriptorType == AUDIO_INTERFACE_DESCRIPTOR_TYPE) &&
|
||||
(pdesc->bDescriptorSubType == AUDIO_CONTROL_HEADER))
|
||||
{
|
||||
pAudioDesc = (uint8_t *)pdesc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pAudioDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief Generic media access Layer.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_audio.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_audio_if_template.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_AUDIO_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options);
|
||||
static int8_t TEMPLATE_DeInit(uint32_t options);
|
||||
static int8_t TEMPLATE_AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd);
|
||||
static int8_t TEMPLATE_VolumeCtl(uint8_t vol);
|
||||
static int8_t TEMPLATE_MuteCtl(uint8_t cmd);
|
||||
static int8_t TEMPLATE_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd);
|
||||
static int8_t TEMPLATE_GetState(void);
|
||||
|
||||
USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops =
|
||||
{
|
||||
TEMPLATE_Init,
|
||||
TEMPLATE_DeInit,
|
||||
TEMPLATE_AudioCmd,
|
||||
TEMPLATE_VolumeCtl,
|
||||
TEMPLATE_MuteCtl,
|
||||
TEMPLATE_PeriodicTC,
|
||||
TEMPLATE_GetState,
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_Init
|
||||
* Initializes the AUDIO media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options)
|
||||
{
|
||||
UNUSED(AudioFreq);
|
||||
UNUSED(Volume);
|
||||
UNUSED(options);
|
||||
|
||||
/*
|
||||
Add your initialization code here
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_DeInit
|
||||
* DeInitializes the AUDIO media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_DeInit(uint32_t options)
|
||||
{
|
||||
UNUSED(options);
|
||||
|
||||
/*
|
||||
Add your deinitialization code here
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_AudioCmd
|
||||
* AUDIO command handler
|
||||
* @param Buf: Buffer of data to be sent
|
||||
* @param size: Number of data to be sent (in bytes)
|
||||
* @param cmd: command opcode
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_AudioCmd(uint8_t *pbuf, uint32_t size, uint8_t cmd)
|
||||
{
|
||||
UNUSED(pbuf);
|
||||
UNUSED(size);
|
||||
UNUSED(cmd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_VolumeCtl
|
||||
* @param vol: volume level (0..100)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_VolumeCtl(uint8_t vol)
|
||||
{
|
||||
UNUSED(vol);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_MuteCtl
|
||||
* @param cmd: vmute command
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_MuteCtl(uint8_t cmd)
|
||||
{
|
||||
UNUSED(cmd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_PeriodicTC
|
||||
* @param cmd
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd)
|
||||
{
|
||||
UNUSED(pbuf);
|
||||
UNUSED(size);
|
||||
UNUSED(cmd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_GetState
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_GetState(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_billboard.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the usbd_billboard.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_BB_H
|
||||
#define __USB_BB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
#include "usbd_desc.h"
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_BB
|
||||
* @brief This file is the Header file for usbd_billboard.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_BB_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define USB_BB_CONFIG_DESC_SIZ 18U
|
||||
|
||||
#ifndef USB_BB_MAX_NUM_ALT_MODE
|
||||
#define USB_BB_MAX_NUM_ALT_MODE 0x2U
|
||||
#endif /* USB_BB_MAX_NUM_ALT_MODE */
|
||||
|
||||
#ifndef USBD_BB_IF_STRING_INDEX
|
||||
#define USBD_BB_IF_STRING_INDEX 0x10U
|
||||
#endif /* USBD_BB_IF_STRING_INDEX */
|
||||
|
||||
|
||||
#define USBD_BILLBOARD_CAPABILITY 0x0DU
|
||||
#define USBD_BILLBOARD_ALTMODE_CAPABILITY 0x0FU
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef struct _BB_DescHeader
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
}
|
||||
USBD_BB_DescHeader_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t wSVID;
|
||||
uint8_t bAlternateMode;
|
||||
uint8_t iAlternateModeString;
|
||||
} USBD_BB_AltModeTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t bIndex;
|
||||
uint32_t dwAlternateModeVdo;
|
||||
} USBD_BB_AltModeCapDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDevCapabilityType;
|
||||
uint8_t iAddtionalInfoURL;
|
||||
uint8_t bNbrOfAltModes;
|
||||
uint8_t bPreferredAltMode;
|
||||
uint16_t VconnPwr;
|
||||
uint8_t bmConfigured[32];
|
||||
uint16_t bcdVersion;
|
||||
uint8_t bAdditionalFailureInfo;
|
||||
uint8_t bReserved;
|
||||
USBD_BB_AltModeTypeDef wSVID[USB_BB_MAX_NUM_ALT_MODE];
|
||||
} USBD_BosBBCapDescTypedef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNSPECIFIED_ERROR = 0,
|
||||
CONFIGURATION_NOT_ATTEMPTED,
|
||||
CONFIGURATION_UNSUCCESSFUL,
|
||||
CONFIGURATION_SUCCESSFUL,
|
||||
} BB_AltModeState;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_BB;
|
||||
#define USBD_BB_CLASS &USBD_BB
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (USBD_CLASS_BOS_ENABLED == 1)
|
||||
void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *buf);
|
||||
void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *buf, uint8_t idx);
|
||||
#endif /* (USBD_CLASS_BOS_ENABLED == 1) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_BB_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+502
@@ -0,0 +1,502 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_billboard.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the high layer firmware functions to manage the
|
||||
* following functionalities of the USB BillBoard Class:
|
||||
* - Initialization and Configuration of high and low layer
|
||||
* - Enumeration as BillBoard Device
|
||||
* - Error management
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* BillBoard Class Description
|
||||
* ===================================================================
|
||||
* This module manages the BillBoard class V1.2.1 following the "Device Class Definition
|
||||
* for BillBoard Devices (BB) Version R1.2.1 Sept 08, 2016".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Device descriptor management
|
||||
* - Configuration descriptor management
|
||||
* - Enumeration as an USB BillBoard device
|
||||
* - Enumeration & management of BillBoard device supported alternate modes
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_billboard.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_BB
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_BB_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_BB_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_BB_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_BB_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev);
|
||||
|
||||
static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length);
|
||||
static uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
|
||||
#if (USBD_CLASS_BOS_ENABLED == 1)
|
||||
USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
|
||||
#endif /* USBD_CLASS_BOS_ENABLED */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_BB_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
USBD_ClassTypeDef USBD_BB =
|
||||
{
|
||||
USBD_BB_Init, /* Init */
|
||||
USBD_BB_DeInit, /* DeInit */
|
||||
USBD_BB_Setup, /* Setup */
|
||||
NULL, /* EP0_TxSent */
|
||||
USBD_BB_EP0_RxReady, /* EP0_RxReady */
|
||||
USBD_BB_DataIn, /* DataIn */
|
||||
USBD_BB_DataOut, /* DataOut */
|
||||
NULL, /* SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
USBD_BB_GetCfgDesc,
|
||||
USBD_BB_GetCfgDesc,
|
||||
USBD_BB_GetOtherSpeedCfgDesc,
|
||||
USBD_BB_GetDeviceQualifierDesc,
|
||||
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
||||
NULL,
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
};
|
||||
|
||||
/* USB Standard Device Qualifier Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_BB_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
||||
{
|
||||
USB_LEN_DEV_QUALIFIER_DESC, /* bLength */
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */
|
||||
0x01, /* bcdUSB */
|
||||
0x20,
|
||||
0x11, /* bDeviceClass */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x01, /* bNumConfigurations */
|
||||
0x00, /* bReserved */
|
||||
};
|
||||
|
||||
/* USB device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_BB_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
USBD_IDX_CONFIG_STR, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
/* 09 */
|
||||
|
||||
/************** Descriptor of BillBoard interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x11, /* bInterfaceClass: billboard */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* nInterfaceProtocol */
|
||||
USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */
|
||||
};
|
||||
|
||||
/* USB device Other Speed Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
|
||||
USB_BB_CONFIG_DESC_SIZ,
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue */
|
||||
USBD_IDX_CONFIG_STR, /* iConfiguration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/************** Descriptor of BillBoard interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x00, /* bNumEndpoints*/
|
||||
0x11, /* bInterfaceClass: billboard */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* nInterfaceProtocol */
|
||||
USBD_BB_IF_STRING_INDEX, /* iInterface: Index of string descriptor */
|
||||
} ;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_BB_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_Init
|
||||
* Initialize the BB interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(cfgidx);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_Init
|
||||
* DeInitialize the BB layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(cfgidx);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_Setup
|
||||
* Handle the BB specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint16_t status_info = 0U;
|
||||
uint16_t AltSetting = 0U;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
break;
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&AltSetting, 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_DataIn
|
||||
* Data sent on non-control IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_DataOut
|
||||
* Data received on non-control Out endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_EP0_RxReady
|
||||
* Handle EP0 Rx Ready event
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_BB_EP0_RxReady(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Prevent unused argument compilation warning */
|
||||
UNUSED(pdev);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_GetCfgDesc
|
||||
* return configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_BB_GetCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_BB_CfgDesc);
|
||||
return USBD_BB_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_GetOtherSpeedCfgDesc
|
||||
* return other speed configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_BB_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_BB_OtherSpeedCfgDesc);
|
||||
return USBD_BB_OtherSpeedCfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_BB_DeviceQualifierDesc);
|
||||
return USBD_BB_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
|
||||
#if (USBD_CLASS_BOS_ENABLED == 1U)
|
||||
/**
|
||||
* @brief USBD_BB_GetNextDesc
|
||||
* This function return the next descriptor header
|
||||
* @param buf: Buffer where the descriptor is available
|
||||
* @param ptr: data pointer inside the descriptor
|
||||
* @retval next header
|
||||
*/
|
||||
USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
|
||||
{
|
||||
USBD_BB_DescHeader_t *pnext = (USBD_BB_DescHeader_t *)(void *)pbuf;
|
||||
|
||||
*ptr += pnext->bLength;
|
||||
pnext = (USBD_BB_DescHeader_t *)(void *)(pbuf + pnext->bLength);
|
||||
|
||||
return (pnext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_GetCapDesc
|
||||
* This function return the Billboard Capability descriptor
|
||||
* @param pdev: device instance
|
||||
* @param pBosDesc: pointer to Bos descriptor
|
||||
* @retval pointer to Billboard Capability descriptor
|
||||
*/
|
||||
void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
|
||||
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
|
||||
USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc;
|
||||
USBD_BosBBCapDescTypedef *pCapDesc = NULL;
|
||||
uint16_t ptr;
|
||||
|
||||
if (desc->wTotalLength > desc->bLength)
|
||||
{
|
||||
ptr = desc->bLength;
|
||||
|
||||
while (ptr < desc->wTotalLength)
|
||||
{
|
||||
pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
|
||||
if (pdesc->bDevCapabilityType == USBD_BILLBOARD_CAPABILITY)
|
||||
{
|
||||
pCapDesc = (USBD_BosBBCapDescTypedef *)(void *)pdesc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (void *)pCapDesc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_BB_GetAltModeDesc
|
||||
* This function return the Billboard Alternate Mode descriptor
|
||||
* @param pdev: device instance
|
||||
* @param pBosDesc: pointer to Bos descriptor
|
||||
* @param idx: Index of requested Alternate Mode descriptor
|
||||
* @retval pointer to Alternate Mode descriptor
|
||||
*/
|
||||
void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_t idx)
|
||||
{
|
||||
UNUSED(pdev);
|
||||
|
||||
USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc;
|
||||
USBD_BosDescTypeDef *desc = (USBD_BosDescTypeDef *)(void *)pBosDesc;
|
||||
USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL;
|
||||
uint8_t cnt = 0U;
|
||||
uint16_t ptr;
|
||||
|
||||
if (desc->wTotalLength > desc->bLength)
|
||||
{
|
||||
ptr = desc->bLength;
|
||||
|
||||
while (ptr < desc->wTotalLength)
|
||||
{
|
||||
pdesc = USBD_BB_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
|
||||
if (pdesc->bDevCapabilityType == USBD_BILLBOARD_ALTMODE_CAPABILITY)
|
||||
{
|
||||
if (cnt == idx)
|
||||
{
|
||||
pAltModDesc = (USBD_BB_AltModeCapDescTypeDef *)(void *)pdesc;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (void *)pAltModDesc;
|
||||
}
|
||||
#endif /* USBD_CLASS_BOS_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,373 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_ccid.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_H
|
||||
#define __USBD_CCID_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_ccid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup usbd_cdc_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef CCID_IN_EP
|
||||
#define CCID_IN_EP 0x81U /* EP1 for data IN */
|
||||
#endif /* CCID_IN_EP */
|
||||
|
||||
#ifndef CCID_OUT_EP
|
||||
#define CCID_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#endif /* CCID_OUT_EP */
|
||||
|
||||
#ifndef CCID_CMD_EP
|
||||
#define CCID_CMD_EP 0x82U /* EP2 for CCID commands */
|
||||
#endif /* CCID_CMD_EP */
|
||||
|
||||
#ifndef CCID_CMD_HS_BINTERVAL
|
||||
#define CCID_CMD_HS_BINTERVAL 0x10U
|
||||
#endif /* CCID_CMD_HS_BINTERVAL */
|
||||
|
||||
#ifndef CCID_CMD_FS_BINTERVAL
|
||||
#define CCID_CMD_FS_BINTERVAL 0x10U
|
||||
#endif /* CCID_CMD_FS_BINTERVAL */
|
||||
|
||||
|
||||
#define CCID_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
|
||||
#define CCID_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
|
||||
#define CCID_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
|
||||
|
||||
#define USB_CCID_CONFIG_DESC_SIZ 93U
|
||||
#define CCID_DATA_HS_IN_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE
|
||||
#define CCID_DATA_HS_OUT_PACKET_SIZE CCID_DATA_HS_MAX_PACKET_SIZE
|
||||
|
||||
#define CCID_DATA_FS_IN_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE
|
||||
#define CCID_DATA_FS_OUT_PACKET_SIZE CCID_DATA_FS_MAX_PACKET_SIZE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* CCID definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define CCID_SEND_ENCAPSULATED_COMMAND 0x00U
|
||||
#define CCID_GET_ENCAPSULATED_RESPONSE 0x01U
|
||||
#define CCID_SET_COMM_FEATURE 0x02U
|
||||
#define CCID_GET_COMM_FEATURE 0x03U
|
||||
#define CCID_CLEAR_COMM_FEATURE 0x04U
|
||||
#define CCID_SET_LINE_CODING 0x20U
|
||||
#define CCID_GET_LINE_CODING 0x21U
|
||||
#define CCID_SET_CONTROL_LINE_STATE 0x22U
|
||||
#define CCID_SEND_BREAK 0x23U
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define REQUEST_ABORT 0x01U
|
||||
#define REQUEST_GET_CLOCK_FREQUENCIES 0x02U
|
||||
#define REQUEST_GET_DATA_RATES 0x03U
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* The Smart Card Device Class Descriptor definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#define CCID_INTERFACE_DESC_SIZE 0x09U
|
||||
#define USB_DEVICE_CLASS_CCID 0x0BU
|
||||
#define CCID_CLASS_DESC_SIZE 0x36U
|
||||
#define CCID_DESC_TYPE 0x21U
|
||||
|
||||
#ifndef CCID_VOLTAGE_SUPP
|
||||
#define CCID_VOLTAGE_SUPP 0x07U
|
||||
#endif /* CCID_VOLTAGE_SUPP */
|
||||
#ifndef USBD_CCID_PROTOCOL
|
||||
#define USBD_CCID_PROTOCOL 0x03U
|
||||
#endif /* USBD_CCID_PROTOCOL */
|
||||
#ifndef USBD_CCID_DEFAULT_CLOCK_FREQ
|
||||
#define USBD_CCID_DEFAULT_CLOCK_FREQ 3600U
|
||||
#endif /* USBD_CCID_DEFAULT_CLOCK_FREQ */
|
||||
#ifndef USBD_CCID_MAX_CLOCK_FREQ
|
||||
#define USBD_CCID_MAX_CLOCK_FREQ USBD_CCID_DEFAULT_CLOCK_FREQ
|
||||
#endif /* USBD_CCID_MAX_CLOCK_FREQ */
|
||||
#ifndef USBD_CCID_DEFAULT_DATA_RATE
|
||||
#define USBD_CCID_DEFAULT_DATA_RATE 9677U
|
||||
#endif /* USBD_CCID_DEFAULT_DATA_RATE */
|
||||
#ifndef USBD_CCID_MAX_DATA_RATE
|
||||
#define USBD_CCID_MAX_DATA_RATE USBD_CCID_DEFAULT_DATA_RATE
|
||||
#endif /* USBD_CCID_MAX_DATA_RATE */
|
||||
#ifndef USBD_CCID_MAX_INF_FIELD_SIZE
|
||||
#define USBD_CCID_MAX_INF_FIELD_SIZE 254U
|
||||
#endif /* USBD_CCID_MAX_INF_FIELD_SIZE */
|
||||
#ifndef CCID_MAX_BLOCK_SIZE_HEADER
|
||||
#define CCID_MAX_BLOCK_SIZE_HEADER 271U
|
||||
#endif /* CCID_MAX_BLOCK_SIZE_HEADER */
|
||||
|
||||
#define TPDU_EXCHANGE 0x01U
|
||||
#define SHORT_APDU_EXCHANGE 0x02U
|
||||
#define EXTENDED_APDU_EXCHANGE 0x04U
|
||||
#define CHARACTER_EXCHANGE 0x00U
|
||||
|
||||
#ifndef EXCHANGE_LEVEL_FEATURE
|
||||
#define EXCHANGE_LEVEL_FEATURE TPDU_EXCHANGE
|
||||
#endif /* EXCHANGE_LEVEL_FEATURE */
|
||||
|
||||
#define CCID_ENDPOINT_DESC_SIZE 0x07U
|
||||
|
||||
#ifndef CCID_EP0_BUFF_SIZ
|
||||
#define CCID_EP0_BUFF_SIZ 64U
|
||||
#endif /* CCID_EP0_BUFF_SIZ */
|
||||
|
||||
#ifndef CCID_BULK_EPIN_SIZE
|
||||
#define CCID_BULK_EPIN_SIZE 64U
|
||||
#endif /* CCID_BULK_EPIN_SIZE */
|
||||
|
||||
#define CCID_INT_BUFF_SIZ 2U
|
||||
/*---------------------------------------------------------------------*/
|
||||
/*
|
||||
* CCID Class specification revision 1.1
|
||||
* Command Pipe. Bulk Messages
|
||||
*/
|
||||
|
||||
/* CCID Bulk Out Command definitions */
|
||||
#define PC_TO_RDR_ICCPOWERON 0x62U
|
||||
#define PC_TO_RDR_ICCPOWEROFF 0x63U
|
||||
#define PC_TO_RDR_GETSLOTSTATUS 0x65U
|
||||
#define PC_TO_RDR_XFRBLOCK 0x6FU
|
||||
#define PC_TO_RDR_GETPARAMETERS 0x6CU
|
||||
#define PC_TO_RDR_RESETPARAMETERS 0x6DU
|
||||
#define PC_TO_RDR_SETPARAMETERS 0x61U
|
||||
#define PC_TO_RDR_ESCAPE 0x6BU
|
||||
#define PC_TO_RDR_ICCCLOCK 0x6EU
|
||||
#define PC_TO_RDR_T0APDU 0x6AU
|
||||
#define PC_TO_RDR_SECURE 0x69U
|
||||
#define PC_TO_RDR_MECHANICAL 0x71U
|
||||
#define PC_TO_RDR_ABORT 0x72U
|
||||
#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73U
|
||||
|
||||
/* CCID Bulk In Command definitions */
|
||||
#define RDR_TO_PC_DATABLOCK 0x80U
|
||||
#define RDR_TO_PC_SLOTSTATUS 0x81U
|
||||
#define RDR_TO_PC_PARAMETERS 0x82U
|
||||
#define RDR_TO_PC_ESCAPE 0x83U
|
||||
#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY 0x84U
|
||||
|
||||
/* CCID Interrupt In Command definitions */
|
||||
#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50U
|
||||
#define RDR_TO_PC_HARDWAREERROR 0x51U
|
||||
|
||||
/* Bulk-only Command Block Wrapper */
|
||||
#define ABDATA_SIZE 261U
|
||||
#define CCID_CMD_HEADER_SIZE 10U
|
||||
#define CCID_RESPONSE_HEADER_SIZE 10U
|
||||
|
||||
/* Number of SLOTS. For single card, this value is 1 */
|
||||
#define CCID_NUMBER_OF_SLOTS 1U
|
||||
|
||||
#define CARD_SLOT_FITTED 1U
|
||||
#define CARD_SLOT_REMOVED 0U
|
||||
|
||||
#define OFFSET_INT_BMESSAGETYPE 0x00U
|
||||
#define OFFSET_INT_BMSLOTICCSTATE 0x01U
|
||||
#define SLOT_ICC_PRESENT 0x01U
|
||||
/* LSb : (0b = no ICC present, 1b = ICC present) */
|
||||
#define SLOT_ICC_CHANGE 0x02U
|
||||
/* MSb : (0b = no change, 1b = change) */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t bitrate;
|
||||
uint8_t format;
|
||||
uint8_t paritytype;
|
||||
uint8_t datatype;
|
||||
} USBD_CCID_LineCodingTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bMessageType; /* Offset = 0*/
|
||||
uint32_t dwLength; /* Offset = 1, The length field (dwLength) is the length
|
||||
of the message not including the 10-byte header.*/
|
||||
uint8_t bSlot; /* Offset = 5*/
|
||||
uint8_t bSeq; /* Offset = 6*/
|
||||
uint8_t bSpecific_0; /* Offset = 7*/
|
||||
uint8_t bSpecific_1; /* Offset = 8*/
|
||||
uint8_t bSpecific_2; /* Offset = 9*/
|
||||
uint8_t abData [ABDATA_SIZE]; /* Offset = 10, For reference, the absolute
|
||||
maximum block size for a TPDU T=0 block is 260 bytes
|
||||
(5 bytes command; 255 bytes data),
|
||||
or for a TPDU T=1 block is 259 bytes,
|
||||
or for a short APDU T=1 block is 261 bytes,
|
||||
or for an extended APDU T=1 block is 65544 bytes.*/
|
||||
} __PACKED USBD_CCID_BulkOut_DataTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bMessageType; /* Offset = 0 */
|
||||
uint32_t dwLength; /* Offset = 1 */
|
||||
uint8_t bSlot; /* Offset = 5, Same as Bulk-OUT message */
|
||||
uint8_t bSeq; /* Offset = 6, Same as Bulk-OUT message */
|
||||
uint8_t bStatus; /* Offset = 7, Slot status as defined in section 6.2.6 */
|
||||
uint8_t bError; /* Offset = 8, Slot error as defined in section 6.2.6 */
|
||||
uint8_t bSpecific; /* Offset = 9 */
|
||||
uint8_t abData[ABDATA_SIZE]; /* Offset = 10 */
|
||||
uint16_t u16SizeToSend;
|
||||
} __PACKED USBD_CCID_BulkIn_DataTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t SlotStatus;
|
||||
__IO uint8_t SlotStatusChange;
|
||||
} USBD_CCID_SlotStatusTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t bAbortRequestFlag;
|
||||
__IO uint8_t bSeq;
|
||||
__IO uint8_t bSlot;
|
||||
} USBD_CCID_ParamTypeDef;
|
||||
|
||||
/*
|
||||
* CCID Class specification revision 1.1
|
||||
* Smart Card Device Class Descriptor Table
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdCCID;
|
||||
uint8_t bMaxSlotIndex;
|
||||
uint8_t bVoltageSupport;
|
||||
uint32_t dwProtocols;
|
||||
uint32_t dwDefaultClock;
|
||||
uint32_t dwMaximumClock;
|
||||
uint8_t bNumClockSupported;
|
||||
uint32_t dwDataRate;
|
||||
uint32_t dwMaxDataRate;
|
||||
uint8_t bNumDataRatesSupported;
|
||||
uint32_t dwMaxIFSD;
|
||||
uint32_t dwSynchProtocols;
|
||||
uint32_t dwMechanical;
|
||||
uint32_t dwFeatures;
|
||||
uint32_t dwMaxCCIDMessageLength;
|
||||
uint8_t bClassGetResponse;
|
||||
uint8_t bClassEnvelope;
|
||||
uint16_t wLcdLayout;
|
||||
uint8_t bPINSupport;
|
||||
uint8_t bMaxCCIDBusySlots;
|
||||
} __PACKED USBD_CCID_DescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t data[CCID_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */
|
||||
uint32_t UsbMessageLength;
|
||||
uint8_t UsbIntData[CCID_CMD_PACKET_SIZE]; /* Buffer for the Interrupt In Data */
|
||||
uint32_t alt_setting;
|
||||
|
||||
USBD_CCID_BulkIn_DataTypeDef UsbBlkInData; /* Buffer for the Out Data */
|
||||
USBD_CCID_BulkOut_DataTypeDef UsbBlkOutData; /* Buffer for the In Data */
|
||||
USBD_CCID_SlotStatusTypeDef SlotStatus;
|
||||
USBD_CCID_ParamTypeDef USBD_CCID_Param;
|
||||
|
||||
__IO uint32_t MaxPcktLen;
|
||||
__IO uint8_t blkt_state; /* Bulk transfer state */
|
||||
|
||||
uint16_t slot_nb;
|
||||
uint16_t seq_nb;
|
||||
} USBD_CCID_HandleTypeDef;
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CCID;
|
||||
#define USBD_CCID_CLASS &USBD_CCID
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
typedef struct _USBD_CCID_Itf
|
||||
{
|
||||
uint8_t (* Init)(USBD_HandleTypeDef *pdev);
|
||||
uint8_t (* DeInit)(USBD_HandleTypeDef *pdev);
|
||||
uint8_t (* Control)(uint8_t req, uint8_t *pbuf, uint16_t *length);
|
||||
uint8_t (* Response_SendData)(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len);
|
||||
uint8_t (* Send_Process)(uint8_t *Command, uint8_t *Data);
|
||||
uint8_t (* SetSlotStatus)(USBD_HandleTypeDef *pdev);
|
||||
} USBD_CCID_ItfTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CCID_ItfTypeDef *fops);
|
||||
|
||||
uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CCID_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_cmd.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_ccid_cmd.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_CMD_H
|
||||
#define __USBD_CCID_CMD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#ifndef __USBD_CCID_IF_H
|
||||
#include "usbd_ccid_if_template.h"
|
||||
#endif /* __USBD_CCID_IF_H */
|
||||
|
||||
#ifndef __USBD_CCID_SC_IF_H
|
||||
#include "usbd_ccid_sc_if_template.h"
|
||||
#endif /* __USBD_CCID_SC_IF_H */
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* ERROR CODES for USB Bulk In Messages : bError */
|
||||
/******************************************************************************/
|
||||
|
||||
#define SLOT_NO_ERROR 0x81U
|
||||
#define SLOTERROR_UNKNOWN 0x82U
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Index of not supported / incorrect message parameter : 7Fh to 01h */
|
||||
/* These Values are used for Return Types between Firmware Layers */
|
||||
/*
|
||||
Failure of a command
|
||||
The CCID cannot parse one parameter or the ICC is not supporting one parameter.
|
||||
Then the Slot Error register contains the index of the first bad parameter as a
|
||||
positive number (1-127). For instance, if the CCID receives an ICC command to
|
||||
an unimplemented slot, then the Slot Error register shall be set to 5 (index of bSlot field) */
|
||||
|
||||
/*
|
||||
* CCID Class specification revision 1.1
|
||||
*/
|
||||
|
||||
/* Following Parameters used in PC_to_RDR_XfrBlock */
|
||||
#define SLOTERROR_BAD_LENTGH 0x01U
|
||||
#define SLOTERROR_BAD_SLOT 0x05U
|
||||
#define SLOTERROR_BAD_POWERSELECT 0x07U
|
||||
#define SLOTERROR_BAD_PROTOCOLNUM 0x07U
|
||||
#define SLOTERROR_BAD_CLOCKCOMMAND 0x07U
|
||||
#define SLOTERROR_BAD_ABRFU_3B 0x07U
|
||||
#define SLOTERROR_BAD_BMCHANGES 0x07U
|
||||
#define SLOTERROR_BAD_BFUNCTION_MECHANICAL 0x07U
|
||||
#define SLOTERROR_BAD_ABRFU_2B 0x08U
|
||||
#define SLOTERROR_BAD_LEVELPARAMETER 0x08U
|
||||
#define SLOTERROR_BAD_FIDI 0x0AU
|
||||
#define SLOTERROR_BAD_T01CONVCHECKSUM 0x0BU
|
||||
#define SLOTERROR_BAD_GUARDTIME 0x0CU
|
||||
#define SLOTERROR_BAD_WAITINGINTEGER 0x0DU
|
||||
#define SLOTERROR_BAD_CLOCKSTOP 0x0EU
|
||||
#define SLOTERROR_BAD_IFSC 0x0FU
|
||||
#define SLOTERROR_BAD_NAD 0x10U
|
||||
#define SLOTERROR_BAD_DWLENGTH 0x08U
|
||||
|
||||
|
||||
/*---------- Table 6.2-2 Slot error register when bmCommandStatus = 1 */
|
||||
#define SLOTERROR_CMD_ABORTED 0xFFU
|
||||
#define SLOTERROR_ICC_MUTE 0xFEU
|
||||
#define SLOTERROR_XFR_PARITY_ERROR 0xFDU
|
||||
#define SLOTERROR_XFR_OVERRUN 0xFCU
|
||||
#define SLOTERROR_HW_ERROR 0xFBU
|
||||
#define SLOTERROR_BAD_ATR_TS 0xF8U
|
||||
#define SLOTERROR_BAD_ATR_TCK 0xF7U
|
||||
#define SLOTERROR_ICC_PROTOCOL_NOT_SUPPORTED 0xF6U
|
||||
#define SLOTERROR_ICC_CLASS_NOT_SUPPORTED 0xF5U
|
||||
#define SLOTERROR_PROCEDURE_BYTE_CONFLICT 0xF4U
|
||||
#define SLOTERROR_DEACTIVATED_PROTOCOL 0xF3U
|
||||
#define SLOTERROR_BUSY_WITH_AUTO_SEQUENCE 0xF2U
|
||||
#define SLOTERROR_PIN_TIMEOUT 0xF0U
|
||||
#define SLOTERROR_PIN_CANCELLED 0xEFU
|
||||
#define SLOTERROR_CMD_SLOT_BUSY 0xE0U
|
||||
#define SLOTERROR_CMD_NOT_SUPPORTED 0x00U
|
||||
|
||||
/* Following Parameters used in PC_to_RDR_ResetParameters */
|
||||
/* DEFAULT_FIDI_VALUE */
|
||||
#ifndef DEFAULT_FIDI
|
||||
#define DEFAULT_FIDI 0x11U
|
||||
#endif /* DEFAULT_FIDI */
|
||||
#ifndef DEFAULT_T01CONVCHECKSUM
|
||||
#define DEFAULT_T01CONVCHECKSUM 0x00U
|
||||
#endif /* DEFAULT_T01CONVCHECKSUM */
|
||||
#ifndef DEFAULT_EXTRA_GUARDTIME
|
||||
#define DEFAULT_EXTRA_GUARDTIME 0x00U
|
||||
#endif /* DEFAULT_EXTRA_GUARDTIME */
|
||||
#ifndef DEFAULT_WAITINGINTEGER
|
||||
#define DEFAULT_WAITINGINTEGER 0x0AU
|
||||
#endif /* DEFAULT_WAITINGINTEGER */
|
||||
#ifndef DEFAULT_CLOCKSTOP
|
||||
#define DEFAULT_CLOCKSTOP 0x00U
|
||||
#endif /* DEFAULT_CLOCKSTOP */
|
||||
#ifndef DEFAULT_IFSC
|
||||
#define DEFAULT_IFSC 0x20U
|
||||
#endif /* DEFAULT_IFSC */
|
||||
#ifndef DEFAULT_NAD
|
||||
#define DEFAULT_NAD 0x00U
|
||||
#endif /* DEFAULT_NAD */
|
||||
|
||||
/* Following Parameters used in PC_to_RDR_IccPowerOn */
|
||||
#define VOLTAGE_SELECTION_AUTOMATIC 0xFFU
|
||||
#define VOLTAGE_SELECTION_3V 0x02U
|
||||
#define VOLTAGE_SELECTION_5V 0x01U
|
||||
#define VOLTAGE_SELECTION_1V8 0x03U
|
||||
|
||||
/*
|
||||
Offset=0 bmICCStatus 2 bit 0, 1, 2
|
||||
0 - An ICC is present and active (power is on and stable, RST is inactive)
|
||||
1 - An ICC is present and inactive (not activated or shut down by hardware error)
|
||||
2 - No ICC is present
|
||||
3 - RFU
|
||||
Offset=0 bmRFU 4 bits 0 RFU
|
||||
Offset=6 bmCommandStatus 2 bits 0, 1, 2
|
||||
0 - Processed without error
|
||||
1 - Failed (error code provided by the error register)
|
||||
2 - Time Extension is requested
|
||||
3 - RFU
|
||||
*/
|
||||
|
||||
#define BM_ICC_PRESENT_ACTIVE 0x00U
|
||||
#define BM_ICC_PRESENT_INACTIVE 0x01U
|
||||
#define BM_ICC_NO_ICC_PRESENT 0x02U
|
||||
|
||||
#define BM_COMMAND_STATUS_OFFSET 0x06U
|
||||
#define BM_COMMAND_STATUS_NO_ERROR 0x00U
|
||||
#define BM_COMMAND_STATUS_FAILED (0x01U << BM_COMMAND_STATUS_OFFSET)
|
||||
#define BM_COMMAND_STATUS_TIME_EXTN (0x02 << BM_COMMAND_STATUS_OFFSET)
|
||||
|
||||
|
||||
#if (ATR_T01 == 0)
|
||||
#define SIZE_OF_ATR 19U
|
||||
#else
|
||||
#define SIZE_OF_ATR 15U
|
||||
#endif /* (ATR_T01 == 0) */
|
||||
|
||||
/* defines for the CCID_CMD Layers */
|
||||
#define LEN_PROTOCOL_STRUCT_T0 5U
|
||||
#define LEN_PROTOCOL_STRUCT_T1 7U
|
||||
|
||||
#define BPROTOCOL_NUM_T0 0U
|
||||
#define BPROTOCOL_NUM_T1 1U
|
||||
|
||||
/************************************************************************************/
|
||||
/* ERROR CODES for RDR_TO_PC_HARDWAREERROR Message : bHardwareErrorCode */
|
||||
/************************************************************************************/
|
||||
|
||||
#define HARDWAREERRORCODE_OVERCURRENT 0x01U
|
||||
#define HARDWAREERRORCODE_VOLTAGEERROR 0x02U
|
||||
#define HARDWAREERRORCODE_OVERCURRENT_IT 0x04U
|
||||
#define HARDWAREERRORCODE_VOLTAGEERROR_IT 0x08U
|
||||
|
||||
|
||||
|
||||
#define CHK_PARAM_SLOT 0x01U
|
||||
#define CHK_PARAM_DWLENGTH 0x02U
|
||||
#define CHK_PARAM_ABRFU2 0x04U
|
||||
#define CHK_PARAM_ABRFU3 0x08U
|
||||
#define CHK_PARAM_CARD_PRESENT 0x10U
|
||||
#define CHK_PARAM_ABORT 0x20U
|
||||
#define CHK_ACTIVE_STATE 0x40U
|
||||
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
uint8_t PC_to_RDR_IccPowerOn(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_IccPowerOff(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_GetSlotStatus(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_XfrBlock(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_GetParameters(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_ResetParameters(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_SetParameters(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_Escape(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_IccClock(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_to_RDR_Abort(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_TO_RDR_T0Apdu(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_TO_RDR_Mechanical(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_TO_RDR_SetDataRateAndClockFrequency(USBD_HandleTypeDef *pdev);
|
||||
uint8_t PC_TO_RDR_Secure(USBD_HandleTypeDef *pdev);
|
||||
|
||||
void RDR_to_PC_DataBlock(uint8_t errorCode, USBD_HandleTypeDef *pdev);
|
||||
void RDR_to_PC_NotifySlotChange(USBD_HandleTypeDef *pdev);
|
||||
void RDR_to_PC_SlotStatus(uint8_t errorCode, USBD_HandleTypeDef *pdev);
|
||||
void RDR_to_PC_Parameters(uint8_t errorCode, USBD_HandleTypeDef *pdev);
|
||||
void RDR_to_PC_Escape(uint8_t errorCode, USBD_HandleTypeDef *pdev);
|
||||
void RDR_to_PC_DataRateAndClockFrequency(uint8_t errorCode, USBD_HandleTypeDef *pdev);
|
||||
|
||||
void CCID_UpdSlotStatus(USBD_HandleTypeDef *pdev, uint8_t slotStatus);
|
||||
void CCID_UpdSlotChange(USBD_HandleTypeDef *pdev, uint8_t changeStatus);
|
||||
uint8_t CCID_IsSlotStatusChange(USBD_HandleTypeDef *pdev);
|
||||
uint8_t CCID_CmdAbort(USBD_HandleTypeDef *pdev, uint8_t slot, uint8_t seq);
|
||||
uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *dataPointer, uint16_t dataLen);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CCID_CMD_H */
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_ccid_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_IF_TEMPLATE_H
|
||||
#define __USBD_CCID_IF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid.h"
|
||||
#include "usbd_ccid_cmd.h"
|
||||
|
||||
#ifndef __USBD_CCID_SMARTCARD_H
|
||||
#include "usbd_ccid_smartcard_template.h"
|
||||
#endif /* __USBD_CCID_SMARTCARD_H */
|
||||
|
||||
/* Exported defines ----------------------------------------------------------*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** CCID Bulk Transfer State machine ********************/
|
||||
/*****************************************************************************/
|
||||
#define CCID_STATE_IDLE 0U
|
||||
#define CCID_STATE_DATA_OUT 1U
|
||||
#define CCID_STATE_RECEIVE_DATA 2U
|
||||
#define CCID_STATE_SEND_RESP 3U
|
||||
#define CCID_STATE_DATAIN 4U
|
||||
#define CCID_STATE_UNCORRECT_LENGTH 5U
|
||||
|
||||
#define DIR_IN 0U
|
||||
#define DIR_OUT 1U
|
||||
#define BOTH_DIR 2U
|
||||
|
||||
/************ Value of the Interrupt transfer status to set ******************/
|
||||
#define INTRSTATUS_COMPLETE 1U
|
||||
#define INTRSTATUS_RESET 0U
|
||||
/************** slot change status *******************************************/
|
||||
#define SLOTSTATUS_CHANGED 1U
|
||||
#define SLOTSTATUS_RESET 0U
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
extern USBD_HandleTypeDef USBD_Device;
|
||||
|
||||
/* CCID Interface callback */
|
||||
extern USBD_CCID_ItfTypeDef USBD_CCID_If_fops;
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CCID_IF_TEMPLATE_H */
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_sc_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_ccid_sc_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_SC_IF_TEMPLATE_H
|
||||
#define __USBD_CCID_SC_IF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid.h"
|
||||
#include "usbd_ccid_cmd.h"
|
||||
|
||||
#ifndef __USBD_CCID_SMARTCARD_H
|
||||
#include "usbd_ccid_smartcard_template.h"
|
||||
#endif /* __USBD_CCID_SMARTCARD_H */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t voltage; /* Voltage for the Card Already Selected */
|
||||
uint8_t USART_GuardTime;
|
||||
uint8_t SC_A2R_FiDi;
|
||||
uint8_t SC_hostFiDi;
|
||||
uint8_t USART_DefaultGuardTime;
|
||||
uint32_t USART_BaudRate;
|
||||
} SC_Param_t;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmFindexDindex;
|
||||
uint8_t bmTCCKST0;
|
||||
uint8_t bGuardTimeT0;
|
||||
uint8_t bWaitingIntegerT0;
|
||||
uint8_t bClockStop;
|
||||
uint8_t bIfsc;
|
||||
uint8_t bNad;
|
||||
} Protocol_01_DataTypeDef;
|
||||
#pragma pack()
|
||||
|
||||
extern Protocol_01_DataTypeDef ProtocolData;
|
||||
extern SC_Param_t SC_Param;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#define MAX_EXTRA_GUARD_TIME (0xFF - DEFAULT_EXTRA_GUARDTIME)
|
||||
|
||||
/* Following macros are used for SC_XferBlock command */
|
||||
#define XFER_BLK_SEND_DATA 1U /* Command is for issuing the data */
|
||||
#define XFER_BLK_RECEIVE_DATA 2U /* Command is for receiving the data */
|
||||
#define XFER_BLK_NO_DATA 3U /* Command type is No data exchange */
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/* APPLICATION LAYER ---------------------------------------------------------*/
|
||||
void SC_Itf_InitParams(void);
|
||||
void SC_Itf_IccPowerOn(uint8_t voltage);
|
||||
void SC_Itf_IccPowerOff(void);
|
||||
uint8_t SC_GetState(void);
|
||||
uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen,
|
||||
uint16_t expectedLen,
|
||||
USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data);
|
||||
|
||||
uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01);
|
||||
uint8_t SC_Itf_Escape(uint8_t *escapePtr, uint32_t escapeLen,
|
||||
uint8_t *responseBuff, uint32_t *responseLen);
|
||||
|
||||
uint8_t SC_Itf_SetClock(uint8_t bClockCommand);
|
||||
uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse,
|
||||
uint8_t bClassEnvelope);
|
||||
|
||||
uint8_t SC_Itf_Mechanical(uint8_t bFunction);
|
||||
uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency,
|
||||
uint32_t dwDataRate);
|
||||
|
||||
uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter,
|
||||
uint8_t *pbuf, uint32_t *returnLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CCID_SC_IF_TEMPLATE_H */
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_smartcard_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_ccid_smartcard_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CCID_SMARTCARD_TEMPLATE_H
|
||||
#define __USBD_CCID_SMARTCARD_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#ifndef __USBD_CCID_IF_H
|
||||
#include "usbd_ccid_if_template.h"
|
||||
#endif /* __USBD_CCID_IF_H */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define T0_PROTOCOL 0x00U /* T0 protocol */
|
||||
#define T1_PROTOCOL 0x01U /* T1 protocol */
|
||||
#define DIRECT 0x3BU /* Direct bit convention */
|
||||
#define INDIRECT 0x3FU /* Indirect bit convention */
|
||||
#define SETUP_LENGTH 20U
|
||||
#define HIST_LENGTH 20U
|
||||
|
||||
#define SC_TRANSMIT_TIMEOUT 200U /* Direction to transmit */
|
||||
#define MAX_PROTOCOLLEVEL 7U /* Maximum levels of protocol */
|
||||
#define MAX_INTERFACEBYTE 4U /* Maximum number of interface bytes per protocol */
|
||||
#define LC_MAX 24U
|
||||
#define SC_RECEIVE_TIMEOUT 0x8000U /* Direction to reader */
|
||||
|
||||
/* T=1 protocol constants */
|
||||
#define T1_I_BLOCK 0x00U /* PCB (I-block: b8 = 0) */
|
||||
#define T1_R_BLOCK 0x80U /* PCB (R-block: b8 b7 = 10) */
|
||||
#define T1_S_BLOCK 0xC0U /* PCB (S-block: b8 b7 = 11) */
|
||||
|
||||
/* I block */
|
||||
#define T1_I_SEQ_SHIFT 6U /* N(S) position (bit 7) */
|
||||
|
||||
/* R block */
|
||||
#define T1_IS_ERROR(pcb) ((pcb) & 0x0FU)
|
||||
#define T1_EDC_ERROR 0x01U /* [b6..b1] = 0-N(R)-0001 */
|
||||
#define T1_OTHER_ERROR 0x02U /* [b6..b1] = 0-N(R)-0010 */
|
||||
#define T1_R_SEQ_SHIFT 4U /* N(R) position (b5) */
|
||||
|
||||
/* S block */
|
||||
#define T1_S_RESPONSE 0x20U /* If response: set bit b6, if request reset b6 in PCB S-Block */
|
||||
#define T1_S_RESYNC 0x00U /* RESYNCH: b6->b1: 000000 of PCB S-Block */
|
||||
#define T1_S_IFS 0x01U /* IFS: b6->b1: 000001 of PCB S-Block */
|
||||
#define T1_S_ABORT 0x02U /* ABORT: b6->b1: 000010 of PCB S-Block */
|
||||
#define T1_S_WTX 0x03U /* WTX: b6->b1: 000011 of PCB S-Block */
|
||||
|
||||
#define NAD 0U /* NAD byte position in the block */
|
||||
#define PCB 1U /* PCB byte position in the block */
|
||||
#define LEN 2U /* LEN byte position in the block */
|
||||
#define DATA 3U /* The position of the first byte of INF field in the block */
|
||||
|
||||
/* Modifiable parameters */
|
||||
#define SAD 0x0U /* Source address: reader (allowed values 0 -> 7) */
|
||||
#define DAD 0x0U /* Destination address: card (allowed values 0 -> 7) */
|
||||
#define IFSD_VALUE 254U /* Max length of INF field Supported by the reader */
|
||||
#define SC_FILE_SIZE 0x100U /* File size */
|
||||
#define SC_FILE_ID 0x0001U /* File identifier */
|
||||
#define SC_CLASS 0x00U
|
||||
|
||||
/* Constant parameters */
|
||||
#define INS_SELECT_FILE 0xA4U /* Select file instruction */
|
||||
#define INS_READ_FILE 0xB0U /* Read file instruction */
|
||||
#define INS_WRITE_FILE 0xD6U /* Write file instruction */
|
||||
#define TRAILER_LENGTH 2U /* Trailer length (SW1 and SW2: 2 bytes) */
|
||||
|
||||
#define SC_T1_RECEIVE_SUCCESS 0U
|
||||
#define SC_T1_BWT_TIMEOUT 1U
|
||||
#define SC_T1_CWT_TIMEOUT 2U
|
||||
|
||||
#define DEFAULT_FIDI_VALUE 0x11U
|
||||
#define PPS_REQUEST 0xFFU
|
||||
|
||||
/* SC Tree Structure -----------------------------------------------------------
|
||||
MasterFile
|
||||
________|___________
|
||||
| | |
|
||||
System UserData Note
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* SC ADPU Command: Operation Code -------------------------------------------*/
|
||||
#define SC_CLA_NAME 0x00U
|
||||
|
||||
/*------------------------ Data Area Management Commands ---------------------*/
|
||||
#define SC_SELECT_FILE 0xA4U
|
||||
#define SC_GET_RESPONCE 0xC0U
|
||||
#define SC_STATUS 0xF2U
|
||||
#define SC_UPDATE_BINARY 0xD6U
|
||||
#define SC_READ_BINARY 0xB0U
|
||||
#define SC_WRITE_BINARY 0xD0U
|
||||
#define SC_UPDATE_RECORD 0xDCU
|
||||
#define SC_READ_RECORD 0xB2U
|
||||
|
||||
/*-------------------------- Administrative Commands -------------------------*/
|
||||
#define SC_CREATE_FILE 0xE0U
|
||||
|
||||
/*-------------------------- Safety Management Commands ----------------------*/
|
||||
#define SC_VERIFY 0x20U
|
||||
#define SC_CHANGE 0x24U
|
||||
#define SC_DISABLE 0x26U
|
||||
#define SC_ENABLE 0x28U
|
||||
#define SC_UNBLOCK 0x2CU
|
||||
#define SC_EXTERNAL_AUTH 0x82U
|
||||
#define SC_GET_CHALLENGE 0x84U
|
||||
|
||||
/*-------------------------- Smartcard Interface Byte-------------------------*/
|
||||
#define SC_INTERFACEBYTE_TA 0U /* Interface byte TA(i) */
|
||||
#define SC_INTERFACEBYTE_TB 1U /* Interface byte TB(i) */
|
||||
#define SC_INTERFACEBYTE_TC 2U /* Interface byte TC(i) */
|
||||
#define SC_INTERFACEBYTE_TD 3U /* Interface byte TD(i) */
|
||||
|
||||
/*-------------------------- Answer to reset Commands ------------------------*/
|
||||
#define SC_GET_A2R 0x00U
|
||||
|
||||
/* SC STATUS: Status Code ----------------------------------------------------*/
|
||||
#define SC_EF_SELECTED 0x9FU
|
||||
#define SC_DF_SELECTED 0x9FU
|
||||
#define SC_OP_TERMINATED 0x9000U
|
||||
|
||||
/* Smartcard Voltage */
|
||||
#define SC_VOLTAGE_5V 0x00U
|
||||
#define SC_VOLTAGE_3V 0x01U
|
||||
#define SC_VOLTAGE_NOINIT 0xFFU
|
||||
/*----------------- ATR Protocole supported ----------------------------------*/
|
||||
#define ATR_T01 0x00U
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
SC_POWER_ON = 0x00,
|
||||
SC_RESET_LOW = 0x01,
|
||||
SC_RESET_HIGH = 0x02,
|
||||
SC_ACTIVE = 0x03,
|
||||
SC_ACTIVE_ON_T0 = 0x04,
|
||||
SC_ACTIVE_ON_T1 = 0x05,
|
||||
SC_POWER_OFF = 0x06,
|
||||
SC_NO_INIT = 0x07
|
||||
|
||||
} SC_State;
|
||||
|
||||
/* Interface Byte structure - TA(i), TB(i), TC(i) and TD(i) ------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Status; /* The Presence of the Interface byte */
|
||||
uint8_t Value; /* The Value of the Interface byte */
|
||||
} SC_InterfaceByteTypeDef;
|
||||
|
||||
/* Protocol Level structure - ------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
SC_InterfaceByteTypeDef InterfaceByte[MAX_INTERFACEBYTE]; /* The Values of the Interface byte
|
||||
TA(i), TB(i), TC(i)and TD(i) */
|
||||
} SC_ProtocolLevelTypeDef;
|
||||
|
||||
/* ATR structure - Answer To Reset -------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t TS; /* Bit Convention Direct/Indirect */
|
||||
uint8_t T0; /* Each bit in the high nibble = Presence of the further interface byte;
|
||||
Low nibble = Number of historical byte */
|
||||
SC_ProtocolLevelTypeDef T[MAX_PROTOCOLLEVEL]; /* Setup array */
|
||||
uint8_t Historical[HIST_LENGTH]; /* Historical array */
|
||||
uint8_t Tlength; /* Setup array dimension */
|
||||
uint8_t Hlength; /* Historical array dimension */
|
||||
uint8_t TCK;
|
||||
} SC_ATRTypeDef;
|
||||
|
||||
/* ADPU-Header command structure ---------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t CLA; /* Command class */
|
||||
uint8_t INS; /* Operation code */
|
||||
uint8_t P1; /* Selection Mode */
|
||||
uint8_t P2; /* Selection Option */
|
||||
} SC_HeaderTypeDef;
|
||||
|
||||
/* ADPU-Body command structure -----------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t LC; /* Data field length */
|
||||
uint8_t Data[LC_MAX]; /* Command parameters */
|
||||
uint8_t LE; /* Expected length of data to be returned */
|
||||
} SC_BodyTypeDef;
|
||||
|
||||
/* ADPU Command structure ----------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
SC_HeaderTypeDef Header;
|
||||
SC_BodyTypeDef Body;
|
||||
} SC_ADPU_CommandsTypeDef;
|
||||
|
||||
/* SC response structure -----------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Data[LC_MAX]; /* Data returned from the card */
|
||||
uint8_t SW1; /* Command Processing status */
|
||||
uint8_t SW2; /* Command Processing qualification */
|
||||
} SC_ADPU_ResponseTypeDef;
|
||||
|
||||
/* SC Command Status -----------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
SC_CS_FAILED = 0x00,
|
||||
SC_CS_PIN_ENABLED = 0x01,
|
||||
SC_CS_PIN_VERIFIED = 0x02,
|
||||
SC_CS_READ = 0x03,
|
||||
SC_CS_PIN_CHANGED = 0x04
|
||||
|
||||
} SC_Command_State;
|
||||
/* SC Response Status -----------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
REP_OK = 0x00,
|
||||
REP_NOT_OK = 0x01,
|
||||
REP_NOT_SUPP = 0x02,
|
||||
REP_ENABLED = 0x03,
|
||||
REP_CHANGE = 0x04
|
||||
|
||||
} REP_Command_t;
|
||||
/* Conforming of Command with ICC APP -----------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
Command_OK = 0x00,
|
||||
Command_NOT_OK = 0x01,
|
||||
|
||||
} Command_State_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SC_DISABLED = 0U,
|
||||
SC_ENABLED = !SC_DISABLED
|
||||
} SCPowerState;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/* APPLICATION LAYER ---------------------------------------------------------*/
|
||||
void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response);
|
||||
void SC_PowerCmd(SCPowerState NewState);
|
||||
void SC_ParityErrorHandler(void);
|
||||
void SC_PTSConfig(void);
|
||||
uint8_t SC_Detect(void);
|
||||
uint32_t SC_GetDTableValue(uint32_t idx);
|
||||
void SC_VoltageConfig(uint32_t SC_Voltage);
|
||||
void SC_SetState(SC_State scState);
|
||||
void SC_IOConfig(void);
|
||||
|
||||
extern uint8_t SC_ATR_Table[40];
|
||||
extern SC_ATRTypeDef SC_A2R;
|
||||
extern SC_ADPU_ResponseTypeDef SC_Response;
|
||||
|
||||
extern uint8_t ProtocolNUM_OUT;
|
||||
extern SC_ADPU_CommandsTypeDef SC_ADPU;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CCID_SMARTCARD_TEMPLATE_H */
|
||||
@@ -0,0 +1,969 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the high layer firmware functions to manage
|
||||
* all the functionalities of the USB CCID Class:
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* CCID Class Driver Description
|
||||
* ===================================================================
|
||||
* This module manages the Specification for Integrated Circuit(s)
|
||||
* Cards Interface Revision 1.1
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Device descriptor management
|
||||
* - Configuration descriptor management
|
||||
* - Enumeration as CCID device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
|
||||
* and enumeration for each implemented memory interface
|
||||
* - Bulk OUT/IN data Transfers
|
||||
* - Requests management
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid.h"
|
||||
#include "usbd_ccid_cmd.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CCID
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CCID_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CCID_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CCID_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CCID_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev);
|
||||
static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pDst, uint16_t u8length);
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CCID_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint8_t CCIDInEpAdd = CCID_IN_EP;
|
||||
static uint8_t CCIDOutEpAdd = CCID_OUT_EP;
|
||||
static uint8_t CCIDCmdEpAdd = CCID_CMD_EP;
|
||||
|
||||
|
||||
/* CCID interface class callbacks structure */
|
||||
USBD_ClassTypeDef USBD_CCID =
|
||||
{
|
||||
USBD_CCID_Init,
|
||||
USBD_CCID_DeInit,
|
||||
USBD_CCID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
NULL, /*EP0_RxReady*/
|
||||
USBD_CCID_DataIn,
|
||||
USBD_CCID_DataOut,
|
||||
NULL, /*SOF */
|
||||
NULL, /*ISOIn*/
|
||||
NULL, /*ISOOut*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
USBD_CCID_GetHSCfgDesc,
|
||||
USBD_CCID_GetFSCfgDesc,
|
||||
USBD_CCID_GetOtherSpeedCfgDesc,
|
||||
USBD_CCID_GetDeviceQualifierDescriptor,
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
|
||||
/* USB CCID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CCID_CfgDesc[USB_CCID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_CCID_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: */
|
||||
0x00, /* iConfiguration: */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/******************** CCID **** interface ********************/
|
||||
CCID_INTERFACE_DESC_SIZE, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x03, /* bNumEndpoints: 3 endpoints used */
|
||||
USB_DEVICE_CLASS_CCID, /* bInterfaceClass: user's interface for CCID */
|
||||
0x00, /* bInterfaceSubClass : No subclass,
|
||||
can be changed but no description in USB 2.0 Spec */
|
||||
0x00, /* nInterfaceProtocol : None */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/******************* CCID class descriptor ********************/
|
||||
CCID_CLASS_DESC_SIZE, /* bLength: CCID Descriptor size */
|
||||
CCID_DESC_TYPE, /* bDescriptorType: Functional Descriptor type. */
|
||||
0x10, /* bcdCCID(LSB): CCID Class Spec release number (1.1) */
|
||||
0x01, /* bcdCCID(MSB) */
|
||||
|
||||
0x00, /* bMaxSlotIndex :highest available slot on this device */
|
||||
CCID_VOLTAGE_SUPP, /* bVoltageSupport: bVoltageSupport: 5v, 3v and 1.8v */
|
||||
LOBYTE(USBD_CCID_PROTOCOL), /* dwProtocols: supports T=0 and T=1 */
|
||||
HIBYTE(USBD_CCID_PROTOCOL),
|
||||
0x00,
|
||||
0x00,
|
||||
LOBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ), /* dwDefaultClock: 3.6Mhz */
|
||||
HIBYTE(USBD_CCID_DEFAULT_CLOCK_FREQ),
|
||||
0x00,
|
||||
0x00,
|
||||
LOBYTE(USBD_CCID_MAX_CLOCK_FREQ), /* dwMaximumClock */
|
||||
HIBYTE(USBD_CCID_MAX_CLOCK_FREQ),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /* bNumClockSupported */
|
||||
LOBYTE(USBD_CCID_DEFAULT_DATA_RATE), /* dwDataRate: 9677 bps */
|
||||
HIBYTE(USBD_CCID_DEFAULT_DATA_RATE),
|
||||
0x00,
|
||||
0x00,
|
||||
|
||||
LOBYTE(USBD_CCID_MAX_DATA_RATE), /* dwMaxDataRate */
|
||||
HIBYTE(USBD_CCID_MAX_DATA_RATE),
|
||||
0x00,
|
||||
0x00,
|
||||
0x35, /* bNumDataRatesSupported */
|
||||
|
||||
LOBYTE(USBD_CCID_MAX_INF_FIELD_SIZE), /* dwMaxIFSD: maximum IFSD supported for T=1 */
|
||||
HIBYTE(USBD_CCID_MAX_INF_FIELD_SIZE),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, 0x00, 0x00, 0x00, /* dwSynchProtocols */
|
||||
0x00, 0x00, 0x00, 0x00, /* dwMechanical: no special characteristics */
|
||||
|
||||
0xBA, 0x04, EXCHANGE_LEVEL_FEATURE, 0x00, /* dwFeatures */
|
||||
LOBYTE(CCID_MAX_BLOCK_SIZE_HEADER), /* dwMaxCCIDMessageLength: Maximum block size + header*/
|
||||
HIBYTE(CCID_MAX_BLOCK_SIZE_HEADER),
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /* bClassGetResponse*/
|
||||
0x00, /* bClassEnvelope */
|
||||
0x00, 0x00, /* wLcdLayout : 0000h no LCD. */
|
||||
0x03, /* bPINSupport : PIN verification and PIN modification */
|
||||
0x01, /* bMaxCCIDBusySlots */
|
||||
|
||||
/******************** CCID Endpoints ********************/
|
||||
CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
|
||||
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
|
||||
CCID_IN_EP, /* Endpoint address (IN, address 1) */
|
||||
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
|
||||
|
||||
LOBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
|
||||
HIBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* Polling interval in milliseconds */
|
||||
CCID_ENDPOINT_DESC_SIZE, /* Endpoint descriptor length = 7 */
|
||||
USB_DESC_TYPE_ENDPOINT, /* Endpoint descriptor type */
|
||||
CCID_OUT_EP, /* Endpoint address (OUT, address 1) */
|
||||
USBD_EP_TYPE_BULK, /* Bulk endpoint type */
|
||||
|
||||
LOBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
|
||||
HIBYTE(CCID_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* Polling interval in milliseconds */
|
||||
CCID_ENDPOINT_DESC_SIZE, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
|
||||
CCID_CMD_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
USBD_EP_TYPE_INTR, /* bmAttributes: Interrupt endpoint */
|
||||
LOBYTE(CCID_CMD_PACKET_SIZE),
|
||||
HIBYTE(CCID_CMD_PACKET_SIZE),
|
||||
CCID_CMD_FS_BINTERVAL /* Polling interval in milliseconds */
|
||||
};
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CCID_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,
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CCID_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_Init
|
||||
* Initialize the CCID interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid;
|
||||
UNUSED(cfgidx);
|
||||
|
||||
/* Allocate CCID structure */
|
||||
hccid = (USBD_CCID_HandleTypeDef *)USBD_malloc(sizeof(USBD_CCID_HandleTypeDef));
|
||||
|
||||
if (hccid == NULL)
|
||||
{
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hccid;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Init the CCID parameters into a state where it can receive a new command message */
|
||||
hccid->USBD_CCID_Param.bAbortRequestFlag = 0U;
|
||||
hccid->USBD_CCID_Param.bSeq = 0U;
|
||||
hccid->USBD_CCID_Param.bSlot = 0U;
|
||||
hccid->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? \
|
||||
CCID_DATA_HS_MAX_PACKET_SIZE : CCID_DATA_FS_MAX_PACKET_SIZE;
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CCIDInEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen);
|
||||
pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, CCIDOutEpAdd, USBD_EP_TYPE_BULK, (uint16_t)hccid->MaxPcktLen);
|
||||
pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open INTR EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CCIDCmdEpAdd,
|
||||
USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE);
|
||||
pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Init physical Interface components */
|
||||
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(pdev);
|
||||
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CCIDOutEpAdd,
|
||||
hccid->data, hccid->MaxPcktLen);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_DeInit
|
||||
* DeInitialize the CCID layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Close EP IN */
|
||||
(void)USBD_LL_CloseEP(pdev, CCIDInEpAdd);
|
||||
pdev->ep_in[CCIDInEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP OUT */
|
||||
(void)USBD_LL_CloseEP(pdev, CCIDOutEpAdd);
|
||||
pdev->ep_out[CCIDOutEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP Command */
|
||||
(void)USBD_LL_CloseEP(pdev, CCIDCmdEpAdd);
|
||||
pdev->ep_in[CCIDCmdEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* DeInit physical Interface components */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
|
||||
{
|
||||
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(pdev);
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_Setup
|
||||
* Handle the CCID specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId];
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint8_t ifalt = 0U;
|
||||
uint16_t status_info = 0U;
|
||||
uint16_t len;
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
/* Class request */
|
||||
case USB_REQ_TYPE_CLASS :
|
||||
if (req->wLength != 0U)
|
||||
{
|
||||
len = MIN(CCID_EP0_BUFF_SIZ, req->wLength);
|
||||
if ((req->bmRequest & 0x80U) != 0U)
|
||||
{
|
||||
hCCIDitf->Control(req->bRequest, hccid->data, &len);
|
||||
(void)USBD_CtlSendData(pdev, hccid->data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)USBD_CtlPrepareRx(pdev, hccid->data, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0U;
|
||||
hCCIDitf->Control(req->bRequest, (uint8_t *)&req->wValue, &len);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Interface & Endpoint request */
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)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;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_DataIn
|
||||
* Data sent on non-control IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CCIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (epnum == (CCIDInEpAdd & 0x7FU))
|
||||
{
|
||||
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
|
||||
|
||||
/*************** Handle Bulk Transfer IN data completion *****************/
|
||||
|
||||
switch (hccid->blkt_state)
|
||||
{
|
||||
case CCID_STATE_SEND_RESP:
|
||||
|
||||
/* won't wait ack to avoid missing a command */
|
||||
hccid->blkt_state = CCID_STATE_IDLE;
|
||||
|
||||
/* Prepare EP to Receive Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
|
||||
hccid->data, hccid->MaxPcktLen);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (epnum == (CCIDCmdEpAdd & 0x7FU))
|
||||
{
|
||||
/* Filter the epnum by masking with 0x7f (mask of IN Direction) */
|
||||
|
||||
/*************** Handle Interrupt Transfer IN data completion *****************/
|
||||
|
||||
(void)USBD_CCID_IntMessage(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_DataOut
|
||||
* Data received on non-control Out endpoint
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint number
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t CurrPcktLen;
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CCIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hccid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
if (epnum == CCIDOutEpAdd)
|
||||
{
|
||||
CurrPcktLen = (uint16_t)USBD_GetRxCount(pdev, epnum);
|
||||
|
||||
switch (hccid->blkt_state)
|
||||
{
|
||||
case CCID_STATE_IDLE:
|
||||
|
||||
if (CurrPcktLen >= (uint16_t)CCID_CMD_HEADER_SIZE)
|
||||
{
|
||||
hccid->UsbMessageLength = CurrPcktLen; /* Store for future use */
|
||||
|
||||
/* Fill CCID_BulkOut Data Buffer from USB Buffer */
|
||||
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
|
||||
(uint16_t)CurrPcktLen);
|
||||
|
||||
/*
|
||||
Refer : 6 CCID Messages
|
||||
The response messages always contain the exact same slot number,
|
||||
and sequence number fields from the header that was contained in
|
||||
the Bulk-OUT command message.
|
||||
*/
|
||||
hccid->UsbBlkInData.bSlot = hccid->UsbBlkOutData.bSlot;
|
||||
hccid->UsbBlkInData.bSeq = hccid->UsbBlkOutData.bSeq;
|
||||
|
||||
if (CurrPcktLen < hccid->MaxPcktLen)
|
||||
{
|
||||
/* Short message, less than the EP Out Size, execute the command,
|
||||
if parameter like dwLength is too big, the appropriate command will
|
||||
give an error */
|
||||
(void)USBD_CCID_DispatchCommand(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if length of data to be sent by host is > buffer size */
|
||||
if (hccid->UsbBlkOutData.dwLength > (uint32_t)ABDATA_SIZE)
|
||||
{
|
||||
/* Too long data received.... Error ! */
|
||||
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Expect more data on OUT EP */
|
||||
hccid->blkt_state = CCID_STATE_RECEIVE_DATA;
|
||||
|
||||
/* Prepare EP to Receive next Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
|
||||
hccid->data, hccid->MaxPcktLen);
|
||||
|
||||
} /* if (CurrPcktLen == CCID_DATA_MAX_PACKET_SIZE) ends */
|
||||
} /* if (CurrPcktLen >= CCID_DATA_MAX_PACKET_SIZE) ends */
|
||||
} /* if (CurrPcktLen >= CCID_CMD_HEADER_SIZE) ends */
|
||||
else
|
||||
{
|
||||
if (CurrPcktLen == 0x00U) /* Zero Length Packet Received */
|
||||
{
|
||||
hccid->blkt_state = CCID_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CCID_STATE_RECEIVE_DATA:
|
||||
hccid->UsbMessageLength += CurrPcktLen;
|
||||
|
||||
if (CurrPcktLen < hccid->MaxPcktLen)
|
||||
{
|
||||
/* Short message, less than the EP Out Size, execute the command,
|
||||
if parameter like dwLength is too big, the appropriate command will
|
||||
give an error */
|
||||
|
||||
/* Full command is received, process the Command */
|
||||
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
|
||||
(uint16_t)CurrPcktLen);
|
||||
|
||||
(void)USBD_CCID_DispatchCommand(pdev);
|
||||
}
|
||||
else if (CurrPcktLen == hccid->MaxPcktLen)
|
||||
{
|
||||
if (hccid->UsbMessageLength < (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE))
|
||||
{
|
||||
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
|
||||
(uint16_t)CurrPcktLen); /* Copy data */
|
||||
|
||||
/* Prepare EP to Receive next Cmd */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CCID_OUT_EP,
|
||||
hccid->data, hccid->MaxPcktLen);
|
||||
}
|
||||
else if (hccid->UsbMessageLength == (hccid->UsbBlkOutData.dwLength + (uint32_t)CCID_CMD_HEADER_SIZE))
|
||||
{
|
||||
/* Full command is received, process the Command */
|
||||
(void)USBD_CCID_ReceiveCmdHeader(pdev, (uint8_t *)&hccid->UsbBlkOutData.bMessageType,
|
||||
(uint16_t)CurrPcktLen);
|
||||
|
||||
(void)USBD_CCID_DispatchCommand(pdev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Too long data received.... Error ! */
|
||||
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Too long data received.... Error ! */
|
||||
hccid->blkt_state = CCID_STATE_UNCORRECT_LENGTH;
|
||||
}
|
||||
break;
|
||||
|
||||
case CCID_STATE_UNCORRECT_LENGTH:
|
||||
hccid->blkt_state = CCID_STATE_IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_DispatchCommand
|
||||
* Parse the commands and Process command
|
||||
* @param pdev: device instance
|
||||
* @retval status value
|
||||
*/
|
||||
static uint8_t USBD_CCID_DispatchCommand(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint8_t errorCode;
|
||||
|
||||
switch (hccid->UsbBlkOutData.bMessageType)
|
||||
{
|
||||
case PC_TO_RDR_ICCPOWERON:
|
||||
errorCode = PC_to_RDR_IccPowerOn(pdev);
|
||||
RDR_to_PC_DataBlock(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_ICCPOWEROFF:
|
||||
errorCode = PC_to_RDR_IccPowerOff(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_GETSLOTSTATUS:
|
||||
errorCode = PC_to_RDR_GetSlotStatus(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_XFRBLOCK:
|
||||
errorCode = PC_to_RDR_XfrBlock(pdev);
|
||||
RDR_to_PC_DataBlock(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_GETPARAMETERS:
|
||||
errorCode = PC_to_RDR_GetParameters(pdev);
|
||||
RDR_to_PC_Parameters(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_RESETPARAMETERS:
|
||||
errorCode = PC_to_RDR_ResetParameters(pdev);
|
||||
RDR_to_PC_Parameters(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_SETPARAMETERS:
|
||||
errorCode = PC_to_RDR_SetParameters(pdev);
|
||||
RDR_to_PC_Parameters(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_ESCAPE:
|
||||
errorCode = PC_to_RDR_Escape(pdev);
|
||||
RDR_to_PC_Escape(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_ICCCLOCK:
|
||||
errorCode = PC_to_RDR_IccClock(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_ABORT:
|
||||
errorCode = PC_to_RDR_Abort(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_T0APDU:
|
||||
errorCode = PC_TO_RDR_T0Apdu(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_MECHANICAL:
|
||||
errorCode = PC_TO_RDR_Mechanical(pdev);
|
||||
RDR_to_PC_SlotStatus(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY:
|
||||
errorCode = PC_TO_RDR_SetDataRateAndClockFrequency(pdev);
|
||||
RDR_to_PC_DataRateAndClockFrequency(errorCode, pdev);
|
||||
break;
|
||||
|
||||
case PC_TO_RDR_SECURE:
|
||||
errorCode = PC_TO_RDR_Secure(pdev);
|
||||
RDR_to_PC_DataBlock(errorCode, pdev);
|
||||
break;
|
||||
|
||||
default:
|
||||
RDR_to_PC_SlotStatus(SLOTERROR_CMD_NOT_SUPPORTED, pdev);
|
||||
break;
|
||||
}
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_Transfer_Data_Request
|
||||
* Prepare the request response to be sent to the host
|
||||
* @param pdev: device instance
|
||||
* @param dataPointer: Pointer to the data buffer to send
|
||||
* @param dataLen : number of bytes to send
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t USBD_CCID_Transfer_Data_Request(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *dataPointer, uint16_t dataLen)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_CCID_ItfTypeDef *hCCIDitf = (USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId];
|
||||
|
||||
UNUSED(dataPointer);
|
||||
|
||||
hccid->blkt_state = CCID_STATE_SEND_RESP;
|
||||
hccid->UsbMessageLength = (uint32_t)dataLen; /* Store for future use */
|
||||
|
||||
/* use the header declared size packet must be well formed */
|
||||
hCCIDitf->Response_SendData(pdev, (uint8_t *)&hccid->UsbBlkInData,
|
||||
(uint16_t)MIN(CCID_DATA_FS_MAX_PACKET_SIZE, hccid->UsbMessageLength));
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_ReceiveCmdHeader
|
||||
* Receive the Data from USB BulkOut Buffer to Pointer
|
||||
* @param pdev: device instance
|
||||
* @param pDst: destination address to copy the buffer
|
||||
* @param u8length: length of data to copy
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CCID_ReceiveCmdHeader(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pDst, uint16_t u8length)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint8_t *pdst = pDst;
|
||||
uint32_t Counter;
|
||||
|
||||
for (Counter = 0U; Counter < u8length; Counter++)
|
||||
{
|
||||
*pdst = hccid->data[Counter];
|
||||
pdst++;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_IntMessage
|
||||
* Send the Interrupt-IN data to the host
|
||||
* @param pdev: device instance
|
||||
* @retval None
|
||||
*/
|
||||
uint8_t USBD_CCID_IntMessage(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CCIDCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Check if there is change in Smartcard Slot status */
|
||||
if (CCID_IsSlotStatusChange(pdev) != 0U)
|
||||
{
|
||||
/* Check Slot Status is changed. Card is Removed/Fitted */
|
||||
RDR_to_PC_NotifySlotChange(pdev);
|
||||
|
||||
/* Set the Slot status */
|
||||
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev);
|
||||
|
||||
(void)USBD_LL_Transmit(pdev, CCIDCmdEpAdd, hccid->UsbIntData, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the Slot status */
|
||||
((USBD_CCID_ItfTypeDef *)pdev->pUserData[pdev->classId])->SetSlotStatus(pdev);
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_CCID_GetHSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CCID_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CCID_DATA_HS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CCID_CMD_HS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
|
||||
return USBD_CCID_CfgDesc;
|
||||
}
|
||||
/**
|
||||
* @brief USBD_CCID_GetFSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CCID_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
|
||||
return USBD_CCID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_GetOtherSpeedCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CCID_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_IN_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CCID_CfgDesc, CCID_CMD_EP);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CCID_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CCID_CMD_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CCID_CfgDesc);
|
||||
return USBD_CCID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_GetDeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CCID_GetDeviceQualifierDescriptor(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)(sizeof(USBD_CCID_DeviceQualifierDesc));
|
||||
return USBD_CCID_DeviceQualifierDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @brief USBD_CCID_RegisterInterface
|
||||
* @param pdev: device instance
|
||||
* @param fops: CD Interface callback
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CCID_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CCID_ItfTypeDef *fops)
|
||||
{
|
||||
if (fops == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+1099
File diff suppressed because it is too large
Load Diff
+270
@@ -0,0 +1,270 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides all the functions for USB Interface for CCID
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid.h"
|
||||
#include "usbd_ccid_if_template.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static REP_Command_t REP_command;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static uint8_t CCID_Init(USBD_HandleTypeDef *pdev);
|
||||
static uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev);
|
||||
static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length);
|
||||
static uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len);
|
||||
static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data);
|
||||
static uint8_t CCID_Response_Process(void);
|
||||
static uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
USBD_CCID_ItfTypeDef USBD_CCID_If_fops =
|
||||
{
|
||||
CCID_Init,
|
||||
CCID_DeInit,
|
||||
CCID_ControlReq,
|
||||
CCID_Response_SendData,
|
||||
CCID_Send_Process,
|
||||
CCID_SetSlotStatus,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief CCID_Init
|
||||
* Initialize the CCID USB Layer
|
||||
* @param pdev: device instance
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t CCID_Init(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#else
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* CCID Related Initialization */
|
||||
|
||||
hccid->blkt_state = CCID_STATE_IDLE;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_DeInit
|
||||
* Uninitialize the CCID Machine
|
||||
* @param pdev: device instance
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t CCID_DeInit(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#else
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
hccid->blkt_state = CCID_STATE_IDLE;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_ControlReq
|
||||
* Manage the CCID class requests
|
||||
* @param Cmd: Command code
|
||||
* @param Buf: Buffer containing command data (request parameters)
|
||||
* @param Len: Number of data to be sent (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static uint8_t CCID_ControlReq(uint8_t req, uint8_t *pbuf, uint16_t *length)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassDataCmsit[USBD_Device.classId];
|
||||
#else
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)USBD_Device.pClassData;
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
UNUSED(length);
|
||||
|
||||
switch (req)
|
||||
{
|
||||
case REQUEST_ABORT:
|
||||
/* The wValue field contains the slot number (bSlot) in the low byte
|
||||
and the sequence number (bSeq) in the high byte.*/
|
||||
hccid->slot_nb = ((uint16_t) * pbuf & 0x0fU);
|
||||
hccid->seq_nb = (((uint16_t) * pbuf & 0xf0U) >> 8);
|
||||
|
||||
if (CCID_CmdAbort(&USBD_Device, (uint8_t)hccid->slot_nb, (uint8_t)hccid->seq_nb) != 0U)
|
||||
{
|
||||
/* If error is returned by lower layer :
|
||||
Generally Slot# may not have matched */
|
||||
return (int8_t)USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case REQUEST_GET_CLOCK_FREQUENCIES:
|
||||
|
||||
/* User have to fill the pbuf with the GetClockFrequency data buffer */
|
||||
|
||||
break;
|
||||
|
||||
case REQUEST_GET_DATA_RATES:
|
||||
|
||||
/* User have to fill the pbuf with the GetDataRates data buffer */
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNUSED(pbuf);
|
||||
|
||||
return ((int8_t)USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_Response_SendData
|
||||
* Send the data on bulk-in EP
|
||||
* @param pdev: device instance
|
||||
* @param buf: pointer to data buffer
|
||||
* @param len: Data Length
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t CCID_Response_SendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
(void)USBD_LL_Transmit(pdev, CCID_IN_EP, buf, len);
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_SEND_Process
|
||||
* @param Command: pointer to a buffer containing command header
|
||||
* @param Data: pointer to a buffer containing data sent from Host
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static uint8_t CCID_Send_Process(uint8_t *Command, uint8_t *Data)
|
||||
{
|
||||
Command_State_t Command_State = Command_NOT_OK;
|
||||
|
||||
/* Initialize ICC APP header */
|
||||
uint8_t SC_Command[5] = {0};
|
||||
UNUSED(Data);
|
||||
UNUSED(Command_State);
|
||||
UNUSED(SC_Command);
|
||||
|
||||
/* Start SC Demo ---------------------------------------------------------*/
|
||||
switch (Command[1]) /* type of instruction */
|
||||
{
|
||||
case SC_ENABLE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case SC_VERIFY:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case SC_READ_BINARY :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case SC_CHANGE :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if Command header is OK */
|
||||
(void)CCID_Response_Process(); /* Get ICC response */
|
||||
|
||||
return ((uint8_t)USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_Response_Process
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static uint8_t CCID_Response_Process(void)
|
||||
{
|
||||
switch (REP_command)
|
||||
{
|
||||
case REP_OK:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case REP_NOT_OK :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case REP_NOT_SUPP :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case REP_ENABLED :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case REP_CHANGE :
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ((uint8_t)USBD_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CCID_SetSlotStatus
|
||||
* Set Slot Status of the Interrupt Transfer
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t CCID_SetSlotStatus(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Get the CCID handler pointer */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#else
|
||||
USBD_CCID_HandleTypeDef *hccid = (USBD_CCID_HandleTypeDef *)pdev->pClassData;
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if ((hccid->SlotStatus.SlotStatus) == 1U) /* Transfer Complete Status
|
||||
of previous Interrupt transfer */
|
||||
{
|
||||
/* Add your code here */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add your code here */
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
+473
@@ -0,0 +1,473 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_sc_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief SmartCard Interface file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid_sc_if_template.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* State Machine for the SmartCard Interface */
|
||||
static SC_State SCState = SC_POWER_OFF;
|
||||
|
||||
/* APDU Transport Structures */
|
||||
SC_ADPU_CommandsTypeDef SC_ADPU;
|
||||
SC_ADPU_ResponseTypeDef SC_Response;
|
||||
SC_Param_t SC_Param;
|
||||
Protocol_01_DataTypeDef ProtocolData;
|
||||
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void SC_SaveVoltage(uint8_t voltage);
|
||||
static void SC_Itf_UpdateParams(void);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/**
|
||||
* @brief SC_Itf_IccPowerOn Manages the Warm and Cold Reset
|
||||
and get the Answer to Reset from ICC
|
||||
* @param voltage: required by host
|
||||
* @retval None
|
||||
*/
|
||||
void SC_Itf_IccPowerOn(uint8_t voltage)
|
||||
{
|
||||
SCState = SC_POWER_ON;
|
||||
SC_ADPU.Header.CLA = 0x00U;
|
||||
SC_ADPU.Header.INS = SC_GET_A2R;
|
||||
SC_ADPU.Header.P1 = 0x00U;
|
||||
SC_ADPU.Header.P2 = 0x00U;
|
||||
SC_ADPU.Body.LC = 0x00U;
|
||||
|
||||
/* Power ON the card */
|
||||
SC_PowerCmd(SC_ENABLED);
|
||||
|
||||
/* Configure the Voltage, Even if IO is still not configured */
|
||||
SC_VoltageConfig(voltage);
|
||||
|
||||
while ((SCState != SC_ACTIVE_ON_T0) && (SCState != SC_ACTIVE_ON_T1)
|
||||
&& (SCState != SC_NO_INIT))
|
||||
{
|
||||
/* If Either The Card has become Active or Become De-Active */
|
||||
SC_Handler(&SCState, &SC_ADPU, &SC_Response);
|
||||
}
|
||||
|
||||
if ((SCState == SC_ACTIVE_ON_T0) || (SCState == SC_ACTIVE_ON_T1))
|
||||
{
|
||||
SC_Itf_UpdateParams();
|
||||
/* Apply the Procedure Type Selection (PTS) */
|
||||
SC_PTSConfig();
|
||||
|
||||
/* Save Voltage for Future use */
|
||||
SC_SaveVoltage(voltage);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_IccPowerOff Power OFF the card
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SC_Itf_IccPowerOff(void)
|
||||
{
|
||||
SC_PowerCmd(SC_DISABLED);
|
||||
SC_SetState(SC_POWER_OFF);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the parameters structures to the default value
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SC_Itf_InitParams(void)
|
||||
{
|
||||
/*
|
||||
FI, the reference to a clock rate conversion factor
|
||||
over the bits b8 to b5
|
||||
- DI, the reference to a baud rate adjustment factor
|
||||
over the bits b4 to bl
|
||||
*/
|
||||
SC_Param.SC_A2R_FiDi = DEFAULT_FIDI;
|
||||
SC_Param.SC_hostFiDi = DEFAULT_FIDI;
|
||||
|
||||
ProtocolData.bmFindexDindex = DEFAULT_FIDI;
|
||||
|
||||
/* Placeholder, Ignored */
|
||||
/* 0 = Direct, first byte of the ICC ATR data. */
|
||||
ProtocolData.bmTCCKST0 = DEFAULT_T01CONVCHECKSUM;
|
||||
|
||||
/* Extra GuardTime = 0 etu */
|
||||
ProtocolData.bGuardTimeT0 = DEFAULT_EXTRA_GUARDTIME;
|
||||
ProtocolData.bWaitingIntegerT0 = DEFAULT_WAITINGINTEGER;
|
||||
ProtocolData.bClockStop = 0U; /* Stopping the Clock is not allowed */
|
||||
|
||||
/*T=1 protocol */
|
||||
ProtocolData.bIfsc = DEFAULT_IFSC;
|
||||
ProtocolData.bNad = DEFAULT_NAD;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save the A2R Parameters for further usage
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_Itf_UpdateParams(void)
|
||||
{
|
||||
/*
|
||||
FI, the reference to a clock rate conversion factor
|
||||
over the bits b8 to b5
|
||||
DI, the reference to a baud rate adjustment factor
|
||||
over the bits b4 to bl
|
||||
*/
|
||||
SC_Param.SC_A2R_FiDi = SC_A2R.T[0].InterfaceByte[0].Value;
|
||||
SC_Param.SC_hostFiDi = SC_A2R.T[0].InterfaceByte[0].Value;
|
||||
|
||||
ProtocolData.bmFindexDindex = SC_A2R.T[0].InterfaceByte[0].Value;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_SetParams
|
||||
* Set the parameters for CCID/USART interface
|
||||
* @param pPtr: pointer to buffer containing the
|
||||
* parameters to be set in USART
|
||||
* @param T_01: type of protocol, T=1 or T=0
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_SetParams(Protocol_01_DataTypeDef *pPtr, uint8_t T_01)
|
||||
{
|
||||
/* uint16_t guardTime; */ /* Keep it 16b for handling 8b additions */
|
||||
uint32_t fi_new;
|
||||
uint32_t di_new;
|
||||
Protocol_01_DataTypeDef New_DataStructure;
|
||||
fi_new = pPtr->bmFindexDindex;
|
||||
di_new = pPtr->bmFindexDindex;
|
||||
|
||||
New_DataStructure.bmTCCKST0 = pPtr->bmTCCKST0;
|
||||
|
||||
New_DataStructure.bGuardTimeT0 = pPtr->bGuardTimeT0;
|
||||
New_DataStructure.bWaitingIntegerT0 = pPtr->bWaitingIntegerT0;
|
||||
New_DataStructure.bClockStop = pPtr->bClockStop;
|
||||
if (T_01 == 0x01U)
|
||||
{
|
||||
New_DataStructure.bIfsc = pPtr->bIfsc;
|
||||
New_DataStructure.bNad = pPtr->bNad;
|
||||
}
|
||||
else
|
||||
{
|
||||
New_DataStructure.bIfsc = 0x00U;
|
||||
New_DataStructure.bNad = 0x00U;
|
||||
}
|
||||
|
||||
/* Check for the FIDI Value set by Host */
|
||||
di_new &= (uint8_t)0x0F;
|
||||
if (SC_GetDTableValue(di_new) == 0U)
|
||||
{
|
||||
return SLOTERROR_BAD_FIDI;
|
||||
}
|
||||
|
||||
fi_new >>= 4U;
|
||||
fi_new &= 0x0FU;
|
||||
|
||||
if (SC_GetDTableValue(fi_new) == 0U)
|
||||
{
|
||||
return SLOTERROR_BAD_FIDI;
|
||||
}
|
||||
|
||||
if ((T_01 == 0x00U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x00U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x02U))
|
||||
{
|
||||
return SLOTERROR_BAD_T01CONVCHECKSUM;
|
||||
}
|
||||
|
||||
if ((T_01 == 0x01U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x10U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x11U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x12U)
|
||||
&& (New_DataStructure.bmTCCKST0 != 0x13U))
|
||||
{
|
||||
return SLOTERROR_BAD_T01CONVCHECKSUM;
|
||||
}
|
||||
|
||||
if ((New_DataStructure.bWaitingIntegerT0 >= 0xA0U)
|
||||
&& ((New_DataStructure.bmTCCKST0 & 0x10U) == 0x10U))
|
||||
{
|
||||
return SLOTERROR_BAD_WAITINGINTEGER;
|
||||
}
|
||||
if ((New_DataStructure.bClockStop != 0x00U)
|
||||
&& (New_DataStructure.bClockStop != 0x03U))
|
||||
{
|
||||
return SLOTERROR_BAD_CLOCKSTOP;
|
||||
}
|
||||
if (New_DataStructure.bNad != 0x00U)
|
||||
{
|
||||
return SLOTERROR_BAD_NAD;
|
||||
}
|
||||
/* Put Total GuardTime in USART Settings */
|
||||
/* USART_SetGuardTime(SC_USART, (uint8_t)(guardTime + DEFAULT_EXTRA_GUARDTIME)); */
|
||||
|
||||
/* Save Extra GuardTime Value */
|
||||
ProtocolData.bGuardTimeT0 = New_DataStructure.bGuardTimeT0;
|
||||
ProtocolData.bmTCCKST0 = New_DataStructure.bmTCCKST0;
|
||||
ProtocolData.bWaitingIntegerT0 = New_DataStructure.bWaitingIntegerT0;
|
||||
ProtocolData.bClockStop = New_DataStructure.bClockStop;
|
||||
ProtocolData.bIfsc = New_DataStructure.bIfsc;
|
||||
ProtocolData.bNad = New_DataStructure.bNad;
|
||||
|
||||
/* Save New bmFindexDindex */
|
||||
SC_Param.SC_hostFiDi = pPtr->bmFindexDindex;
|
||||
SC_PTSConfig();
|
||||
|
||||
ProtocolData.bmFindexDindex = pPtr->bmFindexDindex;
|
||||
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_Escape function from the host
|
||||
* This is user implementable
|
||||
* @param ptrEscape: pointer to buffer containing the Escape data
|
||||
* @param escapeLen: length of escaped data
|
||||
* @param responseBuff: pointer containing escape buffer response
|
||||
* @param responseLen: length of escape response buffer
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_Escape(uint8_t *ptrEscape, uint32_t escapeLen,
|
||||
uint8_t *responseBuff, uint32_t *responseLen)
|
||||
{
|
||||
UNUSED(ptrEscape);
|
||||
UNUSED(escapeLen);
|
||||
UNUSED(responseBuff);
|
||||
UNUSED(responseLen);
|
||||
|
||||
/* Manufacturer specific implementation ... */
|
||||
/*
|
||||
uint32_t idx;
|
||||
uint8_t *pResBuff = responseBuff;
|
||||
uint8_t *pEscape = ptrEscape;
|
||||
|
||||
for(idx = 0; idx < escapeLen; idx++)
|
||||
{
|
||||
*pResBuff = *pEscape;
|
||||
pResBuff++;
|
||||
pEscape++;
|
||||
}
|
||||
|
||||
*responseLen = escapeLen;
|
||||
*/
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_SetClock function to define Clock Status request from the host.
|
||||
* This is user implementable
|
||||
* @param bClockCommand: Clock status from the host
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_SetClock(uint8_t bClockCommand)
|
||||
{
|
||||
/* bClockCommand
|
||||
00h restarts Clock
|
||||
01h Stops Clock in the state shown in the bClockStop
|
||||
field of the PC_to_RDR_SetParameters command
|
||||
and RDR_to_PC_Parameters message.*/
|
||||
|
||||
if (bClockCommand == 0U)
|
||||
{
|
||||
/* 00h restarts Clock : Since Clock is always running, PASS this command */
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bClockCommand == 1U)
|
||||
{
|
||||
return SLOTERROR_BAD_CLOCKCOMMAND;
|
||||
}
|
||||
}
|
||||
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_XferBlock function from the host.
|
||||
* This is user implementable
|
||||
* @param ptrBlock : Pointer containing the data from host
|
||||
* @param blockLen : length of block data for the data transfer
|
||||
* @param expectedLen: expected length of data transfer
|
||||
* @param CCID_BulkIn_Data: Pointer containing the CCID Bulk In Data Structure
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_XferBlock(uint8_t *ptrBlock, uint32_t blockLen, uint16_t expectedLen,
|
||||
USBD_CCID_BulkIn_DataTypeDef *CCID_BulkIn_Data)
|
||||
{
|
||||
uint8_t ErrorCode = SLOT_NO_ERROR;
|
||||
UNUSED(CCID_BulkIn_Data);
|
||||
UNUSED(expectedLen);
|
||||
UNUSED(blockLen);
|
||||
UNUSED(ptrBlock);
|
||||
|
||||
if (ProtocolNUM_OUT == 0x00U)
|
||||
{
|
||||
/* Add your code here */
|
||||
}
|
||||
|
||||
if (ProtocolNUM_OUT == 0x01U)
|
||||
{
|
||||
/* Add your code here */
|
||||
}
|
||||
|
||||
if (ErrorCode != SLOT_NO_ERROR)
|
||||
{
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_T0Apdu
|
||||
Class Specific Request from the host to provide supported data rates
|
||||
* This is Optional function & user implementable
|
||||
* @param bmChanges : value specifying which parameter is valid in
|
||||
* command among next bClassGetResponse, bClassEnvelope
|
||||
* @param bClassGetResponse : Value to force the class byte of the
|
||||
* header in a Get Response command.
|
||||
* @param bClassEnvelope : Value to force the class byte of the header
|
||||
* in a Envelope command.
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_T0Apdu(uint8_t bmChanges, uint8_t bClassGetResponse,
|
||||
uint8_t bClassEnvelope)
|
||||
{
|
||||
UNUSED(bClassEnvelope);
|
||||
UNUSED(bClassGetResponse);
|
||||
|
||||
/* User have to fill the pbuf with the GetDataRates data buffer */
|
||||
|
||||
if (bmChanges == 0U)
|
||||
{
|
||||
/* Bit cleared indicates that the associated field is not significant and
|
||||
that default behaviour defined in CCID class descriptor is selected */
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_Mechanical
|
||||
Mechanical Function being requested by Host
|
||||
* This is Optional function & user implementable
|
||||
* @param bFunction : value corresponds to the mechanical function
|
||||
* being requested by host
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_Mechanical(uint8_t bFunction)
|
||||
{
|
||||
UNUSED(bFunction);
|
||||
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_SetDataRateAndClockFrequency
|
||||
* Set the Clock and data Rate of the Interface
|
||||
* This is Optional function & user implementable
|
||||
* @param dwClockFrequency : value of clock in kHz requested by host
|
||||
* @param dwDataRate : value of data rate requested by host
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_SetDataRateAndClockFrequency(uint32_t dwClockFrequency,
|
||||
uint32_t dwDataRate)
|
||||
{
|
||||
/* User have to fill the pbuf with the GetDataRates data buffer */
|
||||
|
||||
if ((dwDataRate == USBD_CCID_DEFAULT_DATA_RATE) &&
|
||||
(dwClockFrequency == USBD_CCID_DEFAULT_CLOCK_FREQ))
|
||||
{
|
||||
return SLOT_NO_ERROR;
|
||||
}
|
||||
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_Itf_Secure
|
||||
* Process the Secure command
|
||||
* This is Optional function & user implementable
|
||||
* @param dwLength : length of data from the host
|
||||
* @param bBWI : Block Waiting Timeout sent by host
|
||||
* @param wLevelParameter : Parameters sent by host
|
||||
* @param pbuf : buffer containing the data
|
||||
* @param returnLen : Length of data expected to return
|
||||
* @retval status value
|
||||
*/
|
||||
uint8_t SC_Itf_Secure(uint32_t dwLength, uint8_t bBWI, uint16_t wLevelParameter,
|
||||
uint8_t *pbuf, uint32_t *returnLen)
|
||||
{
|
||||
UNUSED(pbuf);
|
||||
UNUSED(wLevelParameter);
|
||||
UNUSED(bBWI);
|
||||
UNUSED(dwLength);
|
||||
*returnLen = 0U;
|
||||
|
||||
return SLOTERROR_CMD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_SaveVoltage
|
||||
Saves the voltage value to be saved for further usage
|
||||
* @param voltage: voltage value to be saved for further usage
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_SaveVoltage(uint8_t voltage)
|
||||
{
|
||||
SC_Param.voltage = voltage;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides the value of SCState variable
|
||||
* @param None
|
||||
* @retval uint8_t SCState
|
||||
*/
|
||||
uint8_t SC_GetState(void)
|
||||
{
|
||||
return (uint8_t)SCState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of SCState variable to Off
|
||||
* @param scState: value of SCState to be updated
|
||||
* @retval None
|
||||
*/
|
||||
void SC_SetState(SC_State scState)
|
||||
{
|
||||
SCState = scState;
|
||||
|
||||
return;
|
||||
}
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_ccid_smartcard_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides all the Smartcard firmware functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup usbd_ccid_Smartcard
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ccid_smartcard_template.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Directories & Files ID */
|
||||
/*The following Directories & Files ID can take any of following Values and can
|
||||
be used in the smartcard application */
|
||||
/*
|
||||
const uint8_t MasterRoot[2] = {0x3F, 0x00};
|
||||
const uint8_t GSMDir[2] = {0x7F, 0x20};
|
||||
const uint8_t ICCID[2] = {0x2F, 0xE2};
|
||||
const uint8_t IMSI[2] = {0x6F, 0x07};
|
||||
|
||||
__IO uint8_t ICCID_Content[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
uint32_t CHV1Status = 0U;
|
||||
|
||||
uint8_t CHV1[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
|
||||
__IO uint8_t IMSI_Content[9] = {0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
*/
|
||||
|
||||
/* F Table: Clock Rate Conversion Table from ISO/IEC 7816-3 */
|
||||
/* static uint32_t F_Table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768,
|
||||
1024, 1536, 2048, 0, 0
|
||||
}; */
|
||||
|
||||
|
||||
/* D Table: Baud Rate Adjustment Factor Table from ISO/IEC 7816-3 */
|
||||
static uint32_t D_Table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* Global variables definition and initialization ----------------------------*/
|
||||
SC_ATRTypeDef SC_A2R;
|
||||
uint8_t SC_ATR_Table[40];
|
||||
uint8_t ProtocolNUM_OUT;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void SC_Init(void);
|
||||
static void SC_DeInit(void);
|
||||
static void SC_AnswerReq(SC_State *SC_state, uint8_t *card, uint8_t length); /* Ask ATR */
|
||||
static uint8_t SC_decode_Answer2reset(uint8_t *card); /* Decode ATR */
|
||||
static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus);
|
||||
/* static void SC_Reset(GPIO_PinState ResetState); */
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Handles all Smartcard states and serves to send and receive all
|
||||
* communication data between Smartcard and reader.
|
||||
* @param SCState: pointer to an SC_State enumeration that will contain the
|
||||
* Smartcard state.
|
||||
* @param SC_ADPU: pointer to an SC_ADPU_Commands structure that will be initialized.
|
||||
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
|
||||
* @retval None
|
||||
*/
|
||||
void SC_Handler(SC_State *SCState, SC_ADPU_CommandsTypeDef *SC_ADPU, SC_ADPU_ResponseTypeDef *SC_Response)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
switch (*SCState)
|
||||
{
|
||||
case SC_POWER_ON:
|
||||
if (SC_ADPU->Header.INS == SC_GET_A2R)
|
||||
{
|
||||
/* Smartcard initialization */
|
||||
SC_Init();
|
||||
|
||||
/* Reset Data from SC buffer */
|
||||
for (i = 0U; i < 40U; i++)
|
||||
{
|
||||
SC_ATR_Table[i] = 0;
|
||||
}
|
||||
|
||||
/* Reset SC_A2R Structure */
|
||||
SC_A2R.TS = 0U;
|
||||
SC_A2R.T0 = 0U;
|
||||
|
||||
for (i = 0U; i < MAX_PROTOCOLLEVEL; i++)
|
||||
{
|
||||
for (j = 0U; j < MAX_INTERFACEBYTE; j++)
|
||||
{
|
||||
SC_A2R.T[i].InterfaceByte[j].Status = 0U;
|
||||
SC_A2R.T[i].InterfaceByte[j].Value = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0U; i < HIST_LENGTH; i++)
|
||||
{
|
||||
SC_A2R.Historical[i] = 0U;
|
||||
}
|
||||
|
||||
SC_A2R.Tlength = 0U;
|
||||
SC_A2R.Hlength = 0U;
|
||||
|
||||
/* Next State */
|
||||
*SCState = SC_RESET_LOW;
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_RESET_LOW:
|
||||
if (SC_ADPU->Header.INS == SC_GET_A2R)
|
||||
{
|
||||
/* If card is detected then Power ON, Card Reset and wait for an answer) */
|
||||
if (SC_Detect() != 0U)
|
||||
{
|
||||
while (((*SCState) != SC_POWER_OFF) && ((*SCState) != SC_ACTIVE))
|
||||
{
|
||||
SC_AnswerReq(SCState, &SC_ATR_Table[0], 40U); /* Check for answer to reset */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*SCState) = SC_POWER_OFF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_ACTIVE:
|
||||
if (SC_ADPU->Header.INS == SC_GET_A2R)
|
||||
{
|
||||
uint8_t protocol = SC_decode_Answer2reset(&SC_ATR_Table[0]);
|
||||
if (protocol == T0_PROTOCOL)
|
||||
{
|
||||
(*SCState) = SC_ACTIVE_ON_T0;
|
||||
ProtocolNUM_OUT = T0_PROTOCOL;
|
||||
}
|
||||
else if (protocol == T1_PROTOCOL)
|
||||
{
|
||||
(*SCState) = SC_ACTIVE_ON_T1;
|
||||
ProtocolNUM_OUT = T1_PROTOCOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*SCState) = SC_POWER_OFF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_ACTIVE_ON_T0:
|
||||
/* process commands other than ATR */
|
||||
SC_SendData(SC_ADPU, SC_Response);
|
||||
break;
|
||||
|
||||
case SC_ACTIVE_ON_T1:
|
||||
/* process commands other than ATR */
|
||||
SC_SendData(SC_ADPU, SC_Response);
|
||||
break;
|
||||
|
||||
case SC_POWER_OFF:
|
||||
SC_DeInit(); /* Disable Smartcard interface */
|
||||
break;
|
||||
|
||||
default:
|
||||
(*SCState) = SC_POWER_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the power to the Smartcard.
|
||||
* @param NewState: new state of the Smartcard power supply.
|
||||
* This parameter can be: SC_ENABLED or SC_DISABLED.
|
||||
* @retval None
|
||||
*/
|
||||
void SC_PowerCmd(SCPowerState NewState)
|
||||
{
|
||||
UNUSED(NewState);
|
||||
/* enable or disable smartcard pin */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets or clears the Smartcard reset pin.
|
||||
* @param ResetState: this parameter specifies the state of the Smartcard
|
||||
* reset pin. BitVal must be one of the BitAction enum values:
|
||||
* @arg Bit_RESET: to clear the port pin.
|
||||
* @arg Bit_SET: to set the port pin.
|
||||
* @retval None
|
||||
*/
|
||||
/* static void SC_Reset(GPIO_PinState ResetState)
|
||||
{
|
||||
UNUSED(ResetState);
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resends the byte that failed to be received (by the Smartcard) correctly.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void SC_ParityErrorHandler(void)
|
||||
{
|
||||
/* Add your code here */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the IO speed (BaudRate) communication.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void SC_PTSConfig(void)
|
||||
{
|
||||
/* Add your code here */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manages the Smartcard transport layer: send APDU commands and receives
|
||||
* the APDU response.
|
||||
* @param SC_ADPU: pointer to a SC_ADPU_Commands structure which will be initialized.
|
||||
* @param SC_Response: pointer to a SC_ADPU_Response structure which will be initialized.
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_SendData(SC_ADPU_CommandsTypeDef *SCADPU, SC_ADPU_ResponseTypeDef *SC_ResponseStatus)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t SC_Command[5];
|
||||
uint8_t SC_DATA[LC_MAX];
|
||||
|
||||
UNUSED(SCADPU);
|
||||
|
||||
/* Reset response buffer */
|
||||
for (i = 0U; i < LC_MAX; i++)
|
||||
{
|
||||
SC_ResponseStatus->Data[i] = 0U;
|
||||
SC_DATA[i] = 0U;
|
||||
}
|
||||
|
||||
/* User to add code here */
|
||||
|
||||
/* send command to ICC and get response status */
|
||||
USBD_CCID_If_fops.Send_Process((uint8_t *)&SC_Command, (uint8_t *)&SC_DATA);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_AnswerReq
|
||||
Requests the reset answer from card.
|
||||
* @param SC_state: pointer to an SC_State enumeration that will contain the Smartcard state.
|
||||
* @param atr_buffer: pointer to a buffer which will contain the card ATR.
|
||||
* @param length: maximum ATR length
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_AnswerReq(SC_State *SC_state, uint8_t *atr_buffer, uint8_t length)
|
||||
{
|
||||
UNUSED(length);
|
||||
UNUSED(atr_buffer);
|
||||
|
||||
/* to be implemented by USER */
|
||||
switch (*SC_state)
|
||||
{
|
||||
case SC_RESET_LOW:
|
||||
/* Check response with reset low */
|
||||
(*SC_state) = SC_ACTIVE;
|
||||
break;
|
||||
|
||||
case SC_ACTIVE:
|
||||
break;
|
||||
case SC_RESET_HIGH:
|
||||
/* Check response with reset high */
|
||||
|
||||
break;
|
||||
|
||||
case SC_POWER_OFF:
|
||||
/* Close Connection if no answer received */
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
(*SC_state) = SC_RESET_LOW;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SC_decode_Answer2reset
|
||||
Decodes the Answer to reset received from card.
|
||||
* @param card: pointer to the buffer containing the card ATR.
|
||||
* @retval None
|
||||
*/
|
||||
static uint8_t SC_decode_Answer2reset(uint8_t *card)
|
||||
{
|
||||
uint32_t i = 0U;
|
||||
uint32_t flag = 0U;
|
||||
uint32_t protocol;
|
||||
uint8_t index = 0U;
|
||||
uint8_t level = 0U;
|
||||
|
||||
/******************************TS/T0 Decode************************************/
|
||||
index++;
|
||||
SC_A2R.TS = card[index]; /* Initial character */
|
||||
|
||||
index++;
|
||||
SC_A2R.T0 = card[index]; /* Format character */
|
||||
|
||||
/*************************Historical Table Length Decode***********************/
|
||||
SC_A2R.Hlength = SC_A2R.T0 & 0x0FU;
|
||||
|
||||
/******************************Protocol Level(1) Decode************************/
|
||||
/* Check TD(1) if present */
|
||||
if ((SC_A2R.T0 & 0x80U) == 0x80U)
|
||||
{
|
||||
flag = 1U;
|
||||
}
|
||||
|
||||
/* Each bits in the T0 high nibble(b8 to b5) equal to 1 indicates the presence
|
||||
of a further interface byte */
|
||||
for (i = 0U; i < 4U; i++)
|
||||
{
|
||||
if ((((SC_A2R.T0 & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
|
||||
{
|
||||
SC_A2R.T[level].InterfaceByte[i].Status = 1U;
|
||||
index++;
|
||||
SC_A2R.T[level].InterfaceByte[i].Value = card[index];
|
||||
SC_A2R.Tlength++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************T Decode*****************************************/
|
||||
if (SC_A2R.T[level].InterfaceByte[3].Status == 1U)
|
||||
{
|
||||
/* Only the protocol(parameter T) present in TD(1) is detected
|
||||
if two or more values of parameter T are present in TD(1), TD(2)..., so the
|
||||
firmware should be updated to support them */
|
||||
protocol = (uint8_t)(SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x0FU);
|
||||
}
|
||||
else
|
||||
{
|
||||
protocol = 0U;
|
||||
}
|
||||
|
||||
/* Protocol Level Increment */
|
||||
/******************************Protocol Level(n>1) Decode**********************/
|
||||
while (flag != 0U)
|
||||
{
|
||||
if ((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0x80U) == 0x80U)
|
||||
{
|
||||
flag = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = 0U;
|
||||
}
|
||||
/* Each bits in the high nibble(b8 to b5) for the TD(i) equal to 1 indicates
|
||||
the presence of a further interface byte */
|
||||
for (i = 0U; i < 4U; i++)
|
||||
{
|
||||
if ((((SC_A2R.T[level].InterfaceByte[SC_INTERFACEBYTE_TD].Value & 0xF0U) >> (4U + i)) & 0x1U) != 0U)
|
||||
{
|
||||
SC_A2R.T[level + 1U].InterfaceByte[i].Status = 1U;
|
||||
index++;
|
||||
SC_A2R.T[level + 1U].InterfaceByte[i].Value = card[index];
|
||||
SC_A2R.Tlength++;
|
||||
}
|
||||
}
|
||||
level++;
|
||||
}
|
||||
|
||||
for (i = 0U; i < SC_A2R.Hlength; i++)
|
||||
{
|
||||
SC_A2R.Historical[i] = card[i + 2U + SC_A2R.Tlength];
|
||||
}
|
||||
/*************************************TCK Decode*******************************/
|
||||
SC_A2R.TCK = card[SC_A2R.Hlength + 2U + SC_A2R.Tlength];
|
||||
|
||||
return (uint8_t)protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes all peripheral used for Smartcard interface.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_Init(void)
|
||||
{
|
||||
/*
|
||||
Add your initialization code here
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Deinitializes all resources used by the Smartcard interface.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void SC_DeInit(void)
|
||||
{
|
||||
/*
|
||||
Add your deinitialization code here
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the card power voltage.
|
||||
* @param SC_Voltage: specifies the card power voltage.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg SC_VOLTAGE_5V: 5V cards.
|
||||
* @arg SC_VOLTAGE_3V: 3V cards.
|
||||
* @retval None
|
||||
*/
|
||||
void SC_VoltageConfig(uint32_t SC_Voltage)
|
||||
{
|
||||
UNUSED(SC_Voltage);
|
||||
/* Add your code here */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures GPIO hardware resources used for Samrtcard.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SC_IOConfig(void)
|
||||
{
|
||||
/* Add your code here */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detects whether the Smartcard is present or not.
|
||||
* @param None.
|
||||
* @retval 1 - Smartcard inserted
|
||||
* 0 - Smartcard not inserted
|
||||
*/
|
||||
uint8_t SC_Detect(void)
|
||||
{
|
||||
uint8_t PIN_State = 0U;
|
||||
|
||||
/* Add your code here */
|
||||
|
||||
return PIN_State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Right Value from the D_Table Index
|
||||
* @param idx : Index to Read from the Table
|
||||
* @retval Value read from the Table
|
||||
*/
|
||||
uint32_t SC_GetDTableValue(uint32_t idx)
|
||||
{
|
||||
return D_Table[idx];
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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 is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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
|
||||
* @{
|
||||
*/
|
||||
#ifndef CDC_IN_EP
|
||||
#define CDC_IN_EP 0x81U /* EP1 for data IN */
|
||||
#endif /* CDC_IN_EP */
|
||||
#ifndef CDC_OUT_EP
|
||||
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#endif /* CDC_OUT_EP */
|
||||
#ifndef CDC_CMD_EP
|
||||
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
|
||||
#endif /* CDC_CMD_EP */
|
||||
|
||||
#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
|
||||
|
||||
#define CDC_REQ_MAX_DATA_SIZE 0x7U
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* 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);
|
||||
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
|
||||
} USBD_CDC_ItfTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit 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);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length, uint8_t ClassId);
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
|
||||
#else
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length);
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
|
||||
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CDC_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for usbd_cdc_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CDC_IF_TEMPLATE_H
|
||||
#define __USBD_CDC_IF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_cdc.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
extern USBD_CDC_ItfTypeDef USBD_CDC_Template_fops;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CDC_IF_TEMPLATE_H */
|
||||
|
||||
@@ -0,0 +1,893 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* 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);
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
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);
|
||||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* 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,
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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,
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
USBD_CDC_GetHSCfgDesc,
|
||||
USBD_CDC_GetFSCfgDesc,
|
||||
USBD_CDC_GetOtherSpeedCfgDesc,
|
||||
USBD_CDC_GetDeviceQualifierDescriptor,
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB CDC device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CDC_CfgDesc[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 */
|
||||
0x00,
|
||||
0x02, /* bNumInterfaces: 2 interfaces */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor
|
||||
describing the configuration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (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 endpoint 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 */
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* 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 */
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
static uint8_t CDCInEpAdd = CDC_IN_EP;
|
||||
static uint8_t CDCOutEpAdd = CDC_OUT_EP;
|
||||
static uint8_t CDCCmdEpAdd = CDC_CMD_EP;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
USBD_CDC_HandleTypeDef *hcdc;
|
||||
|
||||
hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef));
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_HS_IN_PACKET_SIZE);
|
||||
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
|
||||
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Set bInterval for CDC CMD Endpoint */
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_HS_BINTERVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_IN_PACKET_SIZE);
|
||||
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
|
||||
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Set bInterval for CMD Endpoint */
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
/* Open Command IN EP */
|
||||
(void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
hcdc->RxBuffer = NULL;
|
||||
|
||||
/* Init physical Interface components */
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
|
||||
|
||||
/* Init Xfer states */
|
||||
hcdc->TxState = 0U;
|
||||
hcdc->RxState = 0U;
|
||||
|
||||
if (hcdc->RxBuffer == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this CDC class instance */
|
||||
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Close EP IN */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCInEpAdd);
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close EP OUT */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCOutEpAdd);
|
||||
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U;
|
||||
|
||||
/* Close Command IN EP */
|
||||
(void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd);
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* DeInit physical Interface components */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassDataCmsit[pdev->classId];
|
||||
uint16_t len;
|
||||
uint8_t ifalt = 0U;
|
||||
uint16_t status_info = 0U;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
if (req->wLength != 0U)
|
||||
{
|
||||
if ((req->bmRequest & 0x80U) != 0U)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
|
||||
(uint8_t *)hcdc->data,
|
||||
req->wLength);
|
||||
|
||||
len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcdc->CmdOpCode = req->bRequest;
|
||||
hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE);
|
||||
|
||||
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
|
||||
(uint8_t *)req, 0U);
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)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;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)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;
|
||||
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
|
||||
((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
|
||||
{
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[epnum & 0xFU].total_length = 0U;
|
||||
|
||||
/* Send ZLP */
|
||||
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
hcdc->TxState = 0U;
|
||||
|
||||
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL)
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU))
|
||||
{
|
||||
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode,
|
||||
(uint8_t *)hcdc->data,
|
||||
(uint16_t)hcdc->CmdLength);
|
||||
hcdc->CmdOpCode = 0xFFU;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_CDC_GetFSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetHSCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CDC_HS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetOtherSpeedCfgDesc
|
||||
* Return configuration descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
|
||||
|
||||
if (pEpCmdDesc != NULL)
|
||||
{
|
||||
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
|
||||
return USBD_CDC_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_GetDeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
|
||||
|
||||
return USBD_CDC_DeviceQualifierDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (fops == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_SetTxBuffer
|
||||
* @param pdev: device instance
|
||||
* @param pbuff: Tx Buffer
|
||||
* @param length: length of data to be sent
|
||||
* @param ClassId: The Class ID
|
||||
* @retval status
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuff, uint32_t length, uint8_t ClassId)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
|
||||
#else
|
||||
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuff, uint32_t length)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc->TxBuffer = pbuff;
|
||||
hcdc->TxLength = length;
|
||||
|
||||
return (uint8_t)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->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hcdc->RxBuffer = pbuff;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_CDC_TransmitPacket
|
||||
* Transmit packet on IN endpoint
|
||||
* @param pdev: device instance
|
||||
* @param ClassId: The Class ID
|
||||
* @retval status
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
|
||||
#else
|
||||
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
USBD_StatusTypeDef ret = USBD_BUSY;
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hcdc == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (hcdc->TxState == 0U)
|
||||
{
|
||||
/* Tx Transfer in progress */
|
||||
hcdc->TxState = 1U;
|
||||
|
||||
/* Update the packet total length */
|
||||
pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength;
|
||||
|
||||
/* Transmit next packet */
|
||||
(void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer, hcdc->TxLength);
|
||||
|
||||
ret = USBD_OK;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare Out endpoint to receive next packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
|
||||
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief Generic media access Layer.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_cdc_if_template.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 int8_t TEMPLATE_Init(void);
|
||||
static int8_t TEMPLATE_DeInit(void);
|
||||
static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
|
||||
static int8_t TEMPLATE_Receive(uint8_t *pbuf, uint32_t *Len);
|
||||
static int8_t TEMPLATE_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
|
||||
|
||||
USBD_CDC_ItfTypeDef USBD_CDC_Template_fops =
|
||||
{
|
||||
TEMPLATE_Init,
|
||||
TEMPLATE_DeInit,
|
||||
TEMPLATE_Control,
|
||||
TEMPLATE_Receive,
|
||||
TEMPLATE_TransmitCplt
|
||||
};
|
||||
|
||||
USBD_CDC_LineCodingTypeDef linecoding =
|
||||
{
|
||||
115200, /* baud rate*/
|
||||
0x00, /* stop bits-1*/
|
||||
0x00, /* parity - none*/
|
||||
0x08 /* nb. of bits 8*/
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_Init
|
||||
* Initializes the CDC media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_Init(void)
|
||||
{
|
||||
/*
|
||||
Add your initialization code here
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_DeInit
|
||||
* DeInitializes the CDC media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_DeInit(void)
|
||||
{
|
||||
/*
|
||||
Add your deinitialization code here
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_Control
|
||||
* Manage the CDC class requests
|
||||
* @param Cmd: Command code
|
||||
* @param Buf: Buffer containing command data (request parameters)
|
||||
* @param Len: Number of data to be sent (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
|
||||
{
|
||||
UNUSED(length);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CDC_SEND_ENCAPSULATED_COMMAND:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_GET_ENCAPSULATED_RESPONSE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_SET_COMM_FEATURE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_GET_COMM_FEATURE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_CLEAR_COMM_FEATURE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_SET_LINE_CODING:
|
||||
linecoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) | \
|
||||
(pbuf[2] << 16) | (pbuf[3] << 24));
|
||||
linecoding.format = pbuf[4];
|
||||
linecoding.paritytype = pbuf[5];
|
||||
linecoding.datatype = pbuf[6];
|
||||
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_GET_LINE_CODING:
|
||||
pbuf[0] = (uint8_t)(linecoding.bitrate);
|
||||
pbuf[1] = (uint8_t)(linecoding.bitrate >> 8);
|
||||
pbuf[2] = (uint8_t)(linecoding.bitrate >> 16);
|
||||
pbuf[3] = (uint8_t)(linecoding.bitrate >> 24);
|
||||
pbuf[4] = linecoding.format;
|
||||
pbuf[5] = linecoding.paritytype;
|
||||
pbuf[6] = linecoding.datatype;
|
||||
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_SET_CONTROL_LINE_STATE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_SEND_BREAK:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_Receive
|
||||
* Data received over USB OUT endpoint are sent over CDC interface
|
||||
* through this function.
|
||||
*
|
||||
* @note
|
||||
* This function will issue a NAK packet on any OUT packet received on
|
||||
* USB endpoint until exiting this function. If you exit this function
|
||||
* before transfer is complete on CDC interface (ie. using DMA controller)
|
||||
* it will result in receiving more data while previous ones are still
|
||||
* not sent.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len)
|
||||
{
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_TransmitCplt
|
||||
* Data transmitted callback
|
||||
*
|
||||
* @note
|
||||
* This function is IN transfer complete callback used to inform user that
|
||||
* the submitted Data is successfully sent over USB.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
|
||||
{
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_ecm.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_cdc_ecm.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_CDC_ECM_H
|
||||
#define __USB_CDC_ECM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup usbd_cdc_ecm
|
||||
* @brief This file is the Header file for usbd_cdc_ecm.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup usbd_cdc_ecm_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/* Comment this define in order to disable the CDC ECM Notification pipe */
|
||||
|
||||
#ifndef CDC_ECM_IN_EP
|
||||
#define CDC_ECM_IN_EP 0x81U /* EP1 for data IN */
|
||||
#endif /* CDC_ECM_IN_EP */
|
||||
#ifndef CDC_ECM_OUT_EP
|
||||
#define CDC_ECM_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#endif /* CDC_ECM_OUT_EP */
|
||||
#ifndef CDC_ECM_CMD_EP
|
||||
#define CDC_ECM_CMD_EP 0x82U /* EP2 for CDC ECM commands */
|
||||
#endif /* CDC_ECM_CMD_EP */
|
||||
|
||||
#ifndef CDC_ECM_CMD_ITF_NBR
|
||||
#define CDC_ECM_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
|
||||
#endif /* CDC_ECM_CMD_ITF_NBR */
|
||||
|
||||
#ifndef CDC_ECM_COM_ITF_NBR
|
||||
#define CDC_ECM_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */
|
||||
#endif /* CDC_ECM_CMD_ITF_NBR */
|
||||
|
||||
#ifndef CDC_ECM_HS_BINTERVAL
|
||||
#define CDC_ECM_HS_BINTERVAL 0x10U
|
||||
#endif /* CDC_ECM_HS_BINTERVAL */
|
||||
|
||||
#ifndef CDC_ECM_FS_BINTERVAL
|
||||
#define CDC_ECM_FS_BINTERVAL 0x10U
|
||||
#endif /* CDC_ECM_FS_BINTERVAL */
|
||||
|
||||
#ifndef USBD_SUPPORT_USER_STRING_DESC
|
||||
#define USBD_SUPPORT_USER_STRING_DESC 1U
|
||||
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
||||
|
||||
/* CDC_ECM Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
|
||||
#define CDC_ECM_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
|
||||
#define CDC_ECM_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
|
||||
#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
|
||||
|
||||
#define CDC_ECM_CONFIG_DESC_SIZ 79U
|
||||
|
||||
#define CDC_ECM_DATA_BUFFER_SIZE 2000U
|
||||
|
||||
#define CDC_ECM_DATA_HS_IN_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE
|
||||
#define CDC_ECM_DATA_HS_OUT_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE
|
||||
|
||||
#define CDC_ECM_DATA_FS_IN_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE
|
||||
#define CDC_ECM_DATA_FS_OUT_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* CDC_ECM definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
#define CDC_ECM_SEND_ENCAPSULATED_COMMAND 0x00U
|
||||
#define CDC_ECM_GET_ENCAPSULATED_RESPONSE 0x01U
|
||||
#define CDC_ECM_SET_ETH_MULTICAST_FILTERS 0x40U
|
||||
#define CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER 0x41U
|
||||
#define CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER 0x42U
|
||||
#define CDC_ECM_SET_ETH_PACKET_FILTER 0x43U
|
||||
#define CDC_ECM_GET_ETH_STATISTIC 0x44U
|
||||
|
||||
#define CDC_ECM_NET_DISCONNECTED 0x00U
|
||||
#define CDC_ECM_NET_CONNECTED 0x01U
|
||||
|
||||
|
||||
/* Ethernet statistics definitions */
|
||||
#define CDC_ECM_XMIT_OK_VAL CDC_ECM_ETH_STATS_VAL_ENABLED
|
||||
#define CDC_ECM_XMIT_OK 0x01U
|
||||
#define CDC_ECM_RVC_OK 0x02U
|
||||
#define CDC_ECM_XMIT_ERROR 0x04U
|
||||
#define CDC_ECM_RCV_ERROR 0x08U
|
||||
#define CDC_ECM_RCV_NO_BUFFER 0x10U
|
||||
#define CDC_ECM_DIRECTED_BYTES_XMIT 0x20U
|
||||
#define CDC_ECM_DIRECTED_FRAMES_XMIT 0x40U
|
||||
#define CDC_ECM_MULTICAST_BYTES_XMIT 0x80U
|
||||
|
||||
#define CDC_ECM_MULTICAST_FRAMES_XMIT 0x01U
|
||||
#define CDC_ECM_BROADCAST_BYTES_XMIT 0x02U
|
||||
#define CDC_ECM_BROADCAST_FRAMES_XMIT 0x04U
|
||||
#define CDC_ECM_DIRECTED_BYTES_RCV 0x08U
|
||||
#define CDC_ECM_DIRECTED_FRAMES_RCV 0x10U
|
||||
#define CDC_ECM_MULTICAST_BYTES_RCV 0x20U
|
||||
#define CDC_ECM_MULTICAST_FRAMES_RCV 0x40U
|
||||
#define CDC_ECM_BROADCAST_BYTES_RCV 0x80U
|
||||
|
||||
#define CDC_ECM_BROADCAST_FRAMES_RCV 0x01U
|
||||
#define CDC_ECM_RCV_CRC_ERROR 0x02U
|
||||
#define CDC_ECM_TRANSMIT_QUEUE_LENGTH 0x04U
|
||||
#define CDC_ECM_RCV_ERROR_ALIGNMENT 0x08U
|
||||
#define CDC_ECM_XMIT_ONE_COLLISION 0x10U
|
||||
#define CDC_ECM_XMIT_MORE_COLLISIONS 0x20U
|
||||
#define CDC_ECM_XMIT_DEFERRED 0x40U
|
||||
#define CDC_ECM_XMIT_MAX_COLLISIONS 0x80U
|
||||
|
||||
#define CDC_ECM_RCV_OVERRUN 0x40U
|
||||
#define CDC_ECM_XMIT_UNDERRUN 0x40U
|
||||
#define CDC_ECM_XMIT_HEARTBEAT_FAILURE 0x40U
|
||||
#define CDC_ECM_XMIT_TIMES_CRS_LOST 0x40U
|
||||
#define CDC_ECM_XMIT_LATE_COLLISIONS 0x40U
|
||||
|
||||
#define CDC_ECM_ETH_STATS_RESERVED 0xE0U
|
||||
#define CDC_ECM_BMREQUEST_TYPE_ECM 0xA1U
|
||||
|
||||
/* MAC String index */
|
||||
#define CDC_ECM_MAC_STRING_INDEX 6U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
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);
|
||||
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
|
||||
int8_t (* Process)(USBD_HandleTypeDef *pdev);
|
||||
const uint8_t *pStrDesc;
|
||||
} USBD_CDC_ECM_ItfTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequest;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
uint8_t data[8];
|
||||
} USBD_CDC_ECM_NotifTypeDef;
|
||||
|
||||
/*
|
||||
* ECM Class specification revision 1.2
|
||||
* Table 3: Ethernet Networking Functional Descriptor
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bFunctionLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubType;
|
||||
uint8_t iMacAddress;
|
||||
uint8_t bEthernetStatistics3;
|
||||
uint8_t bEthernetStatistics2;
|
||||
uint8_t bEthernetStatistics1;
|
||||
uint8_t bEthernetStatistics0;
|
||||
uint16_t wMaxSegmentSize;
|
||||
uint16_t bNumberMCFiltes;
|
||||
uint8_t bNumberPowerFiltes;
|
||||
} __PACKED USBD_ECMFuncDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[CDC_ECM_DATA_BUFFER_SIZE / 4U]; /* Force 32-bit alignment */
|
||||
uint8_t CmdOpCode;
|
||||
uint8_t CmdLength;
|
||||
uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */
|
||||
uint8_t Reserved2; /* Reserved Byte to force 4 bytes alignment of following fields */
|
||||
uint8_t *RxBuffer;
|
||||
uint8_t *TxBuffer;
|
||||
uint32_t RxLength;
|
||||
uint32_t TxLength;
|
||||
|
||||
__IO uint32_t TxState;
|
||||
__IO uint32_t RxState;
|
||||
|
||||
__IO uint32_t MaxPcktLen;
|
||||
__IO uint32_t LinkStatus;
|
||||
__IO uint32_t NotificationStatus;
|
||||
USBD_CDC_ECM_NotifTypeDef Req;
|
||||
} USBD_CDC_ECM_HandleTypeDef;
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CDC_ECM;
|
||||
#define USBD_CDC_ECM_CLASS &USBD_CDC_ECM
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_ECM_ItfTypeDef *fops);
|
||||
|
||||
uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
|
||||
|
||||
uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
|
||||
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length, uint8_t ClassId);
|
||||
#else
|
||||
uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev);
|
||||
uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
|
||||
uint32_t length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_NotifCodeTypeDef Notif,
|
||||
uint16_t bVal, uint8_t *pData);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CDC_ECM_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file Inc/usbd_cdc_ecm_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for usbd_cdc_ecm_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CDC_ECM_IF_H
|
||||
#define __USBD_CDC_ECM_IF_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */
|
||||
#define CDC_ECM_MAC_STR_DESC (uint8_t *)"000202030000"
|
||||
#define CDC_ECM_MAC_ADDR0 0x00U /* 01 */
|
||||
#define CDC_ECM_MAC_ADDR1 0x02U /* 02 */
|
||||
#define CDC_ECM_MAC_ADDR2 0x02U /* 03 */
|
||||
#define CDC_ECM_MAC_ADDR3 0x03U /* 00 */
|
||||
#define CDC_ECM_MAC_ADDR4 0x00U /* 00 */
|
||||
#define CDC_ECM_MAC_ADDR5 0x00U /* 00 */
|
||||
|
||||
/* Max Number of Trials waiting for Tx ready */
|
||||
#define CDC_ECM_MAX_TX_WAIT_TRIALS 1000000U
|
||||
|
||||
#define CDC_ECM_ETH_STATS_BYTE0 0U
|
||||
/*(uint8_t)(CDC_ECM_XMIT_OK_VAL | CDC_ECM_RVC_OK_VAL | CDC_ECM_XMIT_ERROR_VAL | \
|
||||
CDC_ECM_RCV_ERROR_VAL | CDC_ECM_RCV_NO_BUFFER_VAL | CDC_ECM_DIRECTED_BYTES_XMIT_VAL | \
|
||||
CDC_ECM_DIRECTED_FRAMES_XMIT_VAL | CDC_ECM_MULTICAST_BYTES_XMIT_VAL) */
|
||||
|
||||
#define CDC_ECM_ETH_STATS_BYTE1 0U
|
||||
/*(uint8_t)(CDC_ECM_MULTICAST_FRAMES_XMIT_VAL | CDC_ECM_BROADCAST_BYTES_XMIT_VAL | \
|
||||
CDC_ECM_BROADCAST_FRAMES_XMIT_VAL | CDC_ECM_DIRECTED_BYTES_RCV_VAL | \
|
||||
CDC_ECM_DIRECTED_FRAMES_RCV_VAL | CDC_ECM_MULTICAST_BYTES_RCV_VAL | \
|
||||
CDC_ECM_MULTICAST_FRAMES_RCV_VAL | CDC_ECM_BROADCAST_BYTES_RCV_VAL) */
|
||||
|
||||
#define CDC_ECM_ETH_STATS_BYTE2 0U
|
||||
/*(uint8_t)(CDC_ECM_BROADCAST_FRAMES_RCV_VAL | CDC_ECM_RCV_CRC_ERROR_VAL | \
|
||||
CDC_ECM_TRANSMIT_QUEUE_LENGTH_VAL | CDC_ECM_RCV_ERROR_ALIGNMENT_VAL | \
|
||||
CDC_ECM_XMIT_ONE_COLLISION_VAL | CDC_ECM_XMIT_MORE_COLLISIONS_VAL | \
|
||||
CDC_ECM_XMIT_DEFERRED_VAL | CDC_ECM_XMIT_MAX_COLLISIONS_VAL) */
|
||||
|
||||
#define CDC_ECM_ETH_STATS_BYTE3 0U
|
||||
/*(uint8_t)(CDC_ECM_RCV_OVERRUN_VAL | CDC_ECM_XMIT_UNDERRUN_VAL | CDC_ECM_XMIT_HEARTBEAT_FAILURE_VAL | \
|
||||
CDC_ECM_XMIT_TIMES_CRS_LOST_VAL | CDC_ECM_XMIT_LATE_COLLISIONS_VAL | CDC_ECM_ETH_STATS_RESERVED) */
|
||||
|
||||
/* Ethernet Maximum Segment size, typically 1514 bytes */
|
||||
#define CDC_ECM_ETH_MAX_SEGSZE 1514U
|
||||
|
||||
/* Number of Ethernet multicast filters */
|
||||
#define CDC_ECM_ETH_NBR_MACFILTERS 0U
|
||||
|
||||
/* Number of wakeup power filters */
|
||||
#define CDC_ECM_ETH_NBR_PWRFILTERS 0U
|
||||
|
||||
|
||||
#define CDC_ECM_CONNECT_SPEED_UPSTREAM 0x004C4B40U /* 5Mbps */
|
||||
#define CDC_ECM_CONNECT_SPEED_DOWNSTREAM 0x004C4B40U /* 5Mbps */
|
||||
|
||||
extern USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
#endif /* __USBD_CDC_ECM_IF_H */
|
||||
|
||||
+1046
File diff suppressed because it is too large
Load Diff
+274
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file Src/usbd_cdc_ecm_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source file for USBD CDC_ECM interface
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbd_cdc_ecm_if_template.h"
|
||||
/*
|
||||
|
||||
Include here LwIP files if used
|
||||
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Received Data over USB are stored in this buffer */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif /* ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END;
|
||||
|
||||
/* Transmitted Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif /* ( __ICCARM__ ) */
|
||||
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END;
|
||||
|
||||
static uint8_t CDC_ECMInitialized = 0U;
|
||||
|
||||
/* USB handler declaration */
|
||||
extern USBD_HandleTypeDef USBD_Device;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static int8_t CDC_ECM_Itf_Init(void);
|
||||
static int8_t CDC_ECM_Itf_DeInit(void);
|
||||
static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
|
||||
static int8_t CDC_ECM_Itf_Receive(uint8_t *pbuf, uint32_t *Len);
|
||||
static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
|
||||
static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev);
|
||||
|
||||
USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops =
|
||||
{
|
||||
CDC_ECM_Itf_Init,
|
||||
CDC_ECM_Itf_DeInit,
|
||||
CDC_ECM_Itf_Control,
|
||||
CDC_ECM_Itf_Receive,
|
||||
CDC_ECM_Itf_TransmitCplt,
|
||||
CDC_ECM_Itf_Process,
|
||||
(uint8_t *)CDC_ECM_MAC_STR_DESC,
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_Init
|
||||
* Initializes the CDC_ECM media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_Init(void)
|
||||
{
|
||||
if (CDC_ECMInitialized == 0U)
|
||||
{
|
||||
/*
|
||||
Initialize the TCP/IP stack here
|
||||
*/
|
||||
|
||||
CDC_ECMInitialized = 1U;
|
||||
}
|
||||
|
||||
/* Set Application Buffers */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
(void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U);
|
||||
#else
|
||||
(void)USBD_CDC_ECM_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
(void)USBD_CDC_ECM_SetRxBuffer(&USBD_Device, UserRxBuffer);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_DeInit
|
||||
* DeInitializes the CDC_ECM media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_DeInit(void)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Notify application layer that link is down */
|
||||
hcdc_cdc_ecm->LinkStatus = 0U;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_Control
|
||||
* Manage the CDC_ECM class requests
|
||||
* @param Cmd: Command code
|
||||
* @param Buf: Buffer containing command data (request parameters)
|
||||
* @param Len: Number of data to be sent (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CDC_ECM_SEND_ENCAPSULATED_COMMAND:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_GET_ENCAPSULATED_RESPONSE:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_SET_ETH_MULTICAST_FILTERS:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_SET_ETH_PACKET_FILTER:
|
||||
/* Check if this is the first time we enter */
|
||||
if (hcdc_cdc_ecm->LinkStatus == 0U)
|
||||
{
|
||||
/*
|
||||
Setup the Link up at TCP/IP level
|
||||
*/
|
||||
hcdc_cdc_ecm->LinkStatus = 1U;
|
||||
|
||||
/* Modification for MacOS which doesn't send SetInterface before receiving INs */
|
||||
if (hcdc_cdc_ecm->NotificationStatus == 0U)
|
||||
{
|
||||
/* Send notification: NETWORK_CONNECTION Event */
|
||||
(void)USBD_CDC_ECM_SendNotification(&USBD_Device, NETWORK_CONNECTION,
|
||||
CDC_ECM_NET_CONNECTED, NULL);
|
||||
|
||||
/* Prepare for sending Connection Speed Change notification */
|
||||
hcdc_cdc_ecm->NotificationStatus = 1U;
|
||||
}
|
||||
}
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_ECM_GET_ETH_STATISTIC:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UNUSED(length);
|
||||
UNUSED(pbuf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_Receive
|
||||
* Data received over USB OUT endpoint are sent over CDC_ECM interface
|
||||
* through this function.
|
||||
* @param Buf: Buffer of data to be transmitted
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len)
|
||||
{
|
||||
/* Get the CDC_ECM handler pointer */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Call Eth buffer processing */
|
||||
hcdc_cdc_ecm->RxState = 1U;
|
||||
|
||||
UNUSED(Len);
|
||||
UNUSED(Buf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_TransmitCplt
|
||||
* Data transmitted callback
|
||||
*
|
||||
* @note
|
||||
* This function is IN transfer complete callback used to inform user that
|
||||
* the submitted Data is successfully sent over USB.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
|
||||
{
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_ECM_Itf_Process
|
||||
* Data received over USB OUT endpoint are sent over CDC_ECM interface
|
||||
* through this function.
|
||||
* @param pdef: pointer to the USB Device Handle
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Get the CDC_ECM handler pointer */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
|
||||
#else
|
||||
USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hcdc_cdc_ecm == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (hcdc_cdc_ecm->LinkStatus != 0U)
|
||||
{
|
||||
/*
|
||||
Read a received packet from the Ethernet buffers and send it
|
||||
to the lwIP for handling
|
||||
Call here the TCP/IP background tasks.
|
||||
*/
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
+527
@@ -0,0 +1,527 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_rndis.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_cdc_rndis.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_CDC_RNDIS_H
|
||||
#define __USB_CDC_RNDIS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup usbd_cdc_rndis
|
||||
* @brief This file is the Header file for usbd_cdc_rndis.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup usbd_cdc_rndis_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef CDC_RNDIS_IN_EP
|
||||
#define CDC_RNDIS_IN_EP 0x81U /* EP1 for data IN */
|
||||
#endif /* CDC_RNDIS_IN_EP */
|
||||
#ifndef CDC_RNDIS_OUT_EP
|
||||
#define CDC_RNDIS_OUT_EP 0x01U /* EP1 for data OUT */
|
||||
#endif /* CDC_RNDIS_OUT_EP */
|
||||
#ifndef CDC_RNDIS_CMD_EP
|
||||
#define CDC_RNDIS_CMD_EP 0x82U /* EP2 for CDC_RNDIS commands */
|
||||
#endif /* CDC_RNDIS_CMD_EP */
|
||||
|
||||
#ifndef CDC_RNDIS_CMD_ITF_NBR
|
||||
#define CDC_RNDIS_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
|
||||
#endif /* CDC_RNDIS_CMD_ITF_NBR */
|
||||
|
||||
#ifndef CDC_RNDIS_COM_ITF_NBR
|
||||
#define CDC_RNDIS_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */
|
||||
#endif /* CDC_RNDIS_CMD_ITF_NBR */
|
||||
|
||||
#ifndef CDC_RNDIS_HS_BINTERVAL
|
||||
#define CDC_RNDIS_HS_BINTERVAL 0x10U
|
||||
#endif /* CDC_RNDIS_HS_BINTERVAL */
|
||||
|
||||
#ifndef CDC_RNDIS_FS_BINTERVAL
|
||||
#define CDC_RNDIS_FS_BINTERVAL 0x10U
|
||||
#endif /* CDC_RNDIS_FS_BINTERVAL */
|
||||
|
||||
|
||||
/* CDC_RNDIS Endpoints parameters: you can fine tune these values
|
||||
depending on the needed baudrates and performance. */
|
||||
#define CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
|
||||
#define CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
|
||||
#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
|
||||
|
||||
#define CDC_RNDIS_CONFIG_DESC_SIZ 75U
|
||||
#define CDC_RNDIS_DATA_HS_IN_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE
|
||||
#define CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE
|
||||
|
||||
#define CDC_RNDIS_DATA_FS_IN_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE
|
||||
#define CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* CDC_RNDIS definitions */
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
/** Implemented CDC_RNDIS Version Major */
|
||||
#define CDC_RNDIS_VERSION_MAJOR 0x01U
|
||||
|
||||
/* Implemented CDC_RNDIS Version Minor */
|
||||
#define CDC_RNDIS_VERSION_MINOR 0x00U
|
||||
|
||||
/* Maximum size in bytes of a CDC_RNDIS control message
|
||||
which can be sent or received */
|
||||
#define CDC_RNDIS_MESSAGE_BUFFER_SIZE 128U
|
||||
|
||||
/* Maximum size in bytes of an Ethernet frame
|
||||
according to the Ethernet standard */
|
||||
#define CDC_RNDIS_ETH_FRAME_SIZE_MAX 1536U
|
||||
|
||||
/* Maximum size allocated for buffer
|
||||
inside Query messages structures */
|
||||
#define CDC_RNDIS_MAX_INFO_BUFF_SZ 200U
|
||||
#define CDC_RNDIS_MAX_DATA_SZE 2000U
|
||||
|
||||
/* Notification request value for a CDC_RNDIS
|
||||
Response Available notification */
|
||||
#define CDC_RNDIS_NOTIFICATION_RESP_AVAILABLE 0x00000001UL
|
||||
|
||||
|
||||
#define CDC_RNDIS_PACKET_MSG_ID 0x00000001UL
|
||||
#define CDC_RNDIS_INITIALIZE_MSG_ID 0x00000002UL
|
||||
#define CDC_RNDIS_HALT_MSG_ID 0x00000003UL
|
||||
#define CDC_RNDIS_QUERY_MSG_ID 0x00000004UL
|
||||
#define CDC_RNDIS_SET_MSG_ID 0x00000005UL
|
||||
#define CDC_RNDIS_RESET_MSG_ID 0x00000006UL
|
||||
#define CDC_RNDIS_INDICATE_STATUS_MSG_ID 0x00000007UL
|
||||
#define CDC_RNDIS_KEEPALIVE_MSG_ID 0x00000008UL
|
||||
|
||||
#define CDC_RNDIS_INITIALIZE_CMPLT_ID 0x80000002UL
|
||||
#define CDC_RNDIS_QUERY_CMPLT_ID 0x80000004UL
|
||||
#define CDC_RNDIS_SET_CMPLT_ID 0x80000005UL
|
||||
#define CDC_RNDIS_RESET_CMPLT_ID 0x80000006UL
|
||||
#define CDC_RNDIS_KEEPALIVE_CMPLT_ID 0x80000008UL
|
||||
|
||||
#define CDC_RNDIS_STATUS_SUCCESS 0x00000000UL
|
||||
#define CDC_RNDIS_STATUS_FAILURE 0xC0000001UL
|
||||
#define CDC_RNDIS_STATUS_INVALID_DATA 0xC0010015UL
|
||||
#define CDC_RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
|
||||
#define CDC_RNDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
|
||||
#define CDC_RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
|
||||
/** Media state */
|
||||
#define CDC_RNDIS_MEDIA_STATE_CONNECTED 0x00000000UL
|
||||
#define CDC_RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
|
||||
|
||||
/** Media types */
|
||||
#define CDC_RNDIS_MEDIUM_802_3 0x00000000UL
|
||||
|
||||
#define CDC_RNDIS_DF_CONNECTIONLESS 0x00000001UL
|
||||
#define CDC_RNDIS_DF_CONNECTION_ORIENTED 0x00000002UL
|
||||
|
||||
/** Hardware status of the underlying NIC */
|
||||
#define CDC_RNDIS_HW_STS_READY 0x00000000UL
|
||||
#define CDC_RNDIS_HW_STS_INITIALIZING 0x00000001UL
|
||||
#define CDC_RNDIS_HW_STS_RESET 0x00000002UL
|
||||
#define CDC_RNDIS_HW_STS_CLOSING 0x00000003UL
|
||||
#define CDC_RNDIS_HW_STS_NOT_READY 0x00000004UL
|
||||
|
||||
/** Packet filter */
|
||||
#define CDC_RNDIS_PACKET_DIRECTED 0x00000001UL
|
||||
#define CDC_RNDIS_PACKET_MULTICAST 0x00000002UL
|
||||
#define CDC_RNDIS_PACKET_ALL_MULTICAST 0x00000004UL
|
||||
#define CDC_RNDIS_PACKET_BROADCAST 0x00000008UL
|
||||
#define CDC_RNDIS_PACKET_SOURCE_ROUTING 0x00000010UL
|
||||
#define CDC_RNDIS_PACKET_PROMISCUOUS 0x00000020UL
|
||||
#define CDC_RNDIS_PACKET_SMT 0x00000040UL
|
||||
#define CDC_RNDIS_PACKET_ALL_LOCAL 0x00000080UL
|
||||
#define CDC_RNDIS_PACKET_GROUP 0x00001000UL
|
||||
#define CDC_RNDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
|
||||
#define CDC_RNDIS_PACKET_FUNCTIONAL 0x00004000UL
|
||||
#define CDC_RNDIS_PACKET_MAC_FRAME 0x00008000UL
|
||||
|
||||
#define OID_GEN_SUPPORTED_LIST 0x00010101UL
|
||||
#define OID_GEN_HARDWARE_STATUS 0x00010102UL
|
||||
#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
|
||||
#define OID_GEN_MEDIA_IN_USE 0x00010104UL
|
||||
#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
|
||||
#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
|
||||
#define OID_GEN_LINK_SPEED 0x00010107UL
|
||||
#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
|
||||
#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
|
||||
#define OID_GEN_VENDOR_ID 0x0001010CUL
|
||||
#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
|
||||
#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
|
||||
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
|
||||
#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115UL
|
||||
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
|
||||
#define OID_GEN_XMIT_OK 0x00020101UL
|
||||
#define OID_GEN_RCV_OK 0x00020102UL
|
||||
#define OID_GEN_XMIT_ERROR 0x00020103UL
|
||||
#define OID_GEN_RCV_ERROR 0x00020104UL
|
||||
#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
|
||||
#define OID_GEN_CDC_RNDIS_CONFIG_PARAMETER 0x0001021BUL
|
||||
#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
|
||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
|
||||
#define OID_802_3_MULTICAST_LIST 0x01010103UL
|
||||
#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
|
||||
#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
|
||||
#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
|
||||
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
|
||||
|
||||
|
||||
#define CDC_RNDIS_SEND_ENCAPSULATED_COMMAND 0x00U
|
||||
#define CDC_RNDIS_GET_ENCAPSULATED_RESPONSE 0x01U
|
||||
|
||||
#define CDC_RNDIS_NET_DISCONNECTED 0x00U
|
||||
#define CDC_RNDIS_NET_CONNECTED 0x01U
|
||||
|
||||
#define CDC_RNDIS_BMREQUEST_TYPE_RNDIS 0xA1U
|
||||
#define CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET 8U
|
||||
|
||||
/* MAC String index */
|
||||
#define CDC_RNDIS_MAC_STRING_INDEX 6U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
typedef struct _USBD_CDC_RNDIS_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);
|
||||
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
|
||||
int8_t (* Process)(USBD_HandleTypeDef *pdev);
|
||||
uint8_t *pStrDesc;
|
||||
} USBD_CDC_RNDIS_ItfTypeDef;
|
||||
|
||||
/* CDC_RNDIS State values */
|
||||
typedef enum
|
||||
{
|
||||
CDC_RNDIS_STATE_UNINITIALIZED = 0,
|
||||
CDC_RNDIS_STATE_BUS_INITIALIZED = 1,
|
||||
CDC_RNDIS_STATE_INITIALIZED = 2,
|
||||
CDC_RNDIS_STATE_DATA_INITIALIZED = 3
|
||||
} USBD_CDC_RNDIS_StateTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bmRequest;
|
||||
uint8_t bRequest;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
uint8_t data[8];
|
||||
} USBD_CDC_RNDIS_NotifTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[CDC_RNDIS_MAX_DATA_SZE / 4U]; /* Force 32-bit alignment */
|
||||
uint8_t CmdOpCode;
|
||||
uint8_t CmdLength;
|
||||
uint8_t ResponseRdy; /* Indicates if the Device Response to an CDC_RNDIS msg is ready */
|
||||
uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */
|
||||
uint8_t *RxBuffer;
|
||||
uint8_t *TxBuffer;
|
||||
uint32_t RxLength;
|
||||
uint32_t TxLength;
|
||||
|
||||
USBD_CDC_RNDIS_NotifTypeDef Req;
|
||||
USBD_CDC_RNDIS_StateTypeDef State;
|
||||
|
||||
__IO uint32_t TxState;
|
||||
__IO uint32_t RxState;
|
||||
|
||||
__IO uint32_t MaxPcktLen;
|
||||
__IO uint32_t LinkStatus;
|
||||
__IO uint32_t NotificationStatus;
|
||||
__IO uint32_t PacketFilter;
|
||||
} USBD_CDC_RNDIS_HandleTypeDef;
|
||||
|
||||
/* Messages Sent by the Host ---------------------*/
|
||||
|
||||
/* Type define for a CDC_RNDIS Initialize command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t MaxTransferSize;
|
||||
} USBD_CDC_RNDIS_InitMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Halt Message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
} USBD_CDC_RNDIS_HaltMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Query command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t RequestId;
|
||||
uint32_t Oid;
|
||||
uint32_t InfoBufLength;
|
||||
uint32_t InfoBufOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
|
||||
} USBD_CDC_RNDIS_QueryMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Set command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Oid;
|
||||
uint32_t InfoBufLength;
|
||||
uint32_t InfoBufOffset;
|
||||
uint32_t DeviceVcHandle;
|
||||
uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
|
||||
} USBD_CDC_RNDIS_SetMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Reset message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t Reserved;
|
||||
} USBD_CDC_RNDIS_ResetMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Keepalive command message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
} USBD_CDC_RNDIS_KpAliveMsgTypeDef;
|
||||
|
||||
|
||||
/* Messages Sent by the Device ---------------------*/
|
||||
|
||||
/* Type define for a CDC_RNDIS Initialize complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Status;
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t DeviceFlags;
|
||||
uint32_t Medium;
|
||||
uint32_t MaxPacketsPerTransfer;
|
||||
uint32_t MaxTransferSize;
|
||||
uint32_t PacketAlignmentFactor;
|
||||
uint32_t AFListOffset;
|
||||
uint32_t AFListSize;
|
||||
} USBD_CDC_RNDIS_InitCpltMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Query complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Status;
|
||||
uint32_t InfoBufLength;
|
||||
uint32_t InfoBufOffset;
|
||||
uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
|
||||
} USBD_CDC_RNDIS_QueryCpltMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Set complete response message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Status;
|
||||
} USBD_CDC_RNDIS_SetCpltMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Reset complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t Status;
|
||||
uint32_t AddrReset;
|
||||
} USBD_CDC_RNDIS_ResetCpltMsgTypeDef;
|
||||
|
||||
/* Type define for CDC_RNDIS struct to indicate a change
|
||||
in the status of the device */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t Status;
|
||||
uint32_t StsBufLength;
|
||||
uint32_t StsBufOffset;
|
||||
} USBD_CDC_RNDIS_StsChangeMsgTypeDef;
|
||||
|
||||
/* Type define for a CDC_RNDIS Keepalive complete message */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Status;
|
||||
} USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef;
|
||||
|
||||
|
||||
/* Messages Sent by both Host and Device ---------------------*/
|
||||
|
||||
/* Type define for a CDC_RNDIS packet message, used to encapsulate
|
||||
Ethernet packets sent to and from the adapter */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataLength;
|
||||
uint32_t OOBDataOffset;
|
||||
uint32_t OOBDataLength;
|
||||
uint32_t NumOOBDataElements;
|
||||
uint32_t PerPacketInfoOffset;
|
||||
uint32_t PerPacketInfoLength;
|
||||
uint32_t VcHandle;
|
||||
uint32_t Reserved;
|
||||
} USBD_CDC_RNDIS_PacketMsgTypeDef;
|
||||
|
||||
/* Miscellaneous types used for parsing ---------------------*/
|
||||
|
||||
/* The common part for all CDC_RNDIS messages Complete response */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
uint32_t ReqId;
|
||||
uint32_t Status;
|
||||
} USBD_CDC_RNDIS_CommonCpltMsgTypeDef;
|
||||
|
||||
/* Type define for a single parameter structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ParamNameOffset;
|
||||
uint32_t ParamNameLength;
|
||||
uint32_t ParamType;
|
||||
uint32_t ParamValueOffset;
|
||||
uint32_t ParamValueLength;
|
||||
} USBD_CDC_RNDIS_ParamStructTypeDef;
|
||||
|
||||
|
||||
/* Type define of a single CDC_RNDIS OOB data record */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Size;
|
||||
uint32_t Type;
|
||||
uint32_t ClassInfoType;
|
||||
uint32_t OOBData[sizeof(uint32_t)];
|
||||
} USBD_CDC_RNDIS_OOBPacketTypeDef;
|
||||
|
||||
/* Type define for notification structure */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t notification;
|
||||
uint32_t reserved;
|
||||
} USBD_CDC_RNDIS_NotifStructTypeDef;
|
||||
|
||||
/* This structure will be used to store the type, the size and ID for any
|
||||
received message from the control endpoint */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MsgType;
|
||||
uint32_t MsgLength;
|
||||
} USBD_CDC_RNDIS_CtrlMsgTypeDef;
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CDC_RNDIS;
|
||||
#define USBD_CDC_RNDIS_CLASS &USBD_CDC_RNDIS
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
|
||||
uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_RNDIS_ItfTypeDef *fops);
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId);
|
||||
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuff, uint32_t length, uint8_t ClassId);
|
||||
#else
|
||||
uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev);
|
||||
uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *pbuff, uint32_t length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
|
||||
USBD_CDC_NotifCodeTypeDef Notif,
|
||||
uint16_t bVal, uint8_t *pData);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CDC_RNDIS_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_rndis_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for usbd_cdc_rndis_if.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CDC_RNDIS_IF_H
|
||||
#define __USBD_CDC_RNDIS_IF_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_cdc_rndis.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */
|
||||
#define CDC_RNDIS_MAC_STR_DESC (uint8_t *)"000202030000"
|
||||
#define CDC_RNDIS_MAC_ADDR0 0x00U /* 01 */
|
||||
#define CDC_RNDIS_MAC_ADDR1 0x02U /* 02 */
|
||||
#define CDC_RNDIS_MAC_ADDR2 0x02U /* 03 */
|
||||
#define CDC_RNDIS_MAC_ADDR3 0x03U /* 00 */
|
||||
#define CDC_RNDIS_MAC_ADDR4 0x00U /* 00 */
|
||||
#define CDC_RNDIS_MAC_ADDR5 0x00U /* 00 */
|
||||
|
||||
#define USBD_CDC_RNDIS_VENDOR_DESC "STMicroelectronics"
|
||||
#define USBD_CDC_RNDIS_LINK_SPEED 100000U /* 10Mbps */
|
||||
#define USBD_CDC_RNDIS_VID 0x0483U
|
||||
|
||||
/* Max Number of Trials waiting for Tx ready */
|
||||
#define CDC_RNDIS_MAX_TX_WAIT_TRIALS 1000000U
|
||||
|
||||
/* Ethernet Maximum Segment size, typically 1514 bytes */
|
||||
#define CDC_RNDIS_ETH_MAX_SEGSZE 1514U
|
||||
|
||||
#define CDC_RNDIS_CONNECT_SPEED_UPSTREAM 0x1E000000U
|
||||
#define CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM 0x1E000000U
|
||||
|
||||
|
||||
extern USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops;
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#endif /* __USBD_CDC_RNDIS_IF_H */
|
||||
|
||||
+1704
File diff suppressed because it is too large
Load Diff
+261
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_cdc_rndis_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief Source file for USBD CDC_RNDIS interface template
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
/* Include TCP/IP stack header files */
|
||||
/*
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "http_cgi_ssi.h"
|
||||
#include "ethernetif.h"
|
||||
*/
|
||||
|
||||
#include "usbd_cdc_rndis_if_template.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Received Data over USB are stored in this buffer */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif /* __ICCARM__ */
|
||||
__ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END;
|
||||
|
||||
/* Transmitted Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */
|
||||
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||
#pragma data_alignment=4
|
||||
#endif /* __ICCARM__ */
|
||||
__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END;
|
||||
|
||||
static uint8_t CDC_RNDISInitialized = 0U;
|
||||
|
||||
/* USB handler declaration */
|
||||
extern USBD_HandleTypeDef USBD_Device;
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static int8_t CDC_RNDIS_Itf_Init(void);
|
||||
static int8_t CDC_RNDIS_Itf_DeInit(void);
|
||||
static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
|
||||
static int8_t CDC_RNDIS_Itf_Receive(uint8_t *pbuf, uint32_t *Len);
|
||||
static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
|
||||
static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev);
|
||||
|
||||
USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops =
|
||||
{
|
||||
CDC_RNDIS_Itf_Init,
|
||||
CDC_RNDIS_Itf_DeInit,
|
||||
CDC_RNDIS_Itf_Control,
|
||||
CDC_RNDIS_Itf_Receive,
|
||||
CDC_RNDIS_Itf_TransmitCplt,
|
||||
CDC_RNDIS_Itf_Process,
|
||||
(uint8_t *)CDC_RNDIS_MAC_STR_DESC,
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_Init
|
||||
* Initializes the CDC_RNDIS media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_Init(void)
|
||||
{
|
||||
if (CDC_RNDISInitialized == 0U)
|
||||
{
|
||||
/*
|
||||
Initialize the LwIP stack
|
||||
Add your code here
|
||||
|
||||
*/
|
||||
|
||||
CDC_RNDISInitialized = 1U;
|
||||
}
|
||||
|
||||
/* Set Application Buffers */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
(void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U, 0U);
|
||||
#else
|
||||
(void)USBD_CDC_RNDIS_SetTxBuffer(&USBD_Device, UserTxBuffer, 0U);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
(void)USBD_CDC_RNDIS_SetRxBuffer(&USBD_Device, UserRxBuffer);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_DeInit
|
||||
* DeInitializes the CDC_RNDIS media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_DeInit(void)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/*
|
||||
Add your code here
|
||||
*/
|
||||
|
||||
/* Notify application layer that link is down */
|
||||
hcdc_cdc_rndis->LinkStatus = 0U;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_Control
|
||||
* Manage the CDC_RNDIS class requests
|
||||
* @param Cmd: Command code
|
||||
* @param Buf: Buffer containing command data (request parameters)
|
||||
* @param Len: Number of data to be sent (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
|
||||
{
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CDC_RNDIS_SEND_ENCAPSULATED_COMMAND:
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
case CDC_RNDIS_GET_ENCAPSULATED_RESPONSE:
|
||||
/* Check if this is the first time we enter */
|
||||
if (hcdc_cdc_rndis->LinkStatus == 0U)
|
||||
{
|
||||
/* Setup the Link up at TCP/IP stack level */
|
||||
hcdc_cdc_rndis->LinkStatus = 1U;
|
||||
/*
|
||||
Add your code here
|
||||
*/
|
||||
}
|
||||
/* Add your code here */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Add your code here */
|
||||
break;
|
||||
}
|
||||
|
||||
UNUSED(length);
|
||||
UNUSED(pbuf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_Receive
|
||||
* Data received over USB OUT endpoint are sent over CDC_RNDIS interface
|
||||
* through this function.
|
||||
* @param Buf: Buffer of data to be transmitted
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len)
|
||||
{
|
||||
/* Get the CDC_RNDIS handler pointer */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *) \
|
||||
(USBD_Device.pClassDataCmsit[USBD_Device.classId]);
|
||||
#else
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(USBD_Device.pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Call Eth buffer processing */
|
||||
hcdc_cdc_rndis->RxState = 1U;
|
||||
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_TransmitCplt
|
||||
* Data transmitted callback
|
||||
*
|
||||
* @note
|
||||
* This function is IN transfer complete callback used to inform user that
|
||||
* the submitted Data is successfully sent over USB.
|
||||
*
|
||||
* @param Buf: Buffer of data to be received
|
||||
* @param Len: Number of data received (in bytes)
|
||||
* @param epnum: EP number
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
|
||||
{
|
||||
UNUSED(Buf);
|
||||
UNUSED(Len);
|
||||
UNUSED(epnum);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CDC_RNDIS_Itf_Process
|
||||
* Data received over USB OUT endpoint are sent over CDC_RNDIS interface
|
||||
* through this function.
|
||||
* @param pdef: pointer to the USB Device Handle
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
/* Get the CDC_RNDIS handler pointer */
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassDataCmsit[pdev->classId]);
|
||||
#else
|
||||
USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassData);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hcdc_cdc_rndis == NULL)
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (hcdc_cdc_rndis->LinkStatus != 0U)
|
||||
{
|
||||
/*
|
||||
Add your code here
|
||||
Read a received packet from the Ethernet buffers and send it
|
||||
to the lwIP for handling
|
||||
*/
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_composite_builder.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the usbd_composite_builder.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_COMPOSITE_BUILDER_H__
|
||||
#define __USBD_COMPOSITE_BUILDER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_HID == 1U
|
||||
#include "usbd_hid.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_HID */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_MSC == 1U
|
||||
#include "usbd_msc.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_MSC */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_CDC == 1U
|
||||
#include "usbd_cdc.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CDC */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_DFU == 1U
|
||||
#include "usbd_dfu.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_DFU */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_RNDIS == 1U
|
||||
#include "usbd_cdc_rndis.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
#ifndef __USBD_CDC_ECM_IF_H
|
||||
#include "usbd_cdc_ecm_if_template.h"
|
||||
#endif /* __USBD_CDC_ECM_IF_H */
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1
|
||||
#include "usbd_audio.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1
|
||||
#include "usbd_customhid.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_VIDEO == 1
|
||||
#include "usbd_video.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_PRINTER == 1
|
||||
#include "usbd_printer.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_CCID == 1U
|
||||
#include "usbd_ccid.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CCID */
|
||||
|
||||
#if USBD_CMPSIT_ACTIVATE_MTP == 1U
|
||||
#include "usbd_mtp.h"
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_MTP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* By default all classes are deactivated, in order to activate a class
|
||||
define its value to zero */
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_HID
|
||||
#define USBD_CMPSIT_ACTIVATE_HID 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_HID */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_MSC
|
||||
#define USBD_CMPSIT_ACTIVATE_MSC 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_MSC */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_DFU
|
||||
#define USBD_CMPSIT_ACTIVATE_DFU 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_DFU */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_CDC
|
||||
#define USBD_CMPSIT_ACTIVATE_CDC 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CDC */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_CDC_ECM
|
||||
#define USBD_CMPSIT_ACTIVATE_CDC_ECM 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_RNDIS
|
||||
#define USBD_CMPSIT_ACTIVATE_RNDIS 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_AUDIO
|
||||
#define USBD_CMPSIT_ACTIVATE_AUDIO 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_CUSTOMHID
|
||||
#define USBD_CMPSIT_ACTIVATE_CUSTOMHID 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_VIDEO
|
||||
#define USBD_CMPSIT_ACTIVATE_VIDEO 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_PRINTER
|
||||
#define USBD_CMPSIT_ACTIVATE_PRINTER 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_CCID
|
||||
#define USBD_CMPSIT_ACTIVATE_CCID 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_CCID */
|
||||
|
||||
#ifndef USBD_CMPSIT_ACTIVATE_MTP
|
||||
#define USBD_CMPSIT_ACTIVATE_MTP 0U
|
||||
#endif /* USBD_CMPSIT_ACTIVATE_MTP */
|
||||
|
||||
|
||||
/* This is the maximum supported configuration descriptor size
|
||||
User may define this value in usbd_conf.h in order to optimize footprint */
|
||||
#ifndef USBD_CMPST_MAX_CONFDESC_SZ
|
||||
#define USBD_CMPST_MAX_CONFDESC_SZ 300U
|
||||
#endif /* USBD_CMPST_MAX_CONFDESC_SZ */
|
||||
|
||||
#ifndef USBD_CONFIG_STR_DESC_IDX
|
||||
#define USBD_CONFIG_STR_DESC_IDX 4U
|
||||
#endif /* USBD_CONFIG_STR_DESC_IDX */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USB Iad descriptors structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bFirstInterface;
|
||||
uint8_t bInterfaceCount;
|
||||
uint8_t bFunctionClass;
|
||||
uint8_t bFunctionSubClass;
|
||||
uint8_t bFunctionProtocol;
|
||||
uint8_t iFunction;
|
||||
} USBD_IadDescTypeDef;
|
||||
|
||||
/* USB interface descriptors structure */
|
||||
typedef struct
|
||||
{
|
||||
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;
|
||||
} USBD_IfDescTypeDef;
|
||||
|
||||
#if (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1)
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* CDC Class specification revision 1.2
|
||||
* Table 15: Class-Specific Descriptor Header Format
|
||||
*/
|
||||
/* Header Functional Descriptor */
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint16_t bcdCDC;
|
||||
} __PACKED USBD_CDCHeaderFuncDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Call Management Functional Descriptor */
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bmCapabilities;
|
||||
uint8_t bDataInterface;
|
||||
} USBD_CDCCallMgmFuncDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* ACM Functional Descriptor */
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bmCapabilities;
|
||||
} USBD_CDCACMFuncDescTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* CDC Class specification revision 1.2
|
||||
* Table 16: Union Interface Functional Descriptor
|
||||
*/
|
||||
/* Union Functional Descriptor */
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bMasterInterface;
|
||||
uint8_t bSlaveInterface;
|
||||
} USBD_CDCUnionFuncDescTypeDef;
|
||||
|
||||
#endif /* (USBD_CMPSIT_ACTIVATE_CDC == 1) || (USBD_CMPSIT_ACTIVATE_RNDIS == 1) || (USBD_CMPSIT_ACTIVATE_CDC_ECM == 1)*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CMPSIT;
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev,
|
||||
USBD_ClassTypeDef *pclass,
|
||||
USBD_CompositeClassTypeDef class,
|
||||
uint8_t cfgidx);
|
||||
|
||||
uint32_t USBD_CMPSIT_SetClassID(USBD_HandleTypeDef *pdev,
|
||||
USBD_CompositeClassTypeDef Class,
|
||||
uint32_t Instance);
|
||||
|
||||
uint32_t USBD_CMPSIT_GetClassID(USBD_HandleTypeDef *pdev,
|
||||
USBD_CompositeClassTypeDef Class,
|
||||
uint32_t Instance);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
uint8_t USBD_CMPST_ClearConfDesc(USBD_HandleTypeDef *pdev);
|
||||
|
||||
/* Private macro -----------------------------------------------------------*/
|
||||
#define __USBD_CMPSIT_SET_EP(epadd, eptype, epsize, HSinterval, FSinterval) \
|
||||
do { \
|
||||
/* Append Endpoint descriptor to Configuration descriptor */ \
|
||||
pEpDesc = ((USBD_EpDescTypeDef*)((uint32_t)pConf + *Sze)); \
|
||||
pEpDesc->bLength = (uint8_t)sizeof(USBD_EpDescTypeDef); \
|
||||
pEpDesc->bDescriptorType = USB_DESC_TYPE_ENDPOINT; \
|
||||
pEpDesc->bEndpointAddress = (epadd); \
|
||||
pEpDesc->bmAttributes = (eptype); \
|
||||
pEpDesc->wMaxPacketSize = (uint16_t)(epsize); \
|
||||
if(speed == (uint8_t)USBD_SPEED_HIGH) \
|
||||
{ \
|
||||
pEpDesc->bInterval = HSinterval; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
pEpDesc->bInterval = FSinterval; \
|
||||
} \
|
||||
*Sze += (uint32_t)sizeof(USBD_EpDescTypeDef); \
|
||||
} while(0)
|
||||
|
||||
#define __USBD_CMPSIT_SET_IF(ifnum, alt, eps, class, subclass, protocol, istring) \
|
||||
do { \
|
||||
/* Interface Descriptor */ \
|
||||
pIfDesc = ((USBD_IfDescTypeDef*)((uint32_t)pConf + *Sze)); \
|
||||
pIfDesc->bLength = (uint8_t)sizeof(USBD_IfDescTypeDef); \
|
||||
pIfDesc->bDescriptorType = USB_DESC_TYPE_INTERFACE; \
|
||||
pIfDesc->bInterfaceNumber = ifnum; \
|
||||
pIfDesc->bAlternateSetting = alt; \
|
||||
pIfDesc->bNumEndpoints = eps; \
|
||||
pIfDesc->bInterfaceClass = class; \
|
||||
pIfDesc->bInterfaceSubClass = subclass; \
|
||||
pIfDesc->bInterfaceProtocol = protocol; \
|
||||
pIfDesc->iInterface = istring; \
|
||||
*Sze += (uint32_t)sizeof(USBD_IfDescTypeDef); \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_COMPOSITE_BUILDER_H__ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+1879
File diff suppressed because it is too large
Load Diff
+198
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_customhid.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_customhid.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_CUSTOMHID_H
|
||||
#define __USB_CUSTOMHID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID
|
||||
* @brief This file is the Header file for USBD_customhid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef CUSTOM_HID_EPIN_ADDR
|
||||
#define CUSTOM_HID_EPIN_ADDR 0x81U
|
||||
#endif /* CUSTOM_HID_EPIN_ADDR */
|
||||
|
||||
#ifndef CUSTOM_HID_EPIN_SIZE
|
||||
#define CUSTOM_HID_EPIN_SIZE 0x02U
|
||||
#endif /* CUSTOM_HID_EPIN_SIZE */
|
||||
|
||||
#ifndef CUSTOM_HID_EPOUT_ADDR
|
||||
#define CUSTOM_HID_EPOUT_ADDR 0x01U
|
||||
#endif /* CUSTOM_HID_EPOUT_ADDR */
|
||||
|
||||
#ifndef CUSTOM_HID_EPOUT_SIZE
|
||||
#define CUSTOM_HID_EPOUT_SIZE 0x02U
|
||||
#endif /* CUSTOM_HID_EPOUT_SIZE*/
|
||||
|
||||
#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U
|
||||
#define USB_CUSTOM_HID_DESC_SIZ 9U
|
||||
|
||||
#ifndef CUSTOM_HID_HS_BINTERVAL
|
||||
#define CUSTOM_HID_HS_BINTERVAL 0x05U
|
||||
#endif /* CUSTOM_HID_HS_BINTERVAL */
|
||||
|
||||
#ifndef CUSTOM_HID_FS_BINTERVAL
|
||||
#define CUSTOM_HID_FS_BINTERVAL 0x05U
|
||||
#endif /* CUSTOM_HID_FS_BINTERVAL */
|
||||
|
||||
#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
|
||||
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U
|
||||
#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */
|
||||
|
||||
#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
|
||||
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U
|
||||
#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */
|
||||
|
||||
#define CUSTOM_HID_DESCRIPTOR_TYPE 0x21U
|
||||
#define CUSTOM_HID_REPORT_DESC 0x22U
|
||||
|
||||
#define CUSTOM_HID_REQ_SET_PROTOCOL 0x0BU
|
||||
#define CUSTOM_HID_REQ_GET_PROTOCOL 0x03U
|
||||
|
||||
#define CUSTOM_HID_REQ_SET_IDLE 0x0AU
|
||||
#define CUSTOM_HID_REQ_GET_IDLE 0x02U
|
||||
|
||||
#define CUSTOM_HID_REQ_SET_REPORT 0x09U
|
||||
#define CUSTOM_HID_REQ_GET_REPORT 0x01U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CUSTOM_HID_IDLE = 0U,
|
||||
CUSTOM_HID_BUSY,
|
||||
} CUSTOM_HID_StateTypeDef;
|
||||
|
||||
typedef struct _USBD_CUSTOM_HID_Itf
|
||||
{
|
||||
uint8_t *pReport;
|
||||
int8_t (* Init)(void);
|
||||
int8_t (* DeInit)(void);
|
||||
int8_t (* OutEvent)(uint8_t event_idx, uint8_t state);
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
int8_t (* CtrlReqComplete)(uint8_t request, uint16_t wLength);
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
uint8_t *(* GetReport)(uint16_t *ReportLength);
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
} USBD_CUSTOM_HID_ItfTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
uint32_t IsReportAvailable;
|
||||
CUSTOM_HID_StateTypeDef state;
|
||||
} USBD_CUSTOM_HID_HandleTypeDef;
|
||||
|
||||
/*
|
||||
* HID Class specification version 1.1
|
||||
* 6.2.1 HID Descriptor
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorTypeCHID;
|
||||
uint16_t bcdCUSTOM_HID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wItemLength;
|
||||
} __PACKED USBD_DescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_CUSTOM_HID;
|
||||
#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *report, uint16_t len, uint8_t ClassId);
|
||||
#else
|
||||
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *report, uint16_t len);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
|
||||
|
||||
uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CUSTOM_HID_ItfTypeDef *fops);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_CUSTOMHID_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_customhid_if_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for usbd_customhid_if_template.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_CUSTOMHID_IF_TEMPLATE_H
|
||||
#define __USBD_CUSTOMHID_IF_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_customhid.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_CUSTOMHID_IF_TEMPLATE_H */
|
||||
|
||||
+811
@@ -0,0 +1,811 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_customhid.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the CUSTOM_HID core functions.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* CUSTOM_HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - Usage Page : Generic Desktop
|
||||
* - Usage : Vendor
|
||||
* - Collection : Application
|
||||
*
|
||||
* @note In HS mode and when the DMA is used, all variables and data structures
|
||||
* dealing with the DMA during the transaction process should be 32-bit aligned.
|
||||
*
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_customhid.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
|
||||
static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev);
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_ClassTypeDef USBD_CUSTOM_HID =
|
||||
{
|
||||
USBD_CUSTOM_HID_Init,
|
||||
USBD_CUSTOM_HID_DeInit,
|
||||
USBD_CUSTOM_HID_Setup,
|
||||
NULL, /*EP0_TxSent*/
|
||||
USBD_CUSTOM_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */
|
||||
USBD_CUSTOM_HID_DataIn, /*DataIn*/
|
||||
USBD_CUSTOM_HID_DataOut,
|
||||
NULL, /*SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
USBD_CUSTOM_HID_GetHSCfgDesc,
|
||||
USBD_CUSTOM_HID_GetFSCfgDesc,
|
||||
USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
|
||||
USBD_CUSTOM_HID_GetDeviceQualifierDesc,
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB CUSTOM_HID device FS Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
LOBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */
|
||||
HIBYTE(USB_CUSTOM_HID_CONFIG_DESC_SIZ),
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor
|
||||
describing the configuration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xC0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0x80, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/************** Descriptor of CUSTOM HID interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size*/
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints*/
|
||||
0x03, /* bInterfaceClass: CUSTOM_HID */
|
||||
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0x00, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of CUSTOM_HID *************************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: CUSTOM_HID Descriptor size */
|
||||
CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
|
||||
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors
|
||||
to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
|
||||
HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),
|
||||
/******************** Descriptor of Custom HID endpoints ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
|
||||
CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
LOBYTE(CUSTOM_HID_EPIN_SIZE), /* wMaxPacketSize: 2 Bytes max */
|
||||
HIBYTE(CUSTOM_HID_EPIN_SIZE),
|
||||
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
CUSTOM_HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
LOBYTE(CUSTOM_HID_EPOUT_SIZE), /* wMaxPacketSize: 2 Bytes max */
|
||||
HIBYTE(CUSTOM_HID_EPOUT_SIZE),
|
||||
CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||
/* 41 */
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* USB CUSTOM_HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
/* 18 */
|
||||
0x09, /* bLength: CUSTOM_HID Descriptor size */
|
||||
CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
|
||||
0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors
|
||||
to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
LOBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE), /* wItemLength: Total length of Report descriptor */
|
||||
HIBYTE(USBD_CUSTOM_HID_REPORT_DESC_SIZE),
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_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,
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
static uint8_t CUSTOMHIDInEpAdd = CUSTOM_HID_EPIN_ADDR;
|
||||
static uint8_t CUSTOMHIDOutEpAdd = CUSTOM_HID_EPOUT_ADDR;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CUSTOM_HID_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_Init
|
||||
* Initialize the CUSTOM_HID interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid;
|
||||
|
||||
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef));
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hhid;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
|
||||
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
|
||||
}
|
||||
else /* LOW and FULL-speed endpoints */
|
||||
{
|
||||
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, CUSTOMHIDInEpAdd, USBD_EP_TYPE_INTR,
|
||||
CUSTOM_HID_EPIN_SIZE);
|
||||
|
||||
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
/* Open EP OUT */
|
||||
(void)USBD_LL_OpenEP(pdev, CUSTOMHIDOutEpAdd, USBD_EP_TYPE_INTR,
|
||||
CUSTOM_HID_EPOUT_SIZE);
|
||||
|
||||
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
hhid->state = CUSTOM_HID_IDLE;
|
||||
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
|
||||
|
||||
#ifndef USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED
|
||||
/* Prepare Out endpoint to receive 1st packet */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf,
|
||||
USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
|
||||
#endif /* USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_Init
|
||||
* DeInitialize the CUSTOM_HID layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Close CUSTOM_HID EP IN */
|
||||
(void)USBD_LL_CloseEP(pdev, CUSTOMHIDInEpAdd);
|
||||
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_in[CUSTOMHIDInEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* Close CUSTOM_HID EP OUT */
|
||||
(void)USBD_LL_CloseEP(pdev, CUSTOMHIDOutEpAdd);
|
||||
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_out[CUSTOMHIDOutEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* Free allocated memory */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
|
||||
{
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
|
||||
USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
pdev->pClassData = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_Setup
|
||||
* Handle the CUSTOM_HID specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
|
||||
USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t len = 0U;
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
uint16_t ReportLength = 0U;
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
uint8_t *pbuf = NULL;
|
||||
uint16_t status_info = 0U;
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case CUSTOM_HID_REQ_SET_PROTOCOL:
|
||||
hhid->Protocol = (uint8_t)(req->wValue);
|
||||
break;
|
||||
|
||||
case CUSTOM_HID_REQ_GET_PROTOCOL:
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
|
||||
break;
|
||||
|
||||
case CUSTOM_HID_REQ_SET_IDLE:
|
||||
hhid->IdleState = (uint8_t)(req->wValue >> 8);
|
||||
break;
|
||||
|
||||
case CUSTOM_HID_REQ_GET_IDLE:
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
|
||||
break;
|
||||
|
||||
case CUSTOM_HID_REQ_SET_REPORT:
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL)
|
||||
{
|
||||
/* Let the application decide when to enable EP0 to receive the next report */
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest,
|
||||
req->wLength);
|
||||
}
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
#ifndef USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED
|
||||
hhid->IsReportAvailable = 1U;
|
||||
(void)USBD_CtlPrepareRx(pdev, hhid->Report_buf,
|
||||
MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE));
|
||||
#endif /* USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
|
||||
break;
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
case CUSTOM_HID_REQ_GET_REPORT:
|
||||
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport != NULL)
|
||||
{
|
||||
ReportLength = req->wLength;
|
||||
|
||||
/* Get report data buffer */
|
||||
pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->GetReport(&ReportLength);
|
||||
}
|
||||
|
||||
if ((pbuf != NULL) && (ReportLength != 0U))
|
||||
{
|
||||
len = MIN(ReportLength, req->wLength);
|
||||
|
||||
/* Send the report data over EP0 */
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
if (((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete != NULL)
|
||||
{
|
||||
/* Let the application decide what to do, keep EP0 data phase in NAK state and
|
||||
use USBD_CtlSendData() when data become available or stall the EP0 data phase */
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->CtrlReqComplete(req->bRequest,
|
||||
req->wLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stall EP0 if no data available */
|
||||
USBD_CtlError(pdev, req);
|
||||
}
|
||||
#else
|
||||
/* Stall EP0 if no data available */
|
||||
USBD_CtlError(pdev, req);
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
}
|
||||
break;
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC)
|
||||
{
|
||||
len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
|
||||
pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->pReport;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE)
|
||||
{
|
||||
pbuf = USBD_CUSTOM_HID_Desc;
|
||||
len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (pbuf != NULL)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
hhid->AltSetting = (uint8_t)(req->wValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_SendReport
|
||||
* Send CUSTOM_HID Report
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to report
|
||||
* @param ClassId: The Class ID
|
||||
* @retval status
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *report, uint16_t len, uint8_t ClassId)
|
||||
{
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
|
||||
#else
|
||||
uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
|
||||
uint8_t *report, uint16_t len)
|
||||
{
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get Endpoint IN address allocated for this class instance */
|
||||
CUSTOMHIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, ClassId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
if (hhid->state == CUSTOM_HID_IDLE)
|
||||
{
|
||||
hhid->state = CUSTOM_HID_BUSY;
|
||||
(void)USBD_LL_Transmit(pdev, CUSTOMHIDInEpAdd, report, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (uint8_t)USBD_BUSY;
|
||||
}
|
||||
}
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_GetFSCfgDesc
|
||||
* return FS configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
|
||||
pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
|
||||
pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
|
||||
return USBD_CUSTOM_HID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_GetHSCfgDesc
|
||||
* return HS configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
|
||||
pEpInDesc->bInterval = CUSTOM_HID_HS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
|
||||
pEpOutDesc->bInterval = CUSTOM_HID_HS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
|
||||
return USBD_CUSTOM_HID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_GetOtherSpeedCfgDesc
|
||||
* return other speed configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPIN_ADDR);
|
||||
USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CUSTOM_HID_CfgDesc, CUSTOM_HID_EPOUT_ADDR);
|
||||
|
||||
if (pEpInDesc != NULL)
|
||||
{
|
||||
pEpInDesc->wMaxPacketSize = CUSTOM_HID_EPIN_SIZE;
|
||||
pEpInDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
if (pEpOutDesc != NULL)
|
||||
{
|
||||
pEpOutDesc->wMaxPacketSize = CUSTOM_HID_EPOUT_SIZE;
|
||||
pEpOutDesc->bInterval = CUSTOM_HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgDesc);
|
||||
return USBD_CUSTOM_HID_CfgDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_DataIn
|
||||
* handle data IN Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(epnum);
|
||||
|
||||
/* Ensure that the FIFO is empty before a new transfer, this condition could
|
||||
be caused by a new transfer before the end of the previous transfer */
|
||||
((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = CUSTOM_HID_IDLE;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_DataOut
|
||||
* handle data OUT Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(epnum);
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
/* USB data will be immediately processed, this allow next USB traffic being
|
||||
NAKed till the end of the application processing */
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
|
||||
hhid->Report_buf[1]);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_ReceivePacket
|
||||
* prepare OUT Endpoint for reception
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid;
|
||||
|
||||
if (pdev->pClassDataCmsit[pdev->classId] == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get OUT Endpoint address allocated for this class instance */
|
||||
CUSTOMHIDOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
/* Resume USB Out process */
|
||||
(void)USBD_LL_PrepareReceive(pdev, CUSTOMHIDOutEpAdd, hhid->Report_buf,
|
||||
USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_EP0_RxReady
|
||||
* Handles control request data.
|
||||
* @param pdev: device instance
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
if (hhid->IsReportAvailable == 1U)
|
||||
{
|
||||
((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData[pdev->classId])->OutEvent(hhid->Report_buf[0],
|
||||
hhid->Report_buf[1]);
|
||||
hhid->IsReportAvailable = 0U;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc);
|
||||
|
||||
return USBD_CUSTOM_HID_DeviceQualifierDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @brief USBD_CUSTOM_HID_RegisterInterface
|
||||
* @param pdev: device instance
|
||||
* @param fops: CUSTOMHID Interface callback
|
||||
* @retval status
|
||||
*/
|
||||
uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
|
||||
USBD_CUSTOM_HID_ItfTypeDef *fops)
|
||||
{
|
||||
if (fops == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
pdev->pUserData[pdev->classId] = fops;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_customhid_if_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief USB Device Custom HID interface file.
|
||||
* This template should be copied to the user folder, renamed and customized
|
||||
* following user needs.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_customhid_if_template.h"
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static int8_t TEMPLATE_CUSTOM_HID_Init(void);
|
||||
static int8_t TEMPLATE_CUSTOM_HID_DeInit(void);
|
||||
static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state);
|
||||
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength);
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength);
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
extern USBD_HandleTypeDef USBD_Device;
|
||||
|
||||
__ALIGN_BEGIN static uint8_t TEMPLATE_CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END = {0};
|
||||
|
||||
USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops =
|
||||
{
|
||||
TEMPLATE_CUSTOM_HID_ReportDesc,
|
||||
TEMPLATE_CUSTOM_HID_Init,
|
||||
TEMPLATE_CUSTOM_HID_DeInit,
|
||||
TEMPLATE_CUSTOM_HID_OutEvent,
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
TEMPLATE_CUSTOM_HID_CtrlReqComplete,
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
TEMPLATE_CUSTOM_HID_GetReport,
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
};
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_CUSTOM_HID_Init
|
||||
* Initializes the CUSTOM HID media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_CUSTOM_HID_Init(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_CUSTOM_HID_DeInit
|
||||
* DeInitializes the CUSTOM HID media low layer
|
||||
* @param None
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_CUSTOM_HID_DeInit(void)
|
||||
{
|
||||
/*
|
||||
Add your deinitialization code here
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief TEMPLATE_CUSTOM_HID_Control
|
||||
* Manage the CUSTOM HID class events
|
||||
* @param event_idx: event index
|
||||
* @param state: event state
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state)
|
||||
{
|
||||
UNUSED(event_idx);
|
||||
UNUSED(state);
|
||||
|
||||
/* Start next USB packet transfer once data processing is completed */
|
||||
if (USBD_CUSTOM_HID_ReceivePacket(&USBD_Device) != (uint8_t)USBD_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED
|
||||
/**
|
||||
* @brief TEMPLATE_CUSTOM_HID_CtrlReqComplete
|
||||
* Manage the CUSTOM HID control request complete
|
||||
* @param request: control request
|
||||
* @param wLength: request wLength
|
||||
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||
*/
|
||||
static int8_t TEMPLATE_CUSTOM_HID_CtrlReqComplete(uint8_t request, uint16_t wLength)
|
||||
{
|
||||
UNUSED(wLength);
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case CUSTOM_HID_REQ_SET_REPORT:
|
||||
|
||||
break;
|
||||
|
||||
case CUSTOM_HID_REQ_GET_REPORT:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
|
||||
|
||||
|
||||
#ifdef USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED
|
||||
/**
|
||||
* @brief TEMPLATE_CUSTOM_HID_GetReport
|
||||
* Manage the CUSTOM HID control Get Report request
|
||||
* @param event_idx: event index
|
||||
* @param state: event state
|
||||
* @retval return pointer to HID report
|
||||
*/
|
||||
static uint8_t *TEMPLATE_CUSTOM_HID_GetReport(uint16_t *ReportLength)
|
||||
{
|
||||
UNUSED(ReportLength);
|
||||
uint8_t *pbuff;
|
||||
|
||||
return (pbuff);
|
||||
}
|
||||
#endif /* USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
|
||||
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the usbd_dfu.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DFU_H
|
||||
#define __USB_DFU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_DFU
|
||||
* @brief This file is the Header file for usbd_dfu.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_DFU_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef USBD_DFU_MAX_ITF_NUM
|
||||
#define USBD_DFU_MAX_ITF_NUM 1U
|
||||
#endif /* USBD_DFU_MAX_ITF_NUM */
|
||||
|
||||
#ifndef USBD_DFU_XFER_SIZE
|
||||
#define USBD_DFU_XFER_SIZE 1024U
|
||||
#endif /* USBD_DFU_XFER_SIZE */
|
||||
|
||||
#ifndef USBD_DFU_APP_DEFAULT_ADD
|
||||
#define USBD_DFU_APP_DEFAULT_ADD 0x08008000U /* The first sector (32 KB) is reserved for DFU code */
|
||||
#endif /* USBD_DFU_APP_DEFAULT_ADD */
|
||||
|
||||
#ifndef USBD_DFU_BM_ATTRIBUTES
|
||||
#define USBD_DFU_BM_ATTRIBUTES 0x0BU
|
||||
#endif /* USBD_DFU_BM_ATTRIBUTES */
|
||||
|
||||
#ifndef USBD_DFU_DETACH_TIMEOUT
|
||||
#define USBD_DFU_DETACH_TIMEOUT 0xFFU
|
||||
#endif /* USBD_DFU_DETACH_TIMEOUT */
|
||||
|
||||
#define USB_DFU_CONFIG_DESC_SIZ (18U + (9U * USBD_DFU_MAX_ITF_NUM))
|
||||
#define USB_DFU_DESC_SIZ 9U
|
||||
|
||||
#define DFU_DESCRIPTOR_TYPE 0x21U
|
||||
|
||||
#define DFU_VENDOR_CMD_MAX 32U
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* DFU Requests DFU states */
|
||||
/**************************************************/
|
||||
#define APP_STATE_IDLE 0U
|
||||
#define APP_STATE_DETACH 1U
|
||||
#define DFU_STATE_IDLE 2U
|
||||
#define DFU_STATE_DNLOAD_SYNC 3U
|
||||
#define DFU_STATE_DNLOAD_BUSY 4U
|
||||
#define DFU_STATE_DNLOAD_IDLE 5U
|
||||
#define DFU_STATE_MANIFEST_SYNC 6U
|
||||
#define DFU_STATE_MANIFEST 7U
|
||||
#define DFU_STATE_MANIFEST_WAIT_RESET 8U
|
||||
#define DFU_STATE_UPLOAD_IDLE 9U
|
||||
#define DFU_STATE_ERROR 10U
|
||||
|
||||
/**************************************************/
|
||||
/* DFU errors */
|
||||
/**************************************************/
|
||||
#define DFU_ERROR_NONE 0x00U
|
||||
#define DFU_ERROR_TARGET 0x01U
|
||||
#define DFU_ERROR_FILE 0x02U
|
||||
#define DFU_ERROR_WRITE 0x03U
|
||||
#define DFU_ERROR_ERASE 0x04U
|
||||
#define DFU_ERROR_CHECK_ERASED 0x05U
|
||||
#define DFU_ERROR_PROG 0x06U
|
||||
#define DFU_ERROR_VERIFY 0x07U
|
||||
#define DFU_ERROR_ADDRESS 0x08U
|
||||
#define DFU_ERROR_NOTDONE 0x09U
|
||||
#define DFU_ERROR_FIRMWARE 0x0AU
|
||||
#define DFU_ERROR_VENDOR 0x0BU
|
||||
#define DFU_ERROR_USB 0x0CU
|
||||
#define DFU_ERROR_POR 0x0DU
|
||||
#define DFU_ERROR_UNKNOWN 0x0EU
|
||||
#define DFU_ERROR_STALLEDPKT 0x0FU
|
||||
|
||||
/**************************************************/
|
||||
/* DFU Manifestation State */
|
||||
/**************************************************/
|
||||
#define DFU_MANIFEST_COMPLETE 0x00U
|
||||
#define DFU_MANIFEST_IN_PROGRESS 0x01U
|
||||
|
||||
|
||||
/**************************************************/
|
||||
/* Special Commands with Download Request */
|
||||
/**************************************************/
|
||||
#define DFU_CMD_GETCOMMANDS 0x00U
|
||||
#define DFU_CMD_SETADDRESSPOINTER 0x21U
|
||||
#define DFU_CMD_ERASE 0x41U
|
||||
|
||||
#define DFU_MEDIA_ERASE 0x00U
|
||||
#define DFU_MEDIA_PROGRAM 0x01U
|
||||
|
||||
/**************************************************/
|
||||
/* Other defines */
|
||||
/**************************************************/
|
||||
/* Bit Detach capable = bit 3 in bmAttributes field */
|
||||
#define DFU_DETACH_MASK (1U << 3)
|
||||
#define DFU_MANIFEST_MASK (1U << 2)
|
||||
#define DFU_STATUS_DEPTH 6U
|
||||
|
||||
#define IS_DFU_DOWNLOAD 0x0DFDFU
|
||||
#define IS_DFU_UPLOAD 0x1DFDFU
|
||||
#define IS_DFU_SETADDRESSPOINTER 0x2DFDFU
|
||||
#define IS_DFU_PHY_ADDRESS 0x3DFDFU
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DFU_DETACH = 0U,
|
||||
DFU_DNLOAD,
|
||||
DFU_UPLOAD,
|
||||
DFU_GETSTATUS,
|
||||
DFU_CLRSTATUS,
|
||||
DFU_GETSTATE,
|
||||
DFU_ABORT
|
||||
} DFU_RequestTypeDef;
|
||||
|
||||
typedef void (*pFunction)(void);
|
||||
|
||||
|
||||
/********** Descriptor of DFU interface 0 Alternate setting n ****************/
|
||||
#define USBD_DFU_IF_DESC(n) \
|
||||
0x09, /* bLength: Interface Descriptor size */ \
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
0x00, /* bInterfaceNumber: Number of Interface */ \
|
||||
(n), /* bAlternateSetting: Alternate setting */ \
|
||||
0x00, /* bNumEndpoints*/ \
|
||||
0xFE, /* bInterfaceClass: Application Specific Class Code */ \
|
||||
0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
|
||||
0x02, /* nInterfaceProtocol: DFU mode protocol */ \
|
||||
USBD_IDX_INTERFACE_STR + (n) + 1U /* iInterface: Index of string descriptor */
|
||||
|
||||
#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), ((uint8_t)((size) >> 8))
|
||||
|
||||
#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD))) ? 1 : 0)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t d32[USBD_DFU_XFER_SIZE / 4U];
|
||||
uint8_t d8[USBD_DFU_XFER_SIZE];
|
||||
} buffer;
|
||||
|
||||
uint32_t wblock_num;
|
||||
uint32_t wlength;
|
||||
uint32_t data_ptr;
|
||||
uint32_t app_addr_ptr;
|
||||
uint32_t alt_setting;
|
||||
|
||||
uint8_t dev_status[DFU_STATUS_DEPTH];
|
||||
uint8_t ReservedForAlign[2];
|
||||
uint8_t dev_state;
|
||||
uint8_t manif_state;
|
||||
} USBD_DFU_HandleTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const uint8_t *pStrDesc;
|
||||
uint16_t (* Init)(void);
|
||||
uint16_t (* DeInit)(void);
|
||||
uint16_t (* Erase)(uint32_t Add);
|
||||
uint16_t (* Write)(uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint8_t *(* Read)(uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint16_t (* GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff);
|
||||
#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U)
|
||||
uint16_t (* GetVendorCMD)(uint8_t *cmd, uint8_t *cmdlength);
|
||||
uint16_t (* VendorDownloadCMD)(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status);
|
||||
uint16_t (* VendorUploadCMD)(uint32_t Add, uint32_t BlockNumber, uint32_t *status);
|
||||
#endif /* USBD_DFU_VENDOR_CMD_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U)
|
||||
uint16_t (* VendorCheck)(uint8_t *pbuf, uint32_t ReqType, uint32_t *status);
|
||||
#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U)
|
||||
uint16_t (* LeaveDFU)(uint32_t Add);
|
||||
#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */
|
||||
} USBD_DFU_MediaTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bmAttributes;
|
||||
uint16_t wDetachTimeout;
|
||||
uint16_t wTransferSze;
|
||||
uint16_t bcdDFUVersion;
|
||||
} __PACKED USBD_DFUFuncDescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_DFU;
|
||||
#define USBD_DFU_CLASS &USBD_DFU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
|
||||
USBD_DFU_MediaTypeDef *fops);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_DFU_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu_media_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief header file for the usbd_dfu_media_template.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_DFU_MEDIA_TEMPLATE_H
|
||||
#define __USBD_DFU_MEDIA_TEMPLATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_dfu.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA
|
||||
* @brief header file for the usbd_dfu_media_template.c file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MEDIA_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_DFU_MEDIA_TEMPLATE_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
+250
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_dfu_media_template.c
|
||||
* @author MCD Application Team
|
||||
* @brief Memory management layer
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_dfu_media_template.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Extern function prototypes ------------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
uint16_t MEM_If_Init(void);
|
||||
uint16_t MEM_If_Erase(uint32_t Add);
|
||||
uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len);
|
||||
uint16_t MEM_If_DeInit(void);
|
||||
uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer);
|
||||
#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U)
|
||||
uint16_t MEM_If_GetVendorCMD(uint8_t *cmd, uint8_t *cmdlength);
|
||||
uint16_t MEM_If_VendorDownloadCMD(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status);
|
||||
uint16_t MEM_If_VendorUploadCMD(uint32_t Add, uint32_t BlockNumber, uint32_t *status);
|
||||
#endif /* USBD_DFU_VENDOR_CMD_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U)
|
||||
uint16_t MEM_If_VendorCheck(uint8_t *pbuf, uint32_t ReqType, uint32_t *status);
|
||||
#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U)
|
||||
uint16_t MEM_If_LeaveDFU(uint32_t Add);
|
||||
#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */
|
||||
|
||||
USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops =
|
||||
{
|
||||
(uint8_t *)"DFU MEDIA",
|
||||
MEM_If_Init,
|
||||
MEM_If_DeInit,
|
||||
MEM_If_Erase,
|
||||
MEM_If_Write,
|
||||
MEM_If_Read,
|
||||
MEM_If_GetStatus,
|
||||
#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U)
|
||||
MEM_If_GetVendorCMD,
|
||||
MEM_If_VendorDownloadCMD,
|
||||
MEM_If_VendorUploadCMD,
|
||||
#endif /* USBD_DFU_VENDOR_CMD_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U)
|
||||
MEM_If_VendorCheck,
|
||||
#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */
|
||||
#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U)
|
||||
MEM_If_LeaveDFU
|
||||
#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Init
|
||||
* Memory initialization routine.
|
||||
* @param None
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_DeInit
|
||||
* Memory deinitialization routine.
|
||||
* @param None
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_DeInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Erase
|
||||
* Erase sector.
|
||||
* @param Add: Address of sector to be erased.
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Erase(uint32_t Add)
|
||||
{
|
||||
UNUSED(Add);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Write
|
||||
* Memory write routine.
|
||||
* @param Add: Address to be written to.
|
||||
* @param Len: Number of data to be written (in bytes).
|
||||
* @retval 0 if operation is successful, MAL_FAIL else.
|
||||
*/
|
||||
uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len)
|
||||
{
|
||||
UNUSED(src);
|
||||
UNUSED(dest);
|
||||
UNUSED(Len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MEM_If_Read
|
||||
* Memory read routine.
|
||||
* @param Add: Address to be read from.
|
||||
* @param Len: Number of data to be read (in bytes).
|
||||
* @retval Pointer to the physical address where data should be read.
|
||||
*/
|
||||
uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len)
|
||||
{
|
||||
UNUSED(src);
|
||||
UNUSED(dest);
|
||||
UNUSED(Len);
|
||||
|
||||
/* Return a valid address to avoid HardFault */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flash_If_GetStatus
|
||||
* Memory read routine.
|
||||
* @param Add: Address to be read from.
|
||||
* @param cmd: Number of data to be read (in bytes).
|
||||
* @retval Pointer to the physical address where data should be read.
|
||||
*/
|
||||
uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
|
||||
{
|
||||
UNUSED(Add);
|
||||
UNUSED(buffer);
|
||||
|
||||
switch (Cmd)
|
||||
{
|
||||
case DFU_MEDIA_PROGRAM:
|
||||
|
||||
break;
|
||||
|
||||
case DFU_MEDIA_ERASE:
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if (USBD_DFU_VENDOR_CMD_ENABLED == 1U)
|
||||
/**
|
||||
* @brief Get supported vendor specific commands
|
||||
* @param pointer to supported vendor commands
|
||||
* @param pointer to length of supported vendor commands
|
||||
* @retval 0 if operation is successful
|
||||
*/
|
||||
uint16_t MEM_If_GetVendorCMD(uint8_t *cmd, uint8_t *cmdlength)
|
||||
{
|
||||
UNUSED(cmd);
|
||||
UNUSED(cmdlength);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vendor specific download commands
|
||||
* @param pbuf DFU data buffer
|
||||
* @param BlockNumber DFU memory block number
|
||||
* @param wLength DFU request length
|
||||
* @param pointer to DFU status
|
||||
* @retval 0 if operation is successful
|
||||
*/
|
||||
uint16_t MEM_If_VendorDownloadCMD(uint8_t *pbuf, uint32_t BlockNumber, uint32_t wlength, uint32_t *status)
|
||||
{
|
||||
UNUSED(pbuf);
|
||||
UNUSED(BlockNumber);
|
||||
UNUSED(wlength);
|
||||
UNUSED(status);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Vendor specific upload commands
|
||||
* @param Add memory Address
|
||||
* @param BlockNumber DFU memory block number
|
||||
* @param pointer to DFU status
|
||||
* @retval 0 if operation is successful
|
||||
*/
|
||||
uint16_t MEM_If_VendorUploadCMD(uint32_t Add, uint32_t BlockNumber, uint32_t *status)
|
||||
{
|
||||
UNUSED(Add);
|
||||
UNUSED(BlockNumber);
|
||||
UNUSED(status);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
#endif /* USBD_DFU_VENDOR_CMD_ENABLED */
|
||||
|
||||
#if (USBD_DFU_VENDOR_CHECK_ENABLED == 1U)
|
||||
/**
|
||||
* @brief Vendor memory check
|
||||
* @param pbuf DFU data buffer
|
||||
* @param ReqType IS_DFU_SETADDRESSPOINTER/DOWNLOAD/UPLOAD
|
||||
* @param pointer to DFU status
|
||||
* @retval 0 if operation is successful
|
||||
*/
|
||||
uint16_t MEM_If_VendorCheck(uint8_t *pbuf, uint32_t ReqType, uint32_t *status)
|
||||
{
|
||||
UNUSED(pbuf);
|
||||
UNUSED(ReqType);
|
||||
UNUSED(status);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
#endif /* USBD_DFU_VENDOR_CHECK_ENABLED */
|
||||
|
||||
#if (USBD_DFU_VENDOR_EXIT_ENABLED == 1U)
|
||||
/**
|
||||
* @brief Vendor Leave DFU
|
||||
* @param Application address
|
||||
* @retval 0 if operation is successful
|
||||
*/
|
||||
uint16_t MEM_If_LeaveDFU(uint32_t Add)
|
||||
{
|
||||
UNUSED(Add);
|
||||
|
||||
return 0U;
|
||||
}
|
||||
#endif /* USBD_DFU_VENDOR_EXIT_ENABLED */
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_hid.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the usbd_hid_core.c file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_HID_H
|
||||
#define __USB_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID
|
||||
* @brief This file is the Header file for usbd_hid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#ifndef HID_EPIN_ADDR
|
||||
#define HID_EPIN_ADDR 0x81U
|
||||
#endif /* HID_EPIN_ADDR */
|
||||
#define HID_EPIN_SIZE 0x04U
|
||||
|
||||
#define USB_HID_CONFIG_DESC_SIZ 34U
|
||||
#define USB_HID_DESC_SIZ 9U
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74U
|
||||
|
||||
#define HID_DESCRIPTOR_TYPE 0x21U
|
||||
#define HID_REPORT_DESC 0x22U
|
||||
|
||||
#ifndef HID_HS_BINTERVAL
|
||||
#define HID_HS_BINTERVAL 0x07U
|
||||
#endif /* HID_HS_BINTERVAL */
|
||||
|
||||
#ifndef HID_FS_BINTERVAL
|
||||
#define HID_FS_BINTERVAL 0x0AU
|
||||
#endif /* HID_FS_BINTERVAL */
|
||||
|
||||
#define USBD_HID_REQ_SET_PROTOCOL 0x0BU
|
||||
#define USBD_HID_REQ_GET_PROTOCOL 0x03U
|
||||
|
||||
#define USBD_HID_REQ_SET_IDLE 0x0AU
|
||||
#define USBD_HID_REQ_GET_IDLE 0x02U
|
||||
|
||||
#define USBD_HID_REQ_SET_REPORT 0x09U
|
||||
#define USBD_HID_REQ_GET_REPORT 0x01U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
USBD_HID_IDLE = 0,
|
||||
USBD_HID_BUSY,
|
||||
} USBD_HID_StateTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Protocol;
|
||||
uint32_t IdleState;
|
||||
uint32_t AltSetting;
|
||||
USBD_HID_StateTypeDef state;
|
||||
} USBD_HID_HandleTypeDef;
|
||||
|
||||
/*
|
||||
* HID Class specification version 1.1
|
||||
* 6.2.1 HID Descriptor
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID;
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors;
|
||||
uint8_t bHIDDescriptorType;
|
||||
uint16_t wItemLength;
|
||||
} __PACKED USBD_HIDDescTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern USBD_ClassTypeDef USBD_HID;
|
||||
#define USBD_HID_CLASS &USBD_HID
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId);
|
||||
#else
|
||||
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_HID_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,650 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_hid.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file provides the HID core functions.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - The Mouse protocol
|
||||
* - Usage Page : Generic Desktop
|
||||
* - Usage : Joystick
|
||||
* - Collection : Application
|
||||
*
|
||||
* @note In HS mode and when the DMA is used, all variables and data structures
|
||||
* dealing with the DMA during the transaction process should be 32-bit aligned.
|
||||
*
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* BSPDependencies
|
||||
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
|
||||
- "stm32xxxxx_{eval}{discovery}_io.c"
|
||||
EndBSPDependencies */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_hid.h"
|
||||
#include "usbd_ctlreq.h"
|
||||
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID
|
||||
* @brief usbd core module
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_HID_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||
static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||
static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length);
|
||||
static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBD_ClassTypeDef USBD_HID =
|
||||
{
|
||||
USBD_HID_Init,
|
||||
USBD_HID_DeInit,
|
||||
USBD_HID_Setup,
|
||||
NULL, /* EP0_TxSent */
|
||||
NULL, /* EP0_RxReady */
|
||||
USBD_HID_DataIn, /* DataIn */
|
||||
NULL, /* DataOut */
|
||||
NULL, /* SOF */
|
||||
NULL,
|
||||
NULL,
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#else
|
||||
USBD_HID_GetHSCfgDesc,
|
||||
USBD_HID_GetFSCfgDesc,
|
||||
USBD_HID_GetOtherSpeedCfgDesc,
|
||||
USBD_HID_GetDeviceQualifierDesc,
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB HID device FS Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: Configuration value */
|
||||
0x00, /* iConfiguration: Index of string descriptor
|
||||
describing the configuration */
|
||||
#if (USBD_SELF_POWERED == 1U)
|
||||
0xE0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#else
|
||||
0xA0, /* bmAttributes: Bus Powered according to user configuration */
|
||||
#endif /* USBD_SELF_POWERED */
|
||||
USBD_MAX_POWER, /* MaxPower (mA) */
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
|
||||
|
||||
HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */
|
||||
0x00,
|
||||
HID_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
};
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_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,
|
||||
};
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
|
||||
{
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
|
||||
0x09, 0x02, /* Usage (Mouse) */
|
||||
0xA1, 0x01, /* Collection (Application) */
|
||||
0x09, 0x01, /* Usage (Pointer) */
|
||||
0xA1, 0x00, /* Collection (Physical) */
|
||||
0x05, 0x09, /* Usage Page (Button) */
|
||||
0x19, 0x01, /* Usage Minimum (0x01) */
|
||||
0x29, 0x03, /* Usage Maximum (0x03) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x95, 0x03, /* Report Count (3) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x81, 0x02, /* Input (Data,Var,Abs) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0x75, 0x05, /* Report Size (5) */
|
||||
0x81, 0x01, /* Input (Const,Array,Abs) */
|
||||
0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
|
||||
0x09, 0x30, /* Usage (X) */
|
||||
0x09, 0x31, /* Usage (Y) */
|
||||
0x09, 0x38, /* Usage (Wheel) */
|
||||
0x15, 0x81, /* Logical Minimum (-127) */
|
||||
0x25, 0x7F, /* Logical Maximum (127) */
|
||||
0x75, 0x08, /* Report Size (8) */
|
||||
0x95, 0x03, /* Report Count (3) */
|
||||
0x81, 0x06, /* Input (Data,Var,Rel) */
|
||||
0xC0, /* End Collection */
|
||||
0x09, 0x3C, /* Usage (Motion Wakeup) */
|
||||
0x05, 0xFF, /* Usage Page (Reserved 0xFF) */
|
||||
0x09, 0x01, /* Usage (0x01) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0xB1, 0x22, /* Feature (Data,Var,Abs,NoWrp) */
|
||||
0x75, 0x06, /* Report Size (6) */
|
||||
0x95, 0x01, /* Report Count (1) */
|
||||
0xB1, 0x01, /* Feature (Const,Array,Abs,NoWrp) */
|
||||
0xC0 /* End Collection */
|
||||
};
|
||||
|
||||
static uint8_t HIDInEpAdd = HID_EPIN_ADDR;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_HID_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_Init
|
||||
* Initialize the HID interface
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
USBD_HID_HandleTypeDef *hhid;
|
||||
|
||||
hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef));
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
return (uint8_t)USBD_EMEM;
|
||||
}
|
||||
|
||||
pdev->pClassDataCmsit[pdev->classId] = (void *)hhid;
|
||||
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_HS_BINTERVAL;
|
||||
}
|
||||
else /* LOW and FULL-speed endpoints */
|
||||
{
|
||||
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
/* Open EP IN */
|
||||
(void)USBD_LL_OpenEP(pdev, HIDInEpAdd, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
|
||||
pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 1U;
|
||||
|
||||
hhid->state = USBD_HID_IDLE;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_DeInit
|
||||
* DeInitialize the HID layer
|
||||
* @param pdev: device instance
|
||||
* @param cfgidx: Configuration index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
UNUSED(cfgidx);
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/* Close HID EPs */
|
||||
(void)USBD_LL_CloseEP(pdev, HIDInEpAdd);
|
||||
pdev->ep_in[HIDInEpAdd & 0xFU].is_used = 0U;
|
||||
pdev->ep_in[HIDInEpAdd & 0xFU].bInterval = 0U;
|
||||
|
||||
/* Free allocated memory */
|
||||
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
|
||||
{
|
||||
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
|
||||
pdev->pClassDataCmsit[pdev->classId] = NULL;
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_Setup
|
||||
* Handle the HID specific requests
|
||||
* @param pdev: instance
|
||||
* @param req: usb requests
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_StatusTypeDef ret = USBD_OK;
|
||||
uint16_t len;
|
||||
uint8_t *pbuf;
|
||||
uint16_t status_info = 0U;
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||
{
|
||||
case USB_REQ_TYPE_CLASS :
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USBD_HID_REQ_SET_PROTOCOL:
|
||||
hhid->Protocol = (uint8_t)(req->wValue);
|
||||
break;
|
||||
|
||||
case USBD_HID_REQ_GET_PROTOCOL:
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
|
||||
break;
|
||||
|
||||
case USBD_HID_REQ_SET_IDLE:
|
||||
hhid->IdleState = (uint8_t)(req->wValue >> 8);
|
||||
break;
|
||||
|
||||
case USBD_HID_REQ_GET_IDLE:
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest)
|
||||
{
|
||||
case USB_REQ_GET_STATUS:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if ((req->wValue >> 8) == HID_REPORT_DESC)
|
||||
{
|
||||
len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength);
|
||||
pbuf = HID_MOUSE_ReportDesc;
|
||||
}
|
||||
else if ((req->wValue >> 8) == HID_DESCRIPTOR_TYPE)
|
||||
{
|
||||
pbuf = USBD_HID_Desc;
|
||||
len = MIN(USB_HID_DESC_SIZ, req->wLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
(void)USBD_CtlSendData(pdev, pbuf, len);
|
||||
break;
|
||||
|
||||
case USB_REQ_GET_INTERFACE :
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
(void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
hhid->AltSetting = (uint8_t)(req->wValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_REQ_CLEAR_FEATURE:
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_CtlError(pdev, req);
|
||||
ret = USBD_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
return (uint8_t)ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_SendReport
|
||||
* Send HID Report
|
||||
* @param pdev: device instance
|
||||
* @param buff: pointer to report
|
||||
* @param ClassId: The Class ID
|
||||
* @retval status
|
||||
*/
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len, uint8_t ClassId)
|
||||
{
|
||||
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[ClassId];
|
||||
#else
|
||||
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
|
||||
{
|
||||
USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hhid == NULL)
|
||||
{
|
||||
return (uint8_t)USBD_FAIL;
|
||||
}
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
HIDInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, ClassId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||
{
|
||||
if (hhid->state == USBD_HID_IDLE)
|
||||
{
|
||||
hhid->state = USBD_HID_BUSY;
|
||||
(void)USBD_LL_Transmit(pdev, HIDInEpAdd, report, len);
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_GetPollingInterval
|
||||
* return polling interval from endpoint descriptor
|
||||
* @param pdev: device instance
|
||||
* @retval polling interval
|
||||
*/
|
||||
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
uint32_t polling_interval;
|
||||
|
||||
/* HIGH-speed endpoints */
|
||||
if (pdev->dev_speed == USBD_SPEED_HIGH)
|
||||
{
|
||||
/* Sets the data transfer polling interval for high speed transfers.
|
||||
Values between 1..16 are allowed. Values correspond to interval
|
||||
of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */
|
||||
polling_interval = (((1U << (HID_HS_BINTERVAL - 1U))) / 8U);
|
||||
}
|
||||
else /* LOW and FULL-speed endpoints */
|
||||
{
|
||||
/* Sets the data transfer polling interval for low and full
|
||||
speed transfers */
|
||||
polling_interval = HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
return ((uint32_t)(polling_interval));
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief USBD_HID_GetCfgFSDesc
|
||||
* return FS configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
|
||||
|
||||
if (pEpDesc != NULL)
|
||||
{
|
||||
pEpDesc->bInterval = HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
|
||||
return USBD_HID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_GetCfgHSDesc
|
||||
* return HS configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
|
||||
|
||||
if (pEpDesc != NULL)
|
||||
{
|
||||
pEpDesc->bInterval = HID_HS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
|
||||
return USBD_HID_CfgDesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_GetOtherSpeedCfgDesc
|
||||
* return other speed configuration descriptor
|
||||
* @param speed : current device speed
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length)
|
||||
{
|
||||
USBD_EpDescTypeDef *pEpDesc = USBD_GetEpDesc(USBD_HID_CfgDesc, HID_EPIN_ADDR);
|
||||
|
||||
if (pEpDesc != NULL)
|
||||
{
|
||||
pEpDesc->bInterval = HID_FS_BINTERVAL;
|
||||
}
|
||||
|
||||
*length = (uint16_t)sizeof(USBD_HID_CfgDesc);
|
||||
return USBD_HID_CfgDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
/**
|
||||
* @brief USBD_HID_DataIn
|
||||
* handle data IN Stage
|
||||
* @param pdev: device instance
|
||||
* @param epnum: endpoint index
|
||||
* @retval status
|
||||
*/
|
||||
static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
UNUSED(epnum);
|
||||
/* Ensure that the FIFO is empty before a new transfer, this condition could
|
||||
be caused by a new transfer before the end of the previous transfer */
|
||||
((USBD_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId])->state = USBD_HID_IDLE;
|
||||
|
||||
return (uint8_t)USBD_OK;
|
||||
}
|
||||
|
||||
#ifndef USE_USBD_COMPOSITE
|
||||
/**
|
||||
* @brief DeviceQualifierDescriptor
|
||||
* return Device Qualifier descriptor
|
||||
* @param length : pointer data length
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length)
|
||||
{
|
||||
*length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc);
|
||||
|
||||
return USBD_HID_DeviceQualifierDesc;
|
||||
}
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_msc.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the usbd_msc.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_H
|
||||
#define __USBD_MSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_msc_bot.h"
|
||||
#include "usbd_msc_scsi.h"
|
||||
#include "usbd_ioreq.h"
|
||||
|
||||
/** @addtogroup USBD_MSC_BOT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_MSC
|
||||
* @brief This file is the Header file for usbd_msc.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_BOT_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/* MSC Class Config */
|
||||
#ifndef MSC_MEDIA_PACKET
|
||||
#define MSC_MEDIA_PACKET 512U
|
||||
#endif /* MSC_MEDIA_PACKET */
|
||||
|
||||
#define MSC_MAX_FS_PACKET 0x40U
|
||||
#define MSC_MAX_HS_PACKET 0x200U
|
||||
|
||||
#define BOT_GET_MAX_LUN 0xFE
|
||||
#define BOT_RESET 0xFF
|
||||
#define USB_MSC_CONFIG_DESC_SIZ 32
|
||||
|
||||
#ifndef MSC_EPIN_ADDR
|
||||
#define MSC_EPIN_ADDR 0x81U
|
||||
#endif /* MSC_EPIN_ADDR */
|
||||
|
||||
#ifndef MSC_EPOUT_ADDR
|
||||
#define MSC_EPOUT_ADDR 0x01U
|
||||
#endif /* MSC_EPOUT_ADDR */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USB_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
typedef struct _USBD_STORAGE
|
||||
{
|
||||
int8_t (* Init)(uint8_t lun);
|
||||
int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
|
||||
int8_t (* IsReady)(uint8_t lun);
|
||||
int8_t (* IsWriteProtected)(uint8_t lun);
|
||||
int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
|
||||
int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
|
||||
int8_t (* GetMaxLun)(void);
|
||||
int8_t *pInquiry;
|
||||
|
||||
} USBD_StorageTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t max_lun;
|
||||
uint32_t interface;
|
||||
uint8_t bot_state;
|
||||
uint8_t bot_status;
|
||||
uint32_t bot_data_length;
|
||||
uint8_t bot_data[MSC_MEDIA_PACKET];
|
||||
USBD_MSC_BOT_CBWTypeDef cbw;
|
||||
USBD_MSC_BOT_CSWTypeDef csw;
|
||||
|
||||
USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH];
|
||||
uint8_t scsi_sense_head;
|
||||
uint8_t scsi_sense_tail;
|
||||
uint8_t scsi_medium_state;
|
||||
|
||||
uint16_t scsi_blk_size;
|
||||
uint32_t scsi_blk_nbr;
|
||||
|
||||
uint32_t scsi_blk_addr;
|
||||
uint32_t scsi_blk_len;
|
||||
} USBD_MSC_BOT_HandleTypeDef;
|
||||
|
||||
/* Structure for MSC process */
|
||||
extern USBD_ClassTypeDef USBD_MSC;
|
||||
#define USBD_MSC_CLASS &USBD_MSC
|
||||
|
||||
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
|
||||
USBD_StorageTypeDef *fops);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_msc_bot.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the usbd_msc_bot.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_BOT_H
|
||||
#define __USBD_MSC_BOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_core.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup MSC_BOT
|
||||
* @brief This file is the Header file for usbd_msc_bot.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define USBD_BOT_IDLE 0U /* Idle state */
|
||||
#define USBD_BOT_DATA_OUT 1U /* Data Out state */
|
||||
#define USBD_BOT_DATA_IN 2U /* Data In state */
|
||||
#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */
|
||||
#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */
|
||||
#define USBD_BOT_NO_DATA 5U /* No data Stage */
|
||||
|
||||
#define USBD_BOT_CBW_SIGNATURE 0x43425355U
|
||||
#define USBD_BOT_CSW_SIGNATURE 0x53425355U
|
||||
#define USBD_BOT_CBW_LENGTH 31U
|
||||
#define USBD_BOT_CSW_LENGTH 13U
|
||||
#define USBD_BOT_MAX_DATA 256U
|
||||
|
||||
/* CSW Status Definitions */
|
||||
#define USBD_CSW_CMD_PASSED 0x00U
|
||||
#define USBD_CSW_CMD_FAILED 0x01U
|
||||
#define USBD_CSW_PHASE_ERROR 0x02U
|
||||
|
||||
/* BOT Status */
|
||||
#define USBD_BOT_STATUS_NORMAL 0U
|
||||
#define USBD_BOT_STATUS_RECOVERY 1U
|
||||
#define USBD_BOT_STATUS_ERROR 2U
|
||||
|
||||
|
||||
#define USBD_DIR_IN 0U
|
||||
#define USBD_DIR_OUT 1U
|
||||
#define USBD_BOTH_DIR 2U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup MSC_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataLength;
|
||||
uint8_t bmFlags;
|
||||
uint8_t bLUN;
|
||||
uint8_t bCBLength;
|
||||
uint8_t CB[16];
|
||||
uint8_t ReservedForAlign;
|
||||
} USBD_MSC_BOT_CBWTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataResidue;
|
||||
uint8_t bStatus;
|
||||
uint8_t ReservedForAlign[3];
|
||||
} USBD_MSC_BOT_CSWTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
|
||||
* @{
|
||||
*/
|
||||
void MSC_BOT_Init(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev);
|
||||
void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
|
||||
void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
|
||||
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev,
|
||||
uint8_t CSW_Status);
|
||||
|
||||
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev,
|
||||
uint8_t epnum);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_BOT_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_msc_data.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the usbd_msc_data.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_DATA_H
|
||||
#define __USBD_MSC_DATA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_conf.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_INFO
|
||||
* @brief general defines for the usb device library file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USB_INFO_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define MODE_SENSE6_LEN 0x04U
|
||||
#define MODE_SENSE10_LEN 0x08U
|
||||
#define LENGTH_INQUIRY_PAGE00 0x06U
|
||||
#define LENGTH_INQUIRY_PAGE80 0x08U
|
||||
#define LENGTH_FORMAT_CAPACITIES 0x14U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_INFO_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBD_INFO_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_INFO_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
|
||||
extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
|
||||
extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
|
||||
extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_INFO_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_DATA_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbd_msc_scsi.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for the usbd_msc_scsi.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2015 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBD_MSC_SCSI_H
|
||||
#define __USBD_MSC_SCSI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbd_def.h"
|
||||
|
||||
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_SCSI
|
||||
* @brief header file for the storage disk file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SENSE_LIST_DEEPTH 4U
|
||||
|
||||
/* SCSI Commands */
|
||||
#define SCSI_FORMAT_UNIT 0x04U
|
||||
#define SCSI_INQUIRY 0x12U
|
||||
#define SCSI_MODE_SELECT6 0x15U
|
||||
#define SCSI_MODE_SELECT10 0x55U
|
||||
#define SCSI_MODE_SENSE6 0x1AU
|
||||
#define SCSI_MODE_SENSE10 0x5AU
|
||||
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU
|
||||
#define SCSI_READ6 0x08U
|
||||
#define SCSI_READ10 0x28U
|
||||
#define SCSI_READ12 0xA8U
|
||||
#define SCSI_READ16 0x88U
|
||||
|
||||
#define SCSI_READ_CAPACITY10 0x25U
|
||||
#define SCSI_READ_CAPACITY16 0x9EU
|
||||
|
||||
#define SCSI_REQUEST_SENSE 0x03U
|
||||
#define SCSI_START_STOP_UNIT 0x1BU
|
||||
#define SCSI_TEST_UNIT_READY 0x00U
|
||||
#define SCSI_WRITE6 0x0AU
|
||||
#define SCSI_WRITE10 0x2AU
|
||||
#define SCSI_WRITE12 0xAAU
|
||||
#define SCSI_WRITE16 0x8AU
|
||||
|
||||
#define SCSI_VERIFY10 0x2FU
|
||||
#define SCSI_VERIFY12 0xAFU
|
||||
#define SCSI_VERIFY16 0x8FU
|
||||
|
||||
#define SCSI_SEND_DIAGNOSTIC 0x1DU
|
||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23U
|
||||
|
||||
#define NO_SENSE 0U
|
||||
#define RECOVERED_ERROR 1U
|
||||
#define NOT_READY 2U
|
||||
#define MEDIUM_ERROR 3U
|
||||
#define HARDWARE_ERROR 4U
|
||||
#define ILLEGAL_REQUEST 5U
|
||||
#define UNIT_ATTENTION 6U
|
||||
#define DATA_PROTECT 7U
|
||||
#define BLANK_CHECK 8U
|
||||
#define MSC_VENDOR_SPECIFIC 9U
|
||||
#define COPY_ABORTED 10U
|
||||
#define ABORTED_COMMAND 11U
|
||||
#define VOLUME_OVERFLOW 13U
|
||||
#define MISCOMPARE 14U
|
||||
|
||||
|
||||
#define INVALID_CDB 0x20U
|
||||
#define INVALID_FIELED_IN_COMMAND 0x24U
|
||||
#define PARAMETER_LIST_LENGTH_ERROR 0x1AU
|
||||
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U
|
||||
#define ADDRESS_OUT_OF_RANGE 0x21U
|
||||
#define MEDIUM_NOT_PRESENT 0x3AU
|
||||
#define MEDIUM_HAVE_CHANGED 0x28U
|
||||
#define WRITE_PROTECTED 0x27U
|
||||
#define UNRECOVERED_READ_ERROR 0x11U
|
||||
#define WRITE_FAULT 0x03U
|
||||
|
||||
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU
|
||||
#define READ_CAPACITY10_DATA_LEN 0x08U
|
||||
#define REQUEST_SENSE_DATA_LEN 0x12U
|
||||
#define STANDARD_INQUIRY_DATA_LEN 0x24U
|
||||
#define BLKVFY 0x04U
|
||||
|
||||
#define SCSI_MEDIUM_UNLOCKED 0x00U
|
||||
#define SCSI_MEDIUM_LOCKED 0x01U
|
||||
#define SCSI_MEDIUM_EJECTED 0x02U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBD_SCSI_Exported_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _SENSE_ITEM
|
||||
{
|
||||
uint8_t Skey;
|
||||
union
|
||||
{
|
||||
struct _ASCs
|
||||
{
|
||||
uint8_t ASC;
|
||||
uint8_t ASCQ;
|
||||
} b;
|
||||
uint8_t ASC;
|
||||
uint8_t *pData;
|
||||
} w;
|
||||
} USBD_SCSI_SenseTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_SCSI_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBD_SCSI_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd);
|
||||
|
||||
void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
|
||||
uint8_t ASC);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBD_MSC_SCSI_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user