SDK example for WICED based M.2 WiFi

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SDK example for WICED based M.2 WiFi

Jump to solution
3,837 Views
mspenard603
Contributor IV

Hi All,

 I'm trying out the "evkmimxrt1060_wiced_iperf" example project for M.2 based WiFi. I notice it builds with FreeRTOS. I'd like to not use an RTOS in my code-base. Does the WICED M.2 WiFi code require RTOS? Is there an easy way to exclude it? Is there some #ifdef or compiler #symbol I'm not noticing to do so?

Thank you

Labels (1)
1 Solution
2,956 Views
carstengroen
Senior Contributor II

Mike,

I don't know if it is of any help or not, but I'm using ATWINC1510 module together with LwIP (on multiple NXP platforms). The ATWINC1510 has a passthru mode that lets it interface very nicely with LwIP.

Just a headsup if you look for something else.

View solution in original post

0 Kudos
31 Replies
2,589 Views
jamie3
Contributor II

Hi, I am using the same setup of WINC1510 with a nxp mcu with FreeRtos/LWIP setup can you share any files for the interface/module?

Cheers

Jamie 

0 Kudos
2,589 Views
mspenard603
Contributor IV

My code is for bare-metal. If you're using FreeRTOS Atmel's standard (non-bypass mode) code should work for you.

If you really need to use your own stack (LWIP) take a look at Atmel's bypass-mode template code. It's available in their big ASF(?) library. And the PDF docs outlining it are:

70005333A Ethernet Mode.pdf

ATWINC15x0-Wi-Fi-Network-Controller-Software-Design-Guide-User-Guide-DS00002389B.pdf

WINC1500_SPI_Porting_Guide.pdf

If you need code or help message me and I'll send you my email. I spent a good few months figuring all this out and debugging it. Lets just say it's a non-trival project heh. So I don't mind paying it forward.


First thing to do is get SPI working. And pull the ChipID to verify it's working. Let me know when you're ready and I'll dump my SPI driver code on here. Also, you have a logic analyzer like a Saleae right? You'll very likely need one.

0 Kudos
2,589 Views
jamie3
Contributor II

Hi Mike, Carsten.

Thanks for your help I'll get the SPI working and review the documents then take a long view of the rest of the project.

I am expecting this will be a bit of a marathon, I have struggled to find a better solution for a SPI hosted  as the longsys GT1216 on the NXP IOT development board isn't available to buy. And if i have to do this level of driver work then this module looks like super value on the BOM.

I have a SPI logic analyser but its always a level of dev I would rather avoid......

Cheers

Jamie.

FoobarEngineering.

0 Kudos
2,589 Views
mspenard603
Contributor IV

I ran into issue with my delay_ms(). It's not very accurate despite being boilerplate code. So get a delay_us() and fine tune things if need be.
Also ran into issue with dummy data on the SPI bus. If you get it wrong it will actually work. Up to a certain point, and you'll pound your head wondering why.

Anyhow, these two .c files should get SPI working for you.

0 Kudos
2,589 Views
mspenard603
Contributor IV

// nm_bsp_iMXRT1062.c
// header files needed for GPIO interrupts
#include "board.h"
#include "pin_mux.h"
#include "fsl_common.h"
#include "fsl_gpio.h"

#include "ppsys_util.h" // needed for delay_ms()
#include "ppsys_bsp_spi.h" // our SPI code
#include "ppsys_bsp_network.h" // REMOVE?

#include "nm_bsp.h"
#include "nm_common.h"
#include "conf_winc.h"
#include "m2m_hif.h" // isr()
#include <stdarg.h>

#include "fsl_debug_console.h"

//-----------------------------------------------------------------------------
// I/O definitions
//-----------------------------------------------------------------------------
// register ISR handler
#define local_gpio1_isr GPIO1_Combined_16_31_DriverIRQHandler // for some reason we cant register os_hook_isr() directly?

// SPI port to Wifi module is LPSPI1 on CIRAS platform:
#define PORT_WIFI_WAKE GPIO1
#define PIN_WIFI_WAKE (28U)

#define PORT_WIFI_IRQ GPIO1
#define PIN_WIFI_IRQ (29U)

#define PORT_WIFI_RESET GPIO1
#define PIN_WIFI_RESET (31U)

#define PORT_WIFI_ENABLE GPIO1
#define PIN_WIFI_ENABLE (30U)

#define PORT_WIFI_CS GPIO3
#define PIN_WIFI_CS (13U)

static char buffer[256];
static va_list vararg;
static tpfNmBspIsr gpfIsr;


//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void local_gpio1_isr(void) {
GPIO_PortClearInterruptFlags(PORT_WIFI_IRQ, 1U << PIN_WIFI_IRQ); // need to clear immediately or we get stuck in here
if (gpfIsr) {
gpfIsr();
}
}

void nm_bsp_cs_low(void){
GPIO_ClearPinsOutput(PORT_WIFI_CS, 1U << PIN_WIFI_CS);
}

void nm_bsp_cs_high(void){
GPIO_PortSet(PORT_WIFI_CS, 1U << PIN_WIFI_CS);
}

//-----------------------------------------------------------------------------
// @fn nm_bsp_init
// @brief Initialize BSP
// @return 0 in case of success and -1 in case of failure
//-----------------------------------------------------------------------------
sint8 nm_bsp_init(void) {
gpio_pin_config_t gpio_configINPUT = {
kGPIO_DigitalInput,
0,
kGPIO_IntFallingEdge,
};

gpio_pin_config_t gpio_configOUTPUT = {
kGPIO_DigitalOutput,
0,
kGPIO_NoIntmode,
};

ppsys_bsp_spi1_init();

gpfIsr = NULL; // clear ISR callback

// Init reset signal
GPIO_ClearPinsOutput(PORT_WIFI_RESET, 1U << PIN_WIFI_RESET); // Reset active
GPIO_PinInit(PORT_WIFI_RESET, PIN_WIFI_RESET, &gpio_configOUTPUT);

// Init Enable signal
GPIO_ClearPinsOutput(PORT_WIFI_ENABLE, 1U << PIN_WIFI_ENABLE); // Disable
GPIO_PinInit(PORT_WIFI_ENABLE, PIN_WIFI_ENABLE, &gpio_configOUTPUT);

// Init IRQ input (pin_mux.c configures pin)
GPIO_PinInit(PORT_WIFI_IRQ, PIN_WIFI_IRQ, &gpio_configINPUT);

// Init Wake signal
GPIO_ClearPinsOutput(PORT_WIFI_WAKE, 1U << PIN_WIFI_WAKE);
GPIO_PinInit(PORT_WIFI_WAKE, PIN_WIFI_WAKE, &gpio_configOUTPUT);

// Init CS signal
GPIO_ClearPinsOutput(PORT_WIFI_CS, 1U << PIN_WIFI_CS); // CS
GPIO_PinInit(PORT_WIFI_CS, PIN_WIFI_CS, &gpio_configOUTPUT);

// Perform chip reset
nm_bsp_reset();

return M2M_SUCCESS;
}

//-----------------------------------------------------------------------------
// @fn nm_bsp_deinit
// @brief De-iInitialize BSP
// @return 0 in case of success and -1 in case of failure
//-----------------------------------------------------------------------------
sint8 nm_bsp_deinit(void) {
return M2M_SUCCESS;
}

//-----------------------------------------------------------------------------
// @fn nm_bsp_reset
// @brief Reset NMC1500 SoC by setting CHIP_EN and RESET_N signals low,
// CHIP_EN high then RESET_N high
//-----------------------------------------------------------------------------
void nm_bsp_reset(void) {
GPIO_ClearPinsOutput(PORT_WIFI_ENABLE, 1U <<PIN_WIFI_ENABLE); // Enable module (starts its DC/DC converter etc)
GPIO_ClearPinsOutput(PORT_WIFI_RESET, 1U << PIN_WIFI_RESET); // Reset active
nm_bsp_sleep(100);

//mls
GPIO_PortSet(PORT_WIFI_CS, 1U << PIN_WIFI_CS); // Chip select inactive (high)
nm_bsp_sleep_us(125); // 1ms

GPIO_PortSet(PORT_WIFI_ENABLE, 1U << PIN_WIFI_ENABLE); // Enable(high) module (starts its DC/DC converter etc)
nm_bsp_sleep_us(1250); // this is the critical one; 5ms min; 10ms nominal

GPIO_PortSet(PORT_WIFI_RESET, 1U << PIN_WIFI_RESET); // Reset inactive
nm_bsp_sleep_us(250); // 2ms
}

//-----------------------------------------------------------------------------
// @fn nm_bsp_sleep
// @brief Sleep in units of mSec
// @param[IN] u32TimeMsec
// Time in milliseconds
//-----------------------------------------------------------------------------
void nm_bsp_sleep(uint32 u32TimeMsec) {
delay_ms(u32TimeMsec);
}


void nm_bsp_sleep_us(uint32 u32TimeUsec) {
delay_us(u32TimeUsec);
}


//-----------------------------------------------------------------------------
// @fn nm_bsp_register_isr
// @brief Register interrupt service routine
// @param[IN] pfIsr
// Pointer to ISR handler
//-----------------------------------------------------------------------------
void nm_bsp_register_isr(tpfNmBspIsr pfIsr) {
//Interrupt handler is set with a #define and pfIsr (ie., isr() ) is called from that #define callback; mls
gpfIsr = pfIsr;

EnableIRQ(GPIO1_Combined_16_31_IRQn); // WIFI_IRQ is GPIO1_29
GPIO_PortEnableInterrupts(PORT_WIFI_IRQ, 1U << PIN_WIFI_IRQ);
}

//-----------------------------------------------------------------------------
// @fn nm_bsp_interrupt_ctrl
// @brief Enable/Disable interrupts
// @param[IN] u8Enable
// '0' disable interrupts. '1' enable interrupts
//-----------------------------------------------------------------------------
void nm_bsp_interrupt_ctrl(uint8 u8Enable) {
if (u8Enable)
GPIO_PortEnableInterrupts(PORT_WIFI_IRQ, 1U << PIN_WIFI_IRQ);
else
GPIO_PortDisableInterrupts(PORT_WIFI_IRQ, 1U << PIN_WIFI_IRQ);;
}

0 Kudos
2,589 Views
mspenard603
Contributor IV

/*
* ppsys_bsp_spi.c
*
* Created on: June 10, 2019
* Author: Mike Spenard // PP Systems
*
* -We're using LPSPI1 which required SD Card to be moved to USDHC2
* -ATWINC1500 requires 0x00 dummy data
*
*
*/

/* Standard C Included Files */
#include <stdio.h>
#include <string.h>

#include "fsl_common.h"
#include "fsl_lpspi.h"
#include "fsl_debug_console.h"
#include "ppsys_globals.h"
#include "ppsys_util.h"
#include "ppsys_bsp_spi.h"
#include "ewrte.h"

#define LPSPI1_CLOCK_SOURCE_DIVIDER (7U) // Clock divider for master lpspi clock source; see also board.c's mux setup
#define TRANSFER_BAUDRATE 100000000U // Breadboard board rate: 1 000 000U
#define SPI_MASTER_TRANSMIT_TIMEOUT 10
#define SPI_MASTER_RECEIVE_TIMEOUT 100

static lpspi_master_handle_t handle;
volatile bool g_SPI_MasterCompletionFlag = false;
volatile bool g_SPI_MasterTransferError = false;
t_SPI_data SPI_Data;

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
/*
uint8_t sendSPI1(unsigned char *buffer, int length) {
status_t reVal = kStatus_Fail;
lpspi_transfer_t transfer;
uint16_t transferTimeout = SPI_MASTER_TRANSMIT_TIMEOUT;
uint16_t lastTick;

transfer.dataSize=length;
transfer.txData=buffer;
transfer.rxData=NULL;
transfer.configFlags=kLPSPI_MasterPcsContinuous;

// hold off doing TX if bus is busy; ADD A TIMEOUT
while (LPSPI_GetStatusFlags(LPSPI1) & kLPSPI_ModuleBusyFlag)
{
}

reVal = LPSPI_MasterTransferNonBlocking(LPSPI1, &handle, &transfer);
if (reVal != kStatus_Success)
{
return 0; return 0;
}

g_SPI_MasterCompletionFlag = false; // Reset master completion flag to false
g_SPI_MasterTransferError = false; // clear errors

lastTick = EwGetTicks();
while (!g_SPI_MasterCompletionFlag && !g_SPI_MasterTransferError) // && transferTimeout) // Wait for transfer completed or error or timeout
{
//transferTimeout = transferTimeout - (EwGetTicks() - lastTick);
//lastTick = EwGetTicks();
}
g_SPI_MasterCompletionFlag = false;

for(int i=0; i< length; i++)
PRINTF("tx:0x%02X\n\r", buffer[i]);

return 1;
}
*/

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
uint8_t sendCharSPI1(unsigned char data) {
status_t reVal = kStatus_Fail;
lpspi_transfer_t transfer;
uint16_t transferTimeout = SPI_MASTER_TRANSMIT_TIMEOUT;
uint16_t lastTick;

transfer.dataSize=1;
transfer.txData=&data;
transfer.rxData=NULL;
transfer.configFlags=kLPSPI_MasterPcsContinuous;

// hold off doing TX if bus is busy; ADD A TIMEOUT
while (LPSPI_GetStatusFlags(LPSPI1) & kLPSPI_ModuleBusyFlag)
{
}

g_SPI_MasterCompletionFlag = false; // Reset master completion flag to false
g_SPI_MasterTransferError = false; // clear errors

reVal = LPSPI_MasterTransferNonBlocking(LPSPI1, &handle, &transfer);
if (reVal != kStatus_Success)
{
return 0; return 0;
}

lastTick = EwGetTicks();
while (!g_SPI_MasterCompletionFlag && !g_SPI_MasterTransferError && transferTimeout) // Wait for transfer completed or error or timeout
{
transferTimeout = transferTimeout - (EwGetTicks() - lastTick);
lastTick = EwGetTicks();
}
g_SPI_MasterCompletionFlag = false;

if(g_SPI_MasterTransferError) // if we picked up an error from the ISR then exit
{
PRINTF("SPI_TX TRANSFER ERROR\n\r");
SPI_Data.TXtransferErrors++; // book-keeping var
return 0;
}
if(transferTimeout == 0) // if we timed out something went wrong so reset the bus
{
PRINTF("SPI_TX TIMEOUT\n\r");
SPI_Data.TXtimeouts++; // book-keeping var
//ppsys_bsp_spi_reinit();
return 0;
}


return 1;
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
/*
uint8_t receiveSPI1(unsigned char *buffer, int length) {
status_t reVal = kStatus_Fail;
lpspi_transfer_t transfer;
uint16_t transferTimeout = SPI_MASTER_RECEIVE_TIMEOUT;
uint16_t lastTick;

transfer.dataSize=length;
transfer.txData=NULL;
transfer.rxData=buffer;
transfer.configFlags=kLPSPI_MasterPcsContinuous;

reVal = LPSPI_MasterTransferNonBlocking(LPSPI1, &handle, &transfer);
if (reVal != kStatus_Success)
{
return 0; return 0;
}

g_SPI_MasterCompletionFlag = false; // Reset master completion flag to false
g_SPI_MasterTransferError = false; // clear errors

lastTick = EwGetTicks();
while (!g_SPI_MasterCompletionFlag && !g_SPI_MasterTransferError && transferTimeout) // Wait for transfer completed or error or timeout
{
transferTimeout = transferTimeout - (EwGetTicks() - lastTick);
lastTick = EwGetTicks();
}
g_SPI_MasterCompletionFlag = false;


for(int i=0; i< length; i++)
PRINTF("rx: 0x%02X\n\r", buffer[i]);
return 1;
}
*/

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
unsigned char receiveCharSPI1(void) {
status_t reVal = kStatus_Fail;
unsigned char rx;
lpspi_transfer_t transfer;
uint16_t transferTimeout = SPI_MASTER_RECEIVE_TIMEOUT;
uint16_t lastTick;

transfer.dataSize=1;
transfer.txData=NULL;
transfer.rxData=&rx;
transfer.configFlags=kLPSPI_MasterPcsContinuous;

g_SPI_MasterCompletionFlag = false; // Reset master completion flag to false
g_SPI_MasterTransferError = false; // clear errors

reVal = LPSPI_MasterTransferNonBlocking(LPSPI1, &handle, &transfer);
if (reVal != kStatus_Success)
{
return 0; return 0;
}

lastTick = EwGetTicks();
while (!g_SPI_MasterCompletionFlag && !g_SPI_MasterTransferError && transferTimeout) // Wait for transfer completed or error or timeout
{
transferTimeout = transferTimeout - (EwGetTicks() - lastTick);
lastTick = EwGetTicks();
}
g_SPI_MasterCompletionFlag = false;

if(g_SPI_MasterTransferError) // if we picked up an error from the ISR then exit
{
PRINTF("SPI_RX TRANSFER ERROR\n\r");
SPI_Data.RXtransferErrors++; // book-keeping var
return 0;
}
if(transferTimeout == 0) // if we timed out something went wrong so reset the bus
{
PRINTF("SPI_RX TIMEOUT\n\r");
SPI_Data.RXtimeouts++; // book-keeping var
//ppsys_bsp_spi_reinit();
return 0;
}

return rx;
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
static void ppsys_bsp_spi1_handler(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData) {

switch(status) // see fsl_lpi2c.h for all status flags 2600 to 2610
{
case kStatus_Success: // Signal transfer success when received success status.
g_SPI_MasterCompletionFlag = true;
break;

default: // anything other than 0 is probably an error
PRINTF("SPI1 ERROR Unknown: %u\n\r", status);
g_SPI_MasterTransferError = true;
break;
}
}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void ppsys_bsp_spi1_init(void) {
uint32_t srcClock_Hz;

lpspi_master_config_t masterConfig;

/*Master config*/
masterConfig.baudRate = TRANSFER_BAUDRATE;
masterConfig.bitsPerFrame = 8;
masterConfig.cpol = kLPSPI_ClockPolarityActiveHigh;
masterConfig.cpha = kLPSPI_ClockPhaseFirstEdge;
masterConfig.direction = kLPSPI_MsbFirst;

masterConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.baudRate;

// masterConfig.whichPcs = kLPSPI_Pcs0;
// masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;

masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
masterConfig.dataOutConfig = kLpspiDataOutTristate; // NXP default =kLpspiDataOutRetained

srcClock_Hz = CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (LPSPI1_CLOCK_SOURCE_DIVIDER + 1U);
LPSPI_MasterInit(LPSPI1, &masterConfig, srcClock_Hz);

PRINTF(" SPI1 Clock: %i Hz\n\r", srcClock_Hz / LPSPI1_CLOCK_SOURCE_DIVIDER);
PRINTF(" SPI1 Baud rate: %i \n\r", masterConfig.baudRate);

LPSPI_Enable(LPSPI1, false);
LPSPI1->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
LPSPI_Enable(LPSPI1, true);

LPSPI_SetDummyData(LPSPI1, 0x00); // getting this wrong causes 0xC7|F3| issues with ATWINC1500!

LPSPI_MasterTransferCreateHandle(LPSPI1, &handle, ppsys_bsp_spi1_handler, NULL);
}

0 Kudos
2,589 Views
carstengroen
Senior Contributor II

Jamie,

not more than whats already in here, you should be able to get it running with that (and some digging and investigation of the original code for the WINC)

0 Kudos
2,592 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Mike Spenard,

     Yes, the evkmimxrt1060_wiced_iperf SDK examples is based on the amazon freertos, this project can't be selected as none freertos.

     You can find, even the wifi driver, also have the freertos code, so, the SDK wifi project code is mixed with freertos.

     We still don't have the baremetal code for wiced based m.2 wifi.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,592 Views
mspenard603
Contributor IV

Thanks Kerry. I understand, as M.2 WiFi is new to the April SDK 2.5.1 release. Do you know if conventional bare-metal drivers are on the horizon?

0 Kudos
2,592 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Mike Spenard,

   As I know, there no bare-metal plan, but I will help you to transfer your requirement to our according department when we collect the SDK suggestions.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,592 Views
mspenard603
Contributor IV

Hi Kerry,

 That would be great. As I'd like to add this M.2 interface to our product. If they could cook up conventional drivers in a few months that would be very helpful. I assume the Cypress WICED SDK has something further they could use as a starting point(?).

0 Kudos
2,592 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Mike,

    In my opinion, you also can try to learn our SDK code with freertos, then try to modify the wifi driver without the freertos, because, even I post your suggest, I am not sure it is acceptable, and the bare-metal for wifi code is not guaranteed.

   About the Cypress WICED SDK, you also can check it with cypress, whether their side have the according bare-metal driver or not.

  


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,592 Views
mspenard603
Contributor IV

Understood...subsequent question... What other WiFi interface options do I have? 

0 Kudos
2,592 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Mike,

   Do you mean WICED M.2 WiFi interface?

  It's better to check that wifi module datasheet, you can find that module datasheet from the wifi module company's website.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
2,592 Views
mspenard603
Contributor IV

No no, I mean in general. What other WiFi interface options do I have with the iMXRT? Any that don't require an RTOS? 

0 Kudos
2,957 Views
carstengroen
Senior Contributor II

Mike,

I don't know if it is of any help or not, but I'm using ATWINC1510 module together with LwIP (on multiple NXP platforms). The ATWINC1510 has a passthru mode that lets it interface very nicely with LwIP.

Just a headsup if you look for something else.

0 Kudos
2,592 Views
mspenard603
Contributor IV

Ooo that sounds promising.... Who makes this part?

0 Kudos
2,592 Views
carstengroen
Senior Contributor II

Sorry, its ATWINC1510 (and not WILC....).

And a headsup, you want the version with firmware 19.6.1 (this is a orderable part)

Do a search, not sure about policies here about mentioning other vendors :smileywink:

Otherwise, shoot me a PM

0 Kudos
2,592 Views
mspenard603
Contributor IV

Ah, found it. Any details or code snippets on LWIP integration with its SPI(?) drivers? 

0 Kudos
2,592 Views
carstengroen
Senior Contributor II

Mike, 

some random stuff from one of my projects:

Init of Wifi and LwIP:

 
 tstrWifiInitParam param;
 tstrEthInitParam ethParam;
 int8_t ret;

 memset((uint8_t *)&param, 0, sizeof(tstrWifiInitParam));
 memset((uint8_t *)&ethParam, 0, sizeof(tstrEthInitParam));



 //startWShark("wifi.pcap", LINKTYPE_ETHERNET);
 //startWShark("wifi.pcap", LINKTYPE_RAW);

 ethParam.pfAppEthCb = winc_netif_rx_callback;
 ethParam.au8ethRcvBuf = rx_buf;
 ethParam.u16ethRcvBufSize = PBUF_POOL_BUFSIZE - ETH_PAD_SIZE;
 ethParam.u8EthernetEnable = 1; //For bypassing the TCPIP Stack of WINC
 
 param.strEthInitParam = ethParam;


 // Initialize Wi-Fi driver with data and status callbacks
 param.pfAppWifiCb = wifi_cb;
 nm_bsp_init();

 ret = m2m_wifi_init(&param);
 if (M2M_SUCCESS != ret) {
  messageDebug(DBG_INFO, __MODULE__, __LINE__, "m2m_wifi_init() call error!(%d)", ret);
  os_tsk_delete_self();
 }
 
 OS_WAIT(500);

 messageDebug(DBG_INFO, __MODULE__, __LINE__, "Chip ID : 0x%08X", (unsigned int)nmi_get_chipid());
 messageDebug(DBG_INFO, __MODULE__, __LINE__, "RF Revision ID : 0x%08X", (unsigned int)nmi_get_rfrevid());
 
 uint8_t u8IsMacAddrValid;
 uint8_t mac_addr[M2M_MAC_ADDRES_LEN];
 // Get MAC Address from OTP memory
 m2m_wifi_get_otp_mac_address( (uint8_t *)mac_addr, &u8IsMacAddrValid);
 if (!u8IsMacAddrValid) {
  // Cannot find MAC Address from OTP. Set user define MAC address
  messageDebug(DBG_ERR, __MODULE__, __LINE__, "No valid MAC address!");
 } else {
  // Note - Address should be read from LSB to MSB
  messageDebug(DBG_INFO, __MODULE__, __LINE__, "MAC address: %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
 } 
 
 
 
 // Need to protect this
 sys_lock_tcpip_core();
 /* Add WINC1500 STA interface. */
 netif_add(&winc_netif_sta, &ip_addr, &ip_addr, &ip_addr, 0, cbInitNetIF, tcpip_input);
// netif_set_default(&winc_netif_sta);
 setDefaultNetIFWifiHandler();
 netif_set_status_callback(&winc_netif_sta, cbWifiNetIFStatus);
 netif_set_link_callback(&winc_netif_sta, cbWifiLinkStatus);
 
 netbiosns_init();
 netbiosns_set_name("Peacock");
 sys_unlock_tcpip_core();

Loop passing packets to Wifi device:

  // Handle pending events from network controller
  if (os_sem_wait(semWiFi, 1) != OS_R_TMO)
   m2m_wifi_handle_events(NULL);

  // Needs to be changed to sem/etc
  if (gTX) {
   extern unsigned char tx_buf[];
   ret = m2m_wifi_send_ethernet_pkt(tx_buf, gTX);   
   if (M2M_SUCCESS == ret) {
    //messageDebug(DBG_INFO, __MODULE__, __LINE__, "ETH data transmit, length=%i", gTX);
   } else {
    messageDebug(DBG_ERR, __MODULE__, __LINE__, "Could NOT ETH data transmit, length=%i", gTX);
   }
   gTX=0;
  }
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Callback function for handling packets from WiFi device (and sending them into LwIP:

//---------------------------------------------------------------------------------------
// Receive packets from the winc under HIF thread context.
//---------------------------------------------------------------------------------------
void winc_netif_rx_callback(uint8 msg_type, void * msg, void *ctrl_buf) {
 uint16_t sz;
 uint16_t rem;
 struct pbuf *p;
 uint8_t *b;
 tstrM2mIpCtrlBuf *ctrl = (tstrM2mIpCtrlBuf *)ctrl_buf;

 
 if (msg_type == M2M_WIFI_RESP_ETHERNET_RX_PACKET) {
  
  sz = ctrl->u16DataSize;
  rem = ctrl->u16RemainingDataSize;

  if (sz > sizeof(rx_buf)) {
   messageDebug(DBG_ERR, __MODULE__, __LINE__, "ETH data received, length=%i", sz);
   // Reload memory buffer for further incoming packets
   m2m_wifi_set_receive_buffer(rx_buf, sizeof(rx_buf));
   return;
  } else {
  // messageDebug(DBG_INFO, __MODULE__, __LINE__, "ETH data received, length=%i", sz);
  }

  
  if (!rx_first) {
   rx_first = rx_last = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
   if (rx_first == NULL) {
    LINK_STATS_INC(link.memerr);
    LINK_STATS_INC(link.drop);
    m2m_wifi_set_receive_buffer(rx_buf, sizeof(rx_buf));
    return;
   }
   memcpy(((uint8_t *)rx_first->payload) + ETH_PAD_SIZE, rx_buf, sz);
  }
  p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
  if (rx_first == rx_last) {
#if ETH_PAD_SIZE
   sz += ETH_PAD_SIZE;
#endif // #if ETH_PAD_SIZE
   rx_last->tot_len = sz + rem;
  }
  rx_last->len = sz;
  
 
  // When packet is complete, send it to the right lwIP interface
  if (!rem) {
   if (ERR_OK != winc_netif_sta.input(rx_first, &winc_netif_sta)) {
    pbuf_free(rx_first);
   } else
    newPBufRecordWShark(rx_first);

   LINK_STATS_INC(link.recv);
   rx_first = p;   
  } else {
   if (!p) {
    if (rx_first)
     pbuf_free(rx_first);
    rx_first = 0;
    LINK_STATS_INC(link.memerr);
    LINK_STATS_INC(link.drop);
    // Reload memory buffer for further incoming packets
    m2m_wifi_set_receive_buffer(rx_buf, sizeof(rx_buf));
    return;
   } else {
    p->tot_len = rem;
    rx_last->next = p;
   }
  }
  rx_last = p;
  if (rx_first == rx_last) {
   sz = PBUF_POOL_BUFSIZE - ETH_PAD_SIZE;
   if (rx_first) {
    b = ((uint8_t *)p->payload) + ETH_PAD_SIZE;
   } else {
    b = rx_buf;
   }
  } else {
   b = p->payload;
   sz = PBUF_POOL_BUFSIZE;
  }
  /* Reload memory buffer for further incoming packets. */
  m2m_wifi_set_receive_buffer(b, sz);
 }
}

Again, this is only snippets from the code, its relatively complex to setup, but once done, its working very nicely!

You need to make the BSP layers for the ATWINC device, this is also relatively simple to do.

Regards,

Carsten

0 Kudos