Jump to content
igor

eLua for Stellaris Launchpad

Recommended Posts

I am working on porting eLua to the Stellaris and Tiva Launchpad.

eLua is a version of Lua (a scripting language) for microcontrollers.
Main eLua web site http://www.eluaproject.net/
eLua works as an interpreter running on the virtual serial port.
eLua already runs on several of the Stellaris LM3 development kits.

Source code for my port is available on Github https://github.com/ecdr/elua

in the LM4 branch

Current status:

It compiles (using codesourcery) and runs (i.e. hello world and blinking led work).

Undergoing testing.

It is integer only (may not be enough memory for floating point).
Several peripherals are turned off (no CAN, no I2C).

[Edit: CAN now turned on]

Share this post


Link to post
Share on other sites

I just updated the Stellaris version of eLua to version 0.9

Still needs more testing.

 

Latest build is attached in a zip file.

 

See the eLua site for instructions on how to use.

 

Quick version:

Unzip it.  Flash it to Stellarish Launchpad.

Open a terminal window to the launchpad, (115200 baud, n, 8, 1)

Type help for list of commands at the prompt.

You can type in eLua code, or send it files using xModem.

 

Let me know if you find errors.

elua_lualong_ek-lm4f120-2013-07-03.zip

elua_lualong_ek-lm4f120-2013-08-01.zip

Share this post


Link to post
Share on other sites

Hi Igor,

 

I have successfully flashed the eLua image on my Stellaris Launchpad and it seems to work as expected.

I could run some sample applications with minor changes without issues.

 

I have some questions:

- how much ram is available in eLua on Stellaris?

- will you support an sdcard in the future?

- why only 2 ADCs?

 

Thanks,

Calin

Share this post


Link to post
Share on other sites

Calin

The Launchpad only has 2 ADCs.  I haven't studied the ADC code really carefully, it might be possible to use the ADCs to measure more than 2 sources

by multiplexing (have them cycle through several sources).   Of course that would mean any given source would not be read as frequently.  (For instance I have experimented making a 3rd channel that reads the thermister).

 

eLua has support for SD cards.  (e.g. on the LM3S8962, which has an SD card slot on the evaluation board, and a lot more RAM than the launchpad)  

I suspect that the RAM required may make it impractical on the launchpad (i.e. space for sector buffers), but I am not sure.  I know libraries like 

PetiteFatFS can run in some pretty constrained memory.

I just quickly looked over the code involved (elua_mmc.c, and fatfs), and it is not obvious how much memory it needs.

Not something I am too likely to take on any time soon.

 

What application do you have in mind?  If want to load data or programs, there is the ROMFS to consider (which lets you put files in

flash memory, and use them like a read only file system).  I have not tested that, and I don't know how much flash is available,

although that should be easy enough to figure out from the binary.

 

I am working on adding EEPROM support to eLua to take advantage of the launchpad's built in EEPROM.  

 

I would also like to know how much RAM is available in eLua, so far I haven't found the command to determine that.

 

Igor

Share this post


Link to post
Share on other sites

@@calinp

 

I was just thinking about the SD card thing.  I had a go at compiling eLua with SD card support turned on.

It compiles okay, but I do not have a convenient way to test it.  (Don't have a SD card socket on a breakout board).

If you want to try it out, I can post the compiled code.

 

I set it to use SPI #0, with CS on port A, pin 6 (I think).

Let me know if you want to try it, and if need to change any of the port definitions.

 

As far as memory usage, there is gcinfo(), but that returns number of kbytes used, not the amount available.

 

[Edit: After playing with gcinfo - at the beginning it says about 4 to 5 kb used.  It seems to run out of memory at around 18 kb used,

so looks like something around 14kb available.  This was in the version with the SD card support turned on, may be more without that.]

Share this post


Link to post
Share on other sites

Hi Igor,

 

I can confirm that you can upload programs to the /wo file system and run them from there. As i understood from the documentation, the /romfs can be used to include external programs/modules at compile time. For me, the SD card would enable datalogging

 

I have a SD card connected on SPI0 on default pins on portA:

#define SDC_SSI_CLK GPIO_PIN_2
#define SDC_SSI_TX GPIO_PIN_5
#define SDC_SSI_RX GPIO_PIN_4
#define SDC_SSI_FSS GPIO_PIN_3

 

About the ADC, there are two converter modules that share 12analog input channels. I think with eLua I can access only analog channels 0 and 1 (and the temperature mesurement channel) and it gives an error if I try to access others. Maybe you can rebuild eLua with more channels enabled.

 

Thanks,

Calin

Share this post


Link to post
Share on other sites

Here is a build of elua which should supposedly have SD card support.

I have not tested SPI communications (which the SD card support is based on), so I expect it won't work.

 

http://www.eluaproject.net/doc/v0.8/en_fatfs.html

 

The pins should be as you noted,

In addition, Port A pin 6 should be chip select 

http://www.eluaproject.net/doc/v0.8/en_building.html

 

You didn't say which pin to use for that, so I left it as is. 

 

Try this at your own risk (do not put an SD card in there with your only copy of anything important, ...)

 

Without having an SD card hooked up it does not seem to recognize the /mmc file system, so I suspect

that something isn't set right yet.  But I do not expect that there is any harm in trying it.

 

Let me know how it works out (any symptoms, etc.)

 

I will look at the ADC code a bit closer.

 

Thanks for testing it,

Igor

 

[Edit: The file I posted here last night had SD card, but did not have ADC enabled.  

I recompiled with both SD card and ADC, so the attachment has changed.  ADC still just 2 channels plus temperature.]

[Edit 23 Jul 2013: ADC now has 12 channels, plus temperature (last channel)  Changed select to pin 3 on port A.]

 

elua_lualong_ek-lm4f120-2013-07-23-SD.zip

Share this post


Link to post
Share on other sites

Hi,

Actually Chip select pin is on Port A, Pin 3 -  "#define SDC_SSI_FSS GPIO_PIN_3".

I think I can try your build with Chip Select on pin 6.

 

Calin

 

 

At the first run the SD support is working. I can succesfully list the files on the SD Card ! 

Next i will try to create and edit some files.

 

The card is connected as I posted earlier, with CS on Port A, Pin 3.

 

 

Thanks!

Edited by calinp

Share this post


Link to post
Share on other sites

 

Hi,

 

At the first run the SD support is working. I can succesfully list the files on the SD Card !

Next i will try to create and edit some files.

 

The card is connected as I posted earlier, with CS on Port A, Pin 3.

 

Thanks!

Very cool.

 

Sorry for the confusion on the pins, from the eLua documentation it looked like there was an additional signal for MMCFS, beyond the regular SPI pins.

 

Edit: Looks like the eLua code doesn't use the FSS signal from the SPI port.  Instead it handles chip select directly, and gives option to define it to arbitrary pin.

 

I think I have figured out the ADC thing.  Have built a version that should work with 12 channels, plus temperature sensor.  Will upload presently.

Share this post


Link to post
Share on other sites

Just as a starting point for anyone trying the eLua image, thought I would post the eLua hello world program, adapted to the launchpad.

-- eLua blinking led example, the Hello World of embedded 

local uartid, invert, ledpin = 0, false
if pd.board() == "EK-LM4F120" then
  ledpin = pio.PF_1			-- Red is PF 1, Blue is PF 2, Green is PF 3
else
  print( "\nError: Unknown board " .. pd.board() .. " !" )
  return
end

function cycle()
  if not invert then
    pio.pin.sethigh( ledpin )
  else
    pio.pin.setlow( ledpin )
  end
  tmr.delay( 0, 500000 )
  if not invert then
    pio.pin.setlow( ledpin )
  else
    pio.pin.sethigh( ledpin )
  end
  tmr.delay( 0, 500000 )
end

pio.pin.setdir( pio.OUTPUT, ledpin )
print( "Hello from eLua on " .. pd.board() )
print "Watch your LED blinking :)"
print "Enjoy eLua !"
print "Press any key to end this demo.\n"

while uart.getchar( uartid, 0 ) == "" do
  cycle()
end

Save it in a file.

In your terminal program, type recv.

Upload the file using xmodem from your terminal program.

Watch the blinking light.

 

Adapted for the LM4F120 from https://github.com/elua/examples

 

[Edit: Repository of examples with additions to support LM4F120 at https://github.com/ecdr/examples ]

Share this post


Link to post
Share on other sites

I posted a fresh build of the version with SD card support (above).  It now has chip select on pin 3.  

Also has all the ADC channels enabled (only using 1 of the two ADC).

 

@@calinp In answer to your question about memory usage.  

I added a new function to the cpu module.  cpu.mem() returns the amount of memory available to eLua for dynamic memory allocation.

Usage: print(cpu.mem()) 

This is not the same as how much memory is available for your program (it will not change as memory is used, does not reflect initial memory allocated by 

elua, etc.)  It gives an idea of an upper bound on available memory.

 

For instance,

27,911 bytes - the current build (without CAN, PWM, I2C) but without MMC

27,051 bytes - same as above, but turning on MMC support (so MMC support takes about 860 bytes extra static memory )

27,895 bytes - current build, no MMC, but with the command line editor enabled (3 lines in shell, 10 lines in elua)

 

[Edit: Posted version does not have the function active.  But the results are posted in this message.]

 

Aside, the 8962 kit runs eLua, http://forum.stellarisiti.com/topic/694-stellaris-ekt-lm3s8962-kits/ has a lot more RAM (can use floating point in elua), and has built in small SD card slot, ethernet, and oled with elua support.

Share this post


Link to post
Share on other sites

Latest build posted, CAN now enabled.  I have only tested it with loop back (don't have a transceiver at the moment).  If anybody tests the CAN function, please let me know.

It also now has the line editor enabled, so you can edit last few lines of text entered at the eLua prompt.

Share this post


Link to post
Share on other sites

Another example program.

One of the advantages of something like eLua is it allows exploratory programming.  (Just type in some code to try out a particular feature on the fly, rather than having to go through compile, upload, cycle).

(Similar to bus pirate)

 

Most peripherals on the Stellaris work by special memory addresses, so using memory read/write commands one can try out features that are not 

supported by whatever library one is using.

 

For instance, while experimenting with the CAN module I eventually discovered that unlike other peripherals, you have to read a particular location twice (with a delay) to

get the value of CAN memory addresses (registers).  Figuring out what was going on took some head scratching and digging through example code, but

using eLua meant I could try things quicker and spend more of my time trying to work out the puzzle, and less of it waiting.

-- CAN example
-- use Loopback

assert(can, "No CAN do")

can.setup(0, 500000) -- Clock 500 kHz


if pd.board() == "EK-LM3S8962" or pd.board() == "EK-LM4F120" then

-- Caveat programmer -
--  The CAN registers are not like normal memory addresses
--  You have to read them twice (allowing a delay of 5 times through an empty loop in C) to get the actual value
--  Likewise, when writing, you have to wait 5 times through empty loop before the value actually takes effect
--  Found this from the stellarisware code, not well explained in the documentation

-- control CAN loopback mode (loopon true = make loopback, false = no loopback)

function cantest(id, loopon, silent)
  local canctl, cantst

  if not(id == 0) then
	print("Error: cantest only works with CAN0.")
  end

  canctl = 0x40040000
  cantst = canctl + 0x014

  cpu.r8(canctl)			-- Pre-read (need to read then delay then read again)

  if loopon or silent then
-- bit 7 set is TEST mode (silent, loopback only work when in test mode)
    cpu.w8(canctl,bit.set(cpu.r8(canctl),7))
  else
    cpu.w8(canctl,bit.clear(cpu.r8(canctl),7))
  end

  cpu.r8(cantst)			    -- Pre-read (need to read then delay then read again)

-- bit 4 set LBACK loopback
  if loopon then
    cpu.w8(cantst, bit.set(cpu.r8(cantst), 4))
  else
    cpu.w8(cantst, bit.clear(cpu.r8(cantst), 4))
  end

  cpu.r8(cantst)			    -- Pre-read (need to read then delay then read again)

-- bit 3 is SILENT
  if silent then
    cpu.w8(cantst, bit.set(cpu.r8(cantst), 3))
  else
    cpu.w8(cantst, bit.clear(cpu.r8(cantst), 3))
  end

end

end




print("Can loopback")
cantest(0, true, false)

local canid, canidtype, message

-- canidtype is can.ID_STD (11 bit ID) or can.ID_EXT (29 bit ID)
local canid_s = 42
local message_s = "CAN1"
print("CAN send")

can.send(0, canid_s, can.ID_STD, message_s )

tmr.delay(0,50)			-- Allow some time for send/receive to happen

print("CAN receive")
for i=1, 50 do
	canid, canidtype, message = can.recv( 0 )
	if canid then
		break
	end
end

if not (canid_s == canid) then
	print("canid wrong")
	print(canid)
else
	print("canid OK")
end

if not (canidtype == can.ID_STD) then
	print("canid type wrong")
	print(canidtype)
else
	print("canid type OK")
end

if not (message_s == message) then
	print("message wrong")
	print(message)
else
	print("message OK")
end

Share this post


Link to post
Share on other sites

I'll totally want to try this, as I've designed a CAN boosterpack although my Tiva/Hercules build will wait til I get more RJ45 jacks. Currently playing with 2 MSP430's talking using MCP2515 SPI CAN controllers. But they'll be able to generate traffic for the Tiva.

Share this post


Link to post
Share on other sites

I'll totally want to try this, as I've designed a CAN boosterpack although my Tiva/Hercules build will wait til I get more RJ45 jacks. Currently playing with 2 MSP430's talking using MCP2515 SPI CAN controllers. But they'll be able to generate traffic for the Tiva.

 

That would be great.  If/when you try it, please let me know (post message here, or PM) if it works or if it doesn't (so I can help fix).

I do not have a CAN transceiver, so at the moment the only testing I have done is via the loopback interface.  (So it should work, but would be better to have testing with real connections.)

I also extended the eLua driver to handle buffering of CAN messages (not sure if that code is up on Git yet).

 

I am working on a version specifically for the Tiva launchpad, to handle it's 2 CAN controllers.  

(Also have draft code for the quadrature encoder, and support for the Tiva/Stellaris EEPROM).

Share this post


Link to post
Share on other sites

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...