Part Number: AM4376
Other Parts Discussed in Thread: SYSBIOS
Tool/software: TI-RTOS
Hi all
We are making an application Running on AM4376 TI-RTOS. Application's base is 0x80000000, Boot loader runs from 0x90000000 so that it doesn't step on the application.
It's main file is :
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/family/arm/a8/Mmu.h>
#include <ti/ndk/inc/stkmain.h>
#include <ti/drv/emac/emac_drv.h>
#include <ti/drv/emac/src/v4/emac_drv_v4.h>
#include <ti/starterware/include/types.h>
#include <ti/starterware/include/hw/hw_types.h>
#include <ti/starterware/include/hw/hw_control_am43xx.h>
#include <ti/starterware/include/hw/am437x.h>
#include <ti/starterware/include/ethernet.h>
#include <ti/board/board.h>
/* UART Header files */
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
/* GPIO Header files */
#include "FG_gpio.h"
/* GPMC Header files */
#include <ti/csl/src/ip/gpmc/V1/hw_gpmc.h>
#include <ti/drv/gpmc/GPMC.h>
#include <ti/drv/gpmc/src/V1/GPMC_v1.h>
#include <netmain.h>
#include <_stack.h>
#include <_oskern.h>
#include "FGComm.h"
#include "FG_gpmc.h"
#include "FG_edma.h"
#include "GeneralDef.h"
#include "CommandsApi.h"
#include "FgPcCommonDef.h"
#include "FG_FrameServer.h"
#include "ComStateMachine.h"
extern char *LocalIPAddr;
/* Enable the below macro to have prints on the IO Console */
//#define IO_CONSOLE
#ifndef IO_CONSOLE
#define NIMU_log UART_printf
#else
#define NIMU_log printf
#endif
/* ========================================================================== */
/* Macros */
/* ========================================================================== */
/**Phy address of the CPSW port 1*/
#define EMAC_CPSW_PORT0_PHY_ADDR_SK 4
/**Phy address of the CPSW port 2*/
#define EMAC_CPSW_PORT1_PHY_ADDR_SK 5
#define MAX_TABLE_ENTRIES 3
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
/**Task handle for EIP*/
Task_Handle main_task;
static int nimu_device_index = 0U;
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[MAX_TABLE_ENTRIES];
void TaskFxn(UArg a0, UArg a1);
extern int CpswEmacInit (STKEVENT_Handle hEvent);
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
void CpswPortMacModeSelect(uint32_t portNum, uint32_t macMode)
{
uint32_t regVal = 0U;
regVal = HW_RD_REG32(SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL);
switch(macMode)
{
case ETHERNET_MAC_TYPE_MII:
case ETHERNET_MAC_TYPE_GMII:
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RMII: /* RMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RGMII: /* RGMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
default:
break;
}
HW_WR_REG32((SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL), regVal);
}
#define SYS_MMU_BUFFERABLE 1
#define SYS_MMU_CACHEABLE 2
#define SYS_MMU_SHAREABLE 4
#define SYS_MMU_NO_EXECUTE 8
typedef struct _sys_mmu_entry
{
void* address;
/**< Address to be entered in MMU table. */
unsigned int attributes;
/**< Attributes of the memory. */
}SYS_MMU_ENTRY;
SYS_MMU_ENTRY applMmuEntries[] = {
{(void*)0x01000000,SYS_MMU_NO_EXECUTE}, //GPMC Altera cs0 mem space
{(void*)0x02000000,SYS_MMU_NO_EXECUTE}, //GPMC Altera cs1 mem space
{(void*)0x30000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30100000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30200000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30300000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x40300000,0}, //OCMCRAM - Cacheable
{(void*)0x44D00000, SYS_MMU_BUFFERABLE}, //PRCM - Non bufferable| Non Cacheable
{(void*)0x44E00000, SYS_MMU_BUFFERABLE}, //Clock Module, PRM, GPIO0, UART0, I2C0, - Non bufferable| Non Cacheable
{(void*)0x48800000, 0}, //GPIO1
{(void*)0x48300000, 0}, //GPIO5
{(void*)0x47900000,SYS_MMU_BUFFERABLE}, //QSPI MMR Maddr0space
{(void*)0x48000000, SYS_MMU_BUFFERABLE}, //UART1,UART2,I2C1,McSPI0,McASP0 CFG,McASP1 CFG,DMTIMER,GPIO1 -Non bufferable| Non Cacheable
{(void*)0x48100000, SYS_MMU_BUFFERABLE}, //I2C2,McSPI1,UART3,UART4,UART5, GPIO2,GPIO3,MMC1 - Non bufferable| Non Cacheable
{(void*)0x48200000, SYS_MMU_BUFFERABLE}, //
{(void*)0x48300000, SYS_MMU_BUFFERABLE}, //PWM - Non bufferable| Non Cacheable
{(void*)0x49000000, 0}, //EDMA3CC - Non bufferable| Non Cacheable
{(void*)0x4A000000, SYS_MMU_BUFFERABLE}, //L4 FAST CFG- Non bufferable| Non Cacheable
{(void*)0x4A100000, SYS_MMU_BUFFERABLE}, //CPSW - Non bufferable| Non Cacheable
{(void*)0x50000000, 0}, //GPMC - Non bufferable| Non Cacheable
{(void*)0x49800000, 0}, //EDMA TC0
{(void*)0x49900000, 0}, //EDMA TC1
{(void*)0x49A00000, 0}, //EDMA TC2
{(void*)0x54400000, SYS_MMU_BUFFERABLE}, //PRU-ICSS0/1 -Bufferable| Non Cacheable | Shareable
{(void*)0x80000000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80100000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80200000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0xB0000000, 0}, // image buffers
{(void*)0xFFFFFFFF,0xFFFFFFFF}
};
int SDKMMUInit(SYS_MMU_ENTRY mmuEntries[])
{
unsigned short itr = 0;
char *frameAddr = (char *)FRAME_BUFFER_START_ADDRESS;
int nMemBlocks;
Mmu_FirstLevelDescAttrs attrs;
if(NULL == mmuEntries)
return -1;
Mmu_disable();
Mmu_initDescAttrs(&attrs);
attrs.type = Mmu_FirstLevelDesc_SECTION;
attrs.domain = 0;
attrs.imp = 1;
attrs.accPerm = 3;
for(itr = 0 ; mmuEntries[itr].address != (void*)0xFFFFFFFF ; itr++)
{
attrs.bufferable = ((mmuEntries[itr].attributes) & SYS_MMU_BUFFERABLE) && 1 ;
attrs.cacheable = ((mmuEntries[itr].attributes) & SYS_MMU_CACHEABLE) && 1;
if (!attrs.bufferable && !attrs.cacheable)
attrs.tex = 0; //tex is initialized to 1 and need this to force strongly ordered
attrs.shareable = ((mmuEntries[itr].attributes) & SYS_MMU_SHAREABLE) && 1;
attrs.noexecute = ((mmuEntries[itr].attributes) & SYS_MMU_NO_EXECUTE) && 1;
Mmu_setFirstLevelDesc((Ptr)(mmuEntries[itr].address), (Ptr)(mmuEntries[itr].address) , &attrs); // PWM
}
// setup frame buffer memory access -
nMemBlocks = GetFrameBufferMemorySize() / 0x100000 + 1;
attrs.bufferable = 1;
attrs.cacheable = 1;
attrs.shareable = 0;
attrs.noexecute = 0;
for (itr = 0; itr < nMemBlocks; itr++) {
Mmu_setFirstLevelDesc((Ptr)frameAddr, (Ptr)frameAddr, &attrs);
frameAddr += 0x100000;
}
Mmu_enable();
return 0;
}
GPMC_Params gpmcParams; /* GPMC params structure */
GPMC_Handle hwGpmcHandle; /* GPMC handle */
void StartGpmc(void)
{
/* Init GPMC driver */
//GPMC_init();
/* Use default GPMC config params if no params provided */
//GPMC_Params_init(&gpmcParams);
//hwGpmcHandle = (GPMC_Handle)GPMC_open(0, &gpmcParams);
}
/**
* \name main
* \brief Main Function
* \param none
* \return none
*
*/
int main()
{
/* Call board init functions */
Board_initCfg boardCfg;
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
SDKMMUInit(applMmuEntries);
//Mmu_disable();
boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
Board_init(boardCfg);
//int x = *(volatile uint32_t *)0x481AE000;
//if (x != 0x50600801)
// return 0;
FG_GpioInit();
FGgpmcInit();
/* Chip configuration MII/RMII selection */
CpswPortMacModeSelect(1, ETHERNET_MAC_TYPE_RGMII);
CpswPortMacModeSelect(2, ETHERNET_MAC_TYPE_RGMII);
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create (TaskFxn, &taskParams, NULL);
NIMUDeviceTable[nimu_device_index++].init = &CpswEmacInit ;
NIMUDeviceTable[nimu_device_index].init = NULL ;
BIOS_start();
return -1;
}
/**
* \name TaskFxn
* \brief Task which do EIP initialization
* \param a0
* \param a1
* \return none
*
*/
void TaskFxn(UArg a0, UArg a1)
{
int i;
uint32_t baseAddr = 0x50000000 + GPMC_CONFIG1_N(0);
CI_IPNET NA;
char IPString[16];
//NIMU_log("\n\rSYS/BIOS Ethernet/IP (CPSW) Sample application, EVM IP address: %s\n\r", LocalIPAddr);
FG_edmaInit();
for (i=0; i<7; i++)
{
uint32_t val = *(volatile uint32_t *) (baseAddr + i * 4);
NIMU_log("CONFIG%d: %X\n",i + 1, val);
}
baseAddr = *(volatile uint32_t *) (0x0100003C);
NIMU_log("GPMC Date: %X\n",baseAddr);
NIMU_log("Enable GPMC debug mode\n");
// setup debug transfer of frames
//Write2GPMC(0x0100006C, 1); // debug mode
Write2GPMC(0x01000008, 10000); // 10 seconds frame rate
Write2GPMC(0x0100006E, 52); // 52us fifo fill rate
//Write2GPMC(0x01000012, 1); // start transfer
if (CfgGetImmediate( 0, CFGTAG_IPNET, 0, 1, sizeof(NA), (UINT8 *)&NA) == sizeof(NA))
{
/* Yes the device was configured and we got the IP address/Mask */
NtIPN2Str (NA.IPAddr, IPString);
UART_printf ("IP Address : %s\n", IPString);
NtIPN2Str (NA.IPMask, IPString);
UART_printf ("IP Mask : %s\n", IPString);
}
memset(TxMessageBuffer, 0, sizeof(char) * MAX_TX_MESSAGE_SIZE);
for (i = 0; i < NUM_OF_REAL_CAMERAS; i++)
{
SensorInitialization((eCameras)i);
}
//SensorInitialization(CAMERA1);
// Start the frame server
FGInitFrameServer();
// test frame transfer
StartComm();
System_printf("test system printf\n");
printf("test printf\n");
}
// handle exceptions
void FG_Exeption(uint32_t *stack, uint32_t lr)
{
GPIO_write(GPIO_LED1, 1);
}
/*SOCKET TelnetCallback(PSA pSinClient)
{
NIMU_log("\nTelnet opened at socket %d\n", )
}
}*/
char *VerStr = "\nWelcome To EVS console\n";
We built a boot loader which gets the application image from TFTP server and saves it to memory to address 0x8000000 and jumps to it.
The code of boot loader main is:
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/family/arm/a8/Mmu.h>
#include <ti/ndk/inc/stkmain.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/drv/emac/emac_drv.h>
#include <ti/drv/emac/src/v4/emac_drv_v4.h>
#include <ti/starterware/include/types.h>
#include <ti/starterware/include/hw/hw_types.h>
#include <ti/starterware/include/hw/hw_control_am43xx.h>
#include <ti/starterware/include/hw/am437x.h>
#include <ti/starterware/include/ethernet.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/board/board.h>
/* UART Header files */
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
extern char *LocalIPAddr;
/* Enable the below macro to have prints on the IO Console */
//#define IO_CONSOLE
#ifndef IO_CONSOLE
#define NIMU_log UART_printf
#else
#define NIMU_log printf
#endif
/* ========================================================================== */
/* Macros */
/* ========================================================================== */
/**Phy address of the CPSW port 1*/
#define EMAC_CPSW_PORT0_PHY_ADDR_SK 4
/**Phy address of the CPSW port 2*/
#define EMAC_CPSW_PORT1_PHY_ADDR_SK 5
#define MAX_TABLE_ENTRIES 3
#define REMOTE_IP_ADDRESS "193.100.100.251"
#define FG_BASE_ADDRESS 0x80000000
#define MAX_BLOCK_SIZE 65464
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
/**Task handle for EIP*/
Task_Handle main_task;
static int nimu_device_index = 0U;
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[MAX_TABLE_ENTRIES];
static void (*pfnFGAppEntry)();
void TaskFxn(UArg a0, UArg a1);
extern int CpswEmacInit (STKEVENT_Handle hEvent);
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
void CpswPortMacModeSelect(uint32_t portNum, uint32_t macMode)
{
uint32_t regVal = 0U;
regVal = HW_RD_REG32(SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL);
switch(macMode)
{
case ETHERNET_MAC_TYPE_MII:
case ETHERNET_MAC_TYPE_GMII:
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RMII: /* RMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RGMII: /* RGMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
default:
break;
}
HW_WR_REG32((SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL), regVal);
}
#define SYS_MMU_BUFFERABLE 1
#define SYS_MMU_CACHEABLE 2
#define SYS_MMU_SHAREABLE 4
#define SYS_MMU_NO_EXECUTE 8
typedef struct _sys_mmu_entry
{
void* address;
/**< Address to be entered in MMU table. */
unsigned int attributes;
/**< Attributes of the memory. */
}SYS_MMU_ENTRY;
SYS_MMU_ENTRY applMmuEntries[] = {
{(void*)0x30000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30100000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30200000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30300000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x40300000,0}, //OCMCRAM - Cacheable
{(void*)0x44D00000, SYS_MMU_BUFFERABLE}, //PRCM - Non bufferable| Non Cacheable
{(void*)0x44E00000, SYS_MMU_BUFFERABLE}, //Clock Module, PRM, GPIO0, UART0, I2C0, - Non bufferable| Non Cacheable
{(void*)0x47900000,SYS_MMU_BUFFERABLE}, //QSPI MMR Maddr0space
{(void*)0x48000000, SYS_MMU_BUFFERABLE}, //UART1,UART2,I2C1,McSPI0,McASP0 CFG,McASP1 CFG,DMTIMER,GPIO1 -Non bufferable| Non Cacheable
{(void*)0x48100000,0}, //I2C2,McSPI1,UART3,UART4,UART5, GPIO2,GPIO3,MMC1 - Non bufferable| Non Cacheable
{(void*)0x48200000, SYS_MMU_BUFFERABLE}, //
{(void*)0x48300000, SYS_MMU_BUFFERABLE}, //PWM - Non bufferable| Non Cacheable
{(void*)0x49000000, SYS_MMU_BUFFERABLE}, //EDMA3CC - Non bufferable| Non Cacheable
{(void*)0x4A000000, SYS_MMU_BUFFERABLE}, //L4 FAST CFG- Non bufferable| Non Cacheable
{(void*)0x4A100000, SYS_MMU_BUFFERABLE}, //CPSW - Non bufferable| Non Cacheable
{(void*)0x54400000, SYS_MMU_BUFFERABLE}, //PRU-ICSS0/1 -Bufferable| Non Cacheable | Shareable
//{(void*)0x90000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Non bufferable| Non Cacheable
{(void*)0x80000000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80100000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80200000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90000000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90100000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90200000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0xFFFFFFFF,0xFFFFFFFF}
};
int SDKMMUInit(SYS_MMU_ENTRY mmuEntries[])
{
unsigned short itr = 0;
Mmu_FirstLevelDescAttrs attrs;
if(NULL == mmuEntries)
return -1;
Mmu_disable();
Mmu_initDescAttrs(&attrs);
attrs.type = Mmu_FirstLevelDesc_SECTION;
attrs.domain = 0;
attrs.imp = 1;
attrs.accPerm = 3;
for(itr = 0 ; mmuEntries[itr].address != (void*)0xFFFFFFFF ; itr++)
{
attrs.bufferable = ((mmuEntries[itr].attributes) & SYS_MMU_BUFFERABLE) && 1 ;
attrs.cacheable = ((mmuEntries[itr].attributes) & SYS_MMU_CACHEABLE) && 1;
if (!attrs.bufferable && !attrs.cacheable)
attrs.tex = 0; //tex is initialized to 1 and need this to force strongly ordered
attrs.shareable = ((mmuEntries[itr].attributes) & SYS_MMU_SHAREABLE) && 1;
attrs.noexecute = ((mmuEntries[itr].attributes) & SYS_MMU_NO_EXECUTE) && 1;
Mmu_setFirstLevelDesc((Ptr)(mmuEntries[itr].address), (Ptr)(mmuEntries[itr].address) , &attrs); // PWM
}
Mmu_enable();
return 0;
}
/**
* \name main
* \brief Main Function
* \param none
* \return none
*
*/
int main()
{
/* Call board init functions */
Board_initCfg boardCfg;
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
SDKMMUInit(applMmuEntries);
boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
Board_init(boardCfg);
/* Chip configuration MII/RMII selection */
CpswPortMacModeSelect(1, ETHERNET_MAC_TYPE_RGMII);
CpswPortMacModeSelect(2, ETHERNET_MAC_TYPE_RGMII);
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create (TaskFxn, &taskParams, NULL);
NIMUDeviceTable[nimu_device_index++].init = &CpswEmacInit ;
NIMUDeviceTable[nimu_device_index].init = NULL ;
BIOS_start();
return -1;
}
static void jumpStackPointer(uint32_t address)
{
pfnFGAppEntry = (void (*)(void)) address;
(*pfnFGAppEntry)( );
/*__asm(" mov sp, r0\n" // sp is now *address
" bx r0\n" ); // jump to *address */
}
void jumpToApplication(UArg a0, UArg a1)
{
/*
* Disable interrupts
*/
NIMU_log ("All interrupts are disabled\n");
char *p = (char *)(FG_BASE_ADDRESS);
NIMU_log("jump context = 0x%08X\n", *(unsigned int *)p);
NIMU_log("Jumping... \n");
jumpStackPointer(FG_BASE_ADDRESS);
}
/**
* \name TaskFxn
* \brief Task which do EIP initialization
* \param a0
* \param a1
* \return none
*
*/
void TaskFxn(UArg a0, UArg a1)
{
CI_IPNET NA;
char IPString[16];
char *pBuf = (char *)FG_BASE_ADDRESS;
int firmlen, res;
uint16_t errcode;
/* Allocate the file environment for this task */
fdOpenSession( TaskSelf() );
if (CfgGetImmediate( 0, CFGTAG_IPNET, 0, 1, sizeof(NA), (UINT8 *)&NA) == sizeof(NA)) {
/* Yes the device was configured and we got the IP address/Mask */
NtIPN2Str (NA.IPAddr, IPString);
NIMU_log ("IP Address : %s\n", IPString);
NtIPN2Str (NA.IPMask, IPString);
NIMU_log ("IP Mask : %s\n", IPString);
}
/* Wait for the link to come up */
Task_sleep(10000);
while (1) {
firmlen = MAX_BLOCK_SIZE;
res = NtTftpRecv(inet_addr(REMOTE_IP_ADDRESS), "FGBoardProto.bin", pBuf, (UINT32 *)&firmlen, &errcode);
if (res == 0 || res == 1) {
NIMU_log ("Firmware file found with len %d, res is %d\n", firmlen, res);
break;
} else {
NIMU_log ("Error (%d/%d) fetching firmware\n", res, (int)errcode);
}
}
NIMU_log ("Firmware download is complete. Jumping to FW\n");
{
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create(jumpToApplication, &taskParams, NULL);
}
fdCloseSession( TaskSelf() )
TaskDestroy( TaskSelf() );
}
// handle exceptions
void BL_Exception(uint32_t *stack, uint32_t lr)
{
NIMU_log("Exception occurred \n");
}
Boot loader Config file is as such:
/**
* \file nimu_skam437x.cfg
*
* \brief This file is included in the ethernet switch example
*
*/
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* ================ General configuration ================ */
var enableStaticIP = 1;
/* use modules */
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Main = xdc.useModule('xdc.runtime.Main');
var Memory = xdc.useModule('xdc.runtime.Memory')
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var ti_sysbios_hal_Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var SemiHostSupport = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
/* NDK modules */
var Global = xdc.useModule('ti.ndk.config.Global');
var Ip = xdc.useModule('ti.ndk.config.Ip');
var Tcp = xdc.useModule('ti.ndk.config.Tcp');
var Udp = xdc.useModule('ti.ndk.config.Udp');
var Telnet = xdc.useModule('ti.ndk.config.Telnet');
var Exception = xdc.useModule('ti.sysbios.family.arm.exc.Exception');
/*
* Program.argSize sets the size of the .args section.
* The examples don't use command line args so argSize is set to 0.
*/
//Program.argSize = 0x0;
/* System stack size (used by ISRs and Swis) */
Program.stack = 0x10000;
/*
* Uncomment this line to globally disable Asserts.
* All modules inherit the default from the 'Defaults' module. You
* can override these defaults on a per-module basis using Module.common$.
* Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
*/
/*
* Uncomment this line to keep module names from being loaded on the target.
* The module name strings are placed in the .const section. Setting this
* parameter to false will save space in the .const section. Error and
* Assert messages will contain an "unknown module" prefix instead
* of the actual module name.
Defaults.common$.namedModule = false;
*/
/*
* Minimize exit handler array in System. The System module includes
* an array of functions that are registered with System_atexit() to be
* called by System_exit().
*/
System.maxAtexitHandlers = 4;
/*
* Uncomment this line to disable the Error print function.
* We lose error information when this is disabled since the errors are
* not printed. Disabling the raiseHook will save some code space if
* your app is not using System_printf() since the Error_print() function
* calls System_printf().
Error.raiseHook = null;
*/
/*
* Uncomment this line to keep Error, Assert, and Log strings from being
* loaded on the target. These strings are placed in the .const section.
* Setting this parameter to false will save space in the .const section.
* Error, Assert and Log message will print raw ids and args instead of
* a formatted message.
Text.isLoaded = false;
*/
/*
* Uncomment this line to disable the output of characters by SysMin
* when the program exits. SysMin writes characters to a circular buffer.
* This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
*/
/* ================ BIOS configuration ================ */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.libType = BIOS.LibType_Custom;
/*
* The BIOS module will create the default heap for the system.
* Specify the size of this default heap.
*/
BIOS.heapSize = 0xA0000;
if (enableStaticIP)
{
/* Settings for static IP configuration */
Ip.ResolveIP = false;
Ip.CallByIP = false;
Ip.autoIp = false;
Ip.address = "193.100.100.40";
Ip.mask = "255.255.255.0";
Ip.gatewayIpAddr = "193.100.100.251";
}
else
{
Ip.dhcpClientMode = Ip.CIS_FLG_IFIDXVALID;
}
Global.ndkTickPeriod = 100;
Global.kernTaskPriLevel = 11;
Global.serviceReportHook = null;
Global.IPv6 = false;
Global.pktNumFrameBufs=384;
Tcp.transmitBufSize = 16384;
Tcp.receiveBufSize = 65536;
Tcp.receiveBufLimit = 65536;
Task.defaultStackSize = 4096;
Task.idleTaskStackSize = 4096;
System.SupportProxy = SysMin;
/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x200;
/* ================ Driver configuration ================ */
var socType = "am437x";
/* Load the OSAL package */
var osType = "tirtos";
var Osal = xdc.useModule('ti.osal.Settings');
Osal.osType = osType;
Osal.socType = socType;
/* Load the CSL package */
/*use CSL package*/
var Csl = xdc.loadPackage('ti.csl');
Csl.Settings.deviceType = socType;
/* Load the UART package */
var UART = xdc.loadPackage('ti.drv.uart');
UART.Settings.socType = socType;
/* Load the I2C package */
var I2C = xdc.loadPackage('ti.drv.i2c');
/* Load the Board package and set the board name */
var Board = xdc.loadPackage('ti.board');
Board.Settings.boardName = "skAM437x";
/* Load the EMAC packages */
var Emac = xdc.loadPackage('ti.drv.emac');
Emac.Settings.socType = socType;
/* Load the NIMU packages */
var Nimu = xdc.loadPackage('ti.transport.ndk.nimu');
Nimu.Settings.socType = socType;
/* ================ Cache and MMU configuration ================ */
var Cache = xdc.useModule('ti.sysbios.family.arm.a9.Cache');
Cache.enableCache = true;
var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
Mmu.enableMMU = true;
BIOS.logsEnabled = true;
Exception.excHookFunc = "&BL_Exception";
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/family/arm/a8/Mmu.h>
#include <ti/ndk/inc/stkmain.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/drv/emac/emac_drv.h>
#include <ti/drv/emac/src/v4/emac_drv_v4.h>
#include <ti/starterware/include/types.h>
#include <ti/starterware/include/hw/hw_types.h>
#include <ti/starterware/include/hw/hw_control_am43xx.h>
#include <ti/starterware/include/hw/am437x.h>
#include <ti/starterware/include/ethernet.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/board/board.h>
/* UART Header files */
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
extern char *LocalIPAddr;
/* Enable the below macro to have prints on the IO Console */
//#define IO_CONSOLE
#ifndef IO_CONSOLE
#define NIMU_log UART_printf
#else
#define NIMU_log printf
#endif
/* ========================================================================== */
/* Macros */
/* ========================================================================== */
/**Phy address of the CPSW port 1*/
#define EMAC_CPSW_PORT0_PHY_ADDR_SK 4
/**Phy address of the CPSW port 2*/
#define EMAC_CPSW_PORT1_PHY_ADDR_SK 5
#define MAX_TABLE_ENTRIES 3
#define REMOTE_IP_ADDRESS "193.100.100.251"
#define FG_BASE_ADDRESS 0x80000000
#define MAX_BLOCK_SIZE 65464
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
/**Task handle for EIP*/
Task_Handle main_task;
static int nimu_device_index = 0U;
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[MAX_TABLE_ENTRIES];
static void (*pfnFGAppEntry)();
void TaskFxn(UArg a0, UArg a1);
extern int CpswEmacInit (STKEVENT_Handle hEvent);
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
void CpswPortMacModeSelect(uint32_t portNum, uint32_t macMode)
{
uint32_t regVal = 0U;
regVal = HW_RD_REG32(SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL);
switch(macMode)
{
case ETHERNET_MAC_TYPE_MII:
case ETHERNET_MAC_TYPE_GMII:
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RMII: /* RMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RGMII: /* RGMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
default:
break;
}
HW_WR_REG32((SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL), regVal);
}
#define SYS_MMU_BUFFERABLE 1
#define SYS_MMU_CACHEABLE 2
#define SYS_MMU_SHAREABLE 4
#define SYS_MMU_NO_EXECUTE 8
typedef struct _sys_mmu_entry
{
void* address;
/**< Address to be entered in MMU table. */
unsigned int attributes;
/**< Attributes of the memory. */
}SYS_MMU_ENTRY;
SYS_MMU_ENTRY applMmuEntries[] = {
{(void*)0x30000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30100000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30200000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30300000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x40300000,0}, //OCMCRAM - Cacheable
{(void*)0x44D00000, SYS_MMU_BUFFERABLE}, //PRCM - Non bufferable| Non Cacheable
{(void*)0x44E00000, SYS_MMU_BUFFERABLE}, //Clock Module, PRM, GPIO0, UART0, I2C0, - Non bufferable| Non Cacheable
{(void*)0x47900000,SYS_MMU_BUFFERABLE}, //QSPI MMR Maddr0space
{(void*)0x48000000, SYS_MMU_BUFFERABLE}, //UART1,UART2,I2C1,McSPI0,McASP0 CFG,McASP1 CFG,DMTIMER,GPIO1 -Non bufferable| Non Cacheable
{(void*)0x48100000,0}, //I2C2,McSPI1,UART3,UART4,UART5, GPIO2,GPIO3,MMC1 - Non bufferable| Non Cacheable
{(void*)0x48200000, SYS_MMU_BUFFERABLE}, //
{(void*)0x48300000, SYS_MMU_BUFFERABLE}, //PWM - Non bufferable| Non Cacheable
{(void*)0x49000000, SYS_MMU_BUFFERABLE}, //EDMA3CC - Non bufferable| Non Cacheable
{(void*)0x4A000000, SYS_MMU_BUFFERABLE}, //L4 FAST CFG- Non bufferable| Non Cacheable
{(void*)0x4A100000, SYS_MMU_BUFFERABLE}, //CPSW - Non bufferable| Non Cacheable
{(void*)0x54400000, SYS_MMU_BUFFERABLE}, //PRU-ICSS0/1 -Bufferable| Non Cacheable | Shareable
//{(void*)0x90000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Non bufferable| Non Cacheable
{(void*)0x80000000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80100000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80200000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90000000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90100000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90200000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0xFFFFFFFF,0xFFFFFFFF}
};
int SDKMMUInit(SYS_MMU_ENTRY mmuEntries[])
{
unsigned short itr = 0;
Mmu_FirstLevelDescAttrs attrs;
if(NULL == mmuEntries)
return -1;
Mmu_disable();
Mmu_initDescAttrs(&attrs);
attrs.type = Mmu_FirstLevelDesc_SECTION;
attrs.domain = 0;
attrs.imp = 1;
attrs.accPerm = 3;
for(itr = 0 ; mmuEntries[itr].address != (void*)0xFFFFFFFF ; itr++)
{
attrs.bufferable = ((mmuEntries[itr].attributes) & SYS_MMU_BUFFERABLE) && 1 ;
attrs.cacheable = ((mmuEntries[itr].attributes) & SYS_MMU_CACHEABLE) && 1;
if (!attrs.bufferable && !attrs.cacheable)
attrs.tex = 0; //tex is initialized to 1 and need this to force strongly ordered
attrs.shareable = ((mmuEntries[itr].attributes) & SYS_MMU_SHAREABLE) && 1;
attrs.noexecute = ((mmuEntries[itr].attributes) & SYS_MMU_NO_EXECUTE) && 1;
Mmu_setFirstLevelDesc((Ptr)(mmuEntries[itr].address), (Ptr)(mmuEntries[itr].address) , &attrs); // PWM
}
Mmu_enable();
return 0;
}
/**
* \name main
* \brief Main Function
* \param none
* \return none
*
*/
int main()
{
/* Call board init functions */
Board_initCfg boardCfg;
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
SDKMMUInit(applMmuEntries);
boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
Board_init(boardCfg);
/* Chip configuration MII/RMII selection */
CpswPortMacModeSelect(1, ETHERNET_MAC_TYPE_RGMII);
CpswPortMacModeSelect(2, ETHERNET_MAC_TYPE_RGMII);
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create (TaskFxn, &taskParams, NULL);
NIMUDeviceTable[nimu_device_index++].init = &CpswEmacInit ;
NIMUDeviceTable[nimu_device_index].init = NULL ;
BIOS_start();
return -1;
}
static void jumpStackPointer(uint32_t address)
{
pfnFGAppEntry = (void (*)(void)) address;
//Hwi_disable();
//Mmu_disable();
(*pfnFGAppEntry)( );
/*__asm(" mov sp, r0\n" // sp is now *address
" bx r0\n" ); // jump to *address */
}
void jumpToApplication(UArg a0, UArg a1)
{
/*
* Disable interrupts
*/
NIMU_log ("All interrupts are disabled\n");
char *p = (char *)(FG_BASE_ADDRESS);
NIMU_log("jump context = 0x%08X\n", *(unsigned int *)p);
NIMU_log("Jumping... \n");
jumpStackPointer(FG_BASE_ADDRESS);
}
/**
* \name TaskFxn
* \brief Task which do EIP initialization
* \param a0
* \param a1
* \return none
*
*/
void TaskFxn(UArg a0, UArg a1)
{
CI_IPNET NA;
char IPString[16];
char *pBuf = (char *)FG_BASE_ADDRESS;
int firmlen, res;
uint16_t errcode;
/* Allocate the file environment for this task */
fdOpenSession( TaskSelf() );
if (CfgGetImmediate( 0, CFGTAG_IPNET, 0, 1, sizeof(NA), (UINT8 *)&NA) == sizeof(NA)) {
/* Yes the device was configured and we got the IP address/Mask */
NtIPN2Str (NA.IPAddr, IPString);
NIMU_log ("IP Address : %s\n", IPString);
NtIPN2Str (NA.IPMask, IPString);
NIMU_log ("IP Mask : %s\n", IPString);
}
/* Wait for the link to come up */
Task_sleep(10000);
while (1) {
firmlen = MAX_BLOCK_SIZE;
res = NtTftpRecv(inet_addr(REMOTE_IP_ADDRESS), "FGBoardProto.bin", pBuf, (UINT32 *)&firmlen, &errcode);
if (res == 0 || res == 1) {
NIMU_log ("Firmware file found with len %d, res is %d\n", firmlen, res);
break;
} else {
NIMU_log ("Error (%d/%d) fetching firmware\n", res, (int)errcode);
}
}
NIMU_log ("Firmware download is complete. Jumping to FW\n");
{
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create(jumpToApplication, &taskParams, NULL);
}
fdCloseSession( TaskSelf() );
TaskDestroy( TaskSelf() );
}
// handle exceptions
void BL_Exception(uint32_t *stack, uint32_t lr)
{
NIMU_log("Exception occurred \n");
}
/*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* ========================================================================== */
/* Include Files */
/* ========================================================================== */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/family/arm/a8/Mmu.h>
#include <ti/ndk/inc/stkmain.h>
#include <ti/ndk/inc/netmain.h>
#include <ti/drv/emac/emac_drv.h>
#include <ti/drv/emac/src/v4/emac_drv_v4.h>
#include <ti/starterware/include/types.h>
#include <ti/starterware/include/hw/hw_types.h>
#include <ti/starterware/include/hw/hw_control_am43xx.h>
#include <ti/starterware/include/hw/am437x.h>
#include <ti/starterware/include/ethernet.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/board/board.h>
/* UART Header files */
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
extern char *LocalIPAddr;
/* Enable the below macro to have prints on the IO Console */
//#define IO_CONSOLE
#ifndef IO_CONSOLE
#define NIMU_log UART_printf
#else
#define NIMU_log printf
#endif
/* ========================================================================== */
/* Macros */
/* ========================================================================== */
/**Phy address of the CPSW port 1*/
#define EMAC_CPSW_PORT0_PHY_ADDR_SK 4
/**Phy address of the CPSW port 2*/
#define EMAC_CPSW_PORT1_PHY_ADDR_SK 5
#define MAX_TABLE_ENTRIES 3
#define REMOTE_IP_ADDRESS "193.100.100.251"
#define FG_BASE_ADDRESS 0x80000000
#define MAX_BLOCK_SIZE 65464
/* ========================================================================== */
/* Global Variables */
/* ========================================================================== */
/**Task handle for EIP*/
Task_Handle main_task;
static int nimu_device_index = 0U;
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[MAX_TABLE_ENTRIES];
static void (*pfnFGAppEntry)();
void TaskFxn(UArg a0, UArg a1);
extern int CpswEmacInit (STKEVENT_Handle hEvent);
/* ========================================================================== */
/* Function Definitions */
/* ========================================================================== */
void CpswPortMacModeSelect(uint32_t portNum, uint32_t macMode)
{
uint32_t regVal = 0U;
regVal = HW_RD_REG32(SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL);
switch(macMode)
{
case ETHERNET_MAC_TYPE_MII:
case ETHERNET_MAC_TYPE_GMII:
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RMII: /* RMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 1U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
case ETHERNET_MAC_TYPE_RGMII: /* RGMII */
if(1U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII1, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII1_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII1_IO_CLK_EN, 0U);
}
else if(2U == portNum)
{
HW_SET_FIELD(regVal, CTRL_GMII_SEL_GMII2, 2U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RGMII2_IDMODE, 0U);
HW_SET_FIELD(regVal, CTRL_GMII_SEL_RMII2_IO_CLK_EN, 0U);
}
else
{
/* This error does not happen because of check done already */
}
break;
default:
break;
}
HW_WR_REG32((SOC_CONTROL_MODULE_REG + CTRL_GMII_SEL), regVal);
}
#define SYS_MMU_BUFFERABLE 1
#define SYS_MMU_CACHEABLE 2
#define SYS_MMU_SHAREABLE 4
#define SYS_MMU_NO_EXECUTE 8
typedef struct _sys_mmu_entry
{
void* address;
/**< Address to be entered in MMU table. */
unsigned int attributes;
/**< Attributes of the memory. */
}SYS_MMU_ENTRY;
SYS_MMU_ENTRY applMmuEntries[] = {
{(void*)0x30000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30100000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30200000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x30300000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Cacheable
{(void*)0x40300000,0}, //OCMCRAM - Cacheable
{(void*)0x44D00000, SYS_MMU_BUFFERABLE}, //PRCM - Non bufferable| Non Cacheable
{(void*)0x44E00000, SYS_MMU_BUFFERABLE}, //Clock Module, PRM, GPIO0, UART0, I2C0, - Non bufferable| Non Cacheable
{(void*)0x47900000,SYS_MMU_BUFFERABLE}, //QSPI MMR Maddr0space
{(void*)0x48000000, SYS_MMU_BUFFERABLE}, //UART1,UART2,I2C1,McSPI0,McASP0 CFG,McASP1 CFG,DMTIMER,GPIO1 -Non bufferable| Non Cacheable
{(void*)0x48100000,0}, //I2C2,McSPI1,UART3,UART4,UART5, GPIO2,GPIO3,MMC1 - Non bufferable| Non Cacheable
{(void*)0x48200000, SYS_MMU_BUFFERABLE}, //
{(void*)0x48300000, SYS_MMU_BUFFERABLE}, //PWM - Non bufferable| Non Cacheable
{(void*)0x49000000, SYS_MMU_BUFFERABLE}, //EDMA3CC - Non bufferable| Non Cacheable
{(void*)0x4A000000, SYS_MMU_BUFFERABLE}, //L4 FAST CFG- Non bufferable| Non Cacheable
{(void*)0x4A100000, SYS_MMU_BUFFERABLE}, //CPSW - Non bufferable| Non Cacheable
{(void*)0x54400000, SYS_MMU_BUFFERABLE}, //PRU-ICSS0/1 -Bufferable| Non Cacheable | Shareable
//{(void*)0x90000000,SYS_MMU_CACHEABLE}, //QSPI CS0 Maddr1space - Non bufferable| Non Cacheable
{(void*)0x80000000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80100000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x80200000, SYS_MMU_SHAREABLE | SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90000000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90100000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0x90200000, SYS_MMU_CACHEABLE}, //App memory
{(void*)0xFFFFFFFF,0xFFFFFFFF}
};
int SDKMMUInit(SYS_MMU_ENTRY mmuEntries[])
{
unsigned short itr = 0;
Mmu_FirstLevelDescAttrs attrs;
if(NULL == mmuEntries)
return -1;
Mmu_disable();
Mmu_initDescAttrs(&attrs);
attrs.type = Mmu_FirstLevelDesc_SECTION;
attrs.domain = 0;
attrs.imp = 1;
attrs.accPerm = 3;
for(itr = 0 ; mmuEntries[itr].address != (void*)0xFFFFFFFF ; itr++)
{
attrs.bufferable = ((mmuEntries[itr].attributes) & SYS_MMU_BUFFERABLE) && 1 ;
attrs.cacheable = ((mmuEntries[itr].attributes) & SYS_MMU_CACHEABLE) && 1;
if (!attrs.bufferable && !attrs.cacheable)
attrs.tex = 0; //tex is initialized to 1 and need this to force strongly ordered
attrs.shareable = ((mmuEntries[itr].attributes) & SYS_MMU_SHAREABLE) && 1;
attrs.noexecute = ((mmuEntries[itr].attributes) & SYS_MMU_NO_EXECUTE) && 1;
Mmu_setFirstLevelDesc((Ptr)(mmuEntries[itr].address), (Ptr)(mmuEntries[itr].address) , &attrs); // PWM
}
Mmu_enable();
return 0;
}
/**
* \name main
* \brief Main Function
* \param none
* \return none
*
*/
int main()
{
/* Call board init functions */
Board_initCfg boardCfg;
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
SDKMMUInit(applMmuEntries);
boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
Board_init(boardCfg);
/* Chip configuration MII/RMII selection */
CpswPortMacModeSelect(1, ETHERNET_MAC_TYPE_RGMII);
CpswPortMacModeSelect(2, ETHERNET_MAC_TYPE_RGMII);
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create (TaskFxn, &taskParams, NULL);
NIMUDeviceTable[nimu_device_index++].init = &CpswEmacInit ;
NIMUDeviceTable[nimu_device_index].init = NULL ;
BIOS_start();
return -1;
}
static void jumpStackPointer(uint32_t address)
{
pfnFGAppEntry = (void (*)(void)) address;
//Hwi_disable();
//Mmu_disable();
(*pfnFGAppEntry)( );
/*__asm(" mov sp, r0\n" // sp is now *address
" bx r0\n" ); // jump to *address */
}
void jumpToApplication(UArg a0, UArg a1)
{
/*
* Disable interrupts
*/
NIMU_log ("All interrupts are disabled\n");
char *p = (char *)(FG_BASE_ADDRESS);
NIMU_log("jump context = 0x%08X\n", *(unsigned int *)p);
NIMU_log("Jumping... \n");
jumpStackPointer(FG_BASE_ADDRESS);
}
/**
* \name TaskFxn
* \brief Task which do EIP initialization
* \param a0
* \param a1
* \return none
*
*/
void TaskFxn(UArg a0, UArg a1)
{
CI_IPNET NA;
char IPString[16];
char *pBuf = (char *)FG_BASE_ADDRESS;
int firmlen, res;
uint16_t errcode;
/* Allocate the file environment for this task */
fdOpenSession( TaskSelf() );
if (CfgGetImmediate( 0, CFGTAG_IPNET, 0, 1, sizeof(NA), (UINT8 *)&NA) == sizeof(NA)) {
/* Yes the device was configured and we got the IP address/Mask */
NtIPN2Str (NA.IPAddr, IPString);
NIMU_log ("IP Address : %s\n", IPString);
NtIPN2Str (NA.IPMask, IPString);
NIMU_log ("IP Mask : %s\n", IPString);
}
/* Wait for the link to come up */
Task_sleep(10000);
while (1) {
firmlen = MAX_BLOCK_SIZE;
res = NtTftpRecv(inet_addr(REMOTE_IP_ADDRESS), "FGBoardProto.bin", pBuf, (UINT32 *)&firmlen, &errcode);
if (res == 0 || res == 1) {
NIMU_log ("Firmware file found with len %d, res is %d\n", firmlen, res);
break;
} else {
NIMU_log ("Error (%d/%d) fetching firmware\n", res, (int)errcode);
}
}
NIMU_log ("Firmware download is complete. Jumping to FW\n");
{
Task_Params taskParams;
EMAC_HwAttrs_V4 cfg;
EMAC_socGetInitCfg(0, &cfg);
cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
cfg.port[1].phy_addr = EMAC_CPSW_PORT1_PHY_ADDR_SK;
EMAC_socSetInitCfg(0, &cfg);
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 0x1400;
main_task = Task_create(jumpToApplication, &taskParams, NULL);
}
fdCloseSession( TaskSelf() );
TaskDestroy( TaskSelf() );
}
// handle exceptions
void BL_Exception(uint32_t *stack, uint32_t lr)
{
NIMU_log("Exception occurred \n");
}
I as I jump into the application - it receives an exception and doesn't gets inside application's main.
UART output is:
SetPhyMode:000021e1 Auto:1, FD10:64, HD10:32, FD100:256, HD100:128, FD1000:8192 LPBK:0
ENETPHY_FindingState: PhyNum: 4
ENETPHY_DisablePhy(4)
Enable Phy to negotiate external connection
NWAY Advertising: FullDuplex-1000 FullDuplex-100 HalfDuplex-100 FullDuplex-10 HalfDuplex-10
Negotiated connection: FullDuplex 1000 Mbs
Firmware file found with len 1113309, res is 0
Firmware download is complete. Jumping to FW
All interrupts are disabled
jump context = 0xe59ff018
Jumping...
Exception occurred
What is missing in my solution?
