Merge pull request from caixue1102/mbed-os-rda

Add WIFI support for RDA target UNO_91H
pull/9645/head
Cruz Monrreal 2019-02-12 20:05:27 -06:00 committed by GitHub
commit 3e6cd4e89d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 6066 additions and 24 deletions

View File

@ -35,7 +35,8 @@
!defined(TARGET_MTB_ADV_WISE_1530) && \
!defined(TARGET_MTB_USI_WM_BN_BM_22) && \
!defined(TARGET_MTB_MXCHIP_EMW3166) && \
!defined(TARGET_MTB_UBLOX_ODIN_W2)
!defined(TARGET_MTB_UBLOX_ODIN_W2) && \
!defined(TARGET_UNO_91H)
#error [NOT_SUPPORTED] Wifi tests are not valid for the target
#endif
#endif

View File

@ -0,0 +1,217 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "WiFiInterface.h"
#include "RdaWiFiInterface.h"
#include "rda5991h_wland.h"
#include "nsapi_types.h"
#include "wland_types.h"
#include "rda_sys_wrapper.h"
nsapi_error_t RDAWiFiInterface::set_channel(uint8_t channel)
{
int ret= 0;
init();
if (channel > 13)
return NSAPI_ERROR_PARAMETER;
if (channel == 0) {
_channel = 0;
return NSAPI_ERROR_OK;
}
ret = rda5981_set_channel(channel);
if (ret == 0) {
_channel = channel;
return NSAPI_ERROR_OK;
} else {
return NSAPI_ERROR_TIMEOUT;
}
}
int8_t RDAWiFiInterface::get_rssi()
{
return rda5981_get_rssi();
}
nsapi_error_t RDAWiFiInterface::init()
{
if (!_interface) {
if (!_emac.power_up()) {
LWIP_DEBUGF(NETIF_DEBUG,"power up failed!\n");
}
nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface);
if (err != NSAPI_ERROR_OK) {
_interface = NULL;
return err;
}
_interface->attach(_connection_status_cb);
}
return NSAPI_ERROR_OK;
}
nsapi_error_t RDAWiFiInterface::set_credentials(const char *ssid, const char *pass,
nsapi_security_t security)
{
if (ssid == 0 || strlen(ssid) == 0) {
return NSAPI_ERROR_PARAMETER;
}
if (security != NSAPI_SECURITY_NONE && (pass == 0 || strlen(pass) == 0)) {
return NSAPI_ERROR_PARAMETER;
}
if (strlen(ssid) > 32 || strlen(pass) > 63) {
return NSAPI_ERROR_PARAMETER;
}
memcpy((void*)_ssid, (void*)ssid, strlen(ssid));
_ssid[strlen(ssid)] = '\0';
memcpy((void*)_pass, (void*)pass, strlen(pass));
_pass[strlen(pass)] = '\0';
_security = security;
return NSAPI_ERROR_OK;
}
nsapi_error_t RDAWiFiInterface::connect(const char *ssid, const char *pass,
nsapi_security_t security, uint8_t channel)
{
rda_msg msg;
bool find = false;
int i = 0;
rda5981_scan_result bss;
int ret = 0;
if (ssid == NULL || ssid[0] == 0) {
return NSAPI_ERROR_PARAMETER;
}
init();
if(rda5981_check_scan_result_name(ssid) != 0) {
for (i = 0; i< 5; i++) {
rda5981_scan(NULL, 0, 0);
if(rda5981_check_scan_result_name(ssid) == 0) {
find = true;
break;
}
}
} else {
find = true;
}
if (find == false) {
LWIP_DEBUGF(NETIF_DEBUG,"can not find the ap.\r\n");
return NSAPI_ERROR_CONNECTION_TIMEOUT;
}
bss.channel = 15;
rda5981_get_scan_result_name(&bss, ssid);
if ((channel !=0) && (bss.channel != channel)) {
LWIP_DEBUGF(NETIF_DEBUG, "invalid channel\r\n");
return NSAPI_ERROR_CONNECTION_TIMEOUT;
}
memcpy(gssid, ssid, strlen(ssid));
if (pass[0] != 0) {
memcpy(gpass, pass, strlen(pass));
}
memset(gbssid, 0, NSAPI_MAC_BYTES);
gssid[strlen(ssid)] = gpass[strlen(pass)] = '\0';
msg.type = WLAND_CONNECT;
rda_mail_put(wland_msgQ, (void*)&msg, osWaitForever);
ret = rda_sem_wait(wifi_auth_sem, 10000);
if (ret) {
return NSAPI_ERROR_CONNECTION_TIMEOUT;
}
ret = _interface->bringup(_dhcp,
_ip_address[0] ? _ip_address : 0,
_netmask[0] ? _netmask : 0,
_gateway[0] ? _gateway : 0,
DEFAULT_STACK,
_blocking);
return ret;
}
nsapi_error_t RDAWiFiInterface::connect()
{
return connect(_ssid, _pass, _security, _channel);
}
nsapi_error_t RDAWiFiInterface::disconnect()
{
rda_msg msg;
if(sta_state < 2) {
return NSAPI_ERROR_NO_CONNECTION;
}
msg.type = WLAND_DISCONNECT;
rda_mail_put(wland_msgQ, (void*)&msg, osWaitForever);
if (_interface) {
return _interface->bringdown();
}
return NSAPI_ERROR_NO_CONNECTION;
}
nsapi_size_or_error_t RDAWiFiInterface::scan(WiFiAccessPoint *res, nsapi_size_t count)
{
int bss_num = 0, i;
rda5981_scan_result *bss;
nsapi_wifi_ap_t ap;
init();
rda5981_scan(NULL, 0, 0);
bss_num = rda5981_get_scan_num();
if (count != 0) {
bss_num = (bss_num < count) ? bss_num : count;
}
if (res) {
bss = (rda5981_scan_result *)malloc(bss_num * sizeof(rda5981_scan_result));
rda5981_get_scan_result(bss, bss_num);
for (i=0; i<bss_num; i++) {
memset(&ap, 0, sizeof(nsapi_wifi_ap_t));
memcpy(ap.bssid, bss[i].BSSID, 6);
memcpy(ap.ssid, bss[i].SSID, bss[i].SSID_len);
ap.channel = bss[i].channel;
ap.rssi = bss[i].RSSI;
if (bss[i].secure_type == ENCRYPT_NONE) {
ap.security = NSAPI_SECURITY_NONE;
} else if(bss[i].secure_type & ENCRYPT_WEP) {
ap.security = NSAPI_SECURITY_WEP;
} else if((bss[i].secure_type & (ENCRYPT_WPA_TKIP | ENCRYPT_WPA_CCMP)) && \
(bss[i].secure_type & (ENCRYPT_WPA2_TKIP | ENCRYPT_WPA2_CCMP))) {
ap.security = NSAPI_SECURITY_WPA_WPA2;
} else if((bss[i].secure_type & (ENCRYPT_WPA_TKIP | ENCRYPT_WPA_CCMP))) {
ap.security = NSAPI_SECURITY_WPA;
} else {
ap.security = NSAPI_SECURITY_WPA2;
}
WiFiAccessPoint ap_temp(ap);
memcpy(&res[i], &ap_temp, sizeof(WiFiAccessPoint));
}
free(bss);
}
return bss_num;
}
WiFiInterface *WiFiInterface::get_default_instance() {
static RDAWiFiInterface wifinet;
return &wifinet;
}

View File

@ -0,0 +1,137 @@
/* LWIP implementation of NetworkInterfaceAPI
* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RDA_WIFI_INTERFACE_H
#define RDA_WIFI_INTERFACE_H
#include "nsapi.h"
#include "rtos.h"
#include "EMACInterface.h"
#include "WiFiInterface.h"
/** RDAWiFiInterface class
* Implementation of the NetworkStack for an EMAC-based Ethernet driver
*/
class RDAWiFiInterface : public EMACInterface, public WiFiInterface
{
public:
/** Create an EMAC-based ethernet interface.
*
* The default arguments obtain the default EMAC, which will be target-
* dependent (and the target may have some JSON option to choose which
* is the default, if there are multiple). The default stack is configured
* by JSON option nsapi.default-stack.
*
* Due to inability to return errors from the constructor, no real
* work is done until the first call to connect().
*
* @param emac Reference to EMAC to use
* @param stack Reference to onboard-network stack to use
*/
RDAWiFiInterface(
EMAC &emac = EMAC::get_default_instance(),
OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()) : EMACInterface(emac, stack) {
_ssid[0] = '\0';
_pass[0] = '\0';
_channel = 0;
_security = NSAPI_SECURITY_NONE;
}
//static RDAWiFiInterface *get_target_default_instance();
/** Set the WiFi network credentials
*
* @param ssid Name of the network to connect to
* @param pass Security passphrase to connect to the network
* @param security Type of encryption for connection
* (defaults to NSAPI_SECURITY_NONE)
* @return 0 on success, or error code on failure
*/
virtual nsapi_error_t set_credentials(const char *ssid, const char *pass,
nsapi_security_t security = NSAPI_SECURITY_NONE);
/** Set the WiFi network channel
*
* @param channel Channel on which the connection is to be made, or 0 for any (Default: 0)
* @return 0 on success, or error code on failure
*/
virtual nsapi_error_t set_channel(uint8_t channel);
/** Gets the current radio signal strength for active connection
*
* @return Connection strength in dBm (negative value),
* or 0 if measurement impossible
*/
virtual int8_t get_rssi();
/** Start the interface
*
* Attempts to connect to a WiFi network.
*
* @param ssid Name of the network to connect to
* @param pass Security passphrase to connect to the network
* @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
* @param channel Channel on which the connection is to be made, or 0 for any (Default: 0)
* @return 0 on success, or error code on failure
*/
virtual nsapi_error_t connect(const char *ssid, const char *pass,
nsapi_security_t security = NSAPI_SECURITY_NONE, uint8_t channel = 0);
/** Start the interface
*
* Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
* If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned.
*
* @return 0 on success, negative error code on failure
*/
virtual nsapi_error_t connect();
/** Stop the interface
*
* @return 0 on success, or error code on failure
*/
virtual nsapi_error_t disconnect();
/** Scan for available networks
*
* This function will block. If the @a count is 0, function will only return count of available networks, so that
* user can allocated necessary memory. If the \p count is grater than 0 and the a \p res is not NULL it'll be populated
* with discovered networks up to value of \p count.
*
* @param res Pointer to allocated array to store discovered AP
* @param count Size of allocated @a res array, or 0 to only count available AP
* @return Number of entries in \p count, or if \p count was 0 number of available networks,
* negative on error see @a nsapi_error
*/
virtual nsapi_size_or_error_t scan(WiFiAccessPoint *res, nsapi_size_t count);
virtual nsapi_size_or_error_t init();
private:
char _ssid[33];
char _pass[65];
uint8_t _channel;
nsapi_security_t _security;
};
#endif

View File

@ -0,0 +1,152 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*****************************************************************************/
/* */
/* File Name : csl_mbed.h */
/* */
/* Description : This file contains all declarations and functions */
/* related to the chip support library. */
/* */
/* MbedOS Usage : Call maclib_get_funcs_struct() to get MACLib funcs; */
/* Define mbed_reg_func_t var, Register it by ml_init; */
/* */
/*****************************************************************************/
#ifndef CSL_MBED_H
#define CSL_MBED_H
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************/
/* Constants */
/*****************************************************************************/
#define RDA_EXT_INT_MAC_HW_INDEX 8
#define RDA_EXT_INT_MAC_HW_PRI 0x80
/*****************************************************************************/
/* Enums */
/*****************************************************************************/
typedef enum {
MACLIB_EVENT_PEND = 0,
MACLIB_EVENT_PROCESS = 1,
MACLIB_EVENT_CLEANUP = 2
} MACLIB_EVENT_HANDLE_T;
/*****************************************************************************/
/* Data Types */
/*****************************************************************************/
typedef struct
{
unsigned int ml_id; /* Buffer identification */
unsigned char* ml_data; /* Pkt start address */
unsigned short ml_len; /* Pkt length */
} maclib_buf_t;
/* Structure that contains functions provided by MACLib */
typedef struct {
/* Initialize MAC Library, input param: mbed_reg_func_t *reg_funcs */
int (*ml_init)(void *reg_funcs);
/* As a peroid task to process MAC Library background event */
void (*ml_tasklet)(void);
/* Get a new packet buffer, output param: maclib_buf_t *buf */
void (*ml_get_pkt_buf)(void *buf);
/* Mbed stack send packet to MAC Library, input param: maclib_buf_t *buf*/
int (*ml_xmit_pkt)(void *buf);
/* Mbed receive and processing packet done, input param: unsigned int buf_id */
void (*ml_recv_pkt_comp)(unsigned int buf_id);
} maclib_func_t;
/* Structure that contains functions provided by MbedOS */
typedef struct {
/* MAC Library send packet to mbed stack, input param: maclib_buf_t *buf */
void (*mbed_recv_pkt)(void *buf);
/* Critical section start realized in mbed */
void (*mbed_critical_sec_start)(void);
/* Critical section end realized in mbed */
void (*mbed_critical_sec_end)(void);
/* Create interrupt in mbed, input param: vector/priority/isr(function), */
/* return: interrupt handle, non-zero is valid */
void * (*mbed_create_interrupt)(unsigned int vec, unsigned int pri, void *isr);
/* Delete interrupt in mbed, input param: vector */
void (*mbed_delete_interrupt)(unsigned int vec);
/* Enable interrupt in mbed, input param: vector */
void (*mbed_enable_interrupt)(unsigned int vec);
/* Disable interrupt in mbed, input param: vector */
void (*mbed_disable_interrupt)(unsigned int vec);
/* Get current time realized in mbed, return time in units of micro second */
unsigned long (*mbed_get_cur_time_ms)(void);
/* Create alarm in mbed, input param: func(callback)/data(pass to func), */
/* return: alarm handle, non-zero is valid */
void * (*mbed_create_alarm)(void *func, unsigned int data);
/* Delete alarm in mbed, input param: alarm handle */
void (*mbed_delete_alarm)(void **handle);
/* Start alarm in mbed, input param: alarm handle/timeout(micro second) */
void (*mbed_start_alarm)(void *handle, unsigned int timeout_ms);
/* Stop alarm in mbed, input param: alarm handle */
void (*mbed_stop_alarm)(void *handle);
#if defined(MBED_MUTEX_INTERFACE)
/* Create mutex */
void (*mbed_mutex_create)(void);
/* Delete mutex */
unsigned int (*mbed_mutex_delete)(void *rdamutex);
/* Wait mutex, timer unit : millisec */
unsigned int (*mbed_mutex_wait)(void *rdamutex, unsigned int millisec);
/* Release mutex */
unsigned int (*mbed_mutex_release)(void *rdamutex);
#endif /* MBED_MUTEX_INTERFACE */
/* Event post/get callback function, input param: event_type */
void (*mbed_event_hdl_cb)(unsigned int event);
/* maclib task sleep callback function */
void (*mbed_task_sleep_cb)(void);
/* maclib task wakeup callback function */
void (*mbed_task_wakeup_cb)(void);
} maclib_import_func_t;
/*****************************************************************************/
/* Extern Function Declarations */
/*****************************************************************************/
extern void maclib_get_funcs_struct(maclib_func_t *func_str);
#ifdef __cplusplus
}
#endif
#endif /* CSL_MBED_H */

View File

@ -0,0 +1,69 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file : maclib_task.h
* @brief : WiFi MACLib task header file
* @version: V1.0
* @date : 6. May 2017
*
* @note :
*
******************************************************************************/
#ifndef _MACLIB_TASK_H_
#define _MACLIB_TASK_H_
#define MAC_LIB_MAX_FLEN 1536
/**
* Enums
*/
typedef enum {
MACLIB_MSG_EVNT_HNDL,
MACLIB_MSG_WLAND_XMIT_PKT,
MACLIB_MSG_LWIP_XMIT_PKT
} MACLIB_MSG_TYPE_T;
/**
* Structures
*/
typedef struct {
MACLIB_MSG_TYPE_T type;
void *msg;
int is_free;
} maclib_msg_t;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief : MACLib main task [MACLib api]
* @param[in] : pvParameters(pointer to enet data)
* @param[out]:
* @return :
*/
extern void maclib_task(void *pvParameters);
extern void mbed_event_handle_cb(unsigned int event);
extern void mbed_mltask_sleep_cb(void);
extern void mbed_mltask_wakeup_cb(void);
#ifdef __cplusplus
}
#endif
#endif /* _MACLIB_TASK_H_ */

View File

@ -0,0 +1,105 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RDA5981_FLASH_H_
#define _RDA5981_FLASH_H_
#include "wland_types.h"
/** This struct contains tx power parameter. */
typedef struct
{
u8 b[14];
u8 g[14];
u8 n[14];
u8 sum;
u8 padding1;//alignment
} wland_tx_power_t;
/*
*function: store reg and corresponding value related to test mode
*@valid: 1 means data is valid
*@flag: if biti(i=0~7) == 1, it means reg_val[i] is in use
*@reg_val: store reg and value, reg_val[i][0] is reg, reg_val[i][1] ~ reg_val[i][14] is value
*/
typedef struct {
u32 valid;
u32 flag;
u16 reg_val[8][2];
} wland_rf_t;
typedef struct {
u32 valid;
u32 flag;
u16 reg_val[8][15];
} wland_rf_channels_t;
typedef struct {
u32 valid;
u32 flag;
u32 reg_val[8][2];
} wland_phy_t;
typedef struct {
u32 valid;
u32 flag;
u32 reg_val[8][15];
} wland_phy_channels_t;
/* if you add or delete any macros below, modify RDA5991H_USER_DATA_FLAG_UNINITIALIZED at the same time */
#define RDA5991H_USER_DATA_FLAG_MAC BIT0
#define RDA5991H_USER_DATA_FLAG_STA BIT1
#define RDA5991H_USER_DATA_FLAG_PMK BIT2
#define RDA5991H_USER_DATA_FLAG_IP BIT3
#define RDA5991H_USER_DATA_FLAG_PARTER_DATA_LEN BIT4
#define RDA5991H_USER_DATA_FLAG_TX_POWER BIT5
#define RDA5991H_USER_DATA_FLAG_XTAL_CAL BIT6
#define RDA5991H_USER_DATA_FLAG_TX_POWER_RF BIT7
#define RDA5991H_USER_DATA_FLAG_TX_POWER_PHY_GN BIT8
#define RDA5991H_USER_DATA_FLAG_TX_POWER_PHY_B BIT9
#define RDA5991H_USER_DATA_FLAG_AP BIT10
#define RDA5991H_USER_DATA_FLAG_APNET BIT11
#define RDA5991H_USER_DATA_FLAG_DHCP BIT12
#define RDA5991H_USER_DATA_FLAG_UART BIT13
#define RDA5991H_USER_DATA_FLAG_RF BIT14
#define RDA5991H_USER_DATA_FLAG_RF_CHANNELS BIT15
#define RDA5991H_USER_DATA_FLAG_PHY BIT16
#define RDA5991H_USER_DATA_FLAG_PHY_CHANNELS BIT17
#define RDA5991H_USER_DATA_FLAG_TX_POWER_OFFSET BIT18
#define RDA5981_VBAT_CAL BIT0
#define RDA5981_GPADC0_CAL BIT1
#define RDA5981_GPADC1_CAL BIT2
#define RDA5981_PRODUCT_ID BIT3
#define RDA5981_POWER_CLASS BIT4
#ifdef __cplusplus
extern "C" {
#endif
/*
* function: read VBAT Calibration value
* y = k * x + b
* @k: slope
* @b: offset
* return: 0:success, else:fail
*/
int rda5981_flash_read_vbat_cal(float *k, float *b);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,57 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RDA5981_OTA_H_
#define _RDA5981_OTA_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const unsigned int RDA_FW_INFO_ADDR;
extern const unsigned int RDA_UPGRADE_ADDR;
/*
* function: start to wirte a partition. this func will erase given flash region
* @addr: partition start address, must be 4k alignment
* @img_len: length of image getted from OTA server, must be 4k alignment
* return: 0:success, else:fail
*/
int rda5981_write_partition_start(unsigned int addr, unsigned int img_len);
/*
* function: write image to flash, without erase.
* the write region must be inside of the area given by func rda5981_write_partition_start
* the write region must be in order, otherwise the end function will return crc error.
* the maximum length could be write once time is 0x1000
* @offset: offset from image inital position, must be 1k alignment
* @buf: data to be written
* @len: buffer len, max #0x1000, must be 1k alignment
* return: 0:success, else:fail
*/
int rda5981_write_partition(unsigned int offset, const unsigned char *buf, unsigned int len);
/*
* function: end of writing partition
* return: 0:crc32 check success, else:fail
*/
int rda5981_write_partition_end(void);
#ifdef __cplusplus
}
#endif
#endif /*_RDA5981_OTA_H_*/

View File

@ -0,0 +1,99 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RDA5981_SNIFFER_H_
#define _RDA5981_SNIFFER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "wland_types.h"
/* Enable filtering ACK frames (no support)*/
//#define RDA_RX_FILTER_DROP_ACK BIT0
/* Enable filtering CTS frames (no support)*/
//#define RDA_RX_FILTER_DROP_CTS BIT1
/* Enable filtering RTS frames (no support)*/
//#define RDA_RX_FILTER_DROP_RTS BIT2
/* Enable filtering beacon frames */
#define RDA_RX_FILTER_DROP_BEACON BIT3
/* Enable filtering ATIM frames (no support)*/
//#define RDA_RX_FILTER_DROP_ATIM BIT4
/* Enable filtering CF_END frames (no support)*/
//#define RDA_RX_FILTER_DROP_CF_END BIT5
/* Enable filtering QCF_POLL frames (no support)*/
//#define RDA_RX_FILTER_DROP_QCF_POLL BIT6
/* Filter Management frames which are not directed to current STA */
#define RDA_RX_FILTER_DROP_ND_MGMT BIT7
/* Filter BC/MC MGMT frames belonging to other BSS */
#define RDA_RX_FILTER_DROP_BC_MC_MGMT_OTHER_BSS BIT8
/* Enable filtering of duplicate frames */
#define RDA_RX_FILTER_DROP_DUPLICATE BIT9
/* Enable filtering of frames whose FCS has failed */
#define RDA_RX_FILTER_DROP_FCS_FAILED BIT10
/* Enable filtering of De-authentication frame */
#define RDA_RX_FILTER_DROP_DEAUTH BIT11
/* Filter BA frames which are not received as SIFS response (no support)*/
//#define RDA_RX_FILTER_DROP_NSIFS_RESP_BA BIT12
/* Filter BA frames which are received as SIFS response (no support)*/
//#define RDA_RX_FILTER_DROP_SIFS_RESP_BA BIT13
/* Filter frames which are received in secondary channel (20 MHz PPDU from Secondary channel) */
#define RDA_RX_FILTER_DROP_SEC_CHANNEL BIT14
/* Filter BC/MC DATA frames belonging to other BSS */
#define RDA_RX_FILTER_DROP_BC_MC_DATA_OTHER_BSS BIT15
/* Filter DATA frames not directed to this station */
#define RDA_RX_FILTER_DROP_ND_DATA BIT16
/* Filter Control frames which are not directed to current STA (no support)*/
//#define RDA_RX_FILTER_DROP_ND_CONTROL BIT17
/* Filter Beacon frames (in IBSS mode) which are not used for adoption because the timestamp field is lower than TSF timer */
#define RDA_RX_FILTER_DROP_IBSS_BEACON BIT18
typedef int (*sniffer_handler_t)(unsigned short data_len, void *data);
int rda5981_enable_sniffer(sniffer_handler_t handler);
int rda5981_disable_sniffer(void);
//don't use this in sniffer callback handler
int rda5981_disable_sniffer_nocallback(void);
///TODO: time is no use anymore
int rda5981_start_sniffer(unsigned char channel, unsigned char to_ds,
unsigned char from_ds, unsigned char mgm_frame, unsigned short time);
int rda5981_stop_sniffer(void);
int wland_sniffer_set_channel(unsigned char channel);
int rda5981_set_filter(unsigned char to_ds, unsigned char from_ds, unsigned int mgm_filter);
int rda5981_sniffer_enable_fcs(void);//for hiflying
#ifdef __cplusplus
}
#endif
#endif /*_RDA5981_SNIFFER_H_*/

View File

@ -0,0 +1,658 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _RDA5991H_WLAND_H_
#define _RDA5991H_WLAND_H_
#include "sys_arch.h"
#include "wland_types.h"
/* Mbed interface mac address
* if MBED_MAC_ADD_x are zero, interface uid sets mac address,
* otherwise MAC_ADD_x are used.
*/
extern unsigned char user_mac[6];//not save in flash, need fill before wifi init every time
extern unsigned char gssid[32+1];
extern unsigned char gpass[64+1];
extern unsigned char gchannel;
extern unsigned char gbssid[6];
extern unsigned char gssid_ap[32+1];
extern unsigned char gpass_ap[64+1];
extern unsigned char gchannel_ap;
extern void *wland_msgQ;
extern void *wifi_auth_sem;
extern u8 sta_state;
typedef enum {
WLAND_CONNECT,
WLAND_RECONNECT,
WLAND_DISCONNECT,
WLAND_DISCONNECT_ERROR,
WLAND_STARTAP,
WLAND_STOPAP,
WLAND_ADD_AP_GTK,
WLAND_AP_EAPOL_3_OF_4,
WLAND_ADD_AP_PTK,
WLAND_STAJOINED,
WLAND_STAEXITED,
WLAND_STADEAUTH,
WLAND_MAC_CONNECTED,
WLAND_MAC_AP_CONNECTED,
WLAND_ADD_GTK,
WLAND_ADD_PTK,
WLAND_CON_FINISH,
WLAND_AUTO_RATE,
WLAND_ARP_OFFLOAD,
WLAND_SM_START,
WLAND_SM_STOP,
WLAND_WPS_CONNECT,
WLAND_WPS_START,
WLAND_WPS_DISCONNECT,
}WLAND_MSG;
typedef enum {
MAIN_CONNECT,
MAIN_RECONNECT,
MAIN_DISCONNECT,
MAIN_STOP_AP,
}MAIN_MSG;
typedef struct {
unsigned int type;
unsigned int arg1;
unsigned int arg2;
unsigned int arg3;
}rda_msg;
enum {
D_NONE_LEVEL = 0,
D_ERROR_LEVEL = 1,
D_INFO_LEVEL = 2,
D_DEBUG_LEVEL = 3,
};
#define WLAND_DBG_DUMP 0
#define WPA_DBG_DUMP 0
#define HUT_DBG_DUMP 0
#define WLAND_DBG_LEVEL D_NONE_LEVEL
#define WPA_DBG_LEBEL D_NONE_LEVEL
#define WLANDLIB_DBG_LEVEL D_NONE_LEVEL
#define ETH_ALEN 6
//encrypt type
#define ENCRYPT_NONE (0)
#define ENCRYPT_WPA_TKIP BIT0
#define ENCRYPT_WPA_CCMP BIT1
#define ENCRYPT_WPA2_TKIP BIT2
#define ENCRYPT_WPA2_CCMP BIT3
#define ENCRYPT_WEP BIT4
/* r91h driver data structure */
typedef struct {
struct netif *netif_sta;
struct netif *netif_ap;
sys_thread_t wland_thread;
sys_thread_t maclib_thread;
sys_mbox_t maclib_mbox;
sys_mbox_t wland_mbox;
} rda_enetdata_t;
__STATIC_INLINE int mac_is_valid(char* mac)
{
return (mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]);
}
#ifdef __cplusplus
extern "C" {
#endif
extern void wland_txip_data(void *data, unsigned int len, int mode);
extern void *wland_get_databuf(void);
extern void wland_sta_init(void);
extern void wland_reg_func(void);
extern void r91h_phy_task(void *data);
extern void wland_task(void *arg);
extern void rda_get_macaddr(u8_t *macaddr, int mode);
extern void rda5981_send_rawdata(char* data, unsigned int len);
extern int rda5981_send_nulldata(int power_save);
extern void rda5981_set_country_code(unsigned char country_code);// 0~china(1-14) 1~NA(1-11) 2~EU(1-13)
extern int rda5981_set_retrans_policy(unsigned char count);
extern int rda5981_set_channel(unsigned char channel);
/* default is 0, receive multicast packet, disable please set 1*/
extern int rda5981_filter_multicast(unsigned char enable);
/* default is 0, 0 ~ no hidden, 1 ~ hidden zero len, 2 ~ hidden zero contents */
extern void rda5981_set_AP_hidden_type(unsigned char mode);
extern void rda5981_set_AP_link_num(unsigned char num);
extern char* rda5981_get_ver(void);
extern int rda5981_enter_CE_MODE(unsigned char enable);
/*
* mode 0 - not 11n 1 - 11n
*
* -----------------11n(mode 1)(Mbps)-----------------
* rate HT20 HT40
* GI(800ns) GI(400ns) GI(800ns) GI(400ns)
* 0 6.5 7.2 13.5 15
* 1 13 14.2 27 30
* 2 19.5 21.7 40.5 45
* 3 26 28.9 54 60
* 4 39 43.3 81 90
* 5 52 57.8 108 120
* 6 58.5 65 121.5 135
* 7 65 72 135 150
*
* --------------not 11n(mode 0)(Mbps)-----------------
* rate data rate rate data rate
* 0 autorate 9 9
* 1 1 12 12
* 2 2 18 18
* 5 5.5 24 24
* 11 11 36 36
* 6 6 48 48
*
*/
extern int rda5981_set_data_rate(unsigned char mode, unsigned char rate);
extern void rda5981_set_mode(unsigned char bgn_enable);
extern void rda5981_set_auth_timeout(unsigned char timeout_enable);
typedef struct {
char BSSID[ETH_ALEN];
char SSID[32+1];
signed char RSSI;
unsigned char SSID_len;
unsigned char channel;
unsigned char secure_type;//refer #define ENCRYPT_XXX
unsigned char wmm;
unsigned char *ie;//user program couldn't free(ie);
unsigned short capability;
unsigned int ie_length;
} rda5981_scan_result;
typedef struct {
unsigned char mac[ETH_ALEN];
unsigned int ip;
} rda5981_apsta_info;
//scan one or all channel(if channel is 0) once
int rda5981_scan(const char *SSID, const unsigned char SSID_len, const unsigned char channel);
//0 passive mode, 1 active mode, scan time(unit is second)
int rda5981_scan_v2(const char *SSID, const unsigned char SSID_len, const unsigned char channel, const unsigned char mode, \
const unsigned char scan_time);
int rda5981_get_scan_num();
int rda5981_get_scan_result(rda5981_scan_result *buf, const unsigned char len);
int rda5981_get_scan_result_index(rda5981_scan_result *buf, const unsigned char index);
int rda5981_get_scan_result_name(rda5981_scan_result *buf, const char *name);
int rda5981_get_scan_result_bssid(rda5981_scan_result *buf, const unsigned char *bssid);
int rda5981_check_scan_result_name(const char *name);
int rda5981_check_scan_result(const char *ssid, const char *bssid, const unsigned channel);
int rda5981_check_scan_result_name_bssid(const unsigned char *name, const unsigned char *bssid);
int rda5981_del_scan_all_result(void);
void rda5981_set_expired_time(unsigned int expired_time);
int rda5981_get_joined_AP(rda5981_scan_result *bss);
s8 rda5981_get_rssi();
void rda5981_set_main_queue(void* queue);
void rda5981_set_sta_listen_interval(unsigned char interval);
void rda5981_set_sta_link_loss_time(unsigned char time);
unsigned int rda5981_get_ap_join_info(rda5981_apsta_info *buf, const unsigned char len);
void rda5981_set_AP_white_list(unsigned char flag, unsigned char *mac);
int wland_set_joined_sta_ip(char *mac, unsigned int ip);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_read_mac_addr(unsigned char *mac_addr);
int rda5981_flash_write_mac_addr(unsigned char *mac_addr);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_erase_uart(void);
int rda5981_flash_read_uart(unsigned int *uart);
int rda5981_flash_write_uart(unsigned int *uart);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_read_ip_addr(unsigned char *ip_addr, unsigned char *server_addr);
int rda5981_flash_write_ip_addr(unsigned char *ip_add, unsigned char *server_addr);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_erase_dhcp_data(void);
int rda5981_flash_read_dhcp_data(unsigned int *enable, unsigned int *ip, unsigned int *msk, unsigned int *gw);
int rda5981_flash_write_dhcp_data(unsigned int enable, unsigned int ip, unsigned int msk, unsigned int gw);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_read_ap_data(char *ssid, char *passwd, unsigned char *channel);
int rda5981_flash_write_ap_data(const char *ssid, const char *passwd, unsigned char channel);
int rda5981_flash_erase_ap_data(void);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_read_ap_net_data(unsigned int *ip, unsigned int *msk, unsigned int *gw,
unsigned int *dhcps, unsigned int *dhcpe);
int rda5981_flash_write_ap_net_data(unsigned int ip, unsigned int msk, unsigned int gw,
unsigned int dhcps, unsigned int dhcpe);
int rda5981_flash_erase_ap_net_data(void);
/*
* return 0:ok, else:error.
*/
int rda5981_flash_read_sta_data(char *ssid, char *passwd);
int rda5981_flash_write_sta_data(const char *ssid, const char *passwd);
int rda5981_flash_erase_sta_data(void);
/*
* read 3rd parter data length from flash
* return user data length
*/
int rda5981_flash_read_3rdparter_data_length(void);
/*
* read 3rd parter data from flash
* @buf, buf to store user data
* @buf_len, length of buf
* return user data length
*/
int rda5981_flash_read_3rdparter_data(unsigned char *buf, unsigned int buf_len);
/*
* write 3rd parter data from flash
* @buf, data to write
* @buf_len, length of buf.
* return 0:ok, else:fail
*/
int rda5981_flash_write_3rdparter_data(const unsigned char *buf, unsigned int buf_len);
/*
* erase 3rd parter data from flash
* return 0:ok, else:fail
*/
int rda5981_flash_erase_3rdparter_data(void);
/*
* set flash size
* @size, 1MB:0x100000, 2MB:0x200000, 4MB:0x400000. default size: 1MB
* return 0:ok, else:fail
*/
int rda5981_set_flash_size(const unsigned int size);
/*
* set userdata location on flash
* @sys_data_addr, data to save system parameter, user can not operate this area directly.
* size:4KB. default location:0x180fb000
* @user_data_addr, data to save user data. user can save own data in this area
* by @rda5981_flash_read_3rdparter_data
* and @rda5981_flash_write_3rdparter_data
* default location:0x180fc000
* @user_data_len, user data length, default:4KB
* return 0:ok, else:fail
*/
int rda5981_set_user_data_addr(const unsigned int sys_data_addr,
const unsigned int user_data_addr, const unsigned int user_data_len);
/*
* function: erase flash
* @addr: mast be 4k alignment
* @len: must be 4k alignment. (package 64KB erase and 4KB erase for different condition automatically)
* return: 0:success, else:fail
*/
int rda5981_erase_flash(unsigned int addr, unsigned int len);
/*
* function: write flash
* @addr: mast be 256 alignment
* @buf: data to be written, best be 4 alignment
* @len: buffer len, mast be 4 alignment
* return: 0:success, else:fail
*/
int rda5981_write_flash(unsigned int addr, char *buf, unsigned int len);
/*
* function: read flash to @buf
* @addr: best be 4 alignment
* @buf: best be 4 alignment
* @len: buffer len
* return: 0:success, else:fail
*/
int rda5981_read_flash(unsigned int addr, char *buf, unsigned int len);
/*
* function: read user data
* @data: data to read
* @len: length of data in byte
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_read_user_data(unsigned char *data, unsigned short len, unsigned int flag);
/*
* function: write user data
* @data: data to write
* @len: length of data in byte
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_write_user_data(unsigned char *data, unsigned short len, unsigned int flag);
/*
* function: erase user data
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_erase_user_data(unsigned int flag);
/*
* function: update tx power from efuse data, for reg 11F and 120
* return: 0:success, else:fail
*/
int update_tx_power_from_efuse(void);
/*
* function: update xtal calibration from efuse data, for reg DA
* return: 0:success, else:fail
*/
int update_xtal_cal_from_efuse(void);
/*
* function: update mac addr from flash data
* return: 0:success, else:fail
*/
int update_mac_addr_from_efuse(void);
/*
* function: update tx power from flash data, Deprecated version
* return: 0:success, else:fail
*/
int update_tx_power_from_flash(void);
/*
* function: update tx power from flash data, for reg 8A
* return: 0:success, else:fail
*/
int update_tx_power_rf_from_flash(void);
/*
* function: update tx power from flash data, for reg 11F and 120
* return: 0:success, else:fail
*/
int update_tx_power_phy_from_flash(void);
/*
* function: update xtal calibration from flash data
* return: 0:success, else:fail
*/
int update_xtal_cal_from_flash(void);
/*
* function: update mac addr from flash data
* return: 0:success, else:fail
*/
int update_mac_addr_from_flash(void);
/*
* function: write rf reg
* @reg: rf reg data
* @value: rf reg value
* return: 0:success, else:fail
* eg: 0x00DA:xtal calibration
*/
int wland_rf_write(unsigned short reg, unsigned short value);
/*
* function: write rf reg
* @reg: rf reg data
* @value: rf reg value
* @len : value length
* return: 0:success, else:fail
* eg: 0x008A:tx power rf
*/
int wland_rf_write_all_channels(unsigned short reg, unsigned short *value, unsigned short len);
/*
* function: read rf reg
* @reg: rf reg data
* @value: rf reg value
* return: 0:success, else:fail
*/
int wland_rf_read(unsigned short reg, unsigned short *value);
/*
* function: read rf reg
* @reg: rf reg data
* @value: rf reg value
* return: 0:success, else:fail
* eg: 0x008A:tx power rf
*/
int wland_rf_read_all_channels(unsigned short reg, unsigned short *value);
/*
* function: write phy reg
* @reg: phy reg data
* @value: phy reg value
* return: 0:success, else:fail
*/
int wland_phy_write(unsigned int reg, unsigned int value);
/*
* function: write phy reg
* @reg: phy reg data
* @value: phy reg value
* @len : value length
* return: 0:success, else:fail
*/
int wland_phy_write_all_channels(unsigned int reg, unsigned int *value, unsigned short len);
/*
* function: read phy reg
* @reg: phy reg data
* @value: phy reg value
* return: 0:success, else:fail
*/
int wland_phy_read(unsigned int reg, unsigned int *value);
/*
* function: read phy reg
* @reg: phy reg data
* @value: phy reg value
* return: 0:success, else:fail
*/
int wland_phy_read_all_channels(unsigned int reg, unsigned int *value);
/* efuse API start */
/* Efuse CAN ONLY WRITE ONCE! DO NOT CALL THESE API IF YOU DO KNOW WHAT THEY MEANS!!! */
/*
* function: read all efuse
* @value: buffer to store efuse data, 28 bytes
* return: 0:success, else:fail
*/
int wland_read_efuse(unsigned char *value);
/*
* function: read tx power from efuse
* @tx_power: 2 bytes, first is mode g/n(range 0x25~0x54), second is mode b(range 0x15~0x54).
* return: 0:success, else:fail
*/
int wland_read_tx_power_from_efuse(unsigned char *tx_power);
/*
* function: read tx power from efuse
* @tx_power: 2 bytes, first is mode g/n(range 0x25~0x54), second is mode b(range 0x15~0x54)
* @len: must be 2
* return: 0:success, else:fail
*/
int wland_write_tx_power_to_efuse(unsigned char *tx_power, unsigned char len);
/*
* function: read xtal cal from efuse
* @xtal_cal: 1 byte, maximum 0x7F
* return: 0:success, else:fail
*/
int wland_read_xtal_cal_from_efuse(unsigned char *cal_val);
/*
* function: write xtal cal to efuse
* @xtal_cal: 1 byte, maximum 0x7F
* @len : must be 1
* return: 0:success, else:fail
*/
int wland_write_xtal_cal_to_efuse(unsigned char *xtal_cal, unsigned char len);
/*
* function: write mac to efuse
* @xtal_cal: 6 bytes
* return: 0:success, else:fail
*/
int wland_read_mac_addr_from_efuse(unsigned char *mac_addr);
/*
* function: write mac to efuse
* @xtal_cal: 6 bytes
* @len : must be 6
* return: 0:success, else:fail
*/
int wland_write_mac_addr_to_efuse(unsigned char*mac_addr, unsigned char len);
/* efuse API end */
/*
* function: start rf test
* @argc: number of argv
* @argv: args for test, 6 elements for tx test, 4 elements for rx test
* @is_tx: 1 for tx test, 0 for rx test
* return: 0:success, else:fail
*/
int wland_start_rf_test(unsigned int argc, unsigned int *argv, unsigned int is_tx);
/*
* function: stop rx test
* return: 0:success, else:fail
*/
int wland_stop_rx_test(void);
/*
* function: get rf test result
* @result buffer to store rx result
* return: 0:success, else:fail
*/
int wland_get_rx_result(char *result);
/*
* function: restart rx test, use last rx test args
* return: 0:success, else:fail
*/
int wland_restart_rx_test(void);
/*
* function: stop tx test
* return: 0:success, else:fail
*/
int wland_stop_tx_test(void);
/*
* function: restart tx test, use last tx test args
* return: 0:success, else:fail
*/
int wland_restart_tx_test(void);
#define RDA5981_FIRMWARE_INFO_ADDR 0x18003000
/*
* function: reboot to assigned addr (onece).
* reboot to rf test mode, not for OTA
* @firmware_info_addr: firmware info addr, depend on your flash layout
* @reboot_addr: reboot addr, 0x18001000-0x1840000
* return: 0:success, else:fail
*/
int rda5981_reboot_to_addr(unsigned int firmware_info_addr, unsigned int reboot_addr);
/*
* function: read reg and corresponding value related to test mode stored in flash
* @reg: reg to read
* @value: buffer to store value
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_read_user_data_regs(unsigned char *reg, unsigned char *value, unsigned int flag);
/*
* function: write reg and corresponding value related to test mode stored in flash
* @reg: reg to write
* @value: buffer that stores value
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_write_user_data_regs(unsigned char *reg, unsigned char *value, unsigned int flag);
/*
* function: erase reg and corresponding value related to test mode stored in flash
* @reg: reg to erase
* @flag: user data flag
* return: 0:success, else:fail
*/
int rda5981_erase_user_data_regs(unsigned char *reg, unsigned int flag);
/*
* function: get flash Manufacturer ID
* @mid:
* return: 0:success, else:fail
*/
int rda5981_flash_get_mid(unsigned char *mid);
/*
* function: get flash Device ID
* @did:
* return: 0:success, else:fail
*/
int rda5981_flash_get_did(unsigned char *did);
/*
* function: get flash ID
* @mid:
* return: 0:success, else:fail
*/
int rda5981_flash_get_jdid(unsigned short *jdid);
/*
* function: read mac reg
* @reg: mac reg data
* @value: mac reg value
* return: 0:success, else:fail
*/
int wland_mac_reg_read(unsigned short reg, unsigned int *value);
/*
* function: write mac reg
* @reg: mac reg data
* @value: mac reg value
* return: 0:success, else:fail
*/
int wland_mac_reg_write(unsigned short reg, unsigned int value);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,216 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if 1
#ifndef _RDA_SYS_WRAPPER_H_
#define _RDA_SYS_WRAPPER_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Alarm */
/**
* @brief : get current time in units of micro second
* @param[in] :
* @param[out]:
* @return : return time value with uint32 type
*/
extern unsigned long rda_get_cur_time_ms(void);
/**
* @brief : create an alarm with given function, return timer handle
* @param[in] : func(callback)/data(pass to func)/mode(once or periodic)
* @param[out]:
* @return : return timer handle, a pointer to the timer structure, non-zero is valid
*/
extern void * rda_alarm_create_v2(void *func, unsigned int data, unsigned int mode);
extern void * rda_alarm_create(void *func, unsigned int data);
/**
* @brief : delete an alarm with given handle, then reset the handle
* @param[in] : *handle(pointer to the timer structure)
* @param[out]: **handle(address of the handle variable)
* @return :
*/
extern int rda_alarm_delete(void **handle);
/**
* @brief : start an alarm, raise a function call after given timeout delay
* @param[in] : handle(pointer to the timer structure)/timeout(micro second)
* @param[out]:
* @return :
*/
extern int rda_alarm_start(void *handle, unsigned int timeout_ms);
/**
* @brief : stop an alarm, will not raise a function call any more
* @param[in] : handle(pointer to the timer structure)
* @param[out]:
* @return :
*/
extern int rda_alarm_stop(void *handle);
/* Semaphore */
/**
* @brief : create a semaphore
* @param[in] : name and initial valve of semaphore
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern void* rda_sem_create(unsigned int count);
/**
* @brief : wait a semaphore
* @param[in] : name of semaphore
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_sem_wait(void *sem, unsigned int millisec);
/**
* @brief : release a semaphore
* @param[in] : name of semaphore
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_sem_release(void *sem);
/**
* @brief : delete a semaphore
* @param[in] : name of semaphore
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_sem_delete(void *sem);
/* Queue */
/**
* @brief : create a message queue
* @param[in] : size of message queue
* @param[out]:
* @return : return message queue id or NULL if error
*/
extern void* rda_msgQ_create(unsigned int queuesz);
/**
* @brief : put a message to queue
* @param[in] : message queue id, message value and wait time
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_msg_put(void *msgQId, unsigned int msg, unsigned int millisec);
/**
* @brief : get a message from queue
* @param[in] : message queue id, message value and wait time
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_msg_get(void *msgQId, unsigned int *value, unsigned int millisec);
/* Mail */
/**
* @brief : create a mail
* @param[in] : mail count/size
* @param[out]:
* @return : return mail handle
*/
void* rda_mail_create(unsigned int msgcnt, unsigned int msgsize);
/**
* @brief : get a msg from mail
* @param[in] : handler name of mail/mail/wait time
* @param[out]:
* @return : return ERR or NO_ERR
*/
int rda_mail_get(void *rdahandle, void *evt, unsigned int wait);
/**
* @brief : put a msg to mail
* @param[in] : handler of mail/mail/wait time
* @param[out]:
* @return : return ERR or NO_ERR
*/
int rda_mail_put(void *rdahandle, void *evt, unsigned int wait);
/* Mutex */
/**
* @brief : create a mutex
* @param[in] :
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern void* rda_mutex_create(void);
/**
* @brief : wait a mutex
* @param[in] : id of mutex and wait time
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_mutex_wait(void *rdamutex, unsigned int millisec);
/**
* @brief : release a mutex
* @param[in] : id of mutex
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_mutex_realease(void *rdamutex);
/**
* @brief : delete a mutex
* @param[in] : id of mutex
* @param[out]:
* @return : return ERR or NO_ERR
*/
extern int rda_mutex_delete(void *rdamutex);
/* Thread */
/**
* @brief : creat a thread
* @param[in] : thread name/thread function/thread fuction argument/stacksize/thread priority
* @param[out]:
* @return : return thread id
*/
void* rda_thread_new(const char *pcName, void (*thread)(void *arg), void *arg, int stacksize, int priority);
/**
* @brief : delete a thread
* @param[in] : thread id
* @param[out]:
* @return : return ERR or NO_ERR
*/
int rda_thread_delete(void* id);
/**
* @brief : get current thread id
* @param[in] :
* @param[out]:
* @return : return thread id
*/
void* rda_thread_get_id(void);
#ifdef __cplusplus
}
#endif
#endif /* _RDA_SYS_WRAPPER_H_ */
#endif

View File

@ -0,0 +1,60 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WLAND_DBG_H_
#define _WLAND_DBG_H_
#include <stdio.h>
#include "rda5991h_wland.h"
#include "wland_types.h"
extern int wland_dbg_dump;
extern int wland_dbg_level;
#define RDA_WLAND_DBG
#ifdef RDA_WLAND_DBG
#define WLAND_DBG(level, fmt, ...) do {\
int dbg_level = D_##level##_LEVEL;\
if((dbg_level <= wland_dbg_level)){\
printf("%s,"fmt, __func__, ##__VA_ARGS__);\
} \
} while (0)
//if frmae_len is zero, get len from frame header
static inline void wland_dump_frame(const char* msg, u8 *data, u32 frame_len)
{
u32 len,i;
if(wland_dbg_dump == 1) {
if(frame_len != 0) {
len = frame_len;
} else {
len = data[0] | ((data[1]&0x0f) << 8);
}
printf("%s : ",msg);
for(i=0; i<len; i++)
printf("%02x ", *(data+i));
printf("\r\nframe_len=%d\r\n", len);
}
return;
}
#else
#define WLAND_DBG(level, fmt, ...)
static inline void wland_dump_frame(const char* msg, u8 *data, u32 frame_len)
{}
#endif
#endif /*_WLAND_DBG_H_*/

View File

@ -0,0 +1,311 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WLAND_FLASH_H_
#define _WLAND_FLASH_H_
#include "wland_types.h"
#include "rda5981_flash.h"
#include "rda_ccfg_api.h"
//#define FLASH_READ_CHECK
#ifndef min
#define min(a, b) ((a)<(b)?(a):(b))
#endif /*min*/
/** This struct contains all smartconfig mbed flash parameter. */
typedef struct
{
char ssid[36];
char key[64];
} wland_sta_data_t;
/** This struct contains ap data, include ssid key and channel. */
typedef struct
{
u8 channel;
char ssid[35];
char key[64];
} wland_ap_data_t;
/** This struct contains ap net data. */
typedef struct
{
u32 ip;
u32 msk;
u32 gw;
u32 dhcps;
u32 dhcpe;
} wland_ap_net_data_t;
typedef struct
{
u32 fixip;
u32 ip;
u32 msk;
u32 gw;
} wland_dhcp_t;
#define RDA5991H_USER_DATA_FLAG_UNINITIALIZED (0xFFFFFFFF & \
(~(RDA5991H_USER_DATA_FLAG_MAC | \
RDA5991H_USER_DATA_FLAG_STA | \
RDA5991H_USER_DATA_FLAG_PMK | \
RDA5991H_USER_DATA_FLAG_IP | \
RDA5991H_USER_DATA_FLAG_PARTER_DATA_LEN | \
RDA5991H_USER_DATA_FLAG_TX_POWER | \
RDA5991H_USER_DATA_FLAG_XTAL_CAL | \
RDA5991H_USER_DATA_FLAG_TX_POWER_RF | \
RDA5991H_USER_DATA_FLAG_TX_POWER_PHY_GN | \
RDA5991H_USER_DATA_FLAG_TX_POWER_PHY_B | \
RDA5991H_USER_DATA_FLAG_AP | \
RDA5991H_USER_DATA_FLAG_APNET | \
RDA5991H_USER_DATA_FLAG_DHCP | \
RDA5991H_USER_DATA_FLAG_UART | \
RDA5991H_USER_DATA_FLAG_RF | \
RDA5991H_USER_DATA_FLAG_RF_CHANNELS | \
RDA5991H_USER_DATA_FLAG_PHY | \
RDA5991H_USER_DATA_FLAG_PHY_CHANNELS | \
RDA5991H_USER_DATA_FLAG_TX_POWER_OFFSET)))
#define RDA5991H_USER_DATA_IP_LENGTH 8
#define RDA5981_FLAG_FLAG "RDA5981"
typedef struct
{
u32 flag;
u8 rda5981_flag[8];
u8 mac_addr[6];
u8 tp_offset;
u8 padding1;//alignment
wland_sta_data_t sta_data;
u8 pmk[32];
u8 ip[RDA5991H_USER_DATA_IP_LENGTH];
u32 parter_data_len;
wland_tx_power_t tx_power;
u16 xtal_cal;
u8 padding2[2];//alignment
u16 tx_power_rf[14];
u8 tx_power_phy_gn;
u8 tx_power_phy_b;
u8 padding3[2];
wland_ap_data_t ap_data;
wland_ap_net_data_t ap_net_data;
wland_dhcp_t dhcp;
u32 uart;
wland_rf_t rf;
wland_rf_channels_t rf_channels;
wland_phy_t phy;
wland_phy_channels_t phy_channels;
}rda5991h_user_data;
#define SECTOR_SIZE 4096
#define FLASH_SIZE 0x100000
#define RDA5991H_PARTITION_TABLE_END_ADDR 0x18001000 //partition table end addr
#define RDA5991H_USER_DATA_ADDR 0x180fb000 //4k(partition table)+500k+500k:
#define RDA5991H_3RDPARTER_DATA_ADDR 0x180fc000
#define RDA5991H_3RDPARTER_DATA_LEN 0x1000
#define FLASH_CTL_REG_BASE 0x17fff000
#define FLASH_CTL_TX_CMD_ADDR_REG (FLASH_CTL_REG_BASE + 0x00)
#define CMD_64KB_BLOCK_ERASE (0x000000d8UL)
#define WRITE_REG32(REG, VAL) ((*(volatile unsigned int*)(REG)) = (unsigned int)(VAL))
#define FLASH_ERASE_FUN_ADDR 0x21f1//smartlink_erase_for_mbed
#define FLASH_WRITE_FUN_ADDR 0x2241//smartlink_write_for_mbed
#define FLASH_READ_FUN_ADDR 0x2243//smartlink_read_for_mbed
#define FLASH_ERASE_PARTITION_FUN_ADDR 0x2139//spi_flash_erase_partition
#define SPI_FLASH_READ_DATA_FOR_MBED_ADDR 0x2007//spi_flash_read_data_for_mbed
#define spi_flash_disable_cache_addr 0x1eb7//spi_flash_disable_cache
#define spi_flash_flush_cache_addr 0x1ecd//spi_flash_flush_cache
#define spi_flash_cfg_cache_addr 0x1e9f//spi_flash_cfg_cache
#define spi_flash_erase_4KB_sector_addr 0x23a3
#define spi_wip_reset_addr 0x1d8b
#define spi_write_reset_addr 0x1d9f
#define wait_busy_down_addr 0x1d81
#define FLASH_ERASE_FUN_ADDR_4 0x2221//smartlink_erase_for_mbed
#define FLASH_WRITE_FUN_ADDR_4 0x2271//smartlink_write_for_mbed
#define FLASH_READ_FUN_ADDR_4 0x2273//smartlink_read_for_mbed
#define FLASH_ERASE_PARTITION_FUN_ADDR_4 0x2169//spi_flash_erase_partition
#define SPI_FLASH_READ_DATA_FOR_MBED_ADDR_4 0x2037//spi_flash_read_data_for_mbed
#define spi_flash_disable_cache_addr_4 0x1ee7//spi_flash_disable_cache
#define spi_flash_flush_cache_addr_4 0x1efd//spi_flash_flush_cache
#define spi_flash_cfg_cache_addr_4 0x1ecf//spi_flash_cfg_cache
#define spi_flash_erase_4KB_sector_addr_4 0x23d3
#define spi_wip_reset_addr_4 0x1dbb
#define spi_write_reset_addr_4 0x1dcf
#define wait_busy_down_addr_4 0x1db1
/*
* return 0 if find
*/
int rda5981_flash_read_pmk(u8 *pmk);
int rda5981_flash_read_sta_data(char *ssid, char *passwd);
void rda5981_spi_erase_partition(void *src, u32 counts);
//@len must be 4k aligment
//int rda5981_write_flash(u32 addr, char *buf, u32 len);
//int rda5981_read_flash(u32 addr, char *buf, u32 len);
#define VERSION_SZ 24
struct firmware_info
{
u32 magic;
u8 version[VERSION_SZ];
u32 addr;
u32 size;
u32 crc32;
u32 bootaddr;//add for rf_test
u32 bootmagic;
};
#define RDA5981_FIRMWARE_MAGIC 0xEAEA
static inline void wait_busy_down_2(void)
{
((void(*)(void))wait_busy_down_addr)();
}
static inline void spi_write_reset_2(void)
{
((void(*)(void))spi_write_reset_addr)();
}
static inline void spi_wip_reset_2(void)
{
((void(*)(void))spi_wip_reset_addr)();
}
static inline void wait_busy_down_4(void)
{
((void(*)(void))wait_busy_down_addr_4)();
}
static inline void spi_write_reset_4(void)
{
((void(*)(void))spi_write_reset_addr_4)();
}
static inline void spi_wip_reset_4(void)
{
((void(*)(void))spi_wip_reset_addr_4)();
}
static void wait_busy_down(void)
{
if (rda_ccfg_hwver() >= 4) {
wait_busy_down_4();
} else {
wait_busy_down_2();
}
}
static void spi_write_reset(void)
{
if (rda_ccfg_hwver() >= 4) {
spi_write_reset_4();
} else {
spi_write_reset_2();
}
}
static void spi_wip_reset(void)
{
if (rda_ccfg_hwver() >= 4) {
spi_wip_reset_4();
} else {
spi_wip_reset_2();
}
}
static inline void spi_flash_enable_cache(void)
{
unsigned int func = spi_flash_cfg_cache_addr;
if (rda_ccfg_hwver() >= 4) {
func = spi_flash_cfg_cache_addr_4;
}
((void(*)(void))func)();
}
static inline void spi_flash_disable_cache(void)
{
unsigned int func = spi_flash_disable_cache_addr;
if (rda_ccfg_hwver() >= 4) {
func = spi_flash_disable_cache_addr_4;
}
((void(*)(void))func)();
}
static inline void spi_flash_flush_cache(void)
{
unsigned int func = spi_flash_flush_cache_addr;
if (rda_ccfg_hwver() >= 4) {
func = spi_flash_flush_cache_addr_4;
}
((void(*)(void))func)();
}
static inline void rda5981_spi_flash_erase_4KB_sector(u32 addr)
{
unsigned int func = spi_flash_erase_4KB_sector_addr;
if (rda_ccfg_hwver() >= 4) {
func = spi_flash_erase_4KB_sector_addr_4;
}
((void(*)(u32))func)(addr);
}
static inline void RDA5991H_ERASE_FLASH(void *addr, u32 len)
{
unsigned int func = FLASH_ERASE_FUN_ADDR;
if (rda_ccfg_hwver() >= 4) {
func = FLASH_ERASE_FUN_ADDR_4;
}
((void(*)(void *, u32))func)(addr, len);
}
static inline void RDA5991H_WRITE_FLASH(u32 addr, u8 *data, u32 len)
{
unsigned int func = FLASH_WRITE_FUN_ADDR;
if (rda_ccfg_hwver() >= 4) {
func = FLASH_WRITE_FUN_ADDR_4;
}
((void(*)(u32, u8 *, u32))func)(addr, data, len);
}
static inline void RDA5991H_READ_FLASH(u32 addr, u8 *buf, u32 len)
{
unsigned int func = FLASH_READ_FUN_ADDR;
if (rda_ccfg_hwver() >= 4) {
func = FLASH_READ_FUN_ADDR_4;
}
((void(*)(u32, u8 *, u32))func)(addr, buf, len);
}
static inline void SPI_FLASH_READ_DATA_FOR_MBED(void *addr, void *buf, u32 len)
{
unsigned int func = SPI_FLASH_READ_DATA_FOR_MBED_ADDR;
if (rda_ccfg_hwver() >= 4) {
func = SPI_FLASH_READ_DATA_FOR_MBED_ADDR_4;
}
((void(*)(void *, void *, u32))func)(buf, addr, len);
}
#endif /*_WLAND_FLASH_H_*/

View File

@ -0,0 +1,32 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WLAND_FLASH_WP_H_
#define _WLAND_FLASH_WP_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void flash_wrtie_protect_all();
extern void flash_wrtie_protect_none();
extern void flash_wrtie_protect(unsigned int offset);
extern void rda5981_flash_init();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,39 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WLAND_OTA_H_
#define _WLAND_OTA_H_
#include "wland_types.h"
#include "rda_ccfg_api.h"
extern u32 flash_size;
#define CRC32_TABLE_ADDR 0xbb5c
#define CRC32_ADDR 0x8dff//u32 crc32(const u8 *p, size_t len)
#define CRC32_TABLE_ADDR_4 0xbbd8
#define CRC32_ADDR_4 0x8e33//u32 crc32(const u8 *p, size_t len)
static inline unsigned int bootrom_crc32(unsigned char *p, unsigned int len)
{
unsigned int func = CRC32_ADDR;
if (rda_ccfg_hwver() >= 4) {
func = CRC32_ADDR_4;
}
return ((unsigned int(*)(unsigned char *, unsigned int))func)(p, len);
}
#endif /*_WLAND_OTA_H_*/

View File

@ -0,0 +1,41 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WLAND_RF_H_
#define _WLAND_RF_H_
#include "wland_types.h"
#define WLAND_TXP_NUM 2
#define WLAND_CHANNEL_NUM 14
#define WLAND_TX_POWER_PHY_GN_REG 0x11F
#define WLAND_TX_POWER_PHY_B_REG 0x120
#define WLAND_TX_POWER_RF_REG 0x8A
#define WLAND_XTAL_CAL_REG 0xDA
#define MAKE_WORD16(lsb, msb) (((u16)(msb) << 8) & 0xFF00) | (lsb)
#define MAKE_WORD32(lsw, msw) (((u32)(msw) << 16) & 0xFFFF0000) | (lsw)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,86 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*****************************************************************************/
/* */
/* File Name : wland_types.h */
/* */
/* Description : This file contains all the data type definitions for */
/* MAC implementation. */
/* */
/*****************************************************************************/
#ifndef WLAND_TYPES_H
#define WLAND_TYPES_H
/*****************************************************************************/
/* Constants Definitions */
/*****************************************************************************/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned int size_t;
/** Indicates Bit Value of BITx */
#ifndef BIT
#define BIT(x) (1ul << (x))
/*****************************************************************************/
/* Constant Definitions */
/*****************************************************************************/
#define BIT0 (1ul << 0)
#define BIT1 (1ul << 1)
#define BIT2 (1ul << 2)
#define BIT3 (1ul << 3)
#define BIT4 (1ul << 4)
#define BIT5 (1ul << 5)
#define BIT6 (1ul << 6)
#define BIT7 (1ul << 7)
#define BIT8 (1ul << 8)
#define BIT9 (1ul << 9)
#define BIT10 (1ul << 10)
#define BIT11 (1ul << 11)
#define BIT12 (1ul << 12)
#define BIT13 (1ul << 13)
#define BIT14 (1ul << 14)
#define BIT15 (1ul << 15)
#define BIT16 (1ul << 16)
#define BIT17 (1ul << 17)
#define BIT18 (1ul << 18)
#define BIT19 (1ul << 19)
#define BIT20 (1ul << 20)
#define BIT21 (1ul << 21)
#define BIT22 (1ul << 22)
#define BIT23 (1ul << 23)
#define BIT24 (1ul << 24)
#define BIT25 (1ul << 25)
#define BIT26 (1ul << 26)
#define BIT27 (1ul << 27)
#define BIT28 (1ul << 28)
#define BIT29 (1ul << 29)
#define BIT30 (1ul << 30)
#define BIT31 (1ul << 31)
#endif
#endif /* WLAND_TYPES_H */

View File

@ -0,0 +1,49 @@
Permissive Binary License
Version 1.0, January 2019
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
1) Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
2) Unless to the extent explicitly permitted by law, no reverse
engineering, decompilation, or disassembly of this software is
permitted.
3) Redistribution as part of a software development kit must include the
accompanying file named “DEPENDENCIES” and any dependencies listed in
that file.
4) Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
Limited patent license. The copyright holders (and contributors) grant a
worldwide, non-exclusive, no-charge, royalty-free patent license to
make, have made, use, offer to sell, sell, import, and otherwise
transfer this software, where such license applies only to those patent
claims licensable by the copyright holders (and contributors) that are
necessarily infringed by this software. This patent license shall not
apply to any combinations that include this software. No hardware is
licensed hereunder.
If you institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the software
itself infringes your patent(s), then your rights granted under this
license shall terminate as of the date such litigation is filed.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,7 @@
This directory tree contains binaries build from RDA SDK modified for Mbed OS and released under Permissive Binary License.
libhal files in the subfolders are generated with toolchains:
Arm Compiler 5 - version 5.06u6
GNU Arm Embedded - version 6.3.1
IAR EWARM - version 8.32.2.178

View File

@ -0,0 +1,275 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file : maclib_task.c
* @brief : WiFi MACLib task source file
* @version: V1.0
* @date : 6. May 2017
*
* @note
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbed_interface.h"
#include "cmsis_os.h"
#include "csl_mbed.h"
#include "maclib_task.h"
#include "rda5991h_wland.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
/**
* Macros
*/
#define MACLIB_TASK_DEBUG (0)
/**
* Variables
*/
static int maclib_task_run = 0;
static sys_mbox_t maclib_mbox;
static int g_event_num = 0;
static int g_event_proc_done = 1;
static sys_sem_t g_maclib_sem_sleep;
static int g_maclib_sleep_flag = 0;
extern maclib_func_t *maclib_func_p;
extern void rda_critical_sec_start(void);
extern void rda_critical_sec_end(void);
extern void wland_set_sta_sleep(unsigned char is_sleep);
#define MAX_MSG_POOL_NUM (64)
maclib_msg_t msg_str_pool[MAX_MSG_POOL_NUM];
int msg_str_pool_inited = 0;
void init_msg_str_pool(void)
{
int idx;
for(idx = 0; idx < MAX_MSG_POOL_NUM; idx++) {
msg_str_pool[idx].is_free = 1;
}
}
maclib_msg_t *alloc_msg_str(void)
{
int idx;
maclib_msg_t *ret = NULL;
rda_critical_sec_start();
if (0 == msg_str_pool_inited) {
init_msg_str_pool();
msg_str_pool_inited = 1;
}
rda_critical_sec_end();
for (idx = 0; idx < MAX_MSG_POOL_NUM; idx++) {
rda_critical_sec_start();
ret = &msg_str_pool[idx];
if (1 == ret->is_free) {
ret->is_free = 0;
rda_critical_sec_end();
break;
}
rda_critical_sec_end();
}
return ret;
}
void free_msg_str(maclib_msg_t *p_msg)
{
rda_critical_sec_start();
p_msg->is_free = 1;
rda_critical_sec_end();
}
/**
* Functions
*/
/* maybe called in isr, should not use "printf", "malloc" */
void mbed_event_handle_cb(unsigned int event)
{
MACLIB_EVENT_HANDLE_T type = (MACLIB_EVENT_HANDLE_T)event;
if ((maclib_task_run == 0) && (MACLIB_EVENT_CLEANUP != type)) {
mbed_error_printf("evntHndlCb_nulldata\r\n");
return;
}
switch(type) {
case MACLIB_EVENT_PEND:
rda_critical_sec_start();
g_event_num++;
if((1 == g_event_num) && (1 == g_event_proc_done)) {
maclib_msg_t *msg;
#if MACLIB_TASK_DEBUG
mbed_error_printf("#1-1,%d(%08X)\r\n", g_event_num, __get_xPSR());
#endif
msg = alloc_msg_str();
if(NULL == msg) {
mbed_error_printf("malloc err\r\n");
return;
}
msg->type = MACLIB_MSG_EVNT_HNDL;
msg->msg = NULL;
sys_mbox_trypost(&(maclib_mbox), msg);
#if MACLIB_TASK_DEBUG
mbed_error_printf("#1-2\r\n");
#endif
}
rda_critical_sec_end();
break;
case MACLIB_EVENT_PROCESS:
#if 1
rda_critical_sec_start();
g_event_num--;
if(0 > g_event_num) {
mbed_error_printf("event handle err\r\n");
g_event_num = 0;
}
rda_critical_sec_end();
#if MACLIB_TASK_DEBUG
mbed_error_printf("#3,%d\r\n",g_event_num);
#endif
#endif
break;
case MACLIB_EVENT_CLEANUP:
#if MACLIB_TASK_DEBUG
mbed_error_printf("event cleanup\r\n");
#endif
rda_critical_sec_start();
g_event_num = 0;
rda_critical_sec_end();
break;
default:
break;
}
}
void mbed_mltask_sleep_cb(void)
{
g_maclib_sleep_flag = 1;
sys_arch_sem_wait(&g_maclib_sem_sleep, 0);
}
void mbed_mltask_wakeup_cb(void)
{
rda_critical_sec_start();
if (1 == g_maclib_sleep_flag) {
g_maclib_sleep_flag = 0;
sys_sem_signal(&g_maclib_sem_sleep);
}
rda_critical_sec_end();
}
void maclib_check_status(void)
{
rda_critical_sec_start();
if (1 == g_maclib_sleep_flag) {
if(*((unsigned int *)0x40020580U) & (0x01UL << 2)) {
mbed_mltask_wakeup_cb();
}
}
rda_critical_sec_end();
}
int maclib_is_sleep_allowed(void)
{
return g_maclib_sleep_flag;
}
void maclib_task(void *pvParameters)
{
int ret;
#if 0
sleep_entry_t maclib_sleep_entry = {
wland_set_sta_sleep,
maclib_is_sleep_allowed,
maclib_check_status
};
#endif
sys_sem_new(&g_maclib_sem_sleep, 0);
//sleep_entry_register(&maclib_sleep_entry);
ret = sys_mbox_new(&(maclib_mbox), 8);
if(0 != ret) {
LWIP_DEBUGF(NETIF_DEBUG,"msgbox init err!\r\n");
goto mac_lib_err;
}
#if MACLIB_TASK_DEBUG
LWIP_DEBUGF(NETIF_DEBUG,"#mbox new\r\n");
#endif
maclib_task_run = 1;
while(1) {
int mem_free = 1;
maclib_msg_t *msg = NULL;
unsigned int time = sys_arch_mbox_fetch(&(maclib_mbox), (void **)&msg, 0);
if ((SYS_ARCH_TIMEOUT == time) || (NULL == msg)) {
LWIP_DEBUGF(NETIF_DEBUG, "ml_task: invalid msg\r\n");
continue;
}
switch(msg->type) {
case MACLIB_MSG_EVNT_HNDL: {
rda_critical_sec_start();
g_event_proc_done = 0;
rda_critical_sec_end();
#if MACLIB_TASK_DEBUG
mbed_error_printf("#get event %d\r\n", g_event_num);
#endif
maclib_func_p->ml_tasklet();
#if MACLIB_TASK_DEBUG
mbed_error_printf("#5\r\n");
#endif
rda_critical_sec_start();
#if 0
g_event_num--;
if(0 > g_event_num) {
mbed_error_printf("event handle err\r\n");
} else
#endif
g_event_proc_done = 1;
if(0 < g_event_num) {
#if MACLIB_TASK_DEBUG
mbed_error_printf("#2-1\r\n");
#endif
sys_mbox_trypost(&(maclib_mbox), msg);
#if MACLIB_TASK_DEBUG
mbed_error_printf("#2-2\r\n");
#endif
mem_free = 0;
}
rda_critical_sec_end();
#if MACLIB_TASK_DEBUG
mbed_error_printf("#pDone\r\n");
#endif
break;
}
default:
break;
}
if (mem_free) {
free_msg_str(msg);
#if MACLIB_TASK_DEBUG
mbed_error_printf("#4\r\n");
#endif
}
}
mac_lib_err:
LWIP_DEBUGF(NETIF_DEBUG,"MACLib exit!\r\n");
osDelay(osWaitForever);
}

View File

@ -0,0 +1,509 @@
/* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file rda5991h_wland.c
* @brief RDA5991H wlan driver for LWIP
* @version: V1.0
* @date: 25. July 2016
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/tcpip.h"
#include "netif/etharp.h"
#include "sys_arch.h"
#include "rda5991h_wland.h"
#include "cmsis.h"
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
#include "entropy_poll.h"
#else
#include "trng_api.h"
#endif
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "maclib_task.h"
#include "rda_sys_wrapper.h"
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Global variables */
rda_enetdata_t r91h_wifidata;
int wland_dbg_dump = WLAND_DBG_DUMP;
int wland_dbg_level = WLAND_DBG_LEVEL;
int wpa_dbg_dump = WPA_DBG_DUMP;
int wpa_dbg_level = WPA_DBG_LEBEL;
int wlandlib_dbg_level = WLANDLIB_DBG_LEVEL;
int hut_dbg_dump = HUT_DBG_DUMP;
//#define CONFIG_DISABLE_ALL_INT
#define CRI_SEC_START_PRI_LEVEL 0xF8
#define CRI_SEC_END_PRI_LEVEL 0x00
static unsigned int g_critical_sec_counter = 0U;
#if defined(CONFIG_DISABLE_ALL_INT)
static unsigned int g_critical_ctxt_saved = 0U;
#endif /* CONFIG_DISABLE_ALL_INT */
void *packet_rx_queue;
/* Function statements */
void r91h_wifiif_input(struct netif *netif, u8_t *data, u32_t len, int idx);
void mbed_mac_address(char *mac);
/** \brief Driver transmit and receive thread priorities
*
* Thread priorities for receive thread and TX cleanup thread. Alter
* to prioritize receive or transmit bandwidth. In a heavily loaded
* system or with LEIP_DEBUG enabled, the priorities might be better
* the same. */
#define RX_PRIORITY (osPriorityNormal)
#define TX_PRIORITY (osPriorityNormal)
#define PHY_PRIORITY (osPriorityNormal)
void rda_netif_down(int netif)
{
if (netif == 0) {
netif_set_down(r91h_wifidata.netif_sta);
} else {
netif_set_down(r91h_wifidata.netif_ap);
}
}
void rda_netif_link_down(int netif)
{
rda_msg msg;
msg.type = 1;
msg.arg1 = 0;
rda_mail_put(packet_rx_queue, (void*)&msg, osWaitForever);
}
void rda_netif_up(int netif)
{
if (netif == 0) {
netif_set_up(r91h_wifidata.netif_sta);
} else {
netif_set_up(r91h_wifidata.netif_ap);
}
}
void rda_netif_link_up(int netif)
{
rda_msg msg;
msg.type = 1;
msg.arg1 = 1;
rda_mail_put(packet_rx_queue, (void*)&msg, osWaitForever);
return;
}
void rda_netif_input(u8_t *data, u32_t len, int idx, int netif)
{
if (netif == 0) {
r91h_wifiif_input(r91h_wifidata.netif_sta, data, len, idx++);
} else {
r91h_wifiif_input(r91h_wifidata.netif_ap, data, len, idx++);
}
}
void rda_get_macaddr(u8_t *macaddr, int mode)
{
mbed_mac_address((char *)macaddr);
if (mode == 1) {
if(macaddr[0] & 0x04) {
macaddr[0] &= 0xFB;
} else {
macaddr[0] |= 0x04;
}
}
return;
}
void rda_critical_sec_start(void)
{
if (__get_IPSR() == 0U) {
if (0U == g_critical_sec_counter) {
#if defined(CONFIG_DISABLE_ALL_INT)
g_critical_ctxt_saved = __disable_irq();
#else /* CONFIG_DISABLE_ALL_INT */
__set_BASEPRI(CRI_SEC_START_PRI_LEVEL);
#endif /* CONFIG_DISABLE_ALL_INT */
}
g_critical_sec_counter++;
}
}
void rda_critical_sec_end(void)
{
if (__get_IPSR() == 0U) {
g_critical_sec_counter--;
if (0U == g_critical_sec_counter) {
#if defined(CONFIG_DISABLE_ALL_INT)
__set_PRIMASK(g_critical_ctxt_saved);
#else /* CONFIG_DISABLE_ALL_INT */
__set_BASEPRI(CRI_SEC_END_PRI_LEVEL);
#endif /* CONFIG_DISABLE_ALL_INT */
}
}
}
void * rda_create_interrupt(unsigned int vec, unsigned int pri, void *isr)
{
NVIC_SetPriority((IRQn_Type)vec, (uint32_t) pri);
NVIC_SetVector((IRQn_Type)vec, (uint32_t) isr);
return NULL;
}
void rda_delete_interrupt(unsigned int vec)
{
NVIC_SetVector((IRQn_Type)vec, 0);
}
void rda_enable_interrupt(unsigned int vec)
{
NVIC_EnableIRQ((IRQn_Type)vec);
}
void rda_disable_interrupt(unsigned int vec)
{
NVIC_DisableIRQ((IRQn_Type)vec);
}
/** \brief Allocates a pbuf and returns the data from the incoming packet.
*
* \param[in] netif the lwip network interface structure
* \param[in] idx index of packet to be read
* \return a pbuf filled with the received packet (including MAC header)
*/
static struct pbuf *r91h_low_level_input(struct netif *netif, u8_t *data, u32_t len, int idx)
{
struct pbuf *p, *q;
u16_t index = 0;
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input enter, rxlen:%d\n", len));
/* Obtain the size of the packet and put it into the "len"
variable. */
if(!len) {
return NULL;
}
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != NULL) {
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for (q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* pbuf is the sum of the chained pbuf len members.
*/
/* load rx data from 96 to local mem_pool */
MEMCPY(q->payload, &data[index], q->len);
index += q->len;
if (index >= len) {
break;
}
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
} else {
/* Drop this packet */
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input pbuf_alloc fail, rxlen:%d\n", len));
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
return NULL;
}
return p;
}
/** \brief Attempt to read a packet from the EMAC interface.
*
* \param[in] netif the lwip network interface structure
* \param[in] idx index of packet to be read
*/
void *data_sem = NULL;
void r91h_wifiif_input(struct netif *netif, u8_t *data, u32_t len, int idx)
{
if(data_sem == NULL)
data_sem = rda_sem_create(0);
rda_msg msg;
msg.type = 0;
msg.arg1 = (int)data;
msg.arg2 = len;
msg.arg3 = (int)data_sem;
rda_mail_put(packet_rx_queue, (void*)&msg, osWaitForever);
rda_sem_wait(data_sem, osWaitForever);
return;
}
/** \brief Low level init of the MAC and PHY.
*
* \param[in] netif Pointer to LWIP netif structure
*/
static err_t low_level_init(struct netif *netif)
{
static int init_flag = 0;
if (init_flag == 0) {
wland_reg_func();
init_flag = 1;
}
return ERR_OK;
}
/**
* This function is the ethernet packet send function. It calls
* etharp_output after checking link status.
*
* \param[in] netif the lwip network interface structure for this enetif
* \param[in] q Pointer to pbug to send
* \param[in] ipaddr IP address
* \return ERR_OK or error code
*/
err_t rda91h_etharp_output(struct netif *netif, struct pbuf *q, const ip_addr_t *ipaddr)
{
/* Only send packet is link is up */
if (netif->flags & NETIF_FLAG_LINK_UP)
return etharp_output(netif, q, ipaddr);
return ERR_CONN;
}
/** \brief Low level output of a packet. Never call this from an
* interrupt context, as it may block until TX descriptors
* become available.
*
* \param[in] netif the lwip network interface structure for this netif
* \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
*/
static err_t rda91h_low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
/* rda5996 initiate transfer */
u32_t actual_txlen = 0;
u8_t **data;
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output enter, p:%08x\n", p));
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
data = (void*)wland_get_databuf();
if(data == NULL){
LWIP_DEBUGF(NETIF_DEBUG, ("rda91h_low_level_output, no PKT buf\r\n"));
return ERR_BUF;
}
for(q = p; q != NULL; q = q->next)
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
MEMCPY(&((*data)[actual_txlen+2]), q->payload, q->len);//reserve wid header length
actual_txlen += q->len;
if(actual_txlen > 1514 || actual_txlen > p->tot_len)
{
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output err, actual_txlen:%d, tot_len%d\n",
actual_txlen, p->tot_len));
return ERR_BUF;
}
}
/* Signal rda5996 that packet should be sent */
if(actual_txlen == p->tot_len)
{
if(netif->name[0] == 's' && netif->name[1] == 't') {
wland_txip_data((void*)data, actual_txlen, 0);
} else if(netif->name[0] == 'a' && netif->name[1] == 'p') {
wland_txip_data((void*)data, actual_txlen, 1);
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output pkt len mismatch, actual_txlen:%d, tot_len%d\n",
actual_txlen, p->tot_len));
return ERR_BUF;
}
/**
* Should be called at the beginning of the program to set up the
* network interface.
*
* This function should be passed as a parameter to netif_add().
*
* @param[in] netif the lwip network interface structure for this netif
* @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 wifi_arch_enetif_init(struct netif *netif)
{
err_t err;
static int thread_init_flag = 0;
LWIP_ASSERT("netif != NULL", (netif != NULL));
if (*((int *)netif->state) == 0) {
r91h_wifidata.netif_sta = netif;
netif->name[0] = 's';
netif->name[1] = 't';
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
if(netif->hostname == NULL)
netif->hostname = "lwipr91h_sta";
#endif /* LWIP_NETIF_HOSTNAME */
rda_get_macaddr((u8_t *)(netif->hwaddr), 0);
} else if(*((int *)netif->state) == 1) {
r91h_wifidata.netif_ap = netif;
netif->name[0] = 'a';
netif->name[1] = 'p';
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
if(netif->hostname == NULL)
netif->hostname = "lwipr91h_ap";
#endif /* LWIP_NETIF_HOSTNAME */
rda_get_macaddr((u8_t *)(netif->hwaddr), 1);
}
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
// TODOETH: check if the flags are correct below
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
/* Initialize the hardware */
netif->state = &r91h_wifidata;
err = low_level_init(netif);
if (err != ERR_OK)
return err;
netif->output = rda91h_etharp_output;
netif->linkoutput = rda91h_low_level_output;
if(thread_init_flag == 0){
/* PHY monitoring task */
sys_thread_new("maclib_thread", maclib_task, netif->state, DEFAULT_THREAD_STACKSIZE*8, PHY_PRIORITY);
sys_thread_new("wland_thread", wland_task, NULL, DEFAULT_THREAD_STACKSIZE*5, PHY_PRIORITY);
/* Allow the PHY task to detect the initial link state and set up the proper flags */
osDelay(10);
thread_init_flag = 1;
}
return ERR_OK;
}
unsigned char rda_mac_addr[6] = "\0";
static int is_available_mac_addr(unsigned char *mac_addr)
{
if (mac_addr[0]==0 && mac_addr[1]==0 && mac_addr[2]==0 &&
mac_addr[3]==0 && mac_addr[4]==0 && mac_addr[5]==0)
return 0;
if (mac_addr[0]&0x1)
return 0;
return 1;
}
static void rda_get_macaddr_from_flash(unsigned char *macaddr)
{
int ret;
if (!mac_is_valid((char *)rda_mac_addr)) {
ret = rda5981_flash_read_mac_addr(rda_mac_addr);
if ((ret!=0) || (is_available_mac_addr(rda_mac_addr)==0)) {
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
unsigned int out_len;
ret = mbedtls_hardware_poll(NULL, rda_mac_addr, 6, &out_len);
if (6 != out_len) {
LWIP_DEBUGF(NETIF_DEBUG, ("out_len err:%d\n", out_len));
}
#else
ret = rda_trng_get_bytes(rda_mac_addr, 6);
#endif
rda_mac_addr[0] &= 0xfe; /* clear multicast bit */
rda_mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
rda5981_flash_write_mac_addr(rda_mac_addr);
}
}
memcpy(macaddr, rda_mac_addr, 6);
}
void mbed_mac_address(char *mac)
{
mac[0] = 0xD6;
mac[1] = 0x71;
mac[2] = 0x36;
mac[3] = 0x60;
mac[4] = 0xD8;
#if !MBED_CONF_APP_ECHO_SERVER
mac[5] = 0xF4;
#else
mac[5] = 0xF3;
#endif
return;
}

View File

@ -0,0 +1,450 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if 1
#include "sys_arch.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "lwip/sys.h"
#include "rtx_lib.h"
#include <stdio.h>
#include <string.h>
#include "mbed_assert.h"
#define NO_ERR 0
#define ERR -1
//#define RDA_SYS_DEBUG
#ifdef RDA_SYS_DEBUG
#define RDA_SYS_PRINT(fmt, ...) do {\
printf(fmt, ##__VA_ARGS__);\
} while (0)
#else
#define RDA_SYS_PRINT(fmt, ...)
#endif
/* Alarm */
// Timer definitions
#define osTimerInvalid 0
#define osTimerStopped 1
#define osTimerRunning 2
#if 0
// Timer structures, same as os_timer_cb(rt_CMSIS.c)
typedef struct rda_ostmr_cb {
struct rda_ostmr_cb *next; // Pointer to next active Timer
uint8_t state; // Timer State
uint8_t type; // Timer Type (Periodic/One-shot)
uint16_t reserved; // Reserved
uint32_t tcnt; // Timer Delay Count
uint32_t icnt; // Timer Initial Count
void *arg; // Timer Function Argument
const osTimerDef_t *timer; // Pointer to Timer definition
} rda_ostmr_cb_t;
#endif
//#define USING_STDLIB
#if !defined(USING_STDLIB)
typedef struct rda_tmr_node {
mbed_rtos_storage_timer_t _obj_mem;
} rda_tmr_node_t;
typedef struct rda_tmr_ctrl {
unsigned char *buff;
unsigned char *state;
unsigned char max_node_num;
unsigned char node_size;
unsigned char node_cntr;
unsigned char last_freed_node_idx;
} rda_tmr_ctrl_t;
#define MAX_ALARM_NUM (28)
#define WORD_ALIGN(n) (((n) + 0x03UL) & ~0x03UL)
#define MAX_ALARM_STAT_SIZE WORD_ALIGN(MAX_ALARM_NUM >> 3)
#define MAX_ALARM_MEM_SIZE (MAX_ALARM_NUM * WORD_ALIGN(sizeof(mbed_rtos_storage_timer_t)) + MAX_ALARM_STAT_SIZE)
unsigned long g_alarm_buf[WORD_ALIGN(MAX_ALARM_MEM_SIZE) >> 2] = {0};
rda_tmr_ctrl_t g_alarm_ctrl = {
(unsigned char *)g_alarm_buf + MAX_ALARM_STAT_SIZE,
(unsigned char *)g_alarm_buf,
MAX_ALARM_NUM,
WORD_ALIGN(sizeof(mbed_rtos_storage_timer_t)),
0U,
0U
};
__STATIC_INLINE unsigned char get_node_state(unsigned char *buf, unsigned char idx)
{
unsigned char state, ofst;
ofst = (idx & 0x07U);
buf += (idx >> 3);
state = (*buf >> ofst) & 0x01U;
return state;
}
__STATIC_INLINE void set_node_state(unsigned char *buf, unsigned char idx, unsigned char state)
{
unsigned char ofst, tmp;
ofst = (idx & 0x07U);
buf += (idx >> 3);
tmp = *buf & (~(0x01U << ofst));
*buf = tmp | (((state & 0x01U) << ofst));
}
static rda_tmr_node_t *get_tmr_node(void)
{
rda_tmr_node_t *node = NULL;
unsigned char idx = g_alarm_ctrl.last_freed_node_idx;
if ((idx < g_alarm_ctrl.max_node_num) && (0U == get_node_state(g_alarm_ctrl.state, idx))) {
set_node_state(g_alarm_ctrl.state, idx, 1U);
node = (rda_tmr_node_t *)(g_alarm_ctrl.buff + idx * g_alarm_ctrl.node_size);
g_alarm_ctrl.node_cntr++;
} else {
for (idx = 0U; idx < g_alarm_ctrl.max_node_num; idx++) {
if(0U == get_node_state(g_alarm_ctrl.state, idx)) {
set_node_state(g_alarm_ctrl.state, idx, 1U);
node = (rda_tmr_node_t *)(g_alarm_ctrl.buff + idx * g_alarm_ctrl.node_size);
g_alarm_ctrl.node_cntr++;
break;
}
}
}
return node;
}
static void put_tmr_node(rda_tmr_node_t *node)
{
unsigned char *node_buf = (unsigned char *)node;
unsigned char idx = (node_buf - g_alarm_ctrl.buff) / g_alarm_ctrl.node_size;
if ((node_buf > g_alarm_ctrl.buff) && (idx < g_alarm_ctrl.max_node_num) &&
(1U == get_node_state(g_alarm_ctrl.state, idx))) {
set_node_state(g_alarm_ctrl.state, idx, 0U);
g_alarm_ctrl.node_cntr--;
g_alarm_ctrl.last_freed_node_idx = idx;
}
}
#endif /* !USING_STDLIB */
/**
* @brief : get current time in units of micro second
* @param[in] :
* @param[out]:
* @return : return time value with uint32 type
*/
unsigned long rda_get_cur_time_ms(void)
{
return sys_now();
}
/**
* @brief : create an alarm with given function, return timer handle
* @param[in] : func(callback)/data(pass to func)/mode(once or periodic)
* @param[out]:
* @return : return timer handle, a pointer to the timer structure, non-zero is valid
*/
void * rda_alarm_create_v2(void *func, unsigned int data, unsigned int mode)
{
osTimerId_t handle;
mbed_rtos_storage_timer_t* _obj_mem = NULL;
MBED_ASSERT(func != NULL);
osTimerAttr_t attr = { 0 };
#if defined(USING_STDLIB)
_obj_mem = (mbed_rtos_storage_timer_t*)malloc(sizeof(mbed_rtos_storage_timer_t));
#else /* USING_STDLIB */
_obj_mem = (mbed_rtos_storage_timer_t*)get_tmr_node();
#endif /* USING_STDLIB */
MBED_ASSERT(_obj_mem != NULL);
memset(_obj_mem, 0, sizeof(_obj_mem));
attr.cb_mem = _obj_mem;
attr.cb_size = sizeof(mbed_rtos_storage_timer_t);
//printf("hehehehe fun %p\r\n", func);
handle = osTimerNew((osTimerFunc_t)func, mode, (void *)data, &attr);
//printf("time cb %p handle %p\r\n", _obj_mem, handle);
MBED_ASSERT(handle != NULL);
return handle;
}
void * rda_alarm_create(void *func, unsigned int data)
{
return rda_alarm_create_v2(func, data, osTimerOnce);
}
/**
* @brief : delete an alarm with given handle, then reset the handle
* @param[in] : *handle(pointer to the timer structure)
* @param[out]: **handle(address of the handle variable)
* @return :
*/
int rda_alarm_delete(void **handle)
{
if (NULL != *handle) {
osTimerId timer_id = (osTimerId)(*handle);
osStatus retval = osTimerDelete(timer_id);
if (osOK == retval) {
#if defined(USING_STDLIB)
free(timer_id);
#else /* USING_STDLIB */
put_tmr_node((rda_tmr_node_t *)timer_id);
#endif /* USING_STDLIB */
*handle = NULL;
} else {
RDA_SYS_PRINT("Delete alarm error: %d\r\n", retval);
return ERR;
}
return NO_ERR;
}
return ERR;
}
/**
* @brief : start an alarm, raise a function call after given timeout delay
* @param[in] : handle(pointer to the timer structure)/timeout(micro second)
* @param[out]:
* @return :
*/
int rda_alarm_start(void *handle, unsigned int timeout_ms)
{
if (NULL != handle) {
osTimerId timer_id = (osTimerId)handle;
osStatus retval = osTimerStart(timer_id, (uint32_t)timeout_ms);
if (osOK != retval) {
RDA_SYS_PRINT("Start alarm error: %d\r\n", retval);
return ERR;
}
return NO_ERR;
}
return ERR;
}
/**
* @brief : stop an alarm, will not raise a function call any more
* @param[in] : handle(pointer to the timer structure)
* @param[out]:
* @return :
*/
int rda_alarm_stop(void *handle)
{
if (NULL != handle) {
osTimerId timer_id = (osTimerId)handle;
osStatus retval = osTimerStop(timer_id);
if (osOK != retval) {
RDA_SYS_PRINT("Stop alarm error: %d\r\n", retval);
return ERR;
}
return NO_ERR;
}
return ERR;
}
/* Semaphore */
void* rda_sem_create(unsigned int count)
{
osSemaphoreId_t sem;
mbed_rtos_storage_semaphore_t *_obj_mem = (mbed_rtos_storage_semaphore_t*)malloc(sizeof(mbed_rtos_storage_semaphore_t));
osSemaphoreAttr_t attr = { 0 };
attr.name = "rda_unnamed_sem";
attr.cb_mem = _obj_mem;
attr.cb_size = sizeof(mbed_rtos_storage_semaphore_t);
sem = osSemaphoreNew(1, count, &attr);
MBED_ASSERT(sem != NULL);
return (void*)sem;
}
int rda_sem_wait(void* sem, unsigned int millisec)
{
int res;
res = osSemaphoreWait(sem, millisec);
if (res > 0) {
return NO_ERR;
} else {
RDA_SYS_PRINT("rda_sem_wait error %d\r\n", res);
return ERR;
}
}
int rda_sem_release(void *sem)
{
int res;
res = osSemaphoreRelease(sem);
if (res == 0) {
return NO_ERR;
} else {
RDA_SYS_PRINT("rda_sem_release error %d\r\n", res);
return ERR;
}
}
int rda_sem_delete(void *sem)
{
int res;
res = osSemaphoreDelete(sem);
free(sem);
if (res == 0) {
return NO_ERR;
} else {
RDA_SYS_PRINT("rda_sem_delete error %d\r\n", res);
return ERR;
}
}
/* Mail */
void* rda_mail_create(unsigned int msgcnt, unsigned int msgsize)
{
unsigned int mq_size = msgcnt * (msgsize + sizeof(os_message_t));
osMessageQueueId_t msgq;
mbed_rtos_storage_msg_queue_t *_obj_mem = (mbed_rtos_storage_msg_queue_t*)malloc(sizeof(mbed_rtos_storage_msg_queue_t));
MBED_ASSERT(_obj_mem != NULL);
memset(_obj_mem, 0, sizeof(mbed_rtos_storage_msg_queue_t));
void *_mq_mem = (void *)malloc(mq_size);
MBED_ASSERT(_mq_mem != NULL);
memset(_mq_mem, 0, mq_size);
osMessageQueueAttr_t attr = { 0 };
attr.name = "rda_unnamed_message_queue";
attr.cb_mem = _obj_mem;
attr.cb_size = sizeof(mbed_rtos_storage_msg_queue_t);
attr.mq_mem = _mq_mem;
attr.mq_size = mq_size;
msgq = osMessageQueueNew(msgcnt, msgsize, &attr);
MBED_ASSERT(msgq != NULL);
return (void*)msgq;
}
int rda_mail_get(void *msgq, void *msg, unsigned int wait)
{
int ret;
ret = osMessageQueueGet(msgq, msg, 0, wait);
return ret;
}
int rda_mail_put(void *msgq, void *msg, unsigned int wait)
{
int ret;
ret = osMessageQueuePut(msgq, msg, 0, wait);
return ret;
}
/* Mutex */
void* rda_mutex_create(void)
{
osMutexId_t rdamutex;
osMutexAttr_t attr = { 0 };
mbed_rtos_storage_mutex_t *_obj_mem = (mbed_rtos_storage_mutex_t *)malloc(sizeof(mbed_rtos_storage_mutex_t));
memset(_obj_mem, 0, sizeof(mbed_rtos_storage_mutex_t));
attr.name = "rda_unnamed_mutex";
attr.cb_mem = _obj_mem;
attr.cb_size = sizeof(mbed_rtos_storage_mutex_t);
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
rdamutex = osMutexNew(&attr);
MBED_ASSERT(rdamutex != NULL);
return (void *)rdamutex;
}
int rda_mutex_wait(void *rdamutex, unsigned int millisec)
{
osMutexId_t mutex = (osMutexId_t)rdamutex;
osStatus res;
res = osMutexWait(mutex, millisec);
if (res == osOK) {
return NO_ERR;
} else {
return ERR;
}
}
int rda_mutex_realease(void *rdamutex)
{
osMutexId_t mutex = (osMutexId_t)rdamutex;
osStatus res;
res = osMutexRelease(mutex);
if(res == osOK) {
return NO_ERR;
} else {
return ERR;
}
}
int rda_mutex_delete(void *rdamutex)
{
osMutexId_t mutex = (osMutexId_t)rdamutex;
osStatus res;
res = osMutexDelete(mutex);
free(mutex);
if (res == osOK) {
return NO_ERR;
} else {
return ERR;
}
}
/* Thread */
void* rda_thread_new(const char *pcName,
void (*thread)(void *arg),
void *arg, int stacksize, int priority)
{
osThreadId_t id;
osThreadAttr_t _attr = { 0 };
mbed_rtos_storage_thread_t *_obj_mem = (mbed_rtos_storage_thread_t *)malloc(sizeof(mbed_rtos_storage_thread_t));
MBED_ASSERT(_obj_mem != NULL);
memset(_obj_mem, 0, sizeof(mbed_rtos_storage_thread_t));
_attr.priority = priority;
_attr.stack_size = stacksize;
_attr.name = pcName ? pcName : "rda_unnamed_thread";
_attr.stack_mem = malloc(stacksize);
MBED_ASSERT(_attr.stack_mem != NULL);
_attr.cb_size = sizeof(mbed_rtos_storage_thread_t);
_attr.cb_mem = _obj_mem;
_attr.tz_module = 0;
//Fill the stack with a magic word for maximum usage checking
for (uint32_t i = 0; i < (_attr.stack_size / sizeof(uint32_t)); i++) {
((uint32_t *)_attr.stack_mem)[i] = 0xE25A2EA5;
}
id = osThreadNew(thread, arg, &_attr);
if (id == NULL){
free(_attr.stack_mem);
free(_attr.cb_mem);
RDA_SYS_PRINT("sys_thread_new create error\n");
return NULL;
}
return (void *)id;
}
int rda_thread_delete(void* id)
{
osStatus ret;
unsigned int *stk = ((osRtxThread_t *)id)->stack_mem;
ret = osThreadTerminate(id);
free(id);
free(stk);
if (ret != osOK) {
return ERR;
}
return NO_ERR;
}
void* rda_thread_get_id(void)
{
osThreadId id = osThreadGetId();
return (void*)id;
}
#endif

View File

@ -0,0 +1,366 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_interface.h"
#include "wland_flash.h"
//#define FLASH_PROTECT_ENABLE
#define FLASH_CTL_REG_BASE 0x17fff000
#define FLASH_CTL_TX_CMD_ADDR_REG (FLASH_CTL_REG_BASE + 0x00)
#define FLASH_CTL_TX_BLOCK_SIZE_REG (FLASH_CTL_REG_BASE + 0x04)
#define FLAHS_CTL_TX_FIFO_DATA_REG (FLASH_CTL_REG_BASE + 0x08)
#define FLASH_CTL_STATUS_REG (FLASH_CTL_REG_BASE + 0x0c)
#define FLAHS_CTL_RX_FIFO_DATA_REG (FLASH_CTL_REG_BASE + 0x10)
#define WRITE_REG32(REG, VAL) ((*(volatile unsigned int*)(REG)) = (unsigned int)(VAL))
#define WRITE_REG8(REG, VAL) ((*(volatile unsigned char*)(REG)) = (unsigned char)(VAL))
#define MREAD_WORD(addr) *((volatile unsigned int *)(addr))
#define MID_GD 0xC8
#define MID_WINBOND 0xEF
#define FLASH_1M 0x100000
#define FLASH_2M 0x200000
#define FLASH_4M 0x400000
extern unsigned int flash_size;
#ifdef FLASH_PROTECT_ENABLE
#define FLASH_WP_MASK 0x407c
#define FLASH_WP_NONE 0x0000
#define FLASH_WP_ALL 0x1c
#define FLASH_4M_WP_4K 0x0064
#define FLASH_4M_WP_8K 0x0068
#define FLASH_4M_WP_16K 0x006c
#define FLASH_4M_WP_32K 0x0070
#define FLASH_4M_WP_1_64 0x0024
#define FLASH_4M_WP_1_32 0x0028
#define FLASH_4M_WP_1_16 0x002c
#define FLASH_4M_WP_1_8 0x0030
#define FLASH_4M_WP_1_4 0x0034
#define FLASH_4M_WP_1_2 0x0038
#define FLASH_4M_WP_3_4 0x4014
#define FLASH_4M_WP_7_8 0x4010
#define FLASH_4M_WP_15_16 0x400c
#define FLASH_4M_WP_31_32 0x4008
#define FLASH_4M_WP_63_64 0x4004
#define FLASH_4M_WP_127_128 0x4058
#define FLASH_4M_WP_255_256 0x404C
#define FLASH_4M_WP_1023_1024 0x4044
#define FLASH_2M_WP_4K 0x0064
#define FLASH_2M_WP_8K 0x0068
#define FLASH_2M_WP_16K 0x006c
#define FLASH_2M_WP_32K 0x0070
#define FLASH_2M_WP_1_32 0x0024
#define FLASH_2M_WP_1_16 0x0028
#define FLASH_2M_WP_1_8 0x002c
#define FLASH_2M_WP_1_4 0x0050
#define FLASH_2M_WP_1_2 0x0051
#define FLASH_2M_WP_3_4 0x4010
#define FLASH_2M_WP_7_8 0x400c
#define FLASH_2M_WP_15_16 0x4004
#define FLASH_2M_WP_31_32 0x4000
#define FLASH_2M_WP_63_64 0x4050
#define FLASH_2M_WP_127_128 0x404c
#define FLASH_2M_WP_255_256 0x4048
#define FLASH_2M_WP_511_512 0x4044
#define FLASH_1M_WP_4K 0x0064
#define FLASH_1M_WP_8K 0x0068
#define FLASH_1M_WP_16K 0x006c
#define FLASH_1M_WP_32K 0x0070
#define FLASH_1M_WP_1_16 0x0024
#define FLASH_1M_WP_1_8 0x0028
#define FLASH_1M_WP_1_4 0x002c
#define FLASH_1M_WP_1_2 0x0050
#define FLASH_1M_WP_3_4 0x400C
#define FLASH_1M_WP_7_8 0x4008
#define FLASH_1M_WP_15_16 0x4004
#define FLASH_1M_WP_31_32 0x4050
#define FLASH_1M_WP_63_64 0x404C
#define FLASH_1M_WP_127_128 0x4048
#define FLASH_1M_WP_255_256 0x4044
static unsigned short flash_wrtie_protect_4M(unsigned short status, unsigned int offset)
{
unsigned int wp = FLASH_WP_NONE;
if (offset >= flash_size - flash_size/1024) {
wp = FLASH_4M_WP_1023_1024;
} else if(offset >= flash_size - flash_size/256) {
wp = FLASH_4M_WP_255_256;
} else if(offset >= flash_size - flash_size/128) {
wp = FLASH_4M_WP_127_128;
} else if(offset >= flash_size - flash_size/64) {
wp = FLASH_4M_WP_63_64;
} else if(offset >= flash_size - flash_size/32) {
wp = FLASH_4M_WP_31_32;
} else if(offset >= flash_size - flash_size/16) {
wp = FLASH_4M_WP_15_16;
} else if(offset >= flash_size - flash_size/8) {
wp = FLASH_4M_WP_7_8;
} else if(offset >= flash_size - flash_size/4) {
wp = FLASH_4M_WP_3_4;
} else if(offset >= flash_size/2) {
wp = FLASH_4M_WP_1_2;
} else if(offset >= flash_size/4) {
wp = FLASH_4M_WP_1_4;
} else if(offset >= flash_size/8) {
wp = FLASH_4M_WP_1_8;
} else if(offset >= flash_size/16) {
wp = FLASH_4M_WP_1_16;
} else if(offset >= flash_size/32) {
wp = FLASH_4M_WP_1_32;
} else if(offset >= flash_size/64) {
wp = FLASH_4M_WP_1_64;
} else if(offset >= 32 * 1024) {
wp = FLASH_4M_WP_32K;
} else if(offset >= 16 * 1024) {
wp = FLASH_4M_WP_16K;
} else if(offset >= 8 * 1024) {
wp = FLASH_4M_WP_8K;
} else if(offset >= 4 * 1024) {
wp = FLASH_4M_WP_4K;
}
return (status & ~FLASH_WP_MASK) | wp;
}
static unsigned short flash_wrtie_protect_2M(unsigned short status, unsigned int offset)
{
unsigned int wp = FLASH_WP_NONE;
if (offset >= flash_size - flash_size/256) {
wp = FLASH_2M_WP_255_256;
} else if(offset >= flash_size - flash_size/128) {
wp = FLASH_2M_WP_127_128;
} else if(offset >= flash_size - flash_size/64) {
wp = FLASH_2M_WP_63_64;
} else if(offset >= flash_size - flash_size/32) {
wp = FLASH_2M_WP_31_32;
} else if(offset >= flash_size - flash_size/16) {
wp = FLASH_2M_WP_15_16;
} else if(offset >= flash_size - flash_size/8) {
wp = FLASH_2M_WP_7_8;
} else if(offset >= flash_size - flash_size/4) {
wp = FLASH_2M_WP_3_4;
} else if(offset >= flash_size/2) {
wp = FLASH_2M_WP_1_2;
} else if(offset >= flash_size/4) {
wp = FLASH_2M_WP_1_4;
} else if(offset >= flash_size/8) {
wp = FLASH_2M_WP_1_8;
} else if(offset >= flash_size/16) {
wp = FLASH_2M_WP_1_16;
} else if(offset >= flash_size/32) {
wp = FLASH_2M_WP_1_32;
} else if(offset >= 32 * 1024) {
wp = FLASH_2M_WP_32K;
} else if(offset >= 16 * 1024) {
wp = FLASH_2M_WP_16K;
} else if(offset >= 8 * 1024) {
wp = FLASH_2M_WP_8K;
} else if(offset >= 4 * 1024) {
wp = FLASH_2M_WP_4K;
}
return (status & ~FLASH_WP_MASK) | wp;
}
static unsigned short flash_wrtie_protect_1M(unsigned short status, unsigned int offset)
{
unsigned int wp = FLASH_WP_NONE;
if (offset >= flash_size - flash_size/256) {
wp = FLASH_1M_WP_255_256;
} else if(offset >= flash_size - flash_size/128) {
wp = FLASH_1M_WP_127_128;
} else if(offset >= flash_size - flash_size/64) {
wp = FLASH_1M_WP_63_64;
} else if(offset >= flash_size - flash_size/32) {
wp = FLASH_1M_WP_31_32;
} else if(offset >= flash_size - flash_size/16) {
wp = FLASH_1M_WP_15_16;
} else if(offset >= flash_size - flash_size/8) {
wp = FLASH_1M_WP_7_8;
} else if(offset >= flash_size - flash_size/4) {
wp = FLASH_1M_WP_3_4;
} else if(offset >= flash_size/2) {
wp = FLASH_1M_WP_1_2;
} else if(offset >= flash_size/4) {
wp = FLASH_1M_WP_1_4;
} else if(offset >= flash_size/8) {
wp = FLASH_1M_WP_1_8;
} else if(offset >= flash_size/16) {
wp = FLASH_1M_WP_1_16;
} else if(offset >= 32 * 1024) {
wp = FLASH_1M_WP_32K;
} else if(offset >= 16 * 1024) {
wp = FLASH_1M_WP_16K;
} else if(offset >= 8 * 1024) {
wp = FLASH_1M_WP_8K;
} else if(offset >= 4 * 1024) {
wp = FLASH_1M_WP_4K;
}
return (status & ~FLASH_WP_MASK) | wp;
}
void flash_wrtie_protect_all()
{
unsigned short status;
unsigned char r1, r2;
core_util_critical_section_enter();
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x05);
wait_busy_down();
r1 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x35);
wait_busy_down();
r2 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
//mbed_error_printf("status %x %x\r\n", r2, r1);
status = (r2 << 8) | r1;
status = (status & ~FLASH_WP_MASK) | FLASH_WP_ALL;
//mbed_error_printf("status %04x\r\n", status);
spi_write_reset();
wait_busy_down();
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, (status&0xff));
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, ((status>>8)&0xff));
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x01);
wait_busy_down();
spi_wip_reset();
core_util_critical_section_exit();
return;
}
void flash_wrtie_protect_none()
{
unsigned short status;
unsigned char r1, r2;
core_util_critical_section_enter();
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x05);
wait_busy_down();
r1 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x35);
wait_busy_down();
r2 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
//mbed_error_printf("status %x %x\r\n", r2, r1);
status = (r2 << 8) | r1;
status = status & ~FLASH_WP_MASK;
//mbed_error_printf("status %04x\r\n", status);
spi_write_reset();
wait_busy_down();
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, (status&0xff));
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, ((status>>8)&0xff));
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x01);
wait_busy_down();
spi_wip_reset();
core_util_critical_section_exit();
return;
}
void flash_wrtie_protect(unsigned int offset)
{
unsigned short status;
unsigned char r1, r2;
core_util_critical_section_enter();
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x05);
wait_busy_down();
r1 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x35);
wait_busy_down();
r2 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
//mbed_error_printf("status %x %x\r\n", r2, r1);
status = (r2 << 8) | r1;
if (flash_size == FLASH_4M) {
status = flash_wrtie_protect_4M(status, offset);
} else if(flash_size == FLASH_2M) {
status = flash_wrtie_protect_2M(status, offset);
} else if(flash_size == FLASH_1M) {
status = flash_wrtie_protect_1M(status, offset);
} else [
LWIP_DEBUGF(NETIF_DEBUG,"flash_size is error\r\n");
}
//mbed_error_printf("status %04x\r\n", status);
spi_write_reset();
wait_busy_down();
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, (status&0xff));
WRITE_REG8(FLAHS_CTL_TX_FIFO_DATA_REG, ((status>>8)&0xff));
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x01);
wait_busy_down();
spi_wip_reset();
core_util_critical_section_exit();
return;
}
#else
void flash_wrtie_protect_all()
{
return;
}
void flash_wrtie_protect_none()
{
return;
}
void flash_wrtie_protect(unsigned int offset)
{
return;
}
#endif
void rda5981_flash_init()
{
unsigned int status3, status4, status5;
core_util_critical_section_enter();
WRITE_REG32(FLASH_CTL_TX_BLOCK_SIZE_REG, 3<<8);
status3 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
status4 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
status5 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
wait_busy_down();
spi_wip_reset();
WRITE_REG32(FLASH_CTL_TX_CMD_ADDR_REG, 0x9F);
wait_busy_down();
//WRITE_REG32(FLASH_CTL_TX_BLOCK_SIZE_REG, 3<<8);
//wait_busy_down();
status3 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
status4 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
status5 = MREAD_WORD(FLAHS_CTL_RX_FIFO_DATA_REG);
core_util_critical_section_exit();
if ((status5&0xff != 0x14) && (status5&0xff != 0x15) && (status5&0xff != 0x16)) {
mbed_error_printf("flash size error\r\n");
return;
}
flash_size = (1 << (status5&0xff));
flash_wrtie_protect_all();
return;
}

View File

@ -0,0 +1,145 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wland_ota.h"
#include "wland_flash.h"
#include "rda5981_ota.h"
#include "wland_dbg.h"
#include "wland_types.h"
#include "critical.h"
#include <stdbool.h>
#include <string.h>
#define IMAGE_MAGIC 0xAEAE
u32 wland_ota_partition_addr = 0;
u32 wland_ota_partition_len = 0;
u32 wland_crc_result = ~0UL;
static u32 crc32(const u8 *p, u32 len, u32 crc)
{
const u32 *crc32_tab = (const u32 *)CRC32_TABLE_ADDR;
if (rda_ccfg_hwver() >= 4) {
crc32_tab = (const u32 *)CRC32_TABLE_ADDR_4;
}
/* Calculate CRC */
while(len--) {
crc = crc32_tab[((crc & 0xFF) ^ *p++)] ^ (crc >> 8);
}
return crc;
}
static int rda5981_ota_erase_flash(u32 addr, u32 len)
{
addr &= (flash_size -1);
rda5981_spi_erase_partition((void *)addr, len);
return 0;
}
//write without erase
static int rda5981_ota_write_flash(u32 addr, char *buf, u32 len)
{
int ret = 0;
u8 *temp_buf = NULL, *temp_buf_aligned;
addr &= (flash_size -1);
if ((u32)buf % 4) {
temp_buf = malloc(len + 3);
if (temp_buf == NULL) {
goto out;
}
if ((u32)temp_buf % 4) {
temp_buf_aligned = temp_buf + (4-(u32)temp_buf%4);
} else {
temp_buf_aligned = temp_buf;
}
memcpy(temp_buf_aligned, (unsigned char *)buf, len);
} else {
temp_buf_aligned = (u8 *)buf;
}
core_util_critical_section_enter();
RDA5991H_WRITE_FLASH(addr, temp_buf_aligned, len);
core_util_critical_section_exit();
out:
if (temp_buf) {
free(temp_buf);
}
return ret;
}
int rda5981_write_partition_start(u32 addr, u32 img_len)
{
if (addr < 0x18001000 || addr+img_len>0x18000000+flash_size) {
WLAND_DBG(ERROR,"write partition start addr error. (0x%08x, %u)\r\n", addr, img_len);
return -1;
}
if (addr%0x1000 || img_len%0x1000) {
WLAND_DBG(ERROR,"write partition start length error.(mast be 4k alignment) (0x%08x, %u)\r\n", addr, img_len);
return -1;
}
WLAND_DBG(INFO, "rda5981_write_partition_start:0x%08x, %u\r\n", addr, img_len);
wland_ota_partition_addr = addr;
wland_ota_partition_len = img_len;
wland_crc_result = ~0U;
rda5981_ota_erase_flash(addr, img_len);
return 0;
}
int rda5981_write_partition(u32 offset, const u8 *buf, u32 len)
{
if (wland_ota_partition_addr==0 || offset+len>wland_ota_partition_len) {
WLAND_DBG(ERROR,"write partition error. out of start addr(0x%08x, %u). (0x%08x, %u)\r\n",
wland_ota_partition_addr, wland_ota_partition_len, offset, len);
return -1;
}
if (len%0x400) {
WLAND_DBG(ERROR,"write partition length error.(mast be 1k alignment) (0x%08x, %u)\r\n", offset, len);
return -1;
}
WLAND_DBG(DEBUG, "rda5981_write_partition:0x%08x, %u.(%02x)\r\n",
wland_ota_partition_addr + offset, len, buf[0]);
wland_crc_result = crc32(buf, len, wland_crc_result);
WLAND_DBG(DEBUG, "rda5981_write_partition: wland_crc_result 0x%08x\r\n",
wland_crc_result);
return rda5981_ota_write_flash(wland_ota_partition_addr + offset, (char *)buf, len);
//return rda5981_write_flash(wland_ota_partition_addr + offset, buf, len);
}
int rda5981_write_partition_end(void)
{
WLAND_DBG(INFO, "check crc32:0x%08x, %u\r\n", wland_ota_partition_addr, wland_ota_partition_len);
if (wland_ota_partition_addr == 0) {
WLAND_DBG(ERROR,"OTA is not started\r\n");
return -1;
}
core_util_critical_section_enter();
spi_flash_flush_cache();
//u32 crc32_check = crc32(wland_ota_partition_addr, wland_ota_partition_len, ~0U);
u32 crc32_check = bootrom_crc32((unsigned char *)wland_ota_partition_addr, wland_ota_partition_len);
core_util_critical_section_exit();
WLAND_DBG(INFO, "rda5981_write_partition_end:0x%08x:0x%08x\r\n", wland_crc_result, crc32_check);
wland_ota_partition_addr = 0UL;
if (crc32_check == wland_crc_result) {
return 0;
} else {
WLAND_DBG(ERROR,"check crc32 error\r\n");
return -1;
}
}

View File

@ -0,0 +1,293 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "cmsis_os.h"
#include "mbed_interface.h"
#include "mbed_assert.h"
#include "mbed_shared_queues.h"
#include "netsocket/nsapi_types.h"
#include "lwip/arch.h"
#include "lwip/pbuf.h"
#include "rda5991h_wland.h"
#include "rda5981x_emac_config.h"
#include "rda5981x_emac.h"
#include "rda_sys_wrapper.h"
#include "maclib_task.h"
#define RDA_HWADDR_SIZE (6)
#define RDA_ETH_MTU_SIZE 1500
#define RDA_ETH_IF_NAME "st"
#define RX_PRIORITY (osPriorityNormal)
#define TX_PRIORITY (osPriorityNormal)
#define PHY_PRIORITY (osPriorityNormal)
extern void *packet_rx_queue;
RDA5981x_EMAC::RDA5981x_EMAC()
{
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the memory buffer chain that is passed to the function.
*
* @param buf the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return true if the packet could be sent
* false 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).
*/
bool RDA5981x_EMAC::link_out(emac_mem_buf_t *buf)
{
emac_mem_buf_t *q, *p = buf;
u32_t actual_txlen = 0;
u8_t **data = NULL;
u16_t retry = 400;
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output enter, p:%08x\n", p));
while ((data == NULL) && (retry-- > 0)) {
data = (u8_t**)wland_get_databuf();
osThreadYield();
}
if (data == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("rda91h_low_level_output, no PKT buf\r\n"));
memory_manager->free(buf);
return false;
}
for (q = p; q != NULL; q = memory_manager->get_next(q)) {
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
memcpy(&((*data)[actual_txlen+2]), memory_manager->get_ptr(q), memory_manager->get_len(q));//reserve wid header length
actual_txlen += memory_manager->get_len(q);
if (actual_txlen > 1514 || actual_txlen > memory_manager->get_total_len(p)) {
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output err, actual_txlen:%d, tot_len%d\n", actual_txlen, memory_manager->get_total_len(p)));
memory_manager->free(buf);
return false;
}
}
/* Signal rda5996 that packet should be sent */
if (actual_txlen == memory_manager->get_total_len(p)) {
wland_txip_data((void*)data, actual_txlen, 0);
memory_manager->free(buf);
return true;
}
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output pkt len mismatch, actual_txlen:%d, tot_len%d\n",
actual_txlen, memory_manager->get_total_len(p)));
memory_manager->free(buf);
return false;
}
/**
* Should allocate a contiguous memory buffer and transfer the bytes of the incoming
* packet to the buffer.
*
* @param buf If a frame was received and the memory buffer allocation was successful, a memory
* buffer filled with the received packet (including MAC header)
* @return negative value when no more frames,
* zero when frame is received
*/
emac_mem_buf_t * RDA5981x_EMAC::low_level_input(u8_t *data, int len)
{
emac_mem_buf_t *p, *q;
u16_t index = 0;
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input enter, rxlen:%d\n", len));
/* Obtain the size of the packet and put it into the "len"
variable. */
if (!len) {
return NULL;
}
/* We allocate a pbuf chain of pbufs from the pool. */
p = memory_manager->alloc_pool(len, 0);
if (p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
for (q = p; q != NULL; q = memory_manager->get_next(q)) {
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* pbuf is the sum of the chained pbuf len members.
*/
/* load rx data from 96 to local mem_pool */
memcpy(memory_manager->get_ptr(q), &data[index], memory_manager->get_len(q));
index += memory_manager->get_len(q);
if (index >= len) {
break;
}
}
} else {
/* Drop this packet */
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input pbuf_alloc fail, rxlen:%d\n", len));
return NULL;
}
return p;
}
/** \brief Attempt to read a packet from the EMAC interface.
*
*/
void RDA5981x_EMAC::packet_rx()
{
rda_msg msg;
packet_rx_queue = rda_mail_create(10, sizeof(unsigned int)*4);
/* move received packet into a new buf */
while (1) {
emac_mem_buf_t *p = NULL;
rda_mail_get(packet_rx_queue, (void*)&msg, osWaitForever);
switch(msg.type) {
case 0:
p = low_level_input((unsigned char*)msg.arg1, msg.arg2);
if (p == NULL) {
rda_sem_release((void*)msg.arg3);
break;
}
rda_sem_release((void*)msg.arg3);
if (p) {
emac_link_input_cb(p);
}
break;
case 1:
emac_link_state_cb(msg.arg1);
break;
default:
break;
}
}
}
void RDA5981x_EMAC::thread_function(void *pvParameters)
{
static struct RDA5981x_EMAC *rda5981x_enet = static_cast<RDA5981x_EMAC *>(pvParameters);
rda5981x_enet->packet_rx();
}
bool RDA5981x_EMAC::power_up()
{
/* Initialize the hardware */
static int init_flag = 0;
if (init_flag == 0) {
wland_reg_func();
rda_thread_new("maclib_thread", maclib_task, NULL, DEFAULT_THREAD_STACKSIZE*8, PHY_PRIORITY);
rda_thread_new("wland_thread", wland_task, NULL, DEFAULT_THREAD_STACKSIZE*5, PHY_PRIORITY);
rda_thread_new("packet_rx", RDA5981x_EMAC::thread_function, this, DEFAULT_THREAD_STACKSIZE*5, PHY_PRIORITY);
/* Allow the PHY task to detect the initial link state and set up the proper flags */
osDelay(100);
wland_sta_init();
init_flag = 1;
}
return true;
}
uint32_t RDA5981x_EMAC::get_mtu_size() const
{
return RDA_ETH_MTU_SIZE;
}
uint32_t RDA5981x_EMAC::get_align_preference() const
{
return 0;
}
void RDA5981x_EMAC::get_ifname(char *name, uint8_t size) const
{
memcpy(name, RDA_ETH_IF_NAME, (size < sizeof(RDA_ETH_IF_NAME)) ? size : sizeof(RDA_ETH_IF_NAME));
}
uint8_t RDA5981x_EMAC::get_hwaddr_size() const
{
return RDA_HWADDR_SIZE;
}
bool RDA5981x_EMAC::get_hwaddr(uint8_t *addr) const
{
mbed_mac_address((char *)addr);
return true;
}
void RDA5981x_EMAC::set_hwaddr(const uint8_t *addr)
{
/* No-op at this stage */
}
void RDA5981x_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb)
{
emac_link_input_cb = input_cb;
}
void RDA5981x_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb)
{
emac_link_state_cb = state_cb;
}
void RDA5981x_EMAC::add_multicast_group(const uint8_t *addr)
{
/* No-op at this stage */
}
void RDA5981x_EMAC::remove_multicast_group(const uint8_t *addr)
{
/* No-op at this stage */
}
void RDA5981x_EMAC::set_all_multicast(bool all)
{
/* No-op at this stage */
}
void RDA5981x_EMAC::power_down()
{
/* No-op at this stage */
}
void RDA5981x_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
{
memory_manager = &mem_mngr;
}
RDA5981x_EMAC &RDA5981x_EMAC::get_instance()
{
static RDA5981x_EMAC emac;
return emac;
}
// Weak so a module can override
MBED_WEAK EMAC &EMAC::get_default_instance()
{
return RDA5981x_EMAC::get_instance();
}

View File

@ -0,0 +1,161 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STM32_EMAC_H_
#define STM32_EMAC_H_
#include "EMAC.h"
#include "rtos/Semaphore.h"
#include "rtos/Mutex.h"
class RDA5981x_EMAC : public EMAC {
public:
RDA5981x_EMAC();
static RDA5981x_EMAC &get_instance();
/**
* Return maximum transmission unit
*
* @return MTU in bytes
*/
virtual uint32_t get_mtu_size() const;
/**
* Gets memory buffer alignment preference
*
* Gets preferred memory buffer alignment of the Emac device. IP stack may or may not
* align link out memory buffer chains using the alignment.
*
* @return Memory alignment requirement in bytes
*/
virtual uint32_t get_align_preference() const;
/**
* Return interface name
*
* @param name Pointer to where the name should be written
* @param size Maximum number of character to copy
*/
virtual void get_ifname(char *name, uint8_t size) const;
/**
* Returns size of the underlying interface HW address size.
*
* @return HW address size in bytes
*/
virtual uint8_t get_hwaddr_size() const;
/**
* Return interface-supplied HW address
*
* Copies HW address to provided memory, @param addr has to be of correct size see @a get_hwaddr_size
*
* HW address need not be provided if this interface does not have its own HW
* address configuration; stack will choose address from central system
* configuration if the function returns false and does not write to addr.
*
* @param addr HW address for underlying interface
* @return true if HW address is available
*/
virtual bool get_hwaddr(uint8_t *addr) const;
/**
* Set HW address for interface
*
* Provided address has to be of correct size, see @a get_hwaddr_size
*
* Called to set the MAC address to actually use - if @a get_hwaddr is provided
* the stack would normally use that, but it could be overridden, eg for test
* purposes.
*
* @param addr Address to be set
*/
virtual void set_hwaddr(const uint8_t *addr);
/**
* Sends the packet over the link
*
* That can not be called from an interrupt context.
*
* @param buf Packet to be send
* @return True if the packet was send successfully, False otherwise
*/
virtual bool link_out(emac_mem_buf_t *buf);
/**
* Initializes the HW
*
* @return True on success, False in case of an error.
*/
virtual bool power_up();
/**
* Deinitializes the HW
*
*/
virtual void power_down();
/**
* Sets a callback that needs to be called for packets received for that interface
*
* @param input_cb Function to be register as a callback
*/
virtual void set_link_input_cb(emac_link_input_cb_t input_cb);
/**
* Sets a callback that needs to be called on link status changes for given interface
*
* @param state_cb Function to be register as a callback
*/
virtual void set_link_state_cb(emac_link_state_change_cb_t state_cb);
/** Add device to a multicast group
*
* @param address A multicast group hardware address
*/
virtual void add_multicast_group(const uint8_t *address);
/** Remove device from a multicast group
*
* @param address A multicast group hardware address
*/
virtual void remove_multicast_group(const uint8_t *address);
/** Request reception of all multicast packets
*
* @param all True to receive all multicasts
* False to receive only multicasts addressed to specified groups
*/
virtual void set_all_multicast(bool all);
/** Sets memory manager that is used to handle memory buffers
*
* @param mem_mngr Pointer to memory manager
*/
virtual void set_memory_manager(EMACMemoryManager &mem_mngr);
private:
void packet_rx();
emac_mem_buf_t * low_level_input(u8_t *data, int len);
static void thread_function(void *pvParameters);
emac_link_input_cb_t emac_link_input_cb; /**< Callback for incoming data */
emac_link_state_change_cb_t emac_link_state_cb; /**< Link state change callback */
EMACMemoryManager *memory_manager; /**< Memory manager */
};
#endif /* K64F_EMAC_H_ */

View File

@ -0,0 +1,22 @@
/* Copyright (c) 2019 Unisoc Communications Inc.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef STM32XX_EMAC_CONFIG_H__
#define STM32XX_EMAC_CONFIG_H__
#define THREAD_STACKSIZE 512
#endif // #define STM32XX_EMAC_CONFIG_H__

View File

@ -1,27 +1,17 @@
/******************************************************************************
* @file RDA5991H.h
* @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File for
* RDA RDA5991H Device Series
* @version: V1.09
* @date: 07. June 2018
/* Copyright (c) 2019 Unisoc Communications Inc.
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
* http://www.apache.org/licenses/LICENSE-2.0
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __RDA5991H_H__
#define __RDA5991H_H__

View File

@ -118,4 +118,14 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l
return ret;
}
int rda_trng_get_bytes(unsigned char *output, size_t len)
{
size_t temp;
trng_t trng_obj;
trng_init(&trng_obj);
int ret = trng_get_bytes(&trng_obj, output, len, &temp);
trng_free(&trng_obj);
return ret;
}
#endif

View File

@ -8061,7 +8061,7 @@
"inherits": ["Target"],
"core": "Cortex-M4F",
"public": true,
"extra_labels": ["RDA", "UNO_91H", "FLASH_CMSIS_ALGO"],
"extra_labels": ["RDA", "UNO_91H", "FLASH_CMSIS_ALGO", "RDA_EMAC"],
"supported_toolchains": ["ARM", "GCC_ARM", "IAR"],
"macros": ["TWO_RAM_REGIONS", "CMSIS_NVIC_VIRTUAL", "CMSIS_NVIC_VIRTUAL_HEADER_FILE=\"RDA5981_nvic_virtual.h\""],
"device_has": [
@ -8070,6 +8070,7 @@
"PORTOUT",
"PORTINOUT",
"INTERRUPTIN",
"EMAC",
"SERIAL",
"STDIO_MESSAGES",
"PWMOUT",
@ -8083,7 +8084,10 @@
},
"UNO_91H": {
"inherits": ["RDA5981X"],
"detect_code": ["8001"]
"detect_code": ["8001"],
"overrides": {
"network-default-interface-type" : "WIFI"
}
},
"GD32_Target": {
"inherits": ["Target"],