Просмотр исходного кода

Closes #5 - Adds support for the TI LM3S8962

CapXilinx 12 лет назад
Родитель
Сommit
fea5b63824

+ 3 - 2
.gitignore

@@ -1,8 +1,9 @@
 bin/
 doc/
 contrib/
-src/cip_objects/*
-!src/cip_objects/CMakeLists.txt
+source/src/cip_objects/
+!source/src/cip_objects/CMakeLists.txt
 .project
 .cproject
 *.*~
+*~

+ 1 - 22
source/CMakeLists.txt

@@ -36,28 +36,7 @@ INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer_function_checks.cmake )
 #######################################
 set( OpENer_TRACES OFF CACHE BOOL "Activate OpENer traces" )
 if(OpENer_TRACES)
-  add_definitions( -DOPENER_WITH_TRACES )
-  set( TRACE_LEVEL 0 )
-  set( OpENer_TRACE_LEVEL_ERROR ON CACHE BOOL "Error trace level" )
-  set( OpENer_TRACE_LEVEL_WARNING ON CACHE BOOL "Warning trace level" )
-  set( OpENer_TRACE_LEVEL_STATE ON CACHE BOOL "State trace level" )
-  set( OpENer_TRACE_LEVEL_INFO ON CACHE BOOL "Info trace level" )
-  
-  if(OpENer_TRACE_LEVEL_ERROR)
-    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 1" )
-  endif(OpENer_TRACE_LEVEL_ERROR)
-  if(OpENer_TRACE_LEVEL_WARNING)
-    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 2" )
-  endif(OpENer_TRACE_LEVEL_WARNING)
-  if(OpENer_TRACE_LEVEL_STATE)
-    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 4" )
-  endif(OpENer_TRACE_LEVEL_STATE)
-  if(OpENer_TRACE_LEVEL_INFO)
-    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 8" )
-  endif(OpENer_TRACE_LEVEL_INFO)
-  
-  add_definitions(-DOPENER_TRACE_LEVEL=${TRACE_LEVEL})
-  
+  createTraceLevelOptions()
 endif(OpENer_TRACES)
 
 #######################################

+ 27 - 0
source/buildsupport/OpENer.cmake

@@ -42,3 +42,30 @@ MACRO(opener_add_cip_object NAME DESCRIPTION)
     return()
   endif(NOT OpENer_CIP_OBJECT_${NAME})
 ENDMACRO(opener_add_cip_object)
+
+#######################################
+# Creates options for trace level     #
+####################################### 
+macro(createTraceLevelOptions)
+  add_definitions( -DOPENER_WITH_TRACES )
+  set( TRACE_LEVEL 0 )
+  set( OpENer_TRACE_LEVEL_ERROR ON CACHE BOOL "Error trace level" )
+  set( OpENer_TRACE_LEVEL_WARNING ON CACHE BOOL "Warning trace level" )
+  set( OpENer_TRACE_LEVEL_STATE ON CACHE BOOL "State trace level" )
+  set( OpENer_TRACE_LEVEL_INFO ON CACHE BOOL "Info trace level" )
+  
+  if(OpENer_TRACE_LEVEL_ERROR)
+    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 1" )
+  endif(OpENer_TRACE_LEVEL_ERROR)
+  if(OpENer_TRACE_LEVEL_WARNING)
+    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 2" )
+  endif(OpENer_TRACE_LEVEL_WARNING)
+  if(OpENer_TRACE_LEVEL_STATE)
+    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 4" )
+  endif(OpENer_TRACE_LEVEL_STATE)
+  if(OpENer_TRACE_LEVEL_INFO)
+    math( EXPR TRACE_LEVEL "${TRACE_LEVEL} + 8" )
+  endif(OpENer_TRACE_LEVEL_INFO)
+  
+  add_definitions(-DOPENER_TRACE_LEVEL=${TRACE_LEVEL})
+endmacro(createTraceLevelOptions)

+ 25 - 5
source/src/ports/LM3S8962/CMakeLists.txt

@@ -1,6 +1,22 @@
-#add_subdirectory(sample_application)
+add_subdirectory(sample_application)
 
-set( PLATFORM_SPEC_SRC networkhandler.c basiccip.c)
+#######################################
+# Platform specific options           #
+#######################################
+set( USE_STATIC_IP OFF CACHE BOOL "Use the static IP defined in main.c" )
+
+if( USE_STATIC_IP )
+  add_definitions( -DuseStaticIP=1 )
+else( USE_STATIC_IP )
+  add_definitions( -DuseStaticIP=0 )
+endif( USE_STATIC_IP )
+
+set( NEWLIB_SRC "" CACHE PATH "Path to NewLib source directory" )
+
+set( PLATFORM_SPEC_SRC networkhandler.c basiccip.c flashmgr.c stubs.c startup_gcc.c )
+set( SBRK_SRC ${NEWLIB_SRC}/libgloss/libnosys/sbrk.c)
+
+add_library(sbrk ${SBRK_SRC} )
 
 #######################################
 # Add common includes                 #
@@ -12,10 +28,14 @@ opener_common_includes()
 #######################################
 opener_platform_support("INCLUDES")
 
+include_directories(${CIP_ELECTRICAL_ENERGY_INCLUDE})
 set (PLATFORMLIBNAME ${OpENer_PLATFORM}PLATFORM)
 
-add_library( ${PLATFORMLIBNAME} ${PLATFORM_SPEC_SRC})
+link_directories( ${LM3S8962_CONTRIB_DIR}/driverlib/gcc-cm3 )
+
+add_library( ${PLATFORMLIBNAME} ${PLATFORM_SPEC_SRC} )
 
-add_executable(OpENer main.c)
+add_executable( OpENer ${LM3S8962_CONTRIB_DIR}/utils/lwiplib.c )
 
-target_link_libraries( OpENer ${PLATFORMLIBNAME} CIP SAMPLE_APP ENET_ENCAP ${PLATFORM_SPEC_LIBS} ${OpENer_ADD_CIP_OBJECTS})
+target_link_libraries( OpENer SAMPLE_APP CIP ENET_ENCAP Utils ${PLATFORMLIBNAME} ${PLATFORM_SPEC_LIBS} )
+target_link_libraries( OpENer ${OpENer_ADD_CIP_OBJECTS} ${PLATFORM_LINKER_FLAGS} driver-cm3 m gcc c sbrk "-T ${CMAKE_CURRENT_SOURCE_DIR}/stellaris.ld")

+ 69 - 0
source/src/ports/LM3S8962/README

@@ -0,0 +1,69 @@
+README for the usage of OpENer with a LM3S8962 kit:
+
+Depending on which eval kit you may have please install the kit
+
+For example the eval kits for the Luminary/Texas Instruments(R)
+LM3S8962 eval kit (display board or brushless DC boards) can 
+be found here:
+	http://www.ti.com/tool/sw-ek-lm3s8962
+	http://www.ti.com/tool/sw-rdk-bldc
+
+This port uses the MentorGraphics(R) Code Sourcery Lite ARM-NONE-EABI toolchain
+ which can be found here: 
+http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/overview
+
+On Debian 7+ you need to install ia32-libs before you can install the
+MentorGraphics(R) Code Sourcery Lite ARM-NONE-EABI toolchain. This manual can 
+also be found at the MentorGraphics(R) website:
+
+To install the ia32-libs enter the following commands, which must be executed
+as root:
+
+  dpkg --add-architecture i386
+  apt-get update
+  apt-get install ia32-libs ia32-libs-gtk
+
+This part was also stated in the manual at MentorGraphics(R) but didn't work
+for me, but I was able to install the toolchain anyhow
+
+  wget https://sourcery.mentor.com/GNUToolchain/kbattach150/getlibs-all.deb
+  sudo dpkg -i getlibs-all.deb
+  sudo getlibs -p xulrunner-1.9.2
+  export MOZILLA_FIVE_HOME=/usr/lib32/xulrunner-1.9.2.X
+
+In addition the _sbrk function must be provided. An _sbrk implementation can
+be found in newlib/libgloss/libnosys. The CMake script allows to enter the path
+to the newlib source. The newlib source can be found at:
+  https://sourceware.org/newlib/
+
+If you are using newlib you have to add a user heap section to your linker 
+script like the one provided here:
+
+	/* User_heap_stack section, used to check that there is enough RAM 
+	left */
+	  ._user_heap_stack :
+	  {
+	    . = ALIGN(4);
+	    PROVIDE ( end = . );
+	    PROVIDE ( _end = . );
+	    _heap_start_ = .;
+	    . = . + _Min_Heap_Size;
+	    _heap_end_ = .;
+	    _stack_start_ = .;
+	    . = . + _Min_Stack_Size;
+	    _stack_end_ = .;
+	    . = ALIGN(4);
+	  } > SRAM 
+
+Alternatively, the myLib provided on the CD of the board can be used 
+instead of the newLib and the add-on to the linker script.
+
+Unfortunatly, the myLib isn't provided in the offical download (at the time I 
+was looking it up it was SW-EK-LM3S8962-10636) of the evaluation kit at the 
+Texas Instruments(R) homepage.
+
+Last, but not least, you place the your startup_gcc.c and linker script in the 
+opener/source/src/ports/LM3S8962 directory.
+
+If something in this README isn't clear please put your question here:
+  https://github.com/EIPStackGroup/OpENer

+ 0 - 2
source/src/ports/LM3S8962/archnw.h

@@ -9,8 +9,6 @@
 
 #include "lwiplib.h"
 
-#include "local.h"
-
 extern void *mycalloc(unsigned);
 #define cip_calloc(x,y) mycalloc((unsigned)((x)*(y)))
 

+ 9 - 0
source/src/ports/LM3S8962/config.h

@@ -0,0 +1,9 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Rockwell Automation, Inc.
+ * All rights reserved. 
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Empty config.h file for _sbrk in newlib/libgloss/libnosys
+ ******************************************************************************/

+ 130 - 0
source/src/ports/LM3S8962/flashmgr.c

@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "hw_memmap.h"
+#include "hw_types.h"
+#include "driverlib/flash.h"
+#include "driverlib/gpio.h"
+#include "lwiplib.h"
+
+/*
+ * This flash manager is rudimentary. It does wear leveling by allocating small chunks at a time.
+ * When a new parameter block is to be written the old one is erased by writing zeros to it. When
+ * there is no more space in the 1K chunk for a new parameter block the entire chunk is erased. 
+ *
+ * assumptions:
+ *   -- erased FLASH is all ones
+ *   -- bits in individual words can be written to zero
+ *   -- a word that is part ones and part zeros can be written to all zeros
+ *   -- to get any bits changed back to ones the entire chunk has to be erased
+ * 
+ * A parameter block starts with a one word size field. The size indicates the size of the following data.
+ * If the size field is zero, the block is erased. 
+ * 
+ * A chunk of flash can be in one of three states:
+ *   -- erased (all ones)
+ *   -- data (starts with a size word that is not 0 or 0xffffffff
+ *   -- zeroed (all zeros)
+ * 
+ */
+
+// This flash manger only supports one parameter block at a time.
+// It does not support multiple block types, or multiple instances of blocks.
+
+
+#define FLASHBASE ((unsigned long *)(255*1024))			// parameter sector is the last 1024 byte chunk of the program flash
+#define FLASHEND ((unsigned long *)(256*1024))
+#define CHUNKSIZE 1024
+static const int erasedFlashField = 0xffffffff;
+
+// erase everything in the parameters block
+static void eraseAllParameters(void)
+{
+	FlashErase((unsigned long)FLASHBASE);
+}
+
+// find the parameter block
+// returns the address of the parameter block, or zero if not found
+
+unsigned long* findNextEmptyParameterBlock(void)
+{
+	unsigned long* currentFlashAddress = FLASHBASE;
+	unsigned long* const noSpaceLeft = 0;
+
+	while (currentFlashAddress < FLASHEND)
+	{
+		if (0 == *currentFlashAddress)
+			++currentFlashAddress;
+		else if (erasedFlashField == *currentFlashAddress)
+			return noSpaceLeft;
+		else
+			return currentFlashAddress;
+	}
+	return noSpaceLeft;
+}
+
+// verify that the block to be written is erased
+static int parameterBlockIsEmpty(unsigned long *data, // pointer to are to be checked
+		int dataSize) // sizeof(struct)
+{
+	int const isNotEmpty = 0;
+	int const isEmpty = 1;
+	while (dataSize > 0)
+	{
+		if (*data++ != erasedFlashField)
+			return isNotEmpty;
+		dataSize -= 4;
+	}
+	return isEmpty;
+}
+
+// write a new parameter block
+void writeParameter(unsigned long *data, // pointer to struct to be saved
+		int dataSize) // sizeof(struct)
+{
+	unsigned long *currentParameterBlock = findNextEmptyParameterBlock(); // find the current parameter block;
+	unsigned long zero = 0;
+
+	if (currentParameterBlock) // if found, zero it
+	{
+		int lengthToBeErased = *currentParameterBlock + 4; // calc dataSize of region to be erased
+
+		if (currentParameterBlock + lengthToBeErased / 4 <= FLASHEND) // if properly formatted, zero the current block
+		{
+			while (lengthToBeErased > 0) //   for each word
+			{
+				FlashProgram(&zero, (unsigned long)currentParameterBlock, 4); // zero one word
+				currentParameterBlock++; //     advance to next word
+				lengthToBeErased -= 4; //     dec dataSize
+			}
+		}
+		else // else flash is corrupt -- erase it all
+		{
+			eraseAllParameters();
+			currentParameterBlock = FLASHBASE;
+		}
+	}
+
+	// at this point p should point to useable erased flash
+
+	// currentParameterBlock now points to the first unerased word
+
+	if (currentParameterBlock + dataSize/4 > FLASHEND // if flash is full
+			|| !parameterBlockIsEmpty(currentParameterBlock, dataSize)) // or not properly erased
+	{
+		eraseAllParameters(); // erase the entire block
+		currentParameterBlock = FLASHBASE; // start from the beginning
+	}
+
+	FlashProgram((unsigned long *)&dataSize, (unsigned long)currentParameterBlock, 4); // program the length
+	FlashProgram(data, (unsigned long)(currentParameterBlock+1), dataSize); // program the data
+}
+

+ 8 - 0
source/src/ports/LM3S8962/flashmgr.h

@@ -0,0 +1,8 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Rockwell Automation, Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+extern unsigned long *findNextEmptyParameterBlock(void);
+extern void writeParameter(unsigned long *data, int dataSize);

+ 0 - 505
source/src/ports/LM3S8962/main.c

@@ -1,505 +0,0 @@
-// Scraps of this module were pulled from the following demo program:
-
-//*****************************************************************************
-//
-// enet_lwip.c - Sample WebServer Application using lwIP.
-//
-// Copyright (c) 2007-2008 Luminary Micro, Inc.  All rights reserved.
-// Software License Agreement
-//
-// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
-// exclusively on LMI's microcontroller products.
-//
-// The software is owned by LMI and/or its suppliers, and is protected under
-// applicable copyright laws.  All rights are reserved.  You may not combine
-// this software with "viral" open-source software in order to form a larger
-// program.  Any use in violation of the foregoing restrictions may subject
-// the user to criminal sanctions under applicable laws, as well as to civil
-// liability for the breach of the terms and conditions of this license.
-//
-// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
-// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
-// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
-// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
-//
-// This is part of revision 3618 of the EK-LM3S6965 Rev C Firmware Package.
-//
-//*****************************************************************************
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "hw_ints.h"
-#include "hw_memmap.h"
-#include "hw_nvic.h"
-#include "hw_types.h"
-#include "driverlib/ethernet.h"
-#include "driverlib/flash.h"
-#include "driverlib/gpio.h"
-#include "driverlib/interrupt.h"
-#include "driverlib/sysctl.h"
-#include "driverlib/systick.h"
-#include "lwiplib.h"
-
-#include "local.h"
-#include "flashmgr.h"
-#include "networkhandler.h"
-#include <opener_api.h>
-#include "cipcommon.h"
-#include "random.h"
-#include <trace.h>
-#include <ElectricalEnergy/ElEnergyData.h>
-#include "measurement_extension/eminterface.h"
-
-int callocsize = CALLOCSIZE;
-char callocmem[CALLOCSIZE];
-
-//define here instead of ptpd.h
-volatile unsigned long g_ulSystemTimeSeconds;
-volatile unsigned long g_ulSystemTimeNanoSeconds;
-
-// cast an int as a struct_inaddr (check the "inet_ntoa" man page -- it wants a struct_inaddr passed by value, not an int)
-// static IP-Address?
-//#define useStaticIP 1
-#define useStaticIP 0
-
-struct parm
-{
-  int useStatic; // 1 use static IP address, 0 use DHCP
-  unsigned long ip; // my ip address
-  unsigned long nm; // net mask
-  unsigned long gw; // gateway ip address
-};
-
-
-//*****************************************************************************
-//
-// Defines for setting up the system clock.
-//
-//*****************************************************************************
-#define SYSTICKHZ               100
-#define SYSTICKMS               (1000 / SYSTICKHZ)
-#define SYSTICKUS               (1000000 / SYSTICKHZ)
-#define SYSTICKNS               (1000000000 / SYSTICKHZ)
-
-
-//*****************************************************************************
-//
-// Interrupt priority definitions.  The top 3 bits of these values are
-// significant with lower values indicating higher priority interrupts.
-//
-//*****************************************************************************
-#define SYSTICK_INT_PRIORITY    0xF0
-#define ETHERNET_INT_PRIORITY   0xC2
-
-//*****************************************************************************
-//
-// The error routine that is called if the driver library encounters an error.
-//
-//*****************************************************************************
-#ifdef DEBUG
-void
-__error__(char *pcFilename, unsigned long ulLine)
-  {
-  }
-#endif
-
-void DisplayIPAddress(unsigned long ipaddr, unsigned long ulCol,
-                 unsigned long ulRow);
-void DisplayOdo(EIP_INT64 pa_nValue, unsigned long pa_nRow);
-
-
-void DisplayRealVal(double pa_fValue, const char *pcPrefix, const char *pcPostfix, unsigned long pa_nRow, unsigned long pa_nCol);
-
-
-// change my IP address etc.
-void
-setCIPaddress(unsigned long addr, // my IP address, in network order
-    unsigned long mask, // netmask, in network order
-    unsigned long gw) // gateway, in network order
-{
-  struct in_addr inAddr;
-  inAddr.s_addr = addr;
-  char acIPAddr[16];
-  strncpy(acIPAddr, inet_ntoa(inAddr), 16);
-  inAddr.s_addr = mask;
-  char acNetMask[16];
-  strncpy(acNetMask, inet_ntoa(inAddr), 16);
-  inAddr.s_addr = gw;
-  char acGW[16];
-  strncpy(acGW, inet_ntoa(inAddr), 16);
-
-  configureNetworkInterface(acIPAddr, acNetMask, acGW);
-  configureDomainName("test");
-  configureHostName("karl");
-}
-
-// this gets called every 100 usec by the lwip timer handler
-void
-lwIPHostTimerHandler(void)
-{
-  static unsigned long ulLastIPAddress = 0;
-  unsigned long ulIPAddress;
-  unsigned long ulNetmask;
-  unsigned long ulGateway;
-
-  ulIPAddress = lwIPLocalIPAddrGet();
-
-  if (ulLastIPAddress != ulIPAddress)
-    {
-      ulLastIPAddress = ulIPAddress;
-      ulNetmask = lwIPLocalNetMaskGet();
-      ulGateway = lwIPLocalGWAddrGet();
-      setCIPaddress(ulIPAddress, ulNetmask, ulGateway);
-      DisplayIPAddress((ulIPAddress), 36, 8);
-    }
-}
-
-int
-main(void)
-{
-  int i;
-  unsigned long ulUser0, ulUser1;
-  unsigned char pucMACArray[8];
-
-  unsigned long ip, nm, gw;
-  int valid;
-
-  struct parm parm;
-  struct parm *p;
-  unsigned long *pl;
-
-  IntPriorityGroupingSet(4);
-
-  //
-  // Set the clocking to run directly from the crystal.
-  //
-  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN
-                  | SYSCTL_XTAL_8MHZ);
-
-  SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
-  SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
-
-  // Enable Port F for Ethernet LEDs.
-  //  LED0        Bit 3   Output
-  //  LED1        Bit 2   Output
-  //
-  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
-  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
-  GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_DIR_MODE_HW);
-  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3,
-                  GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
-
-  //
-  // Configure the GPIOs used to read the state of the on-board push buttons.
-  //
-  GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2
-                  | GPIO_PIN_3);
-  GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2
-                  | GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
-  GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_1);
-  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_STRENGTH_2MA,
-                  GPIO_PIN_TYPE_STD_WPU);
-
-  // configure the user LED output
-  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0);
-  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0);
-
-
-
-  //
-  // Configure SysTick for a 100 Hz (10 ms) interrupt.
-  //
-  SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ);
-  SysTickEnable();
-  SysTickIntEnable();
-
-  //
-  // Initialize ADC
-  //
-  EMInterfaceInit();
-  //
-  // Enable processor interrupts.
-  //
-  IntMasterEnable();
-
-
-
-  //
-  // Configure the hardware MAC address for Ethernet Controller filtering of
-  // incoming packets.
-  //
-  // For the LM3S6965 Evaluation Kit, the MAC address will be stored in the
-  // non-volatile USER0 and USER1 registers.  These registers can be read
-  // using the FlashUserGet function, as illustrated below.
-  //
-  FlashUserGet(&ulUser0, &ulUser1);
-  if ((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff))
-    {
-      //
-      // We should never get here.  This is an error if the MAC address has
-      // not been programmed into the device.  Exit the program.
-      //
-
-      while (1)
-        {
-        }
-    }
-
-  //
-  // Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
-  // address needed to program the hardware registers, then program the MAC
-  // address into the Ethernet Controller registers.
-  //
-
-  pucMACArray[0] = ((ulUser0 >> 0) & 0xff);
-  pucMACArray[1] = ((ulUser0 >> 8) & 0xff);
-  pucMACArray[2] = ((ulUser0 >> 16) & 0xff);
-  pucMACArray[3] = ((ulUser1 >> 0) & 0xff);
-  pucMACArray[4] = ((ulUser1 >> 8) & 0xff);
-  pucMACArray[5] = ((ulUser1 >> 16) & 0xff);
-
-  //////////////////////////////////////////////////////////
-  // YOU MUST SET THESE TO VALID VALUES FOR YOUR LOCATION //
-  //////////////////////////////////////////////////////////
-  configureMACAddress(pucMACArray);
-
-  //
-  // Initialze the lwIP library
-  //
-
-
-  pl = parmFind();
-  p = (struct parm *) (pl + 1);
-
-  if (useStaticIP)
-    {
-      OPENER_TRACE_INFO("using static IP address\n");
-
-      ip = 0x8083BAC9; //128.130.200.201
-//      ip = 0x8083BACB; //128.130.200.203
-      nm = 0xFFFFFF00;
-      gw = 0x8083BA01;
-      valid = 7;
-      lwIPInit(pucMACArray, ip, nm, gw, IPADDR_USE_STATIC);
-    }
-  else
-    {
-      //
-      // Initialze the lwIP library, using DHCP.
-      //
-      OPENER_TRACE_INFO("using DHCP\n");
-      valid = 0; //0
-      lwIPInit(pucMACArray, 0, 0, 0, IPADDR_USE_DHCP);
-    }
-
-
-  // Set the interrupt priorities.  We set the SysTick interrupt to a higher
-    // priority than the Ethernet interrupt to ensure that the file system
-    // tick is processed if SysTick occurs while the Ethernet handler is being
-    // processed.  This is very likely since all the TCP/IP and HTTP work is
-    // done in the context of the Ethernet interrupt.
-    //
-    //
-    // Initialize the OLED display.
-    //
-    RIT128x96x4Init(1000000);
-    RIT128x96x4StringDraw("OpENer w/ CIP-Energy", 4, 0, 15);
-    RIT128x96x4StringDraw("-----------------------", 0, 14, 15);
-    RIT128x96x4StringDraw("IP:   ", 0, 8, 15);
-    DisplayIPAddress(htonl(ip), 36, 8);
-
-    RIT128x96x4StringDraw("  TWh GWh MWh kWh  Wh  ", 0, 20, 15);
-
-    RIT128x96x4StringDraw("factor 1000 applies    ", 0, 54, 10);
-    RIT128x96x4StringDraw("to metered values     ", 0, 62, 10);
-    //change time-interval value for call of updateElMeasuringAndMeteringData
-    //in SysTickIntHandler-method to show/provide correct values (see line 370)
-
-  IntPrioritySet(INT_ETH, ETHERNET_INT_PRIORITY);
-  IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY);
-
-  /*for a real device the serial number should be unique per device */
-  setDeviceSerialNumber(123456789);
-
-  /* Setup the CIP Layer */
-  CIP_Init(365);
-  IntMasterDisable();
-  CIP_BaseEnergy_Init();
-  CIP_ElEnergy_Init();
-
-  IntMasterEnable();
-  Start_NetworkHandler();
-
-  // this is a simple command interpreter which reads from serial port 0
-  // it is used to set a static IP address
-  while (1)
-    {
-
-    }
-}
-
-/* implement missing functions rand and srand */
-int _EXFUN(rand,(_VOID))
-{
-  return nextXorShiftUInt32();
-}
-
-_VOID   _EXFUN(srand,(unsigned __seed))
-{
-  setXorShiftSeed(__seed);
-}
-
-
-
-//*****************************************************************************
-//
-// The interrupt handler for the SysTick interrupt.
-// Entry here directly from the interrupt vector
-// This interrupt occurs once every 10 milliseconds
-//*****************************************************************************
-void SysTickIntHandler(void) {
-
-  //
-  // Update internal time and set PPS output, if needed.
-  //
-  g_ulSystemTimeNanoSeconds += SYSTICKNS;
-  if(g_ulSystemTimeNanoSeconds >= 1000000000) //1 second interval
-      {
-          //GPIOPinWrite(PPS_GPIO_BASE, PPS_GPIO_PIN, PPS_GPIO_PIN); ???
-          g_ulSystemTimeNanoSeconds -= 1000000000;
-          g_ulSystemTimeSeconds += 1;
-
-          //TODO: set interval back to 1 second
-          updateElMeasuringAndMeteringData(1000.0, EMInterfaceGetVoltage(), EMInterfaceGetCurrent());
-
-          RIT128x96x4StringDraw("N", 0, 28, 15);
-          DisplayOdo(g_nBE_TotalEnergyValue, 28);
-
-          RIT128x96x4StringDraw("C", 0, 36, 15);
-          DisplayOdo(g_nBE_ConsumedEnergyValue, 36);
-
-          RIT128x96x4StringDraw("P", 0, 44, 15);
-          DisplayOdo(g_nBE_ProducedEnergyValue, 44);
-
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1Current].m_nAttribValue.m_fReal, "I:", "A", 74, 0);
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1toNVoltage].m_nAttribValue.m_fReal, "U:", "V", 74, 66);
-
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELELineFrequency].m_nAttribValue.m_fReal, "f:", "Hz", 82, 0);
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1RealPower].m_nAttribValue.m_fReal, "P:", "W", 82, 66);
-
-      }
-
-
-  //
-  // Call the lwIP timer handler.
-  //
-  lwIPTimer(SYSTICKMS);
-}
-
-
-//*****************************************************************************
-//
-// Display an lwIP type IP Address.
-//
-//*****************************************************************************
-void
-DisplayIPAddress(unsigned long ipaddr, unsigned long ulCol,
-                 unsigned long ulRow)
-{
-    char pucBuf[16];
-    unsigned char *pucTemp = (unsigned char *)&ipaddr;
-
-    //
-    // Convert the IP Address into a string.
-    //
-    sprintf(pucBuf, "%d.%d.%d.%d", pucTemp[0], pucTemp[1], pucTemp[2],
-             pucTemp[3]);
-
-    //
-    // Display the string.
-    //
-    RIT128x96x4StringDraw(pucBuf, ulCol, ulRow, 15);
-}
-
-
-//*****************************************************************************
-//
-// Display a 5 digit odometer
-//
-//*****************************************************************************
-void
-DisplayOdo(EIP_INT64 pa_nValue, unsigned long pa_nRow) {
-  char pucBuf[23];
-  char pucSign[2];
-  UINT16 odoMeter[5] = {0,0,0,0,0};
-  int i = 0;
-
-
-  if (0 > pa_nValue) {
-    pa_nValue = pa_nValue * (-1);
-    sprintf(pucSign,"-");
-  } else {
-    sprintf(pucSign," ");
-  }
-  RIT128x96x4StringDraw(pucSign, 6, pa_nRow, 15);
-
-
-  for (i=0; i<5;++i) {
-      odoMeter[i] = pa_nValue % 1000;
-      pa_nValue /= 1000;
-  }
-
-  sprintf(pucBuf, "%03d,%03d,%03d,%03d,%03d", odoMeter[4], odoMeter[3],
-      odoMeter[2], odoMeter[1], odoMeter[0]);
-
-  RIT128x96x4StringDraw(pucBuf, 12, pa_nRow, 15);
-
-}
-
-
-//*****************************************************************************
-//
-// Split double value at decimal-point and provide integer values
-// for both values. the value after the decimal point is limited to 3 digits
-//
-//*****************************************************************************
-void
-splitDecimal(double pa_fValue, char* pa_pSign, int* pa_pFull, int* pa_pMilli){
-  if (0 <= pa_fValue) {
-      *pa_pSign = ' ';
-      *pa_pFull = floor(pa_fValue);
-      *pa_pMilli = floor(fmod(pa_fValue, 1.0)*1000);
-  } else {
-      *pa_pSign = '-';
-      *pa_pFull = floor(-1.0 * pa_fValue);
-      *pa_pMilli = floor(fmod(pa_fValue * (-1.0), 1.0)*1000);
-  }
-}
-
-
-
-//*****************************************************************************
-//
-// Print the given double-value, preceeded by pre-fix and followed by post-fix
-// at given position of OLED-display
-//
-//*****************************************************************************
-void
-DisplayRealVal(double pa_fValue, const char *pcPrefix, const char *pcPostfix, unsigned long pa_nRow, unsigned long pa_nCol) {
-  char pucBuf[23];
-
-  int Val;
-  int milliVal;
-  char sign;
-
-  splitDecimal(pa_fValue, &sign, &Val, &milliVal);
-//TODO: minor bug: values between -1 and 0 have incorrect sign at output (there is no integer value with -0)
-  sprintf(pucBuf, "%s%c%2d.%03d%s", pcPrefix, sign, Val, milliVal, pcPostfix);
-  RIT128x96x4StringDraw(pucBuf, pa_nCol, pa_nRow, 15);
-}
-

+ 1 - 1
source/src/ports/LM3S8962/sample_application/CMakeLists.txt

@@ -9,4 +9,4 @@ opener_common_includes()
 #######################################
 opener_platform_support("INCLUDES")
 
-add_library(SAMPLE_APP sampleapplication.c)
+add_library( SAMPLE_APP main.c )

+ 9 - 178
source/src/ports/LM3S8962/sample_application/main.c

@@ -8,7 +8,7 @@
 // Software License Agreement
 //
 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
-// exclusively on LMI's microcontroller products.
+// exclusively on LMI's micro controller products.
 //
 // The software is owned by LMI and/or its suppliers, and is protected under
 // applicable copyright laws.  All rights are reserved.  You may not combine
@@ -45,21 +45,15 @@
 #include "driverlib/systick.h"
 #include "lwiplib.h"
 
-#include "local.h"
 #include "flashmgr.h"
 #include "networkhandler.h"
 #include <opener_api.h>
 #include "cipcommon.h"
 #include "random.h"
 #include <trace.h>
-#include "../../cip_energy/ElEnergyData.h"
-#include "eminterface.h"
-
-int callocsize = CALLOCSIZE;
-char callocmem[CALLOCSIZE];
 
 //define here instead of ptpd.h
-volatile unsigned long g_ulSystemTimeSeconds;
+volatile unsigned long g_ulSystemTimeSecfunctiononds;
 volatile unsigned long g_ulSystemTimeNanoSeconds;
 
 // cast an int as a struct_inaddr (check the "inet_ntoa" man page -- it wants a struct_inaddr passed by value, not an int)
@@ -67,6 +61,10 @@ volatile unsigned long g_ulSystemTimeNanoSeconds;
 //#define useStaticIP 1
 #define useStaticIP 0
 
+#ifndef useStaticIP
+#error "useStaticIP undefined"
+#endif
+
 struct parm
 {
   int useStatic; // 1 use static IP address, 0 use DHCP
@@ -108,14 +106,6 @@ __error__(char *pcFilename, unsigned long ulLine)
   }
 #endif
 
-void DisplayIPAddress(unsigned long ipaddr, unsigned long ulCol,
-                 unsigned long ulRow);
-void DisplayOdo(EIP_INT64 pa_nValue, unsigned long pa_nRow);
-
-
-void DisplayRealVal(double pa_fValue, const char *pcPrefix, const char *pcPostfix, unsigned long pa_nRow, unsigned long pa_nCol);
-
-
 // change my IP address etc.
 void
 setCIPaddress(unsigned long addr, // my IP address, in network order
@@ -155,7 +145,6 @@ lwIPHostTimerHandler(void)
       ulNetmask = lwIPLocalNetMaskGet();
       ulGateway = lwIPLocalGWAddrGet();
       setCIPaddress(ulIPAddress, ulNetmask, ulGateway);
-      DisplayIPAddress((ulIPAddress), 36, 8);
     }
 }
 
@@ -218,17 +207,11 @@ main(void)
   SysTickEnable();
   SysTickIntEnable();
 
-  //
-  // Initialize ADC
-  //
-  EMInterfaceInit();
   //
   // Enable processor interrupts.
   //
   IntMasterEnable();
 
-
-
   //
   // Configure the hardware MAC address for Ethernet Controller filtering of
   // incoming packets.
@@ -273,7 +256,7 @@ main(void)
   //
 
 
-  pl = parmFind();
+  pl = findNextEmptyParameterBlock();
   p = (struct parm *) (pl + 1);
 
   if (useStaticIP)
@@ -281,7 +264,6 @@ main(void)
       OPENER_TRACE_INFO("using static IP address\n");
 
       ip = 0x8083BAC9; //128.130.200.201
-//      ip = 0x8083BACB; //128.130.200.203
       nm = 0xFFFFFF00;
       gw = 0x8083BA01;
       valid = 7;
@@ -297,26 +279,6 @@ main(void)
       lwIPInit(pucMACArray, 0, 0, 0, IPADDR_USE_DHCP);
     }
 
-
-  // Set the interrupt priorities.  We set the SysTick interrupt to a higher
-    // priority than the Ethernet interrupt to ensure that the file system
-    // tick is processed if SysTick occurs while the Ethernet handler is being
-    // processed.  This is very likely since all the TCP/IP and HTTP work is
-    // done in the context of the Ethernet interrupt.
-    //
-    //
-    // Initialize the OLED display.
-    //
-    RIT128x96x4Init(1000000);
-    RIT128x96x4StringDraw("OpENer w/ CIP-Energy", 4, 0, 15);
-    RIT128x96x4StringDraw("-----------------------", 0, 14, 15);
-    RIT128x96x4StringDraw("IP:   ", 0, 8, 15);
-    DisplayIPAddress(htonl(ip), 36, 8);
-
-    RIT128x96x4StringDraw("  TWh GWh MWh kWh  Wh  ", 0, 20, 15);
-
-    RIT128x96x4StringDraw("factor 1000 applies    ", 0, 54, 10);
-    RIT128x96x4StringDraw("to metered values     ", 0, 62, 10);
     //change time-interval value for call of updateElMeasuringAndMeteringData
     //in SysTickIntHandler-method to show/provide correct values (see line 370)
 
@@ -329,8 +291,6 @@ main(void)
   /* Setup the CIP Layer */
   CIP_Init(365);
   IntMasterDisable();
-  CIP_BaseEnergy_Init();
-  CIP_ElEnergy_Init();
 
   IntMasterEnable();
   Start_NetworkHandler();
@@ -346,13 +306,12 @@ main(void)
 /* implement missing functions rand and srand */
 int _EXFUN(rand,(_VOID))
 {
-  return RandomNumber();
+  return nextXorShiftUInt32();
 }
 
 _VOID   _EXFUN(srand,(unsigned __seed))
 {
-  RandomAddEntropy(__seed);
-  RandomSeed();
+  setXorShiftSeed(__seed);
 }
 
 
@@ -369,32 +328,6 @@ void SysTickIntHandler(void) {
   // Update internal time and set PPS output, if needed.
   //
   g_ulSystemTimeNanoSeconds += SYSTICKNS;
-  if(g_ulSystemTimeNanoSeconds >= 1000000000) //1 second interval
-      {
-          //GPIOPinWrite(PPS_GPIO_BASE, PPS_GPIO_PIN, PPS_GPIO_PIN); ???
-          g_ulSystemTimeNanoSeconds -= 1000000000;
-          g_ulSystemTimeSeconds += 1;
-
-          //TODO: set interval back to 1 second
-          updateElMeasuringAndMeteringData(1000.0, EMInterfaceGetVoltage(), EMInterfaceGetCurrent());
-
-          RIT128x96x4StringDraw("N", 0, 28, 15);
-          DisplayOdo(g_nBE_TotalEnergyValue, 28);
-
-          RIT128x96x4StringDraw("C", 0, 36, 15);
-          DisplayOdo(g_nBE_ConsumedEnergyValue, 36);
-
-          RIT128x96x4StringDraw("P", 0, 44, 15);
-          DisplayOdo(g_nBE_ProducedEnergyValue, 44);
-
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1Current].m_nAttribValue.m_fReal, "I:", "A", 74, 0);
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1toNVoltage].m_nAttribValue.m_fReal, "U:", "V", 74, 66);
-
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELELineFrequency].m_nAttribValue.m_fReal, "f:", "Hz", 82, 0);
-          DisplayRealVal(g_astEE_ObjInstanceAttribs[eELEL1RealPower].m_nAttribValue.m_fReal, "P:", "W", 82, 66);
-
-      }
-
 
   //
   // Call the lwIP timer handler.
@@ -402,105 +335,3 @@ void SysTickIntHandler(void) {
   lwIPTimer(SYSTICKMS);
 }
 
-
-//*****************************************************************************
-//
-// Display an lwIP type IP Address.
-//
-//*****************************************************************************
-void
-DisplayIPAddress(unsigned long ipaddr, unsigned long ulCol,
-                 unsigned long ulRow)
-{
-    char pucBuf[16];
-    unsigned char *pucTemp = (unsigned char *)&ipaddr;
-
-    //
-    // Convert the IP Address into a string.
-    //
-    sprintf(pucBuf, "%d.%d.%d.%d", pucTemp[0], pucTemp[1], pucTemp[2],
-             pucTemp[3]);
-
-    //
-    // Display the string.
-    //
-    RIT128x96x4StringDraw(pucBuf, ulCol, ulRow, 15);
-}
-
-
-//*****************************************************************************
-//
-// Display a 5 digit odometer
-//
-//*****************************************************************************
-void
-DisplayOdo(EIP_INT64 pa_nValue, unsigned long pa_nRow) {
-  char pucBuf[23];
-  char pucSign[2];
-  UINT16 odoMeter[5] = {0,0,0,0,0};
-  int i = 0;
-
-
-  if (0 > pa_nValue) {
-    pa_nValue = pa_nValue * (-1);
-    sprintf(pucSign,"-");
-  } else {
-    sprintf(pucSign," ");
-  }
-  RIT128x96x4StringDraw(pucSign, 6, pa_nRow, 15);
-
-
-  for (i=0; i<5;++i) {
-      odoMeter[i] = pa_nValue % 1000;
-      pa_nValue /= 1000;
-  }
-
-  sprintf(pucBuf, "%03d,%03d,%03d,%03d,%03d", odoMeter[4], odoMeter[3],
-      odoMeter[2], odoMeter[1], odoMeter[0]);
-
-  RIT128x96x4StringDraw(pucBuf, 12, pa_nRow, 15);
-
-}
-
-
-//*****************************************************************************
-//
-// Split double value at decimal-point and provide integer values
-// for both values. the value after the decimal point is limited to 3 digits
-//
-//*****************************************************************************
-void
-splitDecimal(double pa_fValue, char* pa_pSign, int* pa_pFull, int* pa_pMilli){
-  if (0 <= pa_fValue) {
-      *pa_pSign = ' ';
-      *pa_pFull = floor(pa_fValue);
-      *pa_pMilli = floor(fmod(pa_fValue, 1.0)*1000);
-  } else {
-      *pa_pSign = '-';
-      *pa_pFull = floor(-1.0 * pa_fValue);
-      *pa_pMilli = floor(fmod(pa_fValue * (-1.0), 1.0)*1000);
-  }
-}
-
-
-
-//*****************************************************************************
-//
-// Print the given double-value, preceeded by pre-fix and followed by post-fix
-// at given position of OLED-display
-//
-//*****************************************************************************
-void
-DisplayRealVal(double pa_fValue, const char *pcPrefix, const char *pcPostfix, unsigned long pa_nRow, unsigned long pa_nCol) {
-  char pucBuf[23];
-
-  int Val;
-  int milliVal;
-  char sign;
-
-  splitDecimal(pa_fValue, &sign, &Val, &milliVal);
-//TODO: minor bug: values between -1 and 0 have incorrect sign at output (there is no integer value with -0)
-  sprintf(pucBuf, "%s%c%2d.%03d%s", pcPrefix, sign, Val, milliVal, pcPostfix);
-  RIT128x96x4StringDraw(pucBuf, pa_nCol, pa_nRow, 15);
-}
-

+ 80 - 0
source/src/ports/LM3S8962/stubs.c

@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Rockwell Automation, Inc.
+ * All rights reserved. 
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <trace.h>
+
+int __errno(void)
+  {
+    return 0;
+  }
+
+void raise(void)
+  {
+    while (1)
+      ;
+  }
+
+void abort(void)
+  {
+    while (1)
+      ;
+  }
+
+void BUG(char *s)
+  {
+    while (1)
+      ;
+  }
+
+static char dumpbuf[256];
+
+void __assert_func(const char *__file, int __line, const char *__function,
+    const char *__assertion)
+  {
+    snprintf(dumpbuf, 100,
+        "assert(%s) failed in function %s, file %s, at line %d\n", __assertion,
+        __function, __file, __line);
+
+    OPENER_TRACE_ERR(dumpbuf);
+    while (1)
+      ;
+  }
+
+void dump(unsigned char *p, int size)
+  {
+    int i;
+    char *b;
+
+    while (size>0)
+      {
+        b = dumpbuf;
+        for (i=0; i<16; i++)
+          {
+            if (i<size)
+              b += sprintf(b, "%02x ", p[i]);
+            else
+              b += sprintf(b, "   ");
+          }
+        b += sprintf(b, " |");
+        for (i=0; i<16; i++)
+          {
+            if (i<size)
+              {
+                if (' '<=p[i]&&p[i]<0x7f)
+                  b += sprintf(b, "%c", p[i]);
+                else
+                  b += sprintf(b, ".");
+              }
+          }
+        p += 16;
+        size -= 16;
+        OPENER_TRACE_INFO("%s\n", dumpbuf);
+      }
+  }