1
0
mirror of https://github.com/elua/elua.git synced 2025-01-08 20:56:17 +08:00
elua/docs/platform_modules.txt

268 lines
11 KiB
Plaintext

(NOTE: view this file with a monospaced font)
eLua platform modules
================================================================================
(NOTE: after reading this, check also the "generic_modules.txt" file to
learn about the generic (not platform specific) modules from eLua).
In order to make eLua usable on different platform, eLua provides a number of
"platform modules" that link the language with the hardware platform. They're
mainly tied up with the platform peripherals (PIO, UART, SPI and others).
They are loaded when Lua starts (just like the "standard" modules like os, math,
string).
All the platform modules have two parts: the generic part (the one that is
exposed directly to Lua and it's supposed to be platform independent) and the
platform specific part (the one that links the module operations to actual
hardware operations). Consequently, when adding a new platform, one doesn't need
to rewrite the whole module, just the platform-dependent part. The "platform
interface.txt" file shows the conenction between platform modules and platform
interface functions. For example, the "pio" module (src/modules/pio.c) needs 3
functions for interfacing with a specific platform: platform_pio_has_port,
platform_pio_has_pin and platform_pio_op.
All the modules are located in the "src/modules" directory. Besides their
actual implementation, the "src/modules/auxmods.h" file contains the Lua
compatible description of all the modules in the system.
Sometimes it doesn't make sense to include all the modules for a particular
platform. For example, for the i386 platform it doesn't make sense to include
the "pio" module (although this is technically possible by providing "bogus"
platform interface functions, the module won't be able to do anything on a i386
CPU, unless you want to "emulate" it via the parallel port or some other
peripheral). To accomodate this, each platform must provide a "platform_conf.h"
(src/platform/<your platform>) which (amongst other things) lists the modules
that are used for that specific platform. For example, if we want to enable
only the PIO module for the AT91SAM7X platform, the "platform_conf.h" file
would look like this:
(BEGIN src/platform/at91sam7x/platform_conf.h)
// Auxiliary libraries that will be compiled for this platform
#ifndef __PLATFORM_CONF_H__
#define __PLATFORM_CONF_H__
#include "auxmods.h"
...............................................................
#define LUA_PLATFORM_LIBS\
{ AUXLIB_PIO, luaopen_pio }
#endif
(END src/platform/at91sam7x/platform_conf.h)
On the other hand, for a platform that doesn't need to enable any modules at
all, you don't even need to define the LUA_PLATFORM_LIBS macro.
This is why some of platform functions described in "platform interface.txt" are
optional. If there are no modules that use them in one platform, then you don't
need to define them at all for that platform, not even as "bogus" functions.
================================================================================
=== The PIO module
================================================================================
The PIO module lets Lua access the programmable input/output (PIO) pins of the
microcontroller. It exposes symbolic name for ports (pio.PA, pio.PB, ... pio.PF)
and symbolic names for port pins (pio.PA_0, pio.PA_1, ... pio.PB_30, ...). Also,
it exposes functions to access both ports and pins:
pio.setpin( value, Pin1, Pin2 ... ): set the value to all the pins in the list
to "value" (0 or 1).
pio.set( Pin1, Pin2, ... ): set the value of all the pins in the list to 1.
Val1, Val2, ... = pio.get( Pin1, Pin2, ... ): reads one or more pins and returns
their values (0 or 1).
pio.clear( Pin1, Pin2, ... ): set the value of all the pins in the list to 0.
pio.input( Pin1, Pin2, ... ): set the specified pin(s) as input(s).
pio.output( Pin1, Pin2, ... ): set the specified pin(s) as output(s).
pio.setport( value, Port1, Port2, ... ): set the value of all the ports in the
list to "value".
Val1, Val2, ... = pio.getport( Port1, Port2, ... ): reads one or more ports and
returns their values.
pio.port_input( Port1, Port2, ... ): set the specified port(s) as input(s).
pio.port_output( Port1, Port2, ... ): set the specified port(s) as output(s).
pio.pullup( Pin1, Pin2, ... ): enable internal pullups on the specified pins.
Note that some CPUs might not provide this feature.
pio.pulldown( Pin1, Pin2, ... ): enable internal pulldowns on the specified
pins. Note that some CPUs might not provide this feature.
pio.nopull( Pin1, Pin2, ... ): disable the pullups/pulldowns on the specified
pins. Note that some CPUs might not provide this feature.
Port = pio.port( code ): return the physical port number associated with the
given code. For example, "pio.port( pio.P0_20 )" will return 0.
Pin = pio.pin( code ): return the physical port number associated with the
given code. For example, "pio.pin( pio.P0_20 )" will return 20.
================================================================================
=== The SPI module
================================================================================
The SPI module lets Lua access the SPI interfaces of the target CPU. It exposes
functions for SPI setup and sending/receiving data, selecting/unselecting slave
devices, as well as different SPI specific constants.
Actual_clock = spi.setup( id, spi.MASTER | spi.SLAVE, clock, cpol, cpha,
databits): set the SPI interface with the given parameters, returns the clock
that was set for the interface.
spi.select( id ): sets the SS line of the given interface.
spi.unselect( id ): clears the SS line of the given interface.
spi.send( id, Data1, Data2, ... ): sends all the data to the specified SPI
interface.
In1, In2, ... = spi.send_recv( id, Out1, Out2, ... ): sends all the "out" bytes
to the specified SPI interface and returts the data read after each sent byte.
================================================================================
=== The UART module
================================================================================
The UART module lets Lua access the UART interfaces of the target CPU. It
exposes functions for UART setup and sending/receiving data, as well as some
UART specific constants.
Actual_baud = uart.setup( id, baud, databits,
uart.PAR_EVEN |uart.PAR_ODD | uart.PAR_NONE,
uart.STOP_1 | uart.SSTOP_1_5 | uart.STOP_2 ): set the UART interface with the
given parameters, returns the baud rate that was set for the UART.
uart.send( id, Data1, Data2, ... ): send all the data to the specified UART
interface.
Data = uart.recv( id, uart.NO_TIMEOUT | uart.INF_TIMEOUT | timeout ): reads a
byte from the specified UART interface.
uart.sendstr( id, str1, str2, ... ): this is similar to "uart.send", but its
parameters are string.
================================================================================
=== The timer module
================================================================================
It allows Lua to execute timer specific operations (delay, read timer value,
start timer, get time difference).
tmr.delay( id, delay ): uses timer 'id' to wait for 'delay' us.
Data = tmr.read( id ): reads the value of timer 'id'. The returned value is
platform dependent.
Data = tmr.start( id ): start the timer 'id', and also returns its value at
the moment of start. The returned value is platform dependent.
diff = tmr.diff( id, end, start ): returns the time difference (in us) between
the timer values 'end' and 'start' (obtained from calling tmr.start or
tmr.read). The order of end/start is irrelevant.
Data = tmr.mindelay( id ): returns the minimum delay (in us ) that can be
achieved by calling the tmr.delay function. If the return value is 0, the
platform layer is capable of executing sub-microsecond delays.
Data = tmr.maxdelay( id ): returns the maximum delay (in us) that can be
achieved by calling the tmr.delay function.
Data = tmr.setclock( id, clock ): sets the clock of the given timer. Returns the
actual clock set for the timer.
Data = tmr.getclock( id ): return the clock of the given timer.
================================================================================
=== The platform data module
================================================================================
It allows Lua to identify the platform on which it runs.
Platform = pd.platform(): returns the platform name (f.e. LM3S)
Cpu = pd.cpu(): returns the CPU name (f.e. LM3S8962)
Board = pd.board(): returns the CPU board (f.e. EK-LM3S8962)
================================================================================
=== The PWM module
================================================================================
It allows Lua to use the PWM blocks on the target CPU.
Data = pwm.setup( id, frequency, duty ): sets the PWM block 'id' to generate the
specified frequency with the specified duty cycle (duty is an integer number
from 0 to 100, specifying the duty cycle in percents). It returns the actual
frequency set on the PWM block.
pwm.start( id ): start the PWM block 'id'.
pwm.stop( id ): stop the PWM block 'id'.
Data = pwm.setclock( id, clock ): set the base clock of the PWM block 'id' to
the given clock. In returns the actual clock set on the PWM block.
Data = pwm.getclock( id ): returns the base clock of the PWM block 'id'.
================================================================================
=== The CPU module
================================================================================
It brings low level CPU access to Lua (read/write memory, enable/disable
interrupts).
w32( address, data ) : write the 32-bit data at the specified address
w16( address, data ) : write the 16-bit data at the specified address
w8( address, data ) : write the 8-bit data at the specified address
Data = r32( address ) : reads 32-bit data from the specified address
Data = r16( address ) : reads 16-bit data from the specified address
Data = r8( address ) : reads 8-bit data from the specified address
cli(): disable CPU interrupts
sei(): enable CPU interrupts
Clock = clock(): returns the CPU frequency
Also, you can expose as many CPU constants (for example memory mapped registers)
as you want to this module. You might want to use this feature to access some
CPU memory areas (as defined in the CPU header files from the CPU support
package) directly from Lua. To do this, you'll need to define the
PLATFORM_CPU_CONSTANTS macro in the platform's platform_conf.h file
(src/platform/<platform name>/platform_conf.h). Include all your constants in a
_C( <constant name> ) definition, and then build your project.
For example, let's suppose that your CPU's interrupt controler has 3 memory
mapped registers: INT_REG_ENABLE, INT_REG_DISABLE and INT_REG_MASK. If you want
to access them from Lua, locate the header that defines the values of these
registers (I'll assume its name is "cpu.h") and add these lines to the
platform_conf.h:
#include "cpu.h"
#define PLATFORM_CPU_CONSTANTS\
_C( INT_REG_ENABLE ),\
_C( INT_REG_DISABLE ),\
_C( INT_REG_MASK )
After this you'll be able to access the regs directly from Lua, like this:
data = cpu.r32( cpu.INT_REG_ENABLE )
cpu.w32( cpu.INT_REG_ENABLE, data )
For a "real-life" example, see the src/platform/lm3s/platform_conf.h file.