Jump to content
43oh

New Energia release 0101E0011 - 12/17/2013


Recommended Posts

I am happy to announce that release 0101E0011 just went up on energia.nu. 

 

I want to thank everybody for their support and contributions. Energia would not have been possible without such an awesome community!

 

The highlights are:

  • Lots of bug fixes
  • Major update to the CC3000 WiFi BoosterPackLibrary for the MSP430F5529 and TivaC/Stellaris LaunchPad
  • Updated ARM tools to gcc-arm-embedded
  • Initial C2000 support (thanks to Trey German for all his hard work on getting Energia ported to the C2000)
  • CCSv6 Energia Sketch import
  • Support for MSP-EXP430G2 LaunchPad
  • Support for MSP-EXP430F5529LP LaunchPad
  • Support for EK-TM4C123GXL (TivaC) LaunchPad
  • Support for EK-LM4F120XL (Stellaris) LaunchPad
  • Runs on Windows (XP/7/8), Mac OS X and Linux (32/64 bit)
Happy Making!

 

Robert

Link to post
Share on other sites

New feature (I helped, figured I'd document it here for everyone)-

 

Stellaris / Tiva-C core's HardwareSerial.cpp was previously declaring all 8 available Serial objects with generous buffer sizes (1KB TX & RX), using up a lot of memory especially for serial ports you don't use.

 

Energia 11's HardwareSerial.cpp now allocates its buffers one time during begin() using malloc() (a fairly legit use of malloc, as it's allocated just once at the beginning) with a default TX and RX buffer size of 64 to be conservative.  This means that no TX or RX buffers are allocated until you run a corresponding Serial*'s begin() method.

 

This can be overridden by changing TX and RX buffer sizes BEFORE running Serial*.begin() using the new Serial*.setBufferSize(<tx>, <rx>); method.

void setup() {
  Serial.setBufferSize(1024, 512);  // Able to dump a lot of text at once w/o blocking
  Serial.begin(115200);

  Serial3.setBufferSize(16, 1024);  // Can buffer incoming data for ~1 second before overflowing
  Serial3.begin(9600);
}
Link to post
Share on other sites

I upgraded the driverlib to the latest version. I was very carful with replacing it but it could be that I missed something.

 

 

My Canbus sketch does not work anymore.

Can you please post the Sketch?

 

The pin definitions for the LM4F are not included in pin_map.h.

Can you please be more specific which definitions you are referring to?

 

 

The driverlib for the lm4f (Energia\hardware\lm4f\cores\lm4f\driverlib) seems to be taken from the Tiva C software package.

Yes but LM4F is completely compatible with the TivaC one.

 

 

Where are the definitions for the LM4F's?

 

I would help me a lot if you could specify which definitions these are.

Link to post
Share on other sites

I rewrote the example (multi_rx.c) from the Stellarisware examples for Energia. When I saw that driverlib was taken from TivaWare, I reworked my sketch with the example from TivaWare. I was warned because TI states that TivaWare only works for the C-series.

/*****************************************************************************
// CANtest.ino - Peripheral example demonstrating multiple CAN message
//              reception.
// 
//*****************************************************************************
#include <inttypes.h>

//#include <stdbool.h>
//#include <stdint.h>
//#define PART_LM4F120H5QR
//#include "inc/lm4f120h5qr.h"
#include "inc/hw_can.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/can.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
//#include "utils/uartstdio.h"

//*****************************************************************************
//
//!
//! This example shows how to set up the CAN to receive multiple CAN messages
//! using separate message objects for different messages, and using CAN ID
//! filtering to control which messages are received.  Three message objects
//! are set up to receive 3 of the 4 CAN message IDs that are used by the
//! multi_tx example.  Filtering is used to demonstrate how to receive only
//! specific messages, and therefore not receiving all 4 messages from the
//! multi_tx example.  As messages are received the content of each are printed
//! to the serial console.
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - CAN0 peripheral
//! - GPIO port D peripheral (for CAN0 pins)
//! - CAN0RX - PD0
//! - CAN0TX - PD1
//!
//! The following UART signals are configured only for displaying console
//! messages for this example.  These are not required for operation of CAN.
//! - GPIO port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - INT_CAN0 - CANIntHandler
//
//*****************************************************************************

//*****************************************************************************
//
// A counter that keeps track of the number of times the RX interrupt has
// occurred, which should match the number of messages that were received.
//
//*****************************************************************************
volatile uint32_t g_ui32MsgCount = 0;

//*****************************************************************************
//
// A flag for the interrupt handler to indicate that a message was received.
//
//*****************************************************************************
volatile bool g_bRXFlag1 = 0;
volatile bool g_bRXFlag2 = 0;
volatile bool g_bRXFlag3 = 0;

//*****************************************************************************
//
// A flag to indicate that some reception error occurred.
//
//*****************************************************************************
volatile bool g_bErrFlag = 0;

//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************

// lcd display thru I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x38,16,2);  // LCD address 0x38, charcolumns 16, rows 2

const byte briPin =  9;
unsigned int bri;
String lcdrow_0 = "start";
String lcdrow_1 = "looping";

tCANMsgObject sCANMessage;
unsigned char ucMsgData[8];


void setup()
{
  // Outputs
  Wire.setModule(2);  //use I2C-2 pins
  lcd.init();
  delay(2);
  Serial.begin(115200) ;               //Debugging initialize the serial communication:


  tCANMsgObject sCANMessage;
  uint8_t pui8MsgData[8];
  //
  // Set the clocking to run directly from the external crystal/oscillator.
  // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
  // crystal used on your board.
  //
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);

  //
  // Set up the serial console to use for displaying messages.  This is
  // just for this example program and is not needed for CAN operation.
  //
  // For this example CAN0 is used with RX and TX pins on port D0 and D1.
  // The actual port and pins used may be different on your part, consult
  // the data sheet for more information.
  // GPIO port D needs to be enabled so these pins can be used.
  // TODO: change this to whichever GPIO port you are using
  //
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

  //
  // Configure the GPIO pin muxing to select CAN0 functions for these pins.
  // This step selects which alternate function is available for these pins.
  // This is necessary if your part supports GPIO pin function muxing.
  // Consult the data sheet to see which functions are allocated per pin.
  // TODO: change this to select the port/pin you are using
  //
  GPIOPinConfigure(GPIO_PE4_CAN0RX); //geel
  GPIOPinConfigure(GPIO_PE5_CAN0TX); //oranje

  //
  // Enable the alternate function on the GPIO pins.  The above step selects
  // which alternate function is available.  This step actually enables the
  // alternate function instead of GPIO for these pins.
  // TODO: change this to match the port/pin you are using
  //
  GPIOPinTypeCAN(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);

  //
  // The GPIO port and pins have been set up for CAN.  The CAN peripheral
  // must be enabled.
  //
  SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
  //
  //
  // Initialize the CAN controller
  //
  CANInit(CAN0_BASE);


  //
  // Set up the bit rate for the CAN bus.  This function sets up the CAN
  // bus timing for a nominal configuration.  You can achieve more control
  // over the CAN bus timing by using the function CANBitTimingSet() instead
  // of this one, if needed.
  // In this example, the CAN bus is set to 500 kHz.  In the function below,
  // the call to SysCtlClockGet() is used to determine the clock rate that
  // is used for clocking the CAN peripheral.  This can be replaced with a
  // fixed value if you know the value of the system clock, saving the extra
  // function call.  For some parts, the CAN peripheral is clocked by a fixed
  // 8 MHz regardless of the system clock in which case the call to
  // SysCtlClockGet() should be replaced with 8000000.  Consult the data
  // sheet for more information about CAN peripheral clocking.
  //
  CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);

  //
  // Enable interrupts on the CAN peripheral.  This example uses static
  // allocation of interrupt handlers which means the name of the handler
  // is in the vector table of startup code.  If you want to use dynamic
  // allocation of the vector table, then you must also call CANIntRegister()
  // here.
  //
  // CANIntRegister(CAN0_BASE, CANIntHandler); // if using dynamic vectors
  //
  CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

  //
  // Enable the CAN interrupt on the processor (NVIC).
  //
  IntEnable(INT_CAN0);

  //
  // Enable the CAN for operation.
  //
  CANEnable(CAN0_BASE);

  //
  // Initialize a message object to receive CAN messages with ID 0x1001.
  // The expected ID must be set along with the mask to indicate that all
  // bits in the ID must match.
  //
  sCANMessage.ui32MsgID = 0x1001;               // CAN msg ID
  sCANMessage.ui32MsgIDMask = 0xfffff;          // mask, all 20 bits must match
  sCANMessage.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER |
    MSG_OBJ_EXTENDED_ID);
  sCANMessage.ui32MsgLen = 8;                   // allow up to 8 bytes

  //
  // Now load the message object into the CAN peripheral message object 1.
  // Once loaded the CAN will receive any messages with this CAN ID into
  // this message object, and an interrupt will occur.
  //
  CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_RX);

  //
  // Change the ID to 0x2001, and load into message object 2 which will be
  // used for receiving any CAN messages with this ID.  Since only the CAN
  // ID field changes, we don't need to reload all the other fields.
  //
  sCANMessage.ui32MsgID = 0x2001;
  CANMessageSet(CAN0_BASE, 2, &sCANMessage, MSG_OBJ_TYPE_RX);

  //
  // Change the ID to 0x3001, and load into message object 3 which will be
  // used for receiving any CAN messages with this ID.  Since only the CAN
  // ID field changes, we don't need to reload all the other fields.
  //
  sCANMessage.ui32MsgID = 0x3001;               // CAN msg ID
  CANMessageSet(CAN0_BASE, 3, &sCANMessage, MSG_OBJ_TYPE_RX);

  //
  // Enter loop to process received messages.  This loop just checks flags
  // for each of the 3 expected messages.  The flags are set by the interrupt
  // handler, and if set this loop reads out the message and displays the
  // contents to the console.  This is not a robust method for processing
  // incoming CAN data and can only handle one messages at a time per message
  // object.  If many messages are being received close together using the
  // same message object, then some messages may be dropped.  In a real
  // application, some other method should be used for queuing received
  // messages in a way to ensure they are not lost.  You can also make use
  // of CAN FIFO mode which will allow messages to be buffered before they
  // are processed.
  //

}


void loop()
{

  //
  // If the flag for message object 1 is set, that means that the RX
  // interrupt occurred and there is a message ready to be read from
  // this CAN message object.
  //
  if(g_bRXFlag1)
  {
    //
    // Reuse the same message object that was used earlier to configure
    // the CAN for receiving messages.  A buffer for storing the
    // received data must also be provided, so set the buffer pointer
    // within the message object.  This same buffer is used for all
    // messages in this example, but your application could set a
    // different buffer each time a message is read in order to store
    // different messages in different buffers.
    //
    sCANMessage.pui8MsgData = pui8MsgData;

    //
    // Read the message from the CAN.  Message object number 1 is used
    // (which is not the same thing as CAN ID).  The interrupt clearing
    // flag is not set because this interrupt was already cleared in
    // the interrupt handler.
    //
    CANMessageGet(CAN0_BASE, 1, &sCANMessage, 0);

    //
    // Clear the pending message flag so that the interrupt handler can
    // set it again when the next message arrives.
    //
    g_bRXFlag1 = 0;

    //
    // Print information about the message just received.
    //
    PrintCANMessageInfo(&sCANMessage, 1);
  }

  //
  // Check for message received on message object 2.  If so then
  // read message and print information.
  //
  if(g_bRXFlag2)
  {
    sCANMessage.pui8MsgData = pui8MsgData;
    CANMessageGet(CAN0_BASE, 2, &sCANMessage, 0);
    g_bRXFlag2 = 0;
    PrintCANMessageInfo(&sCANMessage, 2);
  }

  //
  // Check for message received on message object 3.  If so then
  // read message and print information.
  //
  if(g_bRXFlag3)
  {
    sCANMessage.pui8MsgData = pui8MsgData;
    CANMessageGet(CAN0_BASE, 3, &sCANMessage, 0);
    g_bRXFlag3 = 0;
    PrintCANMessageInfo(&sCANMessage, 3);

  }
}

//*****************************************************************************
//
// This function prints some information about the CAN message to the
// serial port for information purposes only.
//
//*****************************************************************************
void
PrintCANMessageInfo(tCANMsgObject *pCANMsg, uint32_t ui32MsgObj)
{
  unsigned int uIdx;

  //
  // Check to see if there is an indication that some messages were
  // lost.
  //
  if(pCANMsg->ui32Flags & MSG_OBJ_DATA_LOST)
  {
    Serial.print("CAN message loss detected on message object %d");
    Serial.println(ui32MsgObj);
    lcd.setCursor(0,0);
    lcd.print("Msg lost ");
    lcd.print(ui32MsgObj);

  }

  //
  // Print out the contents of the message that was received.
  //
  Serial.print("Msg Obj=%u ID=0x%05X len=%u data=0x");
  Serial.print(ui32MsgObj);
  Serial.print(pCANMsg->ui32MsgID, pCANMsg->ui32MsgLen);
  for(uIdx = 0; uIdx < pCANMsg->ui32MsgLen; uIdx++)
  {
    Serial.print("%02X ");
    Serial.print(pCANMsg->pui8MsgData[uIdx]);
  }
  Serial.println("");
}

//*****************************************************************************
//
// This function is the interrupt handler for the CAN peripheral.  It checks
// for the cause of the interrupt, and maintains a count of all messages that
// have been received.
//
//*****************************************************************************
void
CANIntHandler(void)
{
  uint32_t ui32Status;

  //
  // Read the CAN interrupt status to find the cause of the interrupt
  //
  ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);

  //
  // If the cause is a controller status interrupt, then get the status
  //
  if(ui32Status == CAN_INT_INTID_STATUS)
  {
    //
    // Read the controller status.  This will return a field of status
    // error bits that can indicate various errors.  Error processing
    // is not done in this example for simplicity.  Refer to the
    // API documentation for details about the error status bits.
    // The act of reading this status will clear the interrupt.
    //
    ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);

    //
    // Set a flag to indicate some errors may have occurred.
    //
    g_bErrFlag = 1;
  }

  //
  // Check if the cause is message object 1.
  //
  else if(ui32Status == 1)
  {
    //
    // Getting to this point means that the RX interrupt occurred on
    // message object 1, and the message reception is complete.  Clear the
    // message object interrupt.
    //
    CANIntClear(CAN0_BASE, 1);

    //
    // Increment a counter to keep track of how many messages have been
    // received.  In a real application this could be used to set flags to
    // indicate when a message is received.
    //
    g_ui32MsgCount++;

    //
    // Set flag to indicate received message is pending for this message
    // object.
    //
    g_bRXFlag1 = 1;

    //
    // Since a message was received, clear any error flags.
    //
    g_bErrFlag = 0;
  }

  //
  // Check if the cause is message object 2.
  //
  else if(ui32Status == 2)
  {
    CANIntClear(CAN0_BASE, 2);
    g_ui32MsgCount++;
    g_bRXFlag2 = 1;
    g_bErrFlag = 0;
  }

  //
  // Check if the cause is message object 3.
  //
  else if(ui32Status == 3)
  {
    CANIntClear(CAN0_BASE, 3);
    g_ui32MsgCount++;
    g_bRXFlag3 = 1;
    g_bErrFlag = 0;
  }

  //
  // Otherwise, something unexpected caused the interrupt.  This should
  // never happen.
  //
  else
  {
    //
    // Spurious interrupt handling can go here.
    //
  }
}

Error message: CANtest.ino:138:20: error: 'GPIO_PE4_CAN0RX' was not declared in this scope

Link to post
Share on other sites

If you #define PART_TM4C123GH6PM then you will be able to compile.

This just made me realize that the way Energia.h or Arduino.h is included under water needs some work to make it easer to use driverlib. You should not have to #define PART_TM4C123GH6PM as it is already done so in Energia.h. But because of the way Energia.h is included it comes after all the includes the user does in the Sketch. Hence "driverlib/pin_map.h" never sees #define PART_TM4C123GH6PM and GPIO_PE4_CAN0RX is undefined for the Sketch.

 

TivaC and Stellaris LaunchPad are fully compatible so no need to worry about that.

 

Hope this helps.

 

Robert

Link to post
Share on other sites

To clarify an issue that cropped up over here -- http://forum.43oh.com/topic/4842-did-any-driverlib-in-stellaris-change/ -- Energia 11 appears to now use TI's TivaWare driver library for the Stellaris and Tiva-C platforms, rather than StellarisWare as it appears was used in Energia 10 and previous releases.

 

This doesn't change a whole lot, but, if you have written sketches and libraries which utilize the StellarisWare driverlib directly, some porting may be necessary.

 

Please see this document - http://www.ti.com/lit/an/spma050a/spma050a.pdf - Application Report SPMA050A - Migrating Software Projects from StellarisWare® to TivaWare™

This outlines the differences and updates between the two.

Link to post
Share on other sites
  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...