MCUXpresso_MIMXRT1021xxxxx/boards/evkmimxrt1020/aws_examples/shadow_enet/main_enet.c

267 lines
8.6 KiB
C

/*
* FreeRTOS V1.0.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. If you wish to use our Amazon
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://aws.amazon.com/freertos
* http://www.FreeRTOS.org
*/
/*******************************************************************************
* Includes
******************************************************************************/
/* SDK Included Files */
#include "fsl_debug_console.h"
#include "ksdk_mbedtls.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
/* FreeRTOS Demo Includes */
#include "FreeRTOS.h"
#include "task.h"
#include "iot_logging_task.h"
#include "iot_system_init.h"
#include "aws_dev_mode_key_provisioning.h"
#include "platform/iot_threads.h"
#include "types/iot_network_types.h"
#include "aws_demo.h"
#include "fsl_silicon_id.h"
#include "fsl_phy.h"
/* lwIP Includes */
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "netif/ethernet.h"
#include "enet_ethernetif.h"
#include "lwip/netifapi.h"
#include "fsl_phyksz8081.h"
#include "fsl_enet_mdio.h"
#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef EXAMPLE_NETIF_INIT_FN
/*! @brief Network interface initialization function. */
#define EXAMPLE_NETIF_INIT_FN ethernetif0_init
#endif /* EXAMPLE_NETIF_INIT_FN */
#define INIT_SUCCESS 0
#define INIT_FAIL 1
/* Address of PHY interface. */
#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS
/* MDIO operations. */
#define EXAMPLE_MDIO_OPS enet_ops
/* PHY operations. */
#define EXAMPLE_PHY_OPS phyksz8081_ops
/* ENET clock frequency. */
#define EXAMPLE_CLOCK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk)
#define LOGGING_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#define LOGGING_TASK_STACK_SIZE (200)
#define LOGGING_QUEUE_LENGTH (16)
#define DEMO_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE * 15)
#define DEMO_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_InitNetwork(void);
/* Declaration of demo function. */
extern int RunDeviceShadowDemo(bool awsIotMqttMode,
const char *pIdentifier,
void *pNetworkServerInfo,
void *pNetworkCredentialInfo,
const IotNetworkInterface_t *pNetworkInterface);
extern int initNetwork(void);
/*******************************************************************************
* Variables
******************************************************************************/
static mdio_handle_t mdioHandle = {.ops = &EXAMPLE_MDIO_OPS};
static phy_handle_t phyHandle = {.phyAddr = EXAMPLE_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_PHY_OPS};
struct netif netif;
static SemaphoreHandle_t sem_ipv4_addr_valid;
NETIF_DECLARE_EXT_CALLBACK(netif_ext_cb_mem);
/*******************************************************************************
* Code
******************************************************************************/
static void netif_ext_cb(struct netif *cb_netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
{
(void)cb_netif;
(void)args;
if (0U != (reason & (netif_nsc_reason_t)LWIP_NSC_IPV4_ADDR_VALID))
{
(void)xSemaphoreGive(sem_ipv4_addr_valid);
}
}
int initNetwork(void)
{
ip4_addr_t netif_ipaddr, netif_netmask, netif_gw;
ethernetif_config_t enet_config = {
.phyHandle = &phyHandle,
#ifdef configMAC_ADDR
.macAddress = configMAC_ADDR,
#endif
};
mdioHandle.resource.csrClock_Hz = EXAMPLE_CLOCK_FREQ;
#ifndef configMAC_ADDR
/* Set special address for each chip. */
(void)SILICONID_ConvertToMacAddr(&enet_config.macAddress);
#endif
IP4_ADDR(&netif_ipaddr, 0, 0, 0, 0);
IP4_ADDR(&netif_netmask, 0, 0, 0, 0);
IP4_ADDR(&netif_gw, 0, 0, 0, 0);
tcpip_init(NULL, NULL);
sem_ipv4_addr_valid = xSemaphoreCreateBinary();
LOCK_TCPIP_CORE();
netif_add_ext_callback(&netif_ext_cb_mem, netif_ext_cb);
UNLOCK_TCPIP_CORE();
netifapi_netif_add(&netif, &netif_ipaddr, &netif_netmask, &netif_gw, &enet_config, EXAMPLE_NETIF_INIT_FN,
tcpip_input);
netifapi_netif_set_default(&netif);
netifapi_netif_set_up(&netif);
configPRINTF(("Getting IP address from DHCP ...\r\n"));
netifapi_dhcp_start(&netif);
struct dhcp *dhcp;
dhcp = (struct dhcp *)netif_get_client_data(&netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
xSemaphoreTake(sem_ipv4_addr_valid, portMAX_DELAY);
if (dhcp->state == DHCP_STATE_BOUND)
{
configPRINTF(("IPv4 Address: %u.%u.%u.%u\r\n", ((u8_t *)&netif.ip_addr.addr)[0],
((u8_t *)&netif.ip_addr.addr)[1], ((u8_t *)&netif.ip_addr.addr)[2],
((u8_t *)&netif.ip_addr.addr)[3]));
}
configPRINTF(("DHCP OK\r\n"));
return INIT_SUCCESS;
}
void BOARD_InitModuleClock(void)
{
const clock_enet_pll_config_t config = {
.enableClkOutput = true, .enableClkOutput500M = false, .enableClkOutput25M = true, .loopDivider = 1};
CLOCK_InitEnetPll(&config);
}
void delay(void)
{
volatile uint32_t i = 0;
for (i = 0; i < 1000000; ++i)
{
__asm("NOP"); /* delay */
}
}
void print_string(const char *string)
{
PRINTF(string);
}
void vApplicationDaemonTaskStartupHook(void)
{
/* A simple example to demonstrate key and certificate provisioning in
* microcontroller flash using PKCS#11 interface. This should be replaced
* by production ready key provisioning mechanism. */
vDevModeKeyProvisioning();
if (SYSTEM_Init() == pdPASS)
{
if (initNetwork() != 0)
{
configPRINTF(("Network init failed, stopping demo.\r\n"));
vTaskDelete(NULL);
}
else
{
static demoContext_t mqttDemoContext = {.networkTypes = AWSIOT_NETWORK_TYPE_ETH,
.demoFunction = RunDeviceShadowDemo,
.networkConnectedCallback = NULL,
.networkDisconnectedCallback = NULL};
Iot_CreateDetachedThread(runDemoTask, &mqttDemoContext, DEMO_TASK_PRIORITY, DEMO_TASK_STACK_SIZE);
}
}
}
int main(void)
{
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
BOARD_InitModuleClock();
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);
GPIO_PinInit(GPIO1, 4, &gpio_config);
GPIO_PinInit(GPIO1, 22, &gpio_config);
/* pull up the ENET_INT before RESET. */
GPIO_WritePinOutput(GPIO1, 22, 1);
GPIO_WritePinOutput(GPIO1, 4, 0);
delay();
GPIO_WritePinOutput(GPIO1, 4, 1);
CRYPTO_InitHardware();
xLoggingTaskInitialize(LOGGING_TASK_STACK_SIZE, LOGGING_TASK_PRIORITY, LOGGING_QUEUE_LENGTH);
vTaskStartScheduler();
for (;;)
;
}
void *pvPortCalloc(size_t xNum, size_t xSize)
{
void *pvReturn;
pvReturn = pvPortMalloc(xNum * xSize);
if (pvReturn != NULL)
{
memset(pvReturn, 0x00, xNum * xSize);
}
return pvReturn;
}