CARPLAY版本整理

This commit is contained in:
2025-01-21 16:49:37 +08:00
commit f0fb64e4e6
26542 changed files with 13719676 additions and 0 deletions

View File

@ -0,0 +1,425 @@
/*
* FreeRTOS+TCP V2.3.2 LTS Patch 1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/******************************************************************************
*
* See the following web page for essential buffer allocation scheme usage and
* configuration details:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
*
******************************************************************************/
/* Standard includes. */
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkInterface.h"
#include "NetworkBufferManagement.h"
/* For an Ethernet interrupt to be able to obtain a network buffer there must
* be at least this number of buffers available. */
#define baINTERRUPT_BUFFER_GET_THRESHOLD ( 3 )
/* A list of free (available) NetworkBufferDescriptor_t structures. */
static List_t xFreeBuffersList;
/* Some statistics about the use of buffers. */
static UBaseType_t uxMinimumFreeNetworkBuffers = 0U;
/* Declares the pool of NetworkBufferDescriptor_t structures that are available
* to the system. All the network buffers referenced from xFreeBuffersList exist
* in this array. The array is not accessed directly except during initialisation,
* when the xFreeBuffersList is filled (as all the buffers are free when the system
* is booted). */
static NetworkBufferDescriptor_t xNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
/* This constant is defined as true to let FreeRTOS_TCP_IP.c know that the
* network buffers have constant size, large enough to hold the biggest Ethernet
* packet. No resizing will be done. */
const BaseType_t xBufferAllocFixedSize = pdTRUE;
/* The semaphore used to obtain network buffers. */
static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
#if ( ipconfigTCP_IP_SANITY != 0 )
static char cIsLow = pdFALSE;
UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
#else
static UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
#endif /* ipconfigTCP_IP_SANITY */
static void prvShowWarnings( void );
/* The user can define their own ipconfigBUFFER_ALLOC_LOCK() and
* ipconfigBUFFER_ALLOC_UNLOCK() macros, especially for use form an ISR. If these
* are not defined then default them to call the normal enter/exit critical
* section macros. */
#if !defined( ipconfigBUFFER_ALLOC_LOCK )
#define ipconfigBUFFER_ALLOC_INIT() do {} while( ipFALSE_BOOL )
#define ipconfigBUFFER_ALLOC_LOCK_FROM_ISR() \
UBaseType_t uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
{
#define ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR() \
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
}
#define ipconfigBUFFER_ALLOC_LOCK() taskENTER_CRITICAL()
#define ipconfigBUFFER_ALLOC_UNLOCK() taskEXIT_CRITICAL()
#endif /* ipconfigBUFFER_ALLOC_LOCK */
/*-----------------------------------------------------------*/
#if ( ipconfigTCP_IP_SANITY != 0 )
/* HT: SANITY code will be removed as soon as the library is stable
* and and ready to become public
* Function below gives information about the use of buffers */
#define WARN_LOW ( 2 )
#define WARN_HIGH ( ( 5 * ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) / 10 )
#endif /* ipconfigTCP_IP_SANITY */
/*-----------------------------------------------------------*/
#if ( ipconfigTCP_IP_SANITY != 0 )
BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t * pxDescr )
{
return ( bIsValidNetworkDescriptor( pxDescr ) != 0 ) &&
( listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxDescr->xBufferListItem ) ) != 0 );
}
/*-----------------------------------------------------------*/
static void prvShowWarnings( void )
{
UBaseType_t uxCount = uxGetNumberOfFreeNetworkBuffers();
if( ( ( cIsLow == 0 ) && ( uxCount <= WARN_LOW ) ) || ( ( cIsLow != 0 ) && ( uxCount >= WARN_HIGH ) ) )
{
cIsLow = !cIsLow;
FreeRTOS_debug_printf( ( "*** Warning *** %s %lu buffers left\n", cIsLow ? "only" : "now", uxCount ) );
}
}
/*-----------------------------------------------------------*/
UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
uint32_t offset = ( uint32_t ) ( ( ( const char * ) pxDesc ) - ( ( const char * ) xNetworkBuffers ) );
if( ( offset >= sizeof( xNetworkBuffers ) ) ||
( ( offset % sizeof( xNetworkBuffers[ 0 ] ) ) != 0 ) )
{
return pdFALSE;
}
return ( UBaseType_t ) ( pxDesc - xNetworkBuffers ) + 1;
}
/*-----------------------------------------------------------*/
#else /* if ( ipconfigTCP_IP_SANITY != 0 ) */
static UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
{
( void ) pxDesc;
return ( UBaseType_t ) pdTRUE;
}
/*-----------------------------------------------------------*/
static void prvShowWarnings( void )
{
}
/*-----------------------------------------------------------*/
#endif /* ipconfigTCP_IP_SANITY */
BaseType_t xNetworkBuffersInitialise( void )
{
BaseType_t xReturn;
uint32_t x;
/* Only initialise the buffers and their associated kernel objects if they
* have not been initialised before. */
if( xNetworkBufferSemaphore == NULL )
{
/* In case alternative locking is used, the mutexes can be initialised
* here */
ipconfigBUFFER_ALLOC_INIT();
xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
configASSERT( xNetworkBufferSemaphore != NULL );
if( xNetworkBufferSemaphore != NULL )
{
vListInitialise( &xFreeBuffersList );
/* Initialise all the network buffers. The buffer storage comes
* from the network interface, and different hardware has different
* requirements. */
vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers );
for( x = 0U; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
{
/* Initialise and set the owner of the buffer list items. */
vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) );
listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] );
/* Currently, all buffers are available for use. */
vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) );
}
uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
}
}
if( xNetworkBufferSemaphore == NULL )
{
xReturn = pdFAIL;
}
else
{
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
TickType_t xBlockTimeTicks )
{
NetworkBufferDescriptor_t * pxReturn = NULL;
BaseType_t xInvalid = pdFALSE;
UBaseType_t uxCount;
/* The current implementation only has a single size memory block, so
* the requested size parameter is not used (yet). */
( void ) xRequestedSizeBytes;
if( xNetworkBufferSemaphore != NULL )
{
/* If there is a semaphore available, there is a network buffer
* available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and
* interrupts. */
ipconfigBUFFER_ALLOC_LOCK();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
if( ( bIsValidNetworkDescriptor( pxReturn ) != pdFALSE_UNSIGNED ) &&
listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) )
{
( void ) uxListRemove( &( pxReturn->xBufferListItem ) );
}
else
{
xInvalid = pdTRUE;
}
}
ipconfigBUFFER_ALLOC_UNLOCK();
if( xInvalid == pdTRUE )
{
/* _RB_ Can printf() be called from an interrupt? (comment
* above says this can be called from an interrupt too) */
/* _HT_ The function shall not be called from an ISR. Comment
* was indeed misleading. Hopefully clear now?
* So the printf()is OK here. */
FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n",
pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) );
pxReturn = NULL;
}
else
{
/* Reading UBaseType_t, no critical section needed. */
uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
/* For stats, latch the lowest number of network buffers since
* booting. */
if( uxMinimumFreeNetworkBuffers > uxCount )
{
uxMinimumFreeNetworkBuffers = uxCount;
}
pxReturn->xDataLength = xRequestedSizeBytes;
#if ( ipconfigTCP_IP_SANITY != 0 )
{
prvShowWarnings();
}
#endif /* ipconfigTCP_IP_SANITY */
#if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
/* make sure the buffer is not linked */
pxReturn->pxNextBuffer = NULL;
}
#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
}
iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
}
else
{
/* lint wants to see at least a comment. */
iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
}
}
return pxReturn;
}
/*-----------------------------------------------------------*/
NetworkBufferDescriptor_t * pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes )
{
NetworkBufferDescriptor_t * pxReturn = NULL;
/* The current implementation only has a single size memory block, so
* the requested size parameter is not used (yet). */
( void ) xRequestedSizeBytes;
/* If there is a semaphore available then there is a buffer available, but,
* as this is called from an interrupt, only take a buffer if there are at
* least baINTERRUPT_BUFFER_GET_THRESHOLD buffers remaining. This prevents,
* to a certain degree at least, a rapidly executing interrupt exhausting
* buffer and in so doing preventing tasks from continuing. */
if( uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) xNetworkBufferSemaphore ) > ( UBaseType_t ) baINTERRUPT_BUFFER_GET_THRESHOLD )
{
if( xSemaphoreTakeFromISR( xNetworkBufferSemaphore, NULL ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and interrupts. */
ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
{
pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
uxListRemove( &( pxReturn->xBufferListItem ) );
}
ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxReturn );
}
}
if( pxReturn == NULL )
{
iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR();
}
return pxReturn;
}
/*-----------------------------------------------------------*/
BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Ensure the buffer is returned to the list of free buffers before the
* counting semaphore is 'given' to say a buffer is available. */
ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
{
vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
}
ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
( void ) xSemaphoreGiveFromISR( xNetworkBufferSemaphore, &xHigherPriorityTaskWoken );
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
return xHigherPriorityTaskWoken;
}
/*-----------------------------------------------------------*/
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
BaseType_t xListItemAlreadyInFreeList;
if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED )
{
FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
}
else
{
/* Ensure the buffer is returned to the list of free buffers before the
* counting semaphore is 'given' to say a buffer is available. */
ipconfigBUFFER_ALLOC_LOCK();
{
{
xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
if( xListItemAlreadyInFreeList == pdFALSE )
{
vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
}
}
}
ipconfigBUFFER_ALLOC_UNLOCK();
if( xListItemAlreadyInFreeList )
{
FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers() ) );
}
else
{
( void ) xSemaphoreGive( xNetworkBufferSemaphore );
prvShowWarnings();
}
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
}
/*-----------------------------------------------------------*/
UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
{
return uxMinimumFreeNetworkBuffers;
}
/*-----------------------------------------------------------*/
UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
{
return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
}
NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
size_t xNewSizeBytes )
{
/* In BufferAllocation_1.c all network buffer are allocated with a
* maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the
* network buffer. */
pxNetworkBuffer->xDataLength = xNewSizeBytes;
return pxNetworkBuffer;
}
/*#endif */ /* ipconfigINCLUDE_TEST_CODE */

View File

@ -0,0 +1,33 @@
/*
* FreeRTOS+TCP V2.3.2 LTS Patch 2
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
;

View File

@ -0,0 +1,32 @@
/*
* FreeRTOS+TCP V2.3.2 LTS Patch 1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/*****************************************************************************
*
* See the following URL for an explanation of this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
*
*****************************************************************************/
__packed

View File

@ -0,0 +1,767 @@
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
* a Media-Independent Interface (MII), or a Reduced Media-Independent Interface (RMII).
* The EMAC can poll for PHY ports on 32 different addresses. Each of the PHY ports
* shall be treated independently.
*
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "phyHandling.h"
#define phyMIN_PHY_ADDRESS 0
#define phyMAX_PHY_ADDRESS 31
#if defined( PHY_LS_HIGH_CHECK_TIME_MS ) || defined( PHY_LS_LOW_CHECK_TIME_MS )
#warning please use the new defines with 'ipconfig' prefix
#endif
#ifndef ipconfigPHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkStatus in the PHY is still high after 15 seconds of not
* receiving packets. */
#define ipconfigPHY_LS_HIGH_CHECK_TIME_MS 15000UL
#endif
#ifndef ipconfigPHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkStatus in the PHY is still low every second. */
#define ipconfigPHY_LS_LOW_CHECK_TIME_MS 1000UL
#endif
/* As the following 3 macro's are OK in most situations, and so they're not
* included in 'FreeRTOSIPConfigDefaults.h'.
* Users can change their values in the project's 'FreeRTOSIPConfig.h'. */
#ifndef phyPHY_MAX_RESET_TIME_MS
#define phyPHY_MAX_RESET_TIME_MS 1000UL
#endif
#ifndef phyPHY_MAX_NEGOTIATE_TIME_MS
#define phyPHY_MAX_NEGOTIATE_TIME_MS 3000UL
#endif
#ifndef phySHORT_DELAY_MS
#define phySHORT_DELAY_MS 50UL
#endif
/* Naming and numbering of basic PHY registers. */
#define phyREG_00_BMCR 0x00U /* Basic Mode Control Register. */
#define phyREG_01_BMSR 0x01U /* Basic Mode Status Register. */
#define phyREG_02_PHYSID1 0x02U /* PHYS ID 1 */
#define phyREG_03_PHYSID2 0x03U /* PHYS ID 2 */
#define phyREG_04_ADVERTISE 0x04U /* Advertisement control reg */
/* Naming and numbering of extended PHY registers. */
#define PHYREG_10_PHYSTS 0x10U /* 16 PHY status register Offset */
#define phyREG_19_PHYCR 0x19U /* 25 RW PHY Control Register */
#define phyREG_1F_PHYSPCS 0x1FU /* 31 RW PHY Special Control Status */
/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
#define phyBMCR_FULL_DUPLEX 0x0100U /* Full duplex. */
#define phyBMCR_AN_RESTART 0x0200U /* Auto negotiation restart. */
#define phyBMCR_ISOLATE 0x0400U /* 1 = Isolates 0 = Normal operation. */
#define phyBMCR_AN_ENABLE 0x1000U /* Enable auto negotiation. */
#define phyBMCR_SPEED_100 0x2000U /* Select 100Mbps. */
#define phyBMCR_RESET 0x8000U /* Reset the PHY. */
/* Bit fields for 'phyREG_19_PHYCR', the 'PHY Control Register'. */
#define PHYCR_MDIX_EN 0x8000U /* Enable Auto MDIX. */
#define PHYCR_MDIX_FORCE 0x4000U /* Force MDIX crossed. */
#define phyBMSR_AN_COMPLETE 0x0020U /* Auto-Negotiation process completed */
#define phyBMSR_LINK_STATUS 0x0004U
#define phyPHYSTS_LINK_STATUS 0x0001U /* PHY Link mask */
#define phyPHYSTS_SPEED_STATUS 0x0002U /* PHY Speed mask */
#define phyPHYSTS_DUPLEX_STATUS 0x0004U /* PHY Duplex mask */
/* Bit fields for 'phyREG_1F_PHYSPCS
* 001 = 10BASE-T half-duplex
* 101 = 10BASE-T full-duplex
* 010 = 100BASE-TX half-duplex
* 110 = 100BASE-TX full-duplex
*/
#define phyPHYSPCS_SPEED_MASK 0x000CU
#define phyPHYSPCS_SPEED_10 0x0004U
#define phyPHYSPCS_FULL_DUPLEX 0x0010U
/*
* Description of all capabilities that can be advertised to
* the peer (usually a switch or router).
*/
#define phyADVERTISE_CSMA 0x0001U /* Supports IEEE 802.3u: Fast Ethernet at 100 Mbit/s */
#define phyADVERTISE_10HALF 0x0020U /* Try for 10mbps half-duplex. */
#define phyADVERTISE_10FULL 0x0040U /* Try for 10mbps full-duplex. */
#define phyADVERTISE_100HALF 0x0080U /* Try for 100mbps half-duplex. */
#define phyADVERTISE_100FULL 0x0100U /* Try for 100mbps full-duplex. */
#define phyADVERTISE_ALL \
( phyADVERTISE_10HALF | phyADVERTISE_10FULL | \
phyADVERTISE_100HALF | phyADVERTISE_100FULL | \
phyADVERTISE_CSMA )
/* Send a reset command to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask );
static BaseType_t xHas_1F_PHYSPCS( uint32_t ulPhyID )
{
BaseType_t xResult;
switch( ulPhyID )
{
case PHY_ID_LAN8720:
case PHY_ID_LAN8742A:
case PHY_ID_KSZ8041:
/*
* case PHY_ID_KSZ8051: // same ID as 8041
* case PHY_ID_KSZ8081: // same ID as 8041
*/
case PHY_ID_KSZ8081MNXIA:
case PHY_ID_KSZ8863:
default:
/* Most PHY's have a 1F_PHYSPCS */
xResult = pdTRUE;
break;
case PHY_ID_DP83848I:
xResult = pdFALSE;
break;
}
return xResult;
}
/*-----------------------------------------------------------*/
static BaseType_t xHas_19_PHYCR( uint32_t ulPhyID )
{
BaseType_t xResult;
switch( ulPhyID )
{
case PHY_ID_LAN8742A:
case PHY_ID_DP83848I:
xResult = pdTRUE;
break;
default:
/* Most PHY's do not have a 19_PHYCR */
xResult = pdFALSE;
break;
}
return xResult;
}
/*-----------------------------------------------------------*/
/* Initialise the struct and assign a PHY-read and -write function. */
void vPhyInitialise( EthernetPhy_t * pxPhyObject,
xApplicationPhyReadHook_t fnPhyRead,
xApplicationPhyWriteHook_t fnPhyWrite )
{
memset( ( void * ) pxPhyObject, 0, sizeof( *pxPhyObject ) );
pxPhyObject->fnPhyRead = fnPhyRead;
pxPhyObject->fnPhyWrite = fnPhyWrite;
}
/*-----------------------------------------------------------*/
/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
BaseType_t xPhyDiscover( EthernetPhy_t * pxPhyObject )
{
BaseType_t xPhyAddress;
pxPhyObject->xPortCount = 0;
for( xPhyAddress = phyMIN_PHY_ADDRESS; xPhyAddress <= phyMAX_PHY_ADDRESS; xPhyAddress++ )
{
uint32_t ulLowerID;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_03_PHYSID2, &ulLowerID );
/* A valid PHY id can not be all zeros or all ones. */
if( ( ulLowerID != ( uint16_t ) ~0U ) && ( ulLowerID != ( uint16_t ) 0U ) )
{
uint32_t ulUpperID;
uint32_t ulPhyID;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_02_PHYSID1, &ulUpperID );
ulPhyID = ( ( ( uint32_t ) ulUpperID ) << 16 ) | ( ulLowerID & 0xFFF0 );
pxPhyObject->ucPhyIndexes[ pxPhyObject->xPortCount ] = xPhyAddress;
pxPhyObject->ulPhyIDs[ pxPhyObject->xPortCount ] = ulPhyID;
pxPhyObject->xPortCount++;
/* See if there is more storage space. */
if( pxPhyObject->xPortCount == ipconfigPHY_MAX_PORTS )
{
break;
}
}
}
if( pxPhyObject->xPortCount > 0 )
{
FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
}
return pxPhyObject->xPortCount;
}
/*-----------------------------------------------------------*/
/* Send a reset command to a set of PHY-ports. */
static uint32_t xPhyReset( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask )
{
uint32_t ulDoneMask, ulConfig;
TickType_t xRemainingTime;
TimeOut_t xTimer;
BaseType_t xPhyIndex;
/* A bit-mask of PHY ports that are ready. */
ulDoneMask = 0UL;
/* Set the RESET bits high. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Read Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig | phyBMCR_RESET );
}
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_RESET_TIME_MS );
vTaskSetTimeOutState( &xTimer );
/* The reset should last less than a second. */
for( ; ; )
{
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
if( ( ulConfig & phyBMCR_RESET ) == 0 )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET %d ready\n", ( int ) xPhyIndex ) );
ulDoneMask |= ( 1UL << xPhyIndex );
}
}
if( ulDoneMask == ulPhyMask )
{
break;
}
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
break;
}
/* Block for a while */
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
}
/* Clear the reset bits. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
if( ( ulDoneMask & ( 1UL << xPhyIndex ) ) == 0UL )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* The reset operation timed out, clear the bit manually. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
}
}
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
return ulDoneMask;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
const PhyProperties_t * pxPhyProperties )
{
uint32_t ulConfig, ulAdvertise;
BaseType_t xPhyIndex;
if( pxPhyObject->xPortCount < 1 )
{
FreeRTOS_printf( ( "xPhyConfigure: No PHY's detected.\n" ) );
return -1;
}
/* The expected ID for the 'LAN8742A' is 0x0007c130. */
/* The expected ID for the 'LAN8720' is 0x0007c0f0. */
/* The expected ID for the 'DP83848I' is 0x20005C90. */
/* Set advertise register. */
if( ( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_AUTO ) && ( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_AUTO ) )
{
ulAdvertise = phyADVERTISE_ALL;
/* Reset auto-negotiation capability. */
}
else
{
/* Always select protocol 802.3u. */
ulAdvertise = phyADVERTISE_CSMA;
if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_AUTO )
{
if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_100FULL;
}
else
{
ulAdvertise |= phyADVERTISE_10HALF | phyADVERTISE_100HALF;
}
}
else if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_AUTO )
{
if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_10 )
{
ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_10HALF;
}
else
{
ulAdvertise |= phyADVERTISE_100FULL | phyADVERTISE_100HALF;
}
}
else if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_100 )
{
if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_100FULL;
}
else
{
ulAdvertise |= phyADVERTISE_100HALF;
}
}
else
{
if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL )
{
ulAdvertise |= phyADVERTISE_10FULL;
}
else
{
ulAdvertise |= phyADVERTISE_10HALF;
}
}
}
/* Send a reset command to a set of PHY-ports. */
xPhyReset( pxPhyObject, xPhyGetMask( pxPhyObject ) );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
/* Write advertise register. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, ulAdvertise );
/*
* AN_EN AN1 AN0 Forced Mode
* 0 0 0 10BASE-T, Half-Duplex
* 0 0 1 10BASE-T, Full-Duplex
* 0 1 0 100BASE-TX, Half-Duplex
* 0 1 1 100BASE-TX, Full-Duplex
* AN_EN AN1 AN0 Advertised Mode
* 1 0 0 10BASE-T, Half/Full-Duplex
* 1 0 1 100BASE-TX, Half/Full-Duplex
* 1 1 0 10BASE-T Half-Duplex
* 100BASE-TX, Half-Duplex
* 1 1 1 10BASE-T, Half/Full-Duplex
* 100BASE-TX, Half/Full-Duplex
*/
/* Read Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
ulConfig &= ~( phyBMCR_SPEED_100 | phyBMCR_FULL_DUPLEX );
ulConfig |= phyBMCR_AN_ENABLE;
if( ( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_AUTO ) )
{
ulConfig |= phyBMCR_SPEED_100;
}
else if( pxPhyProperties->ucSpeed == ( uint8_t ) PHY_SPEED_10 )
{
ulConfig &= ~phyBMCR_SPEED_100;
}
if( ( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_AUTO ) )
{
ulConfig |= phyBMCR_FULL_DUPLEX;
}
else if( pxPhyProperties->ucDuplex == ( uint8_t ) PHY_DUPLEX_HALF )
{
ulConfig &= ~phyBMCR_FULL_DUPLEX;
}
if( xHas_19_PHYCR( ulPhyID ) )
{
uint32_t ulPhyControl;
/* Read PHY Control register. */
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_19_PHYCR, &ulPhyControl );
/* Clear bits which might get set: */
ulPhyControl &= ~( PHYCR_MDIX_EN | PHYCR_MDIX_FORCE );
if( pxPhyProperties->ucMDI_X == PHY_MDIX_AUTO )
{
ulPhyControl |= PHYCR_MDIX_EN;
}
else if( pxPhyProperties->ucMDI_X == PHY_MDIX_CROSSED )
{
/* Force direct link = Use crossed RJ45 cable. */
ulPhyControl &= ~PHYCR_MDIX_FORCE;
}
else
{
/* Force crossed link = Use direct RJ45 cable. */
ulPhyControl |= PHYCR_MDIX_FORCE;
}
/* update PHY Control Register. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl );
}
FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
}
/* Keep these values for later use. */
pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;
pxPhyObject->ulACRValue = ulAdvertise;
return 0;
}
/*-----------------------------------------------------------*/
/* xPhyFixedValue(): this function is called in case auto-negotiation is disabled.
* The caller has set the values in 'xPhyPreferences' (ucDuplex and ucSpeed).
* The PHY register phyREG_00_BMCR will be set for every connected PHY that matches
* with ulPhyMask. */
BaseType_t xPhyFixedValue( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask )
{
BaseType_t xPhyIndex;
uint32_t ulValue, ulBitMask = ( uint32_t ) 1U;
ulValue = ( uint32_t ) 0U;
if( pxPhyObject->xPhyPreferences.ucDuplex == PHY_DUPLEX_FULL )
{
ulValue |= phyBMCR_FULL_DUPLEX;
}
if( pxPhyObject->xPhyPreferences.ucSpeed == PHY_SPEED_100 )
{
ulValue |= phyBMCR_SPEED_100;
}
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( ulPhyMask & ulBitMask ) != 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Enable Auto-Negotiation. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulValue );
}
}
return 0;
}
/*-----------------------------------------------------------*/
/* xPhyStartAutoNegotiation() is the alternative xPhyFixedValue():
* It sets the BMCR_AN_RESTART bit and waits for the auto-negotiation completion
* ( phyBMSR_AN_COMPLETE ). */
BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask )
{
uint32_t xPhyIndex, ulDoneMask, ulBitMask;
uint32_t ulPHYLinkStatus, ulRegValue;
TickType_t xRemainingTime;
TimeOut_t xTimer;
if( ulPhyMask == ( uint32_t ) 0U )
{
return 0;
}
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++ )
{
if( ( ulPhyMask & ( 1lu << xPhyIndex ) ) != 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
/* Enable Auto-Negotiation. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, pxPhyObject->ulACRValue );
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
}
}
xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_NEGOTIATE_TIME_MS );
vTaskSetTimeOutState( &xTimer );
ulDoneMask = 0;
/* Wait until the auto-negotiation will be completed */
for( ; ; )
{
ulBitMask = ( uint32_t ) 1U;
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( ulPhyMask & ulBitMask ) != 0lu )
{
if( ( ulDoneMask & ulBitMask ) == 0lu )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue );
if( ( ulRegValue & phyBMSR_AN_COMPLETE ) != 0 )
{
ulDoneMask |= ulBitMask;
}
}
}
}
if( ulPhyMask == ulDoneMask )
{
break;
}
if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
{
FreeRTOS_printf( ( "xPhyStartAutoNegotiation: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
break;
}
vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
}
if( ulDoneMask != ( uint32_t ) 0U )
{
ulBitMask = ( uint32_t ) 1U;
pxPhyObject->ulLinkStatusMask &= ~( ulDoneMask );
for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
if( ( ulDoneMask & ulBitMask ) == ( uint32_t ) 0U )
{
continue;
}
/* Clear the 'phyBMCR_AN_RESTART' bit. */
pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue );
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue );
if( ( ulRegValue & phyBMSR_LINK_STATUS ) != 0 )
{
ulPHYLinkStatus |= phyBMSR_LINK_STATUS;
pxPhyObject->ulLinkStatusMask |= ulBitMask;
}
else
{
ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
}
if( ulPhyID == PHY_ID_KSZ8081MNXIA )
{
uint32_t ulControlStatus;
pxPhyObject->fnPhyRead( xPhyAddress, 0x1E, &ulControlStatus );
switch( ulControlStatus & 0x07 )
{
case 0x01:
case 0x05:
/* [001] = 10BASE-T half-duplex */
/* [101] = 10BASE-T full-duplex */
/* 10 Mbps. */
ulRegValue |= phyPHYSTS_SPEED_STATUS;
break;
case 0x02:
case 0x06:
/* [010] = 100BASE-TX half-duplex */
/* [110] = 100BASE-TX full-duplex */
break;
}
switch( ulControlStatus & 0x07 )
{
case 0x05:
case 0x06:
/* [101] = 10BASE-T full-duplex */
/* [110] = 100BASE-TX full-duplex */
/* Full duplex. */
ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
break;
case 0x01:
case 0x02:
/* [001] = 10BASE-T half-duplex */
/* [010] = 100BASE-TX half-duplex */
break;
}
}
else if( xHas_1F_PHYSPCS( ulPhyID ) )
{
/* 31 RW PHY Special Control Status */
uint32_t ulControlStatus;
pxPhyObject->fnPhyRead( xPhyAddress, phyREG_1F_PHYSPCS, &ulControlStatus );
ulRegValue = 0;
if( ( ulControlStatus & phyPHYSPCS_FULL_DUPLEX ) != 0 )
{
ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
}
if( ( ulControlStatus & phyPHYSPCS_SPEED_MASK ) == phyPHYSPCS_SPEED_10 )
{
ulRegValue |= phyPHYSTS_SPEED_STATUS;
}
}
else
{
/* Read the result of the auto-negotiation. */
pxPhyObject->fnPhyRead( xPhyAddress, PHYREG_10_PHYSTS, &ulRegValue );
}
FreeRTOS_printf( ( "Autonego ready: %08lx: %s duplex %u mbit %s status\n",
ulRegValue,
( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0 ) ? "high" : "low" ) );
if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t ) 0U )
{
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
}
else
{
pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_HALF;
}
if( ( ulRegValue & phyPHYSTS_SPEED_STATUS ) != 0 )
{
pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_10;
}
else
{
pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_100;
}
}
} /* if( ulDoneMask != ( uint32_t) 0U ) */
return 0;
}
/*-----------------------------------------------------------*/
BaseType_t xPhyCheckLinkStatus( EthernetPhy_t * pxPhyObject,
BaseType_t xHadReception )
{
uint32_t ulStatus, ulBitMask = 1U;
BaseType_t xPhyIndex;
BaseType_t xNeedCheck = pdFALSE;
if( xHadReception > 0 )
{
/* A packet was received. No need to check for the PHY status now,
* but set a timer to check it later on. */
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0UL )
{
pxPhyObject->ulLinkStatusMask |= ulBitMask;
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
xNeedCheck = pdTRUE;
}
}
}
else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
{
/* Frequent checking the PHY Link Status can affect for the performance of Ethernet controller.
* As long as packets are received, no polling is needed.
* Otherwise, polling will be done when the 'xLinkStatusTimer' expires. */
for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
{
BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
if( pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulStatus ) == 0 )
{
if( !!( pxPhyObject->ulLinkStatusMask & ulBitMask ) != !!( ulStatus & phyBMSR_LINK_STATUS ) )
{
if( ( ulStatus & phyBMSR_LINK_STATUS ) != 0 )
{
pxPhyObject->ulLinkStatusMask |= ulBitMask;
}
else
{
pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
}
FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
xNeedCheck = pdTRUE;
}
}
}
vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
if( ( pxPhyObject->ulLinkStatusMask & ( ulBitMask >> 1 ) ) != 0 )
{
/* The link status is high, so don't poll the PHY too often. */
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
/* The link status is low, polling may be done more frequently. */
pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_LOW_CHECK_TIME_MS );
}
}
return xNeedCheck;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,263 @@
/***********************************************************************************************************************
* Copyright (C) 2021 Arkmicro Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : NetworkInterface.c
* Device(s) : RTL8189FTV
* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
***********************************************************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
/*#include "FreeRTOS_DNS.h" */
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "wifi_constants.h"
#include "net_stack_intf.h"
#include "FreeRTOS_ARP.h"
#include "wifi_conf.h"
#include "board.h"
//#define USE_AP 0
//#define DUMP_NETWORK_DATA
//#undef DUMP_NETWORK_DATA
#ifdef WIFI_SUPPORT
#if CONFIG_USB_DEVICE_CDC_NCM
#error "Do not choose USE_USB_DEVICE when use WIFI_SUPPORT"
#endif
#endif
typedef enum
{
eMACInit, /* Must initialise MAC. */
eMACPass, /* Initialisation was successful. */
eMACFailed, /* Initialisation failed. */
} eMAC_INIT_STATUS_TYPE;
static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
extern void cmd_test(const char* temp_uart_buf);
static int InitializeNetwork( void );
int g_ncm_register(const char *name);
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceInitialise ()
* Description : Initialization of Ethernet driver.
* Arguments : none
* Return Value : pdPASS, pdFAIL
**********************************************************************************************************************/
BaseType_t xNetworkInterfaceInitialise( void )
{
BaseType_t xReturn;
if( xMacInitStatus == eMACInit )
{
//rltk_wlan_set_netif_info(0, NULL, "00:0c:29:5d:2e:05");
/*
* Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
* Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
*
* InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
*/
if( InitializeNetwork() == pdFALSE )
{
xMacInitStatus = eMACFailed;
}
else
{
/* Indicate that the MAC initialisation succeeded. */
xMacInitStatus = eMACPass;
}
FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
}
if( xMacInitStatus == eMACPass )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
return xReturn;
} /* End of function xNetworkInterfaceInitialise() */
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceOutput ()
* Description : Simple network output interface.
* Arguments : pxDescriptor, xReleaseAfterSend
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
#if CONFIG_USB_DEVICE_CDC_NCM
void gether_send(NetworkBufferDescriptor_t * const pxDescriptor);
#endif
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t xReleaseAfterSend )
{
BaseType_t xReturn = pdFALSE;
#ifdef WIFI_SUPPORT
struct eth_drv_sg sg_list = {0};
#endif
#ifdef DUMP_NETWORK_DATA
if (1) {
int i;
char* tmp = (char *)pxDescriptor->pucEthernetBuffer;
printf("\r\nsend len:%d--> ", pxDescriptor->xDataLength);
for (i = 0; i < pxDescriptor->xDataLength; i++) {
printf("%02x ", tmp[i]);
}printf("send end\r\n");
}
#endif
#ifdef WIFI_SUPPORT
if (!rltk_wlan_running(0)) {
goto exit;
}
sg_list.buf = (unsigned int)pxDescriptor->pucEthernetBuffer;
sg_list.len = (unsigned int)pxDescriptor->xDataLength;
xReturn = (BaseType_t)rltk_wlan_send(0, &sg_list, 1, pxDescriptor->xDataLength);
#endif
xReturn = pdTRUE;
#if CONFIG_USB_DEVICE_CDC_NCM
NetworkBufferDescriptor_t *pxDescriptor_eth = pxDescriptor;
if (!xReleaseAfterSend) {
pxDescriptor_eth = pxDuplicateNetworkBufferWithDescriptor(pxDescriptor, pxDescriptor->xDataLength);
xReleaseAfterSend = pdFALSE;
} else {
xReleaseAfterSend = pdFALSE;//release at usb net driver
}
//print_hex(pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, NULL);
gether_send(pxDescriptor_eth);
#else
#ifdef WIFI_SUPPORT
exit:
#endif
#endif
if( xReleaseAfterSend != pdFALSE )
{
/* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
* buffer. The Ethernet buffer is therefore no longer needed, and must be
* freed for re-use. */
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
return xReturn;
} /* End of function xNetworkInterfaceOutput() */
/***********************************************************************************************************************
* Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
* Description : .
* Arguments : pxNetworkBuffers
* Return Value : none
**********************************************************************************************************************/
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
/***********************************************************************************************************************
* Function Name: InitializeNetwork ()
* Description :
* Arguments : none
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
#include "wifi_structures.h"
#if 0
static rtw_result_t ark_rtw_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result )
{
char bssid[32] = {0};
char *ptr = (char *)malloced_scan_result->ap_details.BSSID.octet;
sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
printf("\r\nSSID:%s Bssid:%s Signal strength:%d DB\r\n", malloced_scan_result->ap_details.SSID.val, bssid,
malloced_scan_result->ap_details.signal_strength);
if (malloced_scan_result->scan_complete != 0) {
printf("scan complete!\r\n");
scan_comp_flag = 1;
}
return 0;
}
#endif
static int InitializeNetwork( void )
{
BaseType_t return_code = pdTRUE;
#if CONFIG_USB_DEVICE_CDC_NCM
g_ncm_register("ncm");
#endif
return return_code;
} /* End of function InitializeNetwork() */
/***********************************************************************************************************************
* End of file "NetworkInterface.c"
**********************************************************************************************************************/
static UBaseType_t ulNextRand;
BaseType_t xTotalSuccess = 0;
UBaseType_t uxRand( void )
{
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
ulNextRand = portGET_RUN_TIME_COUNTER_VALUE();
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
}
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort )
{
( void ) ulSourceAddress;
( void ) usSourcePort;
( void ) ulDestinationAddress;
( void ) usDestinationPort;
return uxRand();
}
BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
{
*( pulNumber ) = uxRand();
return pdTRUE;
}
#if 0
void vApplicationPingReplyHook( ePingReplyStatus_t eStatus,
uint16_t usIdentifier )
{
//if( eStatus == eSuccess )
{
FreeRTOS_printf( ( "Ping response received. ID: %d\r\n", usIdentifier ) );
printf("Ping response received. ID: %d\r\n", usIdentifier);
/* Increment successful ping replies. */
xTotalSuccess++;
}
}
#endif

View File

@ -0,0 +1,281 @@
/***********************************************************************************************************************
* Copyright (C) 2021 Arkmicro Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : NetworkInterface.c
* Device(s) : RTL8189FTV
* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
***********************************************************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
/*#include "FreeRTOS_DNS.h" */
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "wifi_constants.h"
#include "net_stack_intf.h"
#define USE_AP 0
//#define DUMP_NETWORK_DATA
#undef DUMP_NETWORK_DATA
typedef enum
{
eMACInit, /* Must initialise MAC. */
eMACPass, /* Initialisation was successful. */
eMACFailed, /* Initialisation failed. */
} eMAC_INIT_STATUS_TYPE;
static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
extern void cmd_test(const char* temp_uart_buf);
static int InitializeNetwork( void );
static int scan_comp_flag = 0;
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceInitialise ()
* Description : Initialization of Ethernet driver.
* Arguments : none
* Return Value : pdPASS, pdFAIL
**********************************************************************************************************************/
BaseType_t xNetworkInterfaceInitialise( void )
{
BaseType_t xReturn;
if( xMacInitStatus == eMACInit )
{
//rltk_wlan_set_netif_info(0, NULL, "00:0c:29:5d:2e:05");
/*
* Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
* Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
*
* InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
*/
if( InitializeNetwork() == pdFALSE )
{
xMacInitStatus = eMACFailed;
}
else
{
/* Indicate that the MAC initialisation succeeded. */
xMacInitStatus = eMACPass;
}
FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
}
if( xMacInitStatus == eMACPass )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
return xReturn;
} /* End of function xNetworkInterfaceInitialise() */
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceOutput ()
* Description : Simple network output interface.
* Arguments : pxDescriptor, xReleaseAfterSend
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t xReleaseAfterSend )
{
BaseType_t xReturn = pdFALSE;
struct eth_drv_sg sg_list = {0};
if (xCheckLoopback( pxDescriptor, xReleaseAfterSend ) != 0 ) {
return pdTRUE;
}
if (!rltk_wlan_running(0)) {
return pdFALSE;
}
sg_list.buf = (unsigned int)pxDescriptor->pucEthernetBuffer;
sg_list.len = (unsigned int)pxDescriptor->xDataLength;
#ifdef DUMP_NETWORK_DATA
if (1) {
int i;
char* tmp = (char *)pxDescriptor->pucEthernetBuffer;
printf("\r\n send:");
for (i = 0; i < sg_list.len; i++) {
printf("%02x ", tmp[i]);
}printf("send end\r\n");
}
#endif
xReturn = (BaseType_t)rltk_wlan_send(0, &sg_list, 1, pxDescriptor->xDataLength);
xReturn = pdTRUE;
if( xReleaseAfterSend != pdFALSE )
{
/* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
* buffer. The Ethernet buffer is therefore no longer needed, and must be
* freed for re-use. */
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
return xReturn;
} /* End of function xNetworkInterfaceOutput() */
/***********************************************************************************************************************
* Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
* Description : .
* Arguments : pxNetworkBuffers
* Return Value : none
**********************************************************************************************************************/
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
/***********************************************************************************************************************
* Function Name: InitializeNetwork ()
* Description :
* Arguments : none
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
#include "wifi_structures.h"
static rtw_result_t ark_rtw_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result )
{
char bssid[32] = {0};
char *ptr = malloced_scan_result->ap_details.BSSID.octet;
sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
printf("\r\nSSID:%s Bssid:%s Signal strength:%d DB\r\n", malloced_scan_result->ap_details.SSID.val, bssid,
malloced_scan_result->ap_details.signal_strength);
if (malloced_scan_result->scan_complete != 0) {
printf("scan complete!\r\n");
scan_comp_flag = 1;
}
}
extern struct sdio_func *wifi_sdio_func;
int ark_wlan_init(void)
{
int return_code = 0;
char *ssid = "ap630";
//rltk_wlan_ctx_init();
#if USE_AP
/*if (wifi_on(RTW_MODE_AP) < 0) {
printf("\r\nopen wifi failed \r\n");
return return_code;
}
printf("\r\n wifi init finished!\r\n");*/
//wifi_start_ap(ssid, RTW_SECURITY_OPEN, NULL, strlen(ssid), 0, 1);
cmd_test("wifi_ap ap630 1");
printf("\r\n wifi start now!\r\n");
#else
//cmd_test("wifi_debug set_mac 000C295D2E05");//0x00, 0x0c, 0x29, 0x5d, 0x2e, 0x05
if (wifi_on(RTW_MODE_STA) < 0) {
printf("\r\nopen wifi failed \r\n");
return return_code;
}
scan_comp_flag = 0;
//wifi_set_mac_address("000c295d2e03");
wifi_scan_networks(ark_rtw_scan_result_handler, NULL);
while(scan_comp_flag == 0)
mdelay(500);
ssid = "ark-9528";
cmd_test("wifi_connect ark-9528 02345678");
#endif
return_code = 1;
return return_code;
}
static int InitializeNetwork( void )
{
BaseType_t return_code = pdFALSE;
return pdTRUE;
} /* End of function InitializeNetwork() */
/***********************************************************************************************************************
* End of file "NetworkInterface.c"
**********************************************************************************************************************/
static UBaseType_t ulNextRand;
BaseType_t xTotalSuccess = 0;
UBaseType_t uxRand( void )
{
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
ulNextRand = portGET_RUN_TIME_COUNTER_VALUE();
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
}
/*-----------------------------------------------------------*/
static void prvSRand( UBaseType_t ulSeed )
{
ulNextRand = ulSeed;
}
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort )
{
( void ) ulSourceAddress;
( void ) usSourcePort;
( void ) ulDestinationAddress;
( void ) usDestinationPort;
return uxRand();
}
BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
{
*( pulNumber ) = uxRand();
return pdTRUE;
}
void vApplicationPingReplyHook( ePingReplyStatus_t eStatus,
uint16_t usIdentifier )
{
//if( eStatus == eSuccess )
{
FreeRTOS_printf( ( "Ping response received. ID: %d\r\n", usIdentifier ) );
printf("Ping response received. ID: %d\r\n", usIdentifier);
/* Increment successful ping replies. */
xTotalSuccess++;
}
}

View File

@ -0,0 +1,108 @@
/*
* FreeRTOS V1.4.8
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/**
* @file aws_wifi_config.h
* @brief WiFi module configuration parameters.
*/
#ifndef _AWS_WIFI_CONFIG_H_
#define _AWS_WIFI_CONFIG_H_
/**
* @brief Maximum number of sockets that can be created simultaneously.
*/
#define wificonfigMAX_SOCKETS ( 4 )
/**
* @brief Maximum number of connection retries.
*/
#define wificonfigNUM_CONNECTION_RETRY ( 3 )
/**
* @brief Maximum number of connected station in Access Point mode.
*/
#define wificonfigMAX_CONNECTED_STATIONS ( 4 )
/**
* @brief Max number of network profiles stored in Non Volatile memory,
* set to zero if not supported.
*/
#define wificonfigMAX_NETWORK_PROFILES ( 0 )
/**
* @brief Max SSID length
*/
#define wificonfigMAX_SSID_LEN ( 32 )
/**
* @brief Max BSSID length
*/
#define wificonfigMAX_BSSID_LEN ( 6 )
/**
* @brief Max number of WEP keys supported.
*/
#define wificonfigMAX_WEPKEYS ( 4 )
/**
* @brief Max WEP key length
*/
#define wificonfigMAX_WEPKEY_LEN ( 26 )
/**
* @brief Max passphrase length
*/
#define wificonfigMAX_PASSPHRASE_LEN ( 32 )
/**
* @brief Soft Access point SSID
*/
#define wificonfigACCESS_POINT_SSID_PREFIX ( "Enter SSID for Soft AP" )
/**
* @brief Soft Access point Passkey
*/
#define wificonfigACCESS_POINT_PASSKEY ( "Enter Password for Soft AP" )
/**
* @brief Soft Access point Channel
*/
#define wificonfigACCESS_POINT_CHANNEL ( 11 )
/**
* @brief WiFi semaphore timeout
*/
#define wificonfigMAX_SEMAPHORE_WAIT_TIME_MS ( 60000 )
/**
* @brief Soft Access point security
* WPA2 Security, see WIFISecurity_t
* other values are - eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA
*/
#define wificonfigACCESS_POINT_SECURITY ( eWiFiSecurityWPA2 )
#endif /* _AWS_WIFI_CONFIG_H_ */

View File

@ -0,0 +1,724 @@
/*
* FreeRTOS Wi-Fi V1.0.0
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/**
* @file iot_wifi.c
* @brief Wi-Fi Interface.
*/
#include <stdbool.h>
/* Socket and Wi-Fi interface includes. */
#include "FreeRTOS.h"
#include "iot_wifi.h"
/* Wi-Fi configuration includes. */
#include "aws_wifi_config.h"
#include "wifi_constants.h"
#include "net_stack_intf.h"
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "semphr.h"
#include "wifi_structures.h"
static rtw_mode_t g_wifi_mode = RTW_MODE_STA;
static SemaphoreHandle_t xWiFiSem;
static bool wifi_started;
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_On( void )
{
WIFIReturnCode_t ret = eWiFiFailure;
xSemaphoreTake(xWiFiSem, portMAX_DELAY );
if (wifi_started) {
ret = eWiFiSuccess;
goto exit;
}
if (wifi_on(g_wifi_mode) < 0) {
printf("\r\nopen wifi failed \r\n");
goto exit;
}
wifi_started = true;
ret = eWiFiSuccess;
exit:
xSemaphoreGive(xWiFiSem);
return ret;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_Off( void )
{
xSemaphoreTake(xWiFiSem, portMAX_DELAY );
wifi_off();
wifi_started = false;
xSemaphoreGive(xWiFiSem);
return eWiFiSuccess;
}
/*-----------------------------------------------------------*/
static rtw_security_t convertWIFISecurity2rtw_security(WIFISecurity_t type)
{
rtw_security_t security_type = RTW_MODE_NONE;
switch (type) {
case eWiFiSecurityOpen:
security_type = RTW_SECURITY_OPEN;
break;
case eWiFiSecurityWPA2:
security_type = RTW_SECURITY_WPA2_AES_PSK;
break;
default:
security_type = RTW_SECURITY_UNKNOWN;
break;
}
return security_type;
}
static WIFISecurity_t convertrtw_security2WIFISecurity(rtw_security_t type)
{
WIFISecurity_t security_type = eWiFiSecurityNotSupported;
switch (type) {
case RTW_SECURITY_OPEN:
security_type = eWiFiSecurityOpen;
break;
case RTW_SECURITY_WPA2_AES_PSK:
security_type = eWiFiSecurityWPA2;
break;
default:
break;
}
return security_type;
}
static rtw_mode_t convertWIFIDevMode2rtwMode(WIFIDeviceMode_t mode)
{
rtw_mode_t rtw_mode = RTW_MODE_NONE;
switch (mode) {
case eWiFiModeStation:
rtw_mode = RTW_MODE_STA;
break;
case eWiFiModeAP:
rtw_mode = RTW_MODE_AP;
break;
case eWiFiModeP2P:
rtw_mode = RTW_MODE_P2P;
break;
case eWiFiModeAPStation:
rtw_mode = RTW_MODE_STA_AP;
break;
case eWiFiModeNotSupported:
rtw_mode = RTW_MODE_NONE;
break;
default:
break;
}
return rtw_mode;
}
static WIFIDeviceMode_t convertrtwMode2WIFIDevMode(rtw_mode_t rtw_mode)
{
WIFIDeviceMode_t dev_mode = eWiFiModeNotSupported;
switch (rtw_mode) {
case RTW_MODE_STA:
dev_mode = eWiFiModeStation;
break;
case RTW_MODE_AP:
dev_mode = eWiFiModeAP;
break;
case RTW_MODE_P2P:
dev_mode = eWiFiModeP2P;
break;
case RTW_MODE_STA_AP:
dev_mode = eWiFiModeAPStation;
break;
case RTW_MODE_NONE:
dev_mode = eWiFiModeNotSupported;
break;
default:
break;
}
return dev_mode;
}
WIFIReturnCode_t WIFI_ConnectAP( const WIFINetworkParams_t * const pxNetworkParams )
{
rtw_security_t security_type;
rtw_result_t ret = RTW_UNSUPPORTED;
if (pxNetworkParams == NULL)
return eWiFiFailure;
xSemaphoreTake(xWiFiSem, portMAX_DELAY );
security_type = convertWIFISecurity2rtw_security(pxNetworkParams->xSecurity);
if (security_type == RTW_SECURITY_WPA2_AES_PSK) {
ret = wifi_connect(pxNetworkParams->ucSSID,
security_type,
pxNetworkParams->xPassword.xWPA.cPassphrase,
pxNetworkParams->ucSSIDLength,
pxNetworkParams->xPassword.xWPA.ucLength, 0, NULL);
} else if (security_type == RTW_SECURITY_OPEN) {
ret = wifi_connect(pxNetworkParams->ucSSID,
security_type,
pxNetworkParams->xPassword.xWPA.cPassphrase,
pxNetworkParams->ucSSIDLength,
RTW_MIN_PSK_LEN, 0, NULL);
}
xSemaphoreGive(xWiFiSem);
if (ret == RTW_TIMEOUT)
return eWiFiTimeout;
else if (ret != RTW_SUCCESS)
return eWiFiFailure;
return eWiFiSuccess;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_Disconnect( void )
{
xSemaphoreTake(xWiFiSem, portMAX_DELAY );
wifi_disconnect();
xSemaphoreGive(xWiFiSem);
return eWiFiSuccess;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_Reset( void )
{
return eWiFiSuccess;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_SetMode( WIFIDeviceMode_t xDeviceMode )
{
WIFIReturnCode_t ret = eWiFiNotSupported;
switch (xDeviceMode) {
case eWiFiModeStation:
ret = eWiFiSuccess;
g_wifi_mode = RTW_MODE_STA;
break;
case eWiFiModeAP:
ret = eWiFiSuccess;
g_wifi_mode = RTW_MODE_AP;
break;
default:
break;
}
return ret;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetMode( WIFIDeviceMode_t * pxDeviceMode )
{
WIFIReturnCode_t ret = eWiFiNotSupported;
if (NULL == pxDeviceMode)
return ret;
switch (g_wifi_mode) {
case RTW_MODE_STA:
ret = eWiFiSuccess;
*pxDeviceMode = eWiFiModeStation;
break;
case RTW_MODE_AP:
ret = eWiFiSuccess;
*pxDeviceMode = eWiFiModeAP;
break;
default:
break;
}
return ret;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_NetworkAdd( const WIFINetworkProfile_t * const pxNetworkProfile,
uint16_t * pusIndex )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_NetworkGet( WIFINetworkProfile_t * pxNetworkProfile,
uint16_t usIndex )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_NetworkDelete( uint16_t usIndex )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_Ping( uint8_t * pucIPAddr,
uint16_t usCount,
uint32_t ulIntervalMS )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetMAC( uint8_t * pucMac )
{
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetHostIP( char * pcHost,
uint8_t * pucIPAddr )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
struct scan_data_ctx
{
WIFIScanResult_t *result;
int index;
int max_num;
bool scan_stop;
QueueHandle_t sem;
};
static rtw_result_t WIFI_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result )
{
char bssid[32] = {0};
WIFIScanResult_t *result;
struct scan_data_ctx* pscan_data = (struct scan_data_ctx*)malloced_scan_result->user_data;
int len;
char *ptr = malloced_scan_result->ap_details.BSSID.octet;
sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
printf("\r\nSSID:%s Bssid:%s Signal strength:%d DB\r\n", malloced_scan_result->ap_details.SSID.val, bssid,
malloced_scan_result->ap_details.signal_strength);
if (pscan_data->scan_stop)
return RTW_SUCCESS;
if (pscan_data->index < pscan_data->max_num) {
result = pscan_data->result + pscan_data->index;
result->ucChannel = malloced_scan_result->ap_details.channel;
result->cRSSI = malloced_scan_result->ap_details.signal_strength;
result->xSecurity = convertrtw_security2WIFISecurity(malloced_scan_result->ap_details.security);
len = wificonfigMAX_SSID_LEN;
if (len < malloced_scan_result->ap_details.SSID.len)
len = malloced_scan_result->ap_details.SSID.len;
memcpy(result->ucSSID, malloced_scan_result->ap_details.SSID.val, len);
len = wificonfigMAX_BSSID_LEN;
if (len != sizeof(malloced_scan_result->ap_details.BSSID.octet))
printf("wrong bssid len\r\n");
memcpy(result->ucBSSID, malloced_scan_result->ap_details.BSSID.octet, len);
}
if (malloced_scan_result->scan_complete != 0) {
printf("scan complete!\r\n");
xQueueSend(pscan_data->sem, NULL, 0);
}
pscan_data->index++;
return RTW_SUCCESS;
}
WIFIReturnCode_t WIFI_Scan( WIFIScanResult_t * pxBuffer,
uint8_t ucNumNetworks )
{
WIFIReturnCode_t ret = eWiFiNotSupported;
struct scan_data_ctx scan_data = {0};
if (!wifi_started)
ret = WIFI_On();
scan_data.index = 0;
scan_data.scan_stop = false;
scan_data.max_num = ucNumNetworks;
scan_data.result = pxBuffer;
scan_data.sem = xQueueCreate(1, 0);
xSemaphoreTake(xWiFiSem, portMAX_DELAY );
wifi_scan_networks(WIFI_scan_result_handler, (void *)&scan_data);
ret = xQueueReceive(scan_data.sem, NULL, portMAX_DELAY);
if( ret != pdPASS ) {
ret = eWiFiFailure;
goto exit;
}
scan_data.scan_stop = true;
vSemaphoreDelete(scan_data.sem);
ret = eWiFiSuccess;
exit:
xSemaphoreGive(xWiFiSem);
return ret;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StartAP( void )
{
WIFIReturnCode_t xWifiStatus;
WIFI_SetMode(eWiFiModeAP);
xWifiStatus = WIFI_On();
return xWifiStatus;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StopAP( void )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_ConfigureAP( const WIFINetworkParams_t * const pxNetworkParams )
{
WIFIReturnCode_t xWifiStatus;
int ret = -1;
if (NULL == pxNetworkParams)
return eWiFiFailure;
if (eWiFiSecurityOpen == pxNetworkParams->xSecurity) {printf("WIFI_ConfigureAP channel:%d\r\n", pxNetworkParams->ucChannel);
ret = wifi_start_ap(pxNetworkParams->ucSSID, RTW_SECURITY_OPEN, NULL,
pxNetworkParams->ucSSIDLength, 0, pxNetworkParams->ucChannel);
} else if (eWiFiSecurityWPA2 == pxNetworkParams->xSecurity) {
ret = wifi_start_ap(pxNetworkParams->ucSSID, RTW_SECURITY_WPA2_AES_PSK,
pxNetworkParams->xPassword.xWPA.cPassphrase,
pxNetworkParams->ucSSIDLength, pxNetworkParams->xPassword.xWPA.ucLength,
pxNetworkParams->ucChannel);
}
if (ret < 0)
xWifiStatus = eWiFiFailure;
else
xWifiStatus = eWiFiSuccess;
return xWifiStatus;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_SetPMMode( WIFIPMMode_t xPMModeType,
const void * pvOptionValue )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetPMMode( WIFIPMMode_t * pxPMModeType,
void * pvOptionValue )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_RegisterEvent( WIFIEventType_t xEventType,
WIFIEventHandler_t xHandler )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
BaseType_t WIFI_IsConnected( const WIFINetworkParams_t * pxNetworkParams )
{
/* FIX ME. */
return pdFALSE;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StartScan( WIFIScanConfig_t * pxScanConfig )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetScanResults( const WIFIScanResult_t ** pxBuffer,
uint16_t * ucNumNetworks )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StartConnectAP( const WIFINetworkParams_t * pxNetworkParams )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StartDisconnect( void )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetConnectionInfo( WIFIConnectionInfo_t * pxConnectionInfo )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetIPInfo( WIFIIPConfiguration_t * pxIPConfig )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetRSSI( int8_t * pcRSSI )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetStationList( WIFIStationInfo_t * pxStationList,
uint8_t * pcStationListSize )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_StartDisconnectStation( uint8_t * pucMac )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_SetMAC( uint8_t * pucMac )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_SetCountryCode( const char * pcCountryCode )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetCountryCode( char * pcCountryCode )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetStatistic( WIFIStatisticInfo_t * pxStats )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
WIFIReturnCode_t WIFI_GetCapability( WIFICapabilityInfo_t * pxCaps )
{
/* FIX ME. */
return eWiFiNotSupported;
}
/*-----------------------------------------------------------*/
int WIFI_Context_init()
{
if (xWiFiSem == NULL)
xWiFiSem = xSemaphoreCreateMutex();
return 0;
}
#define clientcredentialWIFI_SSID "ark-9528"
#define clientcredentialWIFI_PASSWORD "02345678"
#define ucNumNetworks 12
#define serverWIFI_SSID "ap630"
int wifi_sta_test_proc()
{
WIFINetworkParams_t xNetworkParams = {0};
WIFIReturnCode_t xWifiStatus;
WIFI_Context_init();
WIFI_SetMode(eWiFiModeStation);
printf("Turning on wifi...\r\n");
xWifiStatus = WIFI_On();
printf("Checking status...\r\n");
if( xWifiStatus == eWiFiSuccess ) {
printf("WiFi module initialized.\r\n");
} else {
printf("WiFi module failed to initialize.\r\n" );
// Handle module init failure
return -1;
}
/* Some boards might require additional initialization steps to use the Wi-Fi library. */
while (1) {
printf("Starting scan\r\n");
WIFIScanResult_t xScanResults[ ucNumNetworks ] = {0};
xWifiStatus = WIFI_Scan( xScanResults, ucNumNetworks ); // Initiate scan
printf("Scan started\r\n");
// For each scan result, print out the SSID and RSSI
if ( xWifiStatus == eWiFiSuccess ) {
printf("Scan success\r\n");
for ( uint8_t i=0; i<ucNumNetworks; i++ ) {
printf("%s : %d \r\n", xScanResults[i].ucSSID, xScanResults[i].cRSSI);
}
break;
} else {
printf("Scan failed, status code: %d\n", (int)xWifiStatus);
return -1;
}
vTaskDelay(200);
}
/* Setup parameters. */
memset(&xNetworkParams, 0, sizeof(xNetworkParams));
xNetworkParams.ucSSIDLength = strlen( clientcredentialWIFI_SSID );
memcpy(xNetworkParams.ucSSID, clientcredentialWIFI_SSID, xNetworkParams.ucSSIDLength);
xNetworkParams.xPassword.xWPA.ucLength = strlen( clientcredentialWIFI_PASSWORD );
memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, clientcredentialWIFI_PASSWORD, xNetworkParams.ucSSIDLength);
xNetworkParams.xSecurity = eWiFiSecurityWPA2;
// Connect!
xWifiStatus = WIFI_ConnectAP( &( xNetworkParams ) );
if( xWifiStatus == eWiFiSuccess ){
printf( "WiFi Connected to AP.\r\n" );
} else {
printf( "WiFi failed to connect to AP.\r\n" );
// Handle connection failure
return -1;
}
return 0;
}
extern void cmd_test(const char* temp_uart_buf);
int wifi_ap_test_proc()
{
WIFINetworkParams_t xNetworkParams = {0};
WIFIReturnCode_t xWifiStatus;
WIFI_Context_init();
#if 0
WIFI_SetMode(eWiFiModeAP);
printf("Turning on wifi...\r\n");
xWifiStatus = WIFI_On();
vTaskDelay(pdMS_TO_TICKS(1000));
printf("Checking status...\r\n");
if( xWifiStatus == eWiFiSuccess ) {
printf("WiFi module initialized.\r\n");
} else {
printf("WiFi module failed to initialize.\r\n" );
// Handle module init failure
return -1;
}
//xNetworkParams.ucChannel = 1;
//xNetworkParams.ucSSIDLength = (uint8_t)strlen(serverWIFI_SSID);
//memcpy(xNetworkParams.ucSSID, serverWIFI_SSID, strlen(serverWIFI_SSID) + 1);
//xNetworkParams.xSecurity = eWiFiSecurityOpen;
//xWifiStatus = WIFI_ConfigureAP(&xNetworkParams);
//WIFINetworkParams_t *pxNetworkParams = &xNetworkParams;
//printf("WIFI_ConfigureAP channel:%d\r\n", pxNetworkParams->ucChannel);
//wifi_start_ap(pxNetworkParams->ucSSID, RTW_SECURITY_OPEN, NULL,
// pxNetworkParams->ucSSIDLength, 0, pxNetworkParams->ucChannel);
wifi_start_ap("ap630", RTW_SECURITY_OPEN, NULL, 5, 0, 1);
xWifiStatus = eWiFiSuccess;
if( xWifiStatus == eWiFiSuccess ){
printf( "WiFi Configure AP.\r\n" );
} else {
printf( "WiFi failed to Configure AP.\r\n" );
// Handle connection failure
return -1;
}
#else
#if 1
cmd_test("wifi_ap ap630 1");
#else
char *ssid = "ap630";
int channel = 1;
int timeout = 20;
wifi_off();
vTaskDelay(pdMS_TO_TICKS(20));
if (wifi_on(RTW_MODE_AP) < 0) {
printf("\r\nopen wifi failed \r\n");
return -1;
}
printf("\r\n wifi init finished!\r\n");
//wifi_start_ap(ssid, RTW_SECURITY_OPEN, NULL, strlen(ssid), 0, 1);
wifi_start_ap(ssid,
RTW_SECURITY_OPEN,
NULL,
strlen((const char *)ssid),
0,
channel
);
while(1) {
char essid[33];
if(wext_get_ssid("wlan0", (unsigned char *) essid) > 0) {
if(strcmp((const char *) essid, (const char *)ssid) == 0) {
printf("%s started\r\n", ssid);
break;
}
}
if(timeout == 0) {
printf("ERROR: Start AP timeout!\r\n");
break;
}
vTaskDelay(pdMS_TO_TICKS(1000));
timeout --;
}
#endif
#endif
return 0;
}

View File

@ -0,0 +1,571 @@
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2020 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : NetworkInterface.c
* Device(s) : RX
* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
***********************************************************************************************************************/
/***********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* : 07.03.2018 0.1 Development
***********************************************************************************************************************/
/***********************************************************************************************************************
* Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
/*#include "FreeRTOS_DNS.h" */
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "r_ether_rx_if.h"
#include "r_pinset.h"
/***********************************************************************************************************************
* Macro definitions
**********************************************************************************************************************/
#define ETHER_BUFSIZE_MIN 60
#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) || defined( BSP_MCU_RX72M )
#if ETHER_CFG_MODE_SEL == 0
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
#elif ETHER_CFG_MODE_SEL == 1
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
#endif
#elif defined( BSP_MCU_RX63N )
#if ETHER_CFG_MODE_SEL == 0
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
#elif ETHER_CFG_MODE_SEL == 1
#define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
#endif
#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
* receiving packets. */
#define PHY_LS_HIGH_CHECK_TIME_MS 2000
#endif
#ifndef PHY_LS_LOW_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still low every second. */
#define PHY_LS_LOW_CHECK_TIME_MS 1000
#endif
/***********************************************************************************************************************
* Private global variables and functions
**********************************************************************************************************************/
typedef enum
{
eMACInit, /* Must initialise MAC. */
eMACPass, /* Initialisation was successful. */
eMACFailed, /* Initialisation failed. */
} eMAC_INIT_STATUS_TYPE;
static TaskHandle_t ether_receive_check_task_handle = 0;
static TaskHandle_t xTaskToNotify = NULL;
static BaseType_t xPHYLinkStatus;
static BaseType_t xReportedStatus;
static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
static int16_t SendData( uint8_t * pucBuffer,
size_t length );
static int InitializeNetwork( void );
static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
static void clear_all_ether_rx_discriptors( uint32_t event );
int32_t callback_ether_regist( void );
void EINT_Trig_isr( void * );
void get_random_number( uint8_t * data,
uint32_t len );
void prvLinkStatusChange( BaseType_t xStatus );
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceInitialise ()
* Description : Initialization of Ethernet driver.
* Arguments : none
* Return Value : pdPASS, pdFAIL
**********************************************************************************************************************/
BaseType_t xNetworkInterfaceInitialise( void )
{
BaseType_t xReturn;
if( xMacInitStatus == eMACInit )
{
/*
* Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
* Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
*
* InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
*/
if( InitializeNetwork() == pdFALSE )
{
xMacInitStatus = eMACFailed;
}
else
{
/* Indicate that the MAC initialisation succeeded. */
xMacInitStatus = eMACPass;
}
FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
}
if( xMacInitStatus == eMACPass )
{
xReturn = xPHYLinkStatus;
}
else
{
xReturn = pdFAIL;
}
FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
return xReturn;
} /* End of function xNetworkInterfaceInitialise() */
/***********************************************************************************************************************
* Function Name: xNetworkInterfaceOutput ()
* Description : Simple network output interface.
* Arguments : pxDescriptor, xReleaseAfterSend
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
BaseType_t xReleaseAfterSend )
{
BaseType_t xReturn = pdFALSE;
/* Simple network interfaces (as opposed to more efficient zero copy network
* interfaces) just use Ethernet peripheral driver library functions to copy
* data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
* This example assumes SendData() is a peripheral driver library function that
* takes a pointer to the start of the data to be sent and the length of the
* data to be sent as two separate parameters. The start of the data is located
* by pxDescriptor->pucEthernetBuffer. The length of the data is located
* by pxDescriptor->xDataLength. */
if( xPHYLinkStatus != 0 )
{
if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
{
xReturn = pdTRUE;
/* Call the standard trace macro to log the send event. */
iptraceNETWORK_INTERFACE_TRANSMIT();
}
}
else
{
/* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
}
if( xReleaseAfterSend != pdFALSE )
{
/* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
* buffer. The Ethernet buffer is therefore no longer needed, and must be
* freed for re-use. */
vReleaseNetworkBufferAndDescriptor( pxDescriptor );
}
return xReturn;
} /* End of function xNetworkInterfaceOutput() */
/***********************************************************************************************************************
* Function Name: prvEMACDeferredInterruptHandlerTask ()
* Description : The deferred interrupt handler is a standard RTOS task.
* Arguments : pvParameters
* Return Value : none
**********************************************************************************************************************/
static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
{
NetworkBufferDescriptor_t * pxBufferDescriptor;
int32_t xBytesReceived = 0;
/* Avoid compiler warning about unreferenced parameter. */
( void ) pvParameters;
/* Used to indicate that xSendEventStructToIPTask() is being called because
* of an Ethernet receive event. */
IPStackEvent_t xRxEvent;
uint8_t * buffer_pointer;
/* Some variables related to monitoring the PHY. */
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
xTaskToNotify = ether_receive_check_task_handle;
for( ; ; )
{
#if ( ipconfigHAS_PRINTF != 0 )
{
/* Call a function that monitors resources: the amount of free network
* buffers and the amount of free space on the heap. See FreeRTOS_IP.c
* for more detailed comments. */
vPrintResourceStats();
}
#endif /* ( ipconfigHAS_PRINTF != 0 ) */
/* Wait for the Ethernet MAC interrupt to indicate that another packet
* has been received. */
if( xBytesReceived <= 0 )
{
ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
}
/* See how much data was received. */
xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
if( xBytesReceived < 0 )
{
/* This is an error. Logged. */
FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
}
else if( xBytesReceived > 0 )
{
/* Allocate a network buffer descriptor that points to a buffer
* large enough to hold the received frame. As this is the simple
* rather than efficient example the received data will just be copied
* into this buffer. */
pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
if( pxBufferDescriptor != NULL )
{
/* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
* buffer large enough to hold the received data. Copy the
* received data into pcNetworkBuffer->pucEthernetBuffer. Here it
* is assumed ReceiveData() is a peripheral driver function that
* copies the received data into a buffer passed in as the function's
* parameter. Remember! While is is a simple robust technique -
* it is not efficient. An example that uses a zero copy technique
* is provided further down this page. */
memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
/*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
/* Set the actual packet length, in case a larger buffer was returned. */
pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
/* See if the data contained in the received Ethernet frame needs
* to be processed. NOTE! It is preferable to do this in
* the interrupt service routine itself, which would remove the need
* to unblock this task for packets that don't need processing. */
if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
{
/* The event about to be sent to the TCP/IP is an Rx event. */
xRxEvent.eEventType = eNetworkRxEvent;
/* pvData is used to point to the network buffer descriptor that
* now references the received data. */
xRxEvent.pvData = ( void * ) pxBufferDescriptor;
/* Send the data to the TCP/IP stack. */
if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
{
/* The buffer could not be sent to the IP task so the buffer must be released. */
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
/* Make a call to the standard trace macro to log the occurrence. */
iptraceETHERNET_RX_EVENT_LOST();
clear_all_ether_rx_discriptors( 0 );
}
else
{
/* The message was successfully sent to the TCP/IP stack.
* Call the standard trace macro to log the occurrence. */
iptraceNETWORK_INTERFACE_RECEIVE();
R_BSP_NOP();
}
}
else
{
/* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
}
}
else
{
/* The event was lost because a network buffer was not available.
* Call the standard trace macro to log the occurrence. */
iptraceETHERNET_RX_EVENT_LOST();
clear_all_ether_rx_discriptors( 1 );
FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
}
}
if( xBytesReceived > 0 )
{
/* A packet was received. No need to check for the PHY status now,
* but set a timer to check it later on. */
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
/* Indicate that the Link Status is high, so that
* xNetworkInterfaceOutput() can send packets. */
if( xPHYLinkStatus == 0 )
{
xPHYLinkStatus = 1;
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
}
}
else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
{
R_ETHER_LinkProcess( 0 );
if( xPHYLinkStatus != xReportedStatus )
{
xPHYLinkStatus = xReportedStatus;
FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
}
vTaskSetTimeOutState( &xPhyTime );
if( xPHYLinkStatus != 0 )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
else
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
}
}
}
} /* End of function prvEMACDeferredInterruptHandlerTask() */
/***********************************************************************************************************************
* Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
* Description : .
* Arguments : pxNetworkBuffers
* Return Value : none
**********************************************************************************************************************/
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
uint32_t ul;
uint8_t * buffer_address;
R_BSP_SECTION_OPERATORS_INIT( B_ETHERNET_BUFFERS_1 )
buffer_address = R_BSP_SECTOP( B_ETHERNET_BUFFERS_1 );
for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
{
pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
}
} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
/***********************************************************************************************************************
* Function Name: prvLinkStatusChange ()
* Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
* Arguments : xStatus : true when statyus has become high
* Return Value : void
**********************************************************************************************************************/
void prvLinkStatusChange( BaseType_t xStatus )
{
if( xReportedStatus != xStatus )
{
FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
xReportedStatus = xStatus;
}
}
/***********************************************************************************************************************
* Function Name: InitializeNetwork ()
* Description :
* Arguments : none
* Return Value : pdTRUE, pdFALSE
**********************************************************************************************************************/
static int InitializeNetwork( void )
{
ether_return_t eth_ret;
BaseType_t return_code = pdFALSE;
ether_param_t param;
uint8_t myethaddr[ 6 ] =
{
configMAC_ADDR0,
configMAC_ADDR1,
configMAC_ADDR2,
configMAC_ADDR3,
configMAC_ADDR4,
configMAC_ADDR5
}; /*XXX Fix me */
R_ETHER_PinSet_CHANNEL_0();
R_ETHER_Initial();
callback_ether_regist();
param.channel = ETHER_CHANNEL_0;
eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
if( ETHER_SUCCESS != eth_ret )
{
return pdFALSE;
}
eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
if( ETHER_SUCCESS != eth_ret )
{
return pdFALSE;
}
return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
"ETHER_RECEIVE_CHECK_TASK",
512u,
0,
configMAX_PRIORITIES - 1,
&ether_receive_check_task_handle );
if( pdFALSE == return_code )
{
return pdFALSE;
}
return pdTRUE;
} /* End of function InitializeNetwork() */
/***********************************************************************************************************************
* Function Name: SendData ()
* Description :
* Arguments : pucBuffer, length
* Return Value : 0 success, negative fail
**********************************************************************************************************************/
static int16_t SendData( uint8_t * pucBuffer,
size_t length ) /*TODO complete stub function */
{
ether_return_t ret;
uint8_t * pwrite_buffer;
uint16_t write_buf_size;
/* (1) Retrieve the transmit buffer location controlled by the descriptor. */
ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
if( ETHER_SUCCESS == ret )
{
if( write_buf_size >= length )
{
memcpy( pwrite_buffer, pucBuffer, length );
}
if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
{
memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
length = ETHER_BUFSIZE_MIN; /*resize*/
}
ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
}
if( ETHER_SUCCESS != ret )
{
return -5; /* XXX return meaningful value */
}
else
{
return 0;
}
} /* End of function SendData() */
/***********************************************************************************************************************
* Function Name: EINT_Trig_isr
* Description : Standard frame received interrupt handler
* Arguments : ectrl - EDMAC and ETHERC control structure
* Return Value : None
* Note : This callback function is executed when EINT0 interrupt occurred.
***********************************************************************************************************************/
void EINT_Trig_isr( void * ectrl )
{
ether_cb_arg_t * pdecode;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
pdecode = ( ether_cb_arg_t * ) ectrl;
if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
{
if( xTaskToNotify != NULL )
{
vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
}
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
* should be performed to ensure the interrupt returns directly to the highest
* priority task. The macro used for this purpose is dependent on the port in
* use and may be called portEND_SWITCHING_ISR(). */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
/*TODO complete interrupt handler for other events. */
}
} /* End of function EINT_Trig_isr() */
static void clear_all_ether_rx_discriptors( uint32_t event )
{
int32_t xBytesReceived;
uint8_t * buffer_pointer;
/* Avoid compiler warning about unreferenced parameter. */
( void ) event;
while( 1 )
{
/* See how much data was received. */
xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
if( 0 > xBytesReceived )
{
/* This is an error. Ignored. */
}
else if( 0 < xBytesReceived )
{
R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
iptraceETHERNET_RX_EVENT_LOST();
}
else
{
break;
}
}
}
/***********************************************************************************************************************
* End of file "NetworkInterface.c"
**********************************************************************************************************************/

View File

@ -0,0 +1,182 @@
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : ether_callback.c
* Version : ----
* Description : This module solves all the world's problems
***********************************************************************************************************************/
/**********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* : 05.01.2015 ---- Clean up source code.
***********************************************************************************************************************/
/***********************************************************************************************************************
* Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include "r_ether_rx_if.h"
/***********************************************************************************************************************
* Private global variables and functions
***********************************************************************************************************************/
int32_t callback_ether_regist( void );
void callback_ether( void * pparam );
static void callback_wakeon_lan( uint32_t channel );
static void callback_link_on( uint32_t channel );
static void callback_link_off( uint32_t channel );
volatile uint8_t pause_enable = ETHER_FLAG_OFF;
volatile uint8_t magic_packet_detect[ ETHER_CHANNEL_MAX ];
volatile uint8_t link_detect[ ETHER_CHANNEL_MAX ];
void EINT_Trig_isr( void * );
/*
* When that Link Status changes, the following function will be called:
*/
void prvLinkStatusChange( BaseType_t xStatus );
/***********************************************************************************************************************
* Function Name: callback_ether
* Description : Regist of callback function
* Arguments : -
* Return Value : 0: success, -1:failed
***********************************************************************************************************************/
int32_t callback_ether_regist( void )
{
ether_param_t param;
ether_cb_t cb_func;
int32_t ret;
/* Set the callback function (LAN cable connect/disconnect event) */
cb_func.pcb_func = &callback_ether;
param.ether_callback = cb_func;
ret = R_ETHER_Control( CONTROL_SET_CALLBACK, param );
if( ETHER_SUCCESS != ret )
{
return -1;
}
/* Set the callback function (Ether interrupt event) */
cb_func.pcb_int_hnd = &EINT_Trig_isr;
param.ether_callback = cb_func;
ret = R_ETHER_Control( CONTROL_SET_INT_HANDLER, param );
if( ETHER_SUCCESS != ret )
{
return -1;
}
return 0;
} /* End of function callback_ether_regist() */
/***********************************************************************************************************************
* Function Name: callback_ether
* Description : Sample of the callback function
* Arguments : pparam -
*
* Return Value : none
***********************************************************************************************************************/
void callback_ether( void * pparam )
{
ether_cb_arg_t * pdecode;
uint32_t channel;
pdecode = ( ether_cb_arg_t * ) pparam;
channel = pdecode->channel; /* Get Ethernet channel number */
switch( pdecode->event_id )
{
/* Callback function that notifies user to have detected magic packet. */
case ETHER_CB_EVENT_ID_WAKEON_LAN:
callback_wakeon_lan( channel );
break;
/* Callback function that notifies user to have become Link up. */
case ETHER_CB_EVENT_ID_LINK_ON:
callback_link_on( channel );
break;
/* Callback function that notifies user to have become Link down. */
case ETHER_CB_EVENT_ID_LINK_OFF:
callback_link_off( channel );
break;
default:
break;
}
} /* End of function callback_ether() */
/***********************************************************************************************************************
* Function Name: callback_wakeon_lan
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_wakeon_lan( uint32_t channel )
{
if( ETHER_CHANNEL_MAX > channel )
{
magic_packet_detect[ channel ] = 1;
/* Please add necessary processing when magic packet is detected. */
}
} /* End of function callback_wakeon_lan() */
/***********************************************************************************************************************
* Function Name: callback_link_on
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_link_on( uint32_t channel )
{
if( ETHER_CHANNEL_MAX > channel )
{
link_detect[ channel ] = ETHER_FLAG_ON_LINK_ON;
/* Please add necessary processing when becoming Link up. */
prvLinkStatusChange( 1 );
}
} /* End of function callback_link_on() */
/***********************************************************************************************************************
* Function Name: callback_link_off
* Description :
* Arguments : channel -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
static void callback_link_off( uint32_t channel )
{
if( ETHER_CHANNEL_MAX > channel )
{
link_detect[ channel ] = ETHER_FLAG_ON_LINK_OFF;
/* Please add necessary processing when becoming Link down. */
prvLinkStatusChange( 0 );
}
} /* End of function ether_cb_link_off() */
/* End of File */

View File

@ -0,0 +1,64 @@
/*
* FreeRTOS+TCP V2.3.2 LTS Patch 1
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "list.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
* driver will filter incoming packets and only pass the stack those packets it
* considers need processing. */
#if ( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
#else
#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
#endif
BaseType_t xNetworkInterfaceInitialise( void )
{
/* FIX ME. */
return pdFALSE;
}
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer,
BaseType_t xReleaseAfterSend )
{
/* FIX ME. */
return pdFALSE;
}
void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
/* FIX ME. */
}
BaseType_t xGetPhyLinkStatus( void )
{
/* FIX ME. */
return pdFALSE;
}

View File

@ -0,0 +1 @@
Update NetworkInterface.c and include other files needed by FreeRTOS+TCP here.

View File

@ -0,0 +1,128 @@
/*
* Handling of Ethernet PHY's
* PHY's communicate with an EMAC either through
* a Media-Independent Interface (MII), or a Reduced Media-Independent Interface (RMII).
* The EMAC can poll for PHY ports on 32 different addresses. Each of the PHY ports
* shall be treated independently.
*
*/
#ifndef PHYHANDLING_H
#define PHYHANDLING_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ipconfigPHY_MAX_PORTS
/* There can be at most 32 PHY ports, but in most cases there are 4 or less. */
#define ipconfigPHY_MAX_PORTS 4
#endif
/* A generic user-provided function that reads from the PHY-port at 'xAddress'( 0-based ). A 16-bit value shall be stored in
* '*pulValue'. xRegister is the register number ( 0 .. 31 ). In fact all PHY registers are 16-bit.
* Return non-zero in case the action failed. */
typedef BaseType_t ( * xApplicationPhyReadHook_t )( BaseType_t xAddress,
BaseType_t xRegister,
uint32_t * pulValue );
/* A generic user-provided function that writes 'ulValue' to the
* PHY-port at 'xAddress' ( 0-based ). xRegister is the register number ( 0 .. 31 ).
* Return non-zero in case the action failed. */
typedef BaseType_t ( * xApplicationPhyWriteHook_t )( BaseType_t xAddress,
BaseType_t xRegister,
uint32_t ulValue );
typedef struct xPhyProperties
{
uint8_t ucSpeed;
uint8_t ucMDI_X; /* MDI-X : Medium Dependent Interface - Crossover */
uint8_t ucDuplex;
uint8_t ucSpare;
} PhyProperties_t;
typedef struct xEthernetPhy
{
xApplicationPhyReadHook_t fnPhyRead;
xApplicationPhyWriteHook_t fnPhyWrite;
uint32_t ulPhyIDs[ ipconfigPHY_MAX_PORTS ];
uint8_t ucPhyIndexes[ ipconfigPHY_MAX_PORTS ];
TimeOut_t xLinkStatusTimer;
TickType_t xLinkStatusRemaining;
BaseType_t xPortCount;
uint32_t ulBCRValue;
uint32_t ulACRValue;
uint32_t ulLinkStatusMask;
PhyProperties_t xPhyPreferences;
PhyProperties_t xPhyProperties;
} EthernetPhy_t;
/* Some defines used internally here to indicate preferences about speed, MDIX
* (wired direct or crossed), and duplex (half or full). */
/* Values for PhyProperties_t::ucSpeed : */
#define PHY_SPEED_10 1
#define PHY_SPEED_100 2
#define PHY_SPEED_AUTO 3
/* Values for PhyProperties_t::ucMDI_X : */
#define PHY_MDIX_DIRECT 1
#define PHY_MDIX_CROSSED 2
#define PHY_MDIX_AUTO 3
/* Values for PhyProperties_t::ucDuplex : */
#define PHY_DUPLEX_HALF 1
#define PHY_DUPLEX_FULL 2
#define PHY_DUPLEX_AUTO 3
/* ID's of supported PHY's : */
#define PHY_ID_LAN8742A 0x0007c130
#define PHY_ID_LAN8720 0x0007c0f0
#define PHY_ID_KSZ8041 0x000010A1
#define PHY_ID_KSZ8051 0x000010A1
#define PHY_ID_KSZ8081 0x000010A1
#define PHY_ID_KSZ8863 0x00221430
#define PHY_ID_KSZ8081MNXIA 0x00221560
#define PHY_ID_DP83848I 0x20005C90
/* Initialise the struct and assign a PHY-read and -write function. */
void vPhyInitialise( EthernetPhy_t * pxPhyObject,
xApplicationPhyReadHook_t fnPhyRead,
xApplicationPhyWriteHook_t fnPhyWrite );
/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
BaseType_t xPhyDiscover( EthernetPhy_t * pxPhyObject );
/* Send a reset command to the connected PHY ports and send configuration. */
BaseType_t xPhyConfigure( EthernetPhy_t * pxPhyObject,
const PhyProperties_t * pxPhyProperties );
/* Give a command to start auto negotiation on a set of PHY port's. */
BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask );
/* Do not use auto negotiation but use predefined values from 'pxPhyObject->xPhyPreferences'. */
BaseType_t xPhyFixedValue( EthernetPhy_t * pxPhyObject,
uint32_t ulPhyMask );
/* Check the current Link Status.
* 'xHadReception' : make this true if a packet has been received since the
* last call to this function. */
BaseType_t xPhyCheckLinkStatus( EthernetPhy_t * pxPhyObject,
BaseType_t xHadReception );
/* Get the bitmask of a given 'EthernetPhy_t'. */
#define xPhyGetMask( pxPhyObject ) \
( ( ( ( uint32_t ) 1u ) << ( pxPhyObject )->xPortCount ) - 1u )
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef PHYHANDLING_H */

View File

@ -0,0 +1,108 @@
/*
* FreeRTOS V1.4.8
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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.
*
* 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
*/
/**
* @file aws_wifi_config.h
* @brief WiFi module configuration parameters.
*/
#ifndef _AWS_WIFI_CONFIG_H_
#define _AWS_WIFI_CONFIG_H_
/**
* @brief Maximum number of sockets that can be created simultaneously.
*/
#define wificonfigMAX_SOCKETS ( 4 )
/**
* @brief Maximum number of connection retries.
*/
#define wificonfigNUM_CONNECTION_RETRY ( 3 )
/**
* @brief Maximum number of connected station in Access Point mode.
*/
#define wificonfigMAX_CONNECTED_STATIONS ( 4 )
/**
* @brief Max number of network profiles stored in Non Volatile memory,
* set to zero if not supported.
*/
#define wificonfigMAX_NETWORK_PROFILES ( 0 )
/**
* @brief Max SSID length
*/
#define wificonfigMAX_SSID_LEN ( 32 )
/**
* @brief Max BSSID length
*/
#define wificonfigMAX_BSSID_LEN ( 6 )
/**
* @brief Max number of WEP keys supported.
*/
#define wificonfigMAX_WEPKEYS ( 4 )
/**
* @brief Max WEP key length
*/
#define wificonfigMAX_WEPKEY_LEN ( 26 )
/**
* @brief Max passphrase length
*/
#define wificonfigMAX_PASSPHRASE_LEN ( 32 )
/**
* @brief Soft Access point SSID
*/
#define wificonfigACCESS_POINT_SSID_PREFIX ( "Enter SSID for Soft AP" )
/**
* @brief Soft Access point Passkey
*/
#define wificonfigACCESS_POINT_PASSKEY ( "Enter Password for Soft AP" )
/**
* @brief Soft Access point Channel
*/
#define wificonfigACCESS_POINT_CHANNEL ( 11 )
/**
* @brief WiFi semaphore timeout
*/
#define wificonfigMAX_SEMAPHORE_WAIT_TIME_MS ( 60000 )
/**
* @brief Soft Access point security
* WPA2 Security, see WIFISecurity_t
* other values are - eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA
*/
#define wificonfigACCESS_POINT_SECURITY ( eWiFiSecurityWPA2 )
#endif /* _AWS_WIFI_CONFIG_H_ */