Skip to content

Updated ODIN drivers to v2.5.0 RC1 #6913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions features/FEATURE_LWIP/lwip-interface/LWIPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,11 @@ nsapi_error_t LWIP::Interface::bringdown()
#if LWIP_IPV6
mbed_lwip_clear_ipv6_addresses(&netif);
#endif
#if LWIP_IPV4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this needed? My recollection was that lwip did zero this itself, and forgot to for IPv6, but maybe that's not true.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaslarssonublox could you please respond to this?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was not done for IPv4 and discovered for some case like re-connecting with static IP.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've got no problem with this going in - don't see how it can hurt.

But let's try to avoid too many miscellaneous tweaks going in - we've got a deadline (Friday) and a misbehaving CI system.

ip_addr_set_zero(&(netif.ip_addr));
ip_addr_set_zero(&(netif.netmask));
ip_addr_set_zero(&(netif.gw));
#endif

osSemaphoreDelete(has_any_addr);
osSemaphoreAttr_t attr;
Expand Down
2 changes: 2 additions & 0 deletions features/FEATURE_LWIP/lwip-interface/lwip-sys/lwip_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip_random.h"

#include "randLIB.h"

void lwip_seed_random(void)
{
randLIB_seed_random();

}

void lwip_add_random_seed(uint64_t seed)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
#if DEVICE_WIFI

#include "mbed_interface.h"
#include "mbed_assert.h"
#include "netsocket/nsapi_types.h"

#include "wifi_emac.h"

#include "cb_wlan_target_data.h"
#include "cb_wlan_types.h"
#include "cb_wlan.h"
#include "cb_otp.h"
#include "cb_main.h"

#define OdinWiFiEMAC_MTU_SIZE (1500U)
static const char _ifname[] = "WL0";

cb_boolean handleWlanTargetCopyFromDataFrame(uint8_t* buffer, cbWLANTARGET_dataFrame* frame, uint32_t size, uint32_t offsetInFrame);
cb_boolean handleWlanTargetCopyToDataFrame(cbWLANTARGET_dataFrame* frame, uint8_t* buffer, uint32_t size, uint32_t offsetInFrame);
cbWLANTARGET_dataFrame* handleWlanTargetAllocDataFrame(uint32_t size);
void handleWlanTargetFreeDataFrame(cbWLANTARGET_dataFrame* frame);
cb_uint32 handleWlanTargetGetDataFrameSize(cbWLANTARGET_dataFrame* frame);
cb_uint8 handleWlanTargetGetDataFrameTID(cbWLANTARGET_dataFrame* frame);
void handleWlanStatusIndication(void *dummy, cbWLAN_StatusIndicationInfo status, void *data);
void handleWlanPacketIndication(void *dummy, cbWLAN_PacketIndicationInfo *packetInfo);
void send_wlan_packet(void *buf);

static const cbWLANTARGET_Callback _wlanTargetCallback =
{
handleWlanTargetCopyFromDataFrame,
handleWlanTargetCopyToDataFrame,
handleWlanTargetAllocDataFrame,
handleWlanTargetFreeDataFrame,
handleWlanTargetGetDataFrameSize,
handleWlanTargetGetDataFrameTID
};

void handleWlanStatusIndication(void *dummy, cbWLAN_StatusIndicationInfo status, void *data)
{
OdinWiFiEMAC &instance = OdinWiFiEMAC::get_instance();
bool linkUp = false;
bool sendCb = true;
(void)dummy;
(void)data;

switch (status) {
case cbWLAN_STATUS_CONNECTED:
case cbWLAN_STATUS_AP_STA_ADDED:
linkUp = true;
break;
case cbWLAN_STATUS_STOPPED:
case cbWLAN_STATUS_ERROR:
case cbWLAN_STATUS_DISCONNECTED:
case cbWLAN_STATUS_CONNECTION_FAILURE:
break;
case cbWLAN_STATUS_CONNECTING:
default:
sendCb = false;
break;
}
if (sendCb && instance.emac_link_state_cb) {
instance.emac_link_state_cb(linkUp);
}
}

void handleWlanPacketIndication(void *dummy, cbWLAN_PacketIndicationInfo *packetInfo)
{
OdinWiFiEMAC &instance = OdinWiFiEMAC::get_instance();
(void)dummy;

if (instance.emac_link_input_cb) {
instance.emac_link_input_cb((void*)packetInfo->rxData);
}
}

cb_boolean handleWlanTargetCopyFromDataFrame(uint8_t* buffer, cbWLANTARGET_dataFrame* frame, uint32_t size, uint32_t offsetInFrame)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);

emac_mem_buf_t* phead = static_cast<emac_mem_buf_t *>(frame);
emac_mem_buf_t* pbuf;
uint32_t copySize, bytesCopied = 0, pbufOffset = 0;

MBED_ASSERT(frame != NULL);
MBED_ASSERT(buffer != NULL);

pbuf = phead;
while (pbuf != NULL) {
if ((pbufOffset + mem->get_len(pbuf)) >= offsetInFrame) {
copySize = cb_MIN(size, mem->get_len(pbuf) - (offsetInFrame - pbufOffset));
memcpy(buffer, (int8_t *)mem->get_ptr(pbuf) + (offsetInFrame - pbufOffset), copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
break;
}
pbufOffset += mem->get_len(pbuf);
pbuf = mem->get_next(pbuf);
}

while (pbuf != NULL && bytesCopied < size) {
copySize = cb_MIN(mem->get_len(pbuf), size - bytesCopied);
memcpy(buffer, mem->get_ptr(pbuf), copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
}

MBED_ASSERT(bytesCopied <= size);

return (bytesCopied == size);
}

cb_boolean handleWlanTargetCopyToDataFrame(cbWLANTARGET_dataFrame* frame, uint8_t* buffer, uint32_t size, uint32_t offsetInFrame)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);

emac_mem_buf_t* phead = static_cast<emac_mem_buf_t *>(frame);
emac_mem_buf_t* pbuf;
uint32_t copySize, bytesCopied = 0, pbufOffset = 0;

MBED_ASSERT(frame != NULL);
MBED_ASSERT(buffer != NULL);

pbuf = phead;
while (pbuf != NULL) {
if ((pbufOffset + mem->get_len(pbuf)) >= offsetInFrame) {
copySize = cb_MIN(size, mem->get_len(pbuf) - (offsetInFrame - pbufOffset));
memcpy((uint8_t *)mem->get_ptr(pbuf) + (offsetInFrame - pbufOffset), buffer, copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
break;
}
pbufOffset += mem->get_len(pbuf);
pbuf = mem->get_next(pbuf);
}

while (pbuf != NULL && bytesCopied < size) {
copySize = cb_MIN(mem->get_len(pbuf), size - bytesCopied);
memcpy(mem->get_ptr(pbuf), buffer, copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
}

MBED_ASSERT(bytesCopied <= size);

return (bytesCopied == size);
}

cbWLANTARGET_dataFrame* handleWlanTargetAllocDataFrame(uint32_t size)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
return (cbWLANTARGET_dataFrame*)mem->alloc_pool(size, 0);
}

void handleWlanTargetFreeDataFrame(cbWLANTARGET_dataFrame* frame)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
mem->free(static_cast<emac_mem_buf_t *>(frame));
}

uint32_t handleWlanTargetGetDataFrameSize(cbWLANTARGET_dataFrame* frame)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
return mem->get_total_len(static_cast<emac_mem_buf_t *>(frame));
}

uint8_t handleWlanTargetGetDataFrameTID(cbWLANTARGET_dataFrame* frame)
{
(void)frame;
return (uint8_t)cbWLAN_AC_BE;
}

OdinWiFiEMAC::OdinWiFiEMAC()
{
emac_link_input_cb = NULL;
emac_link_state_cb = NULL;
cbWLANTARGET_registerCallbacks((cbWLANTARGET_Callback*)&_wlanTargetCallback);
}

void send_wlan_packet(void *buf)
{
cbWLAN_sendPacket(buf);
}

bool OdinWiFiEMAC::link_out(emac_mem_buf_t *buf)
{
EMACMemoryManager *mem = OdinWiFiEMAC::get_instance().memory_manager;

// Break call chain to avoid the driver affecting stack usage for the IP stack thread too much
emac_mem_buf_t *new_buf = mem->alloc_pool(mem->get_total_len(buf), 0);
if (new_buf != NULL) {
mem->copy(new_buf, buf);
int id = cbMAIN_getEventQueue()->call(send_wlan_packet, new_buf);
if (id != 0) {
cbMAIN_dispatchEventQueue();
} else {
mem->free(new_buf);
}
}
mem->free(buf);
return true;
}

bool OdinWiFiEMAC::power_up()
{
/* Initialize the hardware */
/* No-op at this stage */
return true;
}

uint32_t OdinWiFiEMAC::get_mtu_size() const
{
return OdinWiFiEMAC_MTU_SIZE;
}

void OdinWiFiEMAC::get_ifname(char *name, uint8_t size) const
{
memcpy(name, _ifname, (size < sizeof(_ifname)) ? size : sizeof(_ifname));
}

uint8_t OdinWiFiEMAC::get_hwaddr_size() const
{
return sizeof(cbWLAN_MACAddress);
}

bool OdinWiFiEMAC::get_hwaddr(uint8_t *addr) const
{
cbOTP_read(cbOTP_MAC_WLAN, sizeof(cbWLAN_MACAddress), addr);
return true;
}

void OdinWiFiEMAC::set_hwaddr(const uint8_t *addr)
{
/* No-op at this stage */
}

void OdinWiFiEMAC::set_link_input_cb(emac_link_input_cb_t input_cb)
{
emac_link_input_cb = input_cb;

cbMAIN_driverLock();
cbWLAN_registerPacketIndicationCallback(handleWlanPacketIndication, NULL);
cbMAIN_driverUnlock();
}

void OdinWiFiEMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb)
{
emac_link_state_cb = state_cb;

cbMAIN_driverLock();
cbWLAN_registerStatusCallback(handleWlanStatusIndication, NULL);
cbMAIN_driverUnlock();
}

void OdinWiFiEMAC::power_down()
{
/* No-op at this stage */
}

void OdinWiFiEMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
{
memory_manager = &mem_mngr;
}

uint32_t OdinWiFiEMAC::get_align_preference() const
{
return 1;
}

void OdinWiFiEMAC::add_multicast_group(const uint8_t *address)
{

}

void OdinWiFiEMAC::remove_multicast_group(const uint8_t *address)
{

}

void OdinWiFiEMAC::set_all_multicast(bool all)
{

}

OdinWiFiEMAC &OdinWiFiEMAC::get_instance() {
static OdinWiFiEMAC emac;
return emac;
}

#endif // DEVICE_WIFI
Loading