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

Merge branch 'master' into include_git_rev

This commit is contained in:
James Snyder 2012-01-20 17:22:56 -06:00
commit 8060e0e2c9
30 changed files with 341 additions and 278 deletions

View File

@ -1,12 +1,15 @@
eLua - Lua for microcontrollers
===============================
*eLua* stands for *Embedded Lua* and the project aims to offer the full
implementation of the http://www.lua.org[Lua Programming Language] to the
embedded world, extending it with specific features for efficient and portable
software embedded development. For more details please visit the link:http://www.eluaproject.net[project page].
*eLua* stands for *Embedded Lua* and the project aims to offer the
full implementation of the http://www.lua.org[Lua Programming
Language] to the embedded world, extending it with specific features
for efficient and portable software embedded development. For more
details please visit the link:http://www.eluaproject.net[project
page].
If you've just downloaded *eLua* and are looking to get started check out link:http://www.eluaproject.net/en_using.html[using eLua].
If you've just downloaded *eLua* and are looking to get started check
out link:http://www.eluaproject.net/en_using.html[using eLua].
General Features
@ -63,6 +66,19 @@ Some aspects of eLua are:
For more information about the functionality (implemented and planned) in eLua
check link:http://www.eluaproject.net/en_status.html[our status page].
Documentation
-------------
Online documentation can be found on the web for the most recent
release version and development versions in the
link:http://www.eluaproject.net/get-better[get better] section of the
project website.
Project documentation can be generated for the version of the project
associated with this document by following the instructions in the
README.TXT file in the doc directory.
Contacts
--------

View File

@ -15,7 +15,7 @@ data_en =
timers with a single exception: you can't set the clock of a virtual timer (using @#tmr.setclock@tmr.setclock@). To use virtual timers with this
module, specify $tmr.VIRTx$ as the timer ID instead of a number. For example, if the eLua image was configured to support 4 virtual timers, they will
be available by using $tmr.VIRT0$ to $tmr.VIRT3$ as timer IDs. The @arch_platform_timers.html#the_system_timer@system timer@ can also be used with
any of these functions by ommiting the timer ID or specifying it as $tmr.SYS_TIMER$.</p>
any of these functions by omitting the timer ID or specifying it as $tmr.SYS_TIMER$.</p>
<p>All "time units" (delays, differences in time) in this module, as well as in other parts of eLua (timeouts) are expressed in microseconds. However,
please keep in mind that the actual timer resolution depends on many factors. For example, it's very likely that the @#tmr.delay@tmr.delay@ function won't
be able to delay for the exact amount you specify (in us), as the real delay depends on a number of variables, most notably the base clock of the timer

View File

@ -1,4 +1,4 @@
-- eLaa reference manual - platform data
-- eLua reference manual - platform data
data_en =
{
@ -11,7 +11,7 @@ data_en =
-- Overview
overview = [[This module contains functions to drive the two-line character LCD panel of the Mizar32 display module.</p>
<p>Physically, the display has 16 characters per line but internally it has a 40 characters by two line memory. It displays 16 of those 40 columns at a time, with various ways to determine which of the 40 columns appear in the 16-column display. If you just want to display 16x2 characters, the $reset$, $goto$ and $print$ functions are enough to do this.]],
<p>Physically, the display has 16 characters per line but internally it has a 40 character by two line memory. It displays 16 of those 40 columns at a time, with various ways to determine which of the 40 columns appear in the 16-column display. If you just want to display 16x2 characters, the $reset$, $goto$ and $print$ functions are enough to do this.]],
-- Functions
funcs =
@ -24,21 +24,21 @@ data_en =
desc = "This can be used to set some of the stranger operating modes of the LCD display. Both parameters are optional and if you omit them, they default to $false$, which sets sensible mode.",
args =
{
[[$display_shift$ - If $true$, then with each character you subsequently print, the cursor will move by one place in the character memory as usual but the display's contents will also move by one position horizontally so that the cursor remains in the same column of the physical display. This can be used to achieve "scrolling text" effects. Note, however, that when the cursor passes from column 40 to column 1 or vice versa, it flips over to the other row.]],
"$right_to_left$ - If $true$, text will be printed right-to-left: the cursor will move one position to the left in the character memory and, if display shifting is also enabled, the display will shift so as to keep the cursor in the same column on the screen."
[[$display_shift$ - If $true$, then with each character you subsequently print, the cursor will move by one place in the character memory as usual but the display's contents will also move by one position horizontally in the opposite direction so that the cursor remains in the same column of the physical display. This can be used to achieve "scrolling text" effects. Note, however, that when the cursor passes from column 40 to column 1 or vice versa, it flips over to the other row.]],
"$right_to_left$ - If $true$, text will be printed right-to-left: the cursor will move one position to the left in the character memory and, if display shifting is also enabled, the contents of the display will shift to the right so that the cursor stays in the same column on the screen."
}
},
{ sig = "#mizar32.lcd.clear#()",
desc = "Clears the display, move the cursor to the top left (position 1,1) and reset the display shift to show columns 1-16."
desc = "Clears the display, moves the cursor to the top left (position 1,1) and resets the display shift to show columns 1 to 16."
},
{ sig = "#mizar32.lcd.home#()",
desc = "Moves the cursor to the top left (position 1,1) and reset the display shift."
desc = "Moves the cursor to the top left (position 1,1) and resets the display shift."
},
{ sig = "#mizar32.lcd.goto#( row, column )",
desc = "Move the cursor to the specified row and column.",
desc = "Moves the cursor to the specified row and column.",
args =
{
"$row$ - A number (1 or 2) giving the row you want to move to.",
@ -46,6 +46,15 @@ data_en =
}
},
{ sig = "#row, column = mizar32.lcd.getpos#()",
desc = "Returns the current cursor position.",
ret =
{
"$row$ - A number (1 or 2) giving the current row.",
"$column$ - A number (1 to 40) giving the current column in the character memory."
}
},
{ sig = "#mizar32.lcd.print#( [data1] [, data2] ... [datan] )",
desc = "Writes into the LCD character memory starting at the current cursor position. The cursor will advance by one position for each character printed. When it goes past column 40, it moves to column 1 of the other line, (and vice versa when printing right-to-left).",
args =
@ -82,6 +91,14 @@ data_en =
"$glyph$ - A table of up to eight numbers giving the bit-patterns for the eight rows of the character, in order from top to bottom. Each of these number is a value from 0 to 31, to define which of the 5 bits in the row should be black. The pixels' values from left to right are 16, 8, 4, 2 and 1. For example, { 1, 3, 7, 15, 31, 15, 7, 3, 1, 0 } would define a left-pointing solid triangle in the top 7 rows. Extra rows are ignored, and missing rows are blanked."
}
},
{ sig = "#buttons = mizar32.lcd.buttons#()",
desc = "Tells which of the five user buttons are currently pressed.",
ret =
{
"$buttons$ - A string containing up to five of the characters $L$, $R$, $U$, $D$ and $S$ to say whether the Left, Right, Up, Down and Select buttons are currently held down. If none are pressed, an empty string is returned. The hardare allows Select to be detected reliably and up to two of the other four: if three of Left, Right, Up and Down are being held, all four are returned."
}
},
},
}

View File

@ -2,7 +2,7 @@ $$HEADER$$
<h3>Using <b>eLua</b> with the AT91SAM7X CPUs from Atmel</h3>
<p><a href="http://www.atmel.com">Atmel</a> is a company that doesn't need any kind of introduction :) Their huge product range include some quite nice ARM7TDMI core implementations.
Among them are the <a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=3755">AT91SAM7X256</a> and
<a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=4104">AT91SAM7X512</a> CPUs. The only difference between them is the ammount of internal memory (256k Flash+64k RAM for
<a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=4104">AT91SAM7X512</a> CPUs. The only difference between them is the amount of internal memory (256k Flash+64k RAM for
AT91SAM7X256 vs. 512k Flash+128k RAM for AT91SAM7X512). Loaded with peripherals, and accompanied by a good support package, they make a perfect host for <b>eLua</b>. For this tutorial
I'm going to use the <a href="http://www.olimex.com/dev/sam7-ex256.html">SAM7-EX256</a> development board from <a href="http://www.olimex.com">Olimex</a>. It's quite a
decent board, and also reasonably priced, although it lacks a proper documentation package in my oppinion. It is equipped with an AT91SAM7X256 CPU. As much as I'd like to get

View File

@ -6,7 +6,7 @@ Starting with link:downloads.html[version 0.8] eLua supports interrupt handlers
interrupt is generated. A *supported interrupt* is any interrupt that is handled by the platform C code (see link:arch_ints.html[here] for more details).
[red]*IMPORTANT*: before learning how to use interrupt handlers in Lua, please keep in mind that Lua interrupt handlers don't work the same way as
regular \(C) interrupt handlers. As Lua doesn't have direct support for interrupts, they have to be emulated. eLua emulates them using a queue that is populated with
regular \(C) interrupt handlers. As Lua doesn't have direct support for interrupts, they have to be emulated. eLua emulates them using a queue that is populated with
interrupt data by the C support code. As long as the queue is not empty, a Lua hook is set to run every 2 Lua bytecode instructions. This hook function is the Lua interrupt
handler. After all the interrupts are handled and the queue is emptied, the hook is automatically disabled. Consequently:
@ -24,7 +24,7 @@ handler. After all the interrupts are handled and the queue is emptied, the hook
C function that is executed for every VM instruction. If this function blocks for some reason, the VM instructions are not executed anymore. It's not hard to make
this function block; for example, it blocks everytime the Lua code waits for some user input at the console, or when a link:refman_gen_tmr.html#tmr.delay[tmr.delay] is executed,
or when link:refman_gen_uart.html#uart.read[uart.read] is called with an infinite or very large timeout; in general, any function from a Lua library that doesn't return
immediately or after a short ammount of time will block the VM. Care must be taken to avoid such operations as much as possible, otherwise the interrupt support code won't run properly.
immediately or after a short amount of time will block the VM. Care must be taken to avoid such operations as much as possible, otherwise the interrupt support code won't run properly.
* There is a single interrupt handler per interrupt type in Lua (the same holds true for C interrupt support), as opposed to the many hardware interrupts
handlers usually found on the eLua targets. It is however easy to differentiate between different interrupt sources, as will be explained in the next

View File

@ -76,7 +76,7 @@ pio_type platform_pio_op( unsigned port, pio_type pinmask, int op );
#if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_INTEGRAL_LONGLONG )
// Maximum values of the system timer
#define PLATFORM_TIMER_SYS_MAX ( ( 1LL << 32 ) - 2 )
#define PLATFORM_TIMER_SYS_MAX ( ( 1LL << 31 ) - 2 )
// Timer data type
typedef u32 timer_data_type;
#else

View File

@ -112,6 +112,9 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
termdata.c_iflag &= ~( IXON | IXOFF | IXANY );
termdata.c_iflag |= IGNBRK;
// Disable input processing
termdata.c_iflag &= ~( INLCR | ICRNL | IGNCR );
// Raw input
termdata.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
@ -146,16 +149,21 @@ u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
fd_set readfs;
struct timeval tv;
int retval;
u32 readbytes = 0;
FD_ZERO( &readfs );
FD_SET( ( int )id, &readfs );
tv.tv_sec = timeout / 1000;
tv.tv_usec = ( timeout % 1000 ) * 1000;
retval = select( ( int )id + 1, &readfs, NULL, NULL, timeout == SER_INF_TIMEOUT ? NULL : &tv );
if( retval == -1 || retval == 0 )
return 0;
else
return ( u32 )read( id, dest, maxsize );
while( readbytes < maxsize )
{
FD_ZERO( &readfs );
FD_SET( ( int )id, &readfs );
tv.tv_sec = timeout / 1000;
tv.tv_usec = ( timeout % 1000 ) * 1000;
retval = select( ( int )id + 1, &readfs, NULL, NULL, timeout == SER_INF_TIMEOUT ? NULL : &tv );
if( retval == -1 || retval == 0 )
break;
else
readbytes += ( u32 )read( id, dest + readbytes, maxsize - readbytes );
}
return readbytes;
}
// Read a single byte and return it (or -1 for error)

View File

@ -706,6 +706,9 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */
luaC_fullgc(L);
if(nsize > osize && L != NULL) {
#if defined(LUA_STRESS_EMERGENCY_GC)
luaC_fullgc(L);
#endif
if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize))
return NULL;
}

View File

@ -556,6 +556,15 @@ static void atomic (lua_State *L) {
g->estimate = g->totalbytes - udsize; /* first estimate */
}
static void sweepstrstep (global_State *g, lua_State *L) {
lu_mem old = g->totalbytes;
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
g->gcstate = GCSsweep; /* end sweep-string phase */
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
}
static l_mem singlestep (lua_State *L) {
global_State *g = G(L);
@ -574,12 +583,7 @@ static l_mem singlestep (lua_State *L) {
}
}
case GCSsweepstring: {
lu_mem old = g->totalbytes;
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
g->gcstate = GCSsweep; /* end sweep-string phase */
lua_assert(old >= g->totalbytes);
g->estimate -= old - g->totalbytes;
sweepstrstep(g, L);
return GCSWEEPCOST;
}
case GCSsweep: {
@ -641,6 +645,14 @@ void luaC_step (lua_State *L) {
unset_block_gc(L);
}
int luaC_sweepstrgc (lua_State *L) {
global_State *g = G(L);
if (g->gcstate == GCSsweepstring) {
sweepstrstep(g, L);
return (g->gcstate == GCSsweepstring) ? 1 : 0;
}
return 0;
}
void luaC_fullgc (lua_State *L) {
global_State *g = G(L);

View File

@ -123,6 +123,7 @@ LUAI_FUNC void luaC_callGCTM (lua_State *L);
LUAI_FUNC void luaC_freeall (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_fullgc (lua_State *L);
LUAI_FUNC int luaC_sweepstrgc (lua_State *L);
LUAI_FUNC void luaC_marknew (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);

View File

@ -375,9 +375,9 @@ static void close_func (LexState *ls) {
lua_assert(luaG_checkcode(f));
lua_assert(fs->bl == NULL);
ls->fs = fs->prev;
L->top -= 2; /* remove table and prototype from the stack */
/* last token read was anchored in defunct function; must reanchor it */
if (fs) anchor_token(ls);
L->top -= 2; /* remove table and prototype from the stack */
}
@ -385,14 +385,18 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
struct LexState lexstate;
struct FuncState *pfuncstate = (struct FuncState*)malloc(sizeof(struct FuncState));
Proto *res;
TString *tname = luaS_new(L, name);
setsvalue2s(L, L->top, tname); /* protect name */
incr_top(L);
lexstate.buff = buff;
luaX_setinput(L, &lexstate, z, luaS_new(L, name));
luaX_setinput(L, &lexstate, z, tname);
open_func(&lexstate, pfuncstate);
pfuncstate->f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
luaX_next(&lexstate); /* read first token */
chunk(&lexstate);
check(&lexstate, TK_EOS);
close_func(&lexstate);
L->top--; /* remove 'name' from stack */
lua_assert(pfuncstate->prev == NULL);
lua_assert(pfuncstate->f->nups == 0);
lua_assert(lexstate.fs == NULL);

View File

@ -23,7 +23,7 @@ void luaS_resize (lua_State *L, int newsize) {
stringtable *tb;
int i;
tb = &G(L)->strt;
if (G(L)->gcstate == GCSsweepstring || newsize == tb->size || is_resizing_strings_gc(L))
if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L))
return; /* cannot resize during GC traverse or doesn't need to be resized */
set_resizing_strings_gc(L);
if (newsize > tb->size) {

View File

@ -408,7 +408,13 @@
*/
#define LUA_COMPAT_OPENLIB
/*
@@ LUA_STRESS_EMERGENCY_GC enables stress testing code for the Emergency GC.
** CHANGE it to defined if you want to test for Emergency GC related bugs.
** Note that this will make the Lua vm very slow, since it will force a
** full GC on every new allocation.
*/
#undef LUA_STRESS_EMERGENCY_GC
/*
@@ luai_apicheck is the assert macro used by the Lua-C API.

View File

@ -171,6 +171,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
L->top--;
unfixedstack(L);
setobj2t(L, oldval, val);
((Table *)h)->flags = 0;
luaC_barriert(L, (Table*)h, val);
}
return;

View File

@ -200,8 +200,10 @@ const LUA_REG_TYPE tmr_map[] =
#endif
#if VTMR_NUM_TIMERS > 0
{ LSTRKEY( "__index" ), LFUNCVAL( tmr_mt_index ) },
{ LSTRKEY( "SYS_TIMER" ), LNUMVAL( PLATFORM_TIMER_SYS_ID ) },
#endif
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "SYS_TIMER" ), LNUMVAL( PLATFORM_TIMER_SYS_ID ) },
#endif
#if LUA_OPTIMIZE_MEMORY > 0 && defined( BUILD_LUA_INT_HANDLERS )
{ LSTRKEY( "INT_ONESHOT" ), LNUMVAL( PLATFORM_TIMER_INT_ONESHOT ) },
{ LSTRKEY( "INT_CYCLIC" ), LNUMVAL( PLATFORM_TIMER_INT_CYCLIC ) },

View File

@ -182,7 +182,7 @@ _ssize_t _write_r( struct _reent *r, int file, const void *ptr, size_t len )
}
// ****************************************************************************
// Miscalenous functions
// Miscellaneous functions
int _isatty_r( struct _reent* r, int fd )
{
@ -375,7 +375,7 @@ const DM_DEVICE* std_get_desc()
#endif // #if !defined( BUILD_CON_GENERIC ) && !defined( BUILD_CON_TCP )
// ****************************************************************************
// memcpy is broken on AVR32's Newlib, so impolement a simple version here
// memcpy is broken on AVR32's Newlib, so implement a simple version here
// same goes for strcmp apparently
#ifdef FORAVR32
void* memcpy( void *dst, const void* src, size_t len )

View File

@ -105,6 +105,7 @@
// Virtual timers (0 if not used)
#define VTMR_NUM_TIMERS 4
#define VTMR_FREQ_HZ 10
#define VTMR_CH 2 // Which hardware timer to use for VTMR
// Number of resources (0 if not available/not implemented)
#define NUM_PIO 4

View File

@ -75,6 +75,7 @@
// Virtual timers (0 if not used)
#define VTMR_NUM_TIMERS 4
#define VTMR_FREQ_HZ 10
#define VTMR_CH 2 // Which hardware timer to use for VTMR
// Number of resources (0 if not available/not implemented)
#define NUM_PIO 2

View File

@ -60,6 +60,8 @@
*/
//! @{
#define FOSC32 32768 //!< Osc32 frequency: Hz.
#define FOSC0 12000000 //!< Osc0 frequency: Hz.
#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods.

View File

@ -39,7 +39,7 @@
#endif
#ifdef BUILD_UIP
//#define BUILD_DHCPC
#define BUILD_DHCPC
#define BUILD_DNS
//#define BUILD_CON_TCP
#endif
@ -121,7 +121,6 @@
#define LUA_PLATFORM_LIBS_ROM\
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
#else
@ -152,6 +151,7 @@
// Virtual timers (0 if not used)
#define VTMR_NUM_TIMERS 4
#define VTMR_FREQ_HZ 10
#define VTMR_CH 2 // Which hardware timer to use for VTMR
// Number of resources (0 if not available/not implemented)
#define NUM_PIO 4

View File

@ -302,19 +302,13 @@ unsigned char i2c_read_byte(int nack)
// Pause for half an I2C bus clock cycle
static void I2CDELAY()
{
// Code stolen from sdramc.c::sdramc_ck_delay()
// Use the CPU cycle counter (CPU and HSB clocks are the same).
u32 delay_start_cycle = Get_system_register(AVR32_COUNT);
u32 delay_end_cycle = delay_start_cycle + i2c_delay;
// To be safer, the end of wait is based on an inequality test, so CPU cycle
// counter wrap around is checked.
if (delay_start_cycle > delay_end_cycle)
{
while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle);
}
while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle);
// at 60MHz the count register wraps every 71.68 secs, at 66MHz every 65s.
// The following unsigned arithmetic handles the wraparound condition.
while( (u32)Get_system_register(AVR32_COUNT) - delay_start_cycle < i2c_delay )
/* wait */;
}
// Set SCL as input and return current level of line

View File

@ -11,7 +11,7 @@
#include "i2c.h"
// Since the LCD firmware currently only runs at up to 20kHz on the I2C bus,
// The LCD firmware only runs at up to 50kHz on the I2C bus, so
// we bracket all I2C packets to the LCD module with two functions
// to be able to save, change and restore the I2C clock rate to what it was
// before.
@ -41,100 +41,97 @@ static void lcd_stop()
// Send a command or data packet.
// "address" is LCD_CMD for LCD commands, LCD_DATA for LCD data.
static int send_generic(char address, const char *data, int len)
static int send_generic( u8 address, const u8 *data, int len )
{
while (len > 0) {
int nbytes; // number of bytes sent in this I2C packet
lcd_start();
i2c_start_cond();
i2c_write_byte( address );
// Mizar32 LCD module has a maximum of 31 bytes per data packet
nbytes = 0;
while ( len > 0 && nbytes < 31 ) {
i2c_write_byte( *data++ );
nbytes++; len--;
}
i2c_stop_cond();
lcd_stop();
lcd_start();
i2c_start_cond();
i2c_write_byte( address );
while ( len > 0 ) {
i2c_write_byte( *data++ );
len--;
}
i2c_stop_cond();
lcd_stop();
return 0;
}
// Send a single command byte
static int send_command(const char command)
// Send an I2C read-data command and return the answer.
// "address" is LCD_GETPOS to read the cursor position,
// LCD_BUTTONS for to read the buttons.
// The answer is always a single byte.
static u8 recv_generic( u8 address )
{
return send_generic(LCD_CMD, &command, 1);
u8 retval;
lcd_start();
i2c_start_cond();
// Send the slave address.
if ( i2c_write_byte( address ) == 0 )
// NAK the single byte to signal end of transfer
retval = i2c_read_byte( TRUE );
else
// The address was not acknowledged, so no slave is present.
// There is no way to signal this to the Lua layer, so return a
// harmless value (meaning no buttons pressed or cursor at (1,1)).
retval = 0;
i2c_stop_cond();
lcd_stop();
return retval;
}
// Send multiple command bytes as one message
static int send_commands(const char *commands, int len)
// Send a command byte
static int send_command( const u8 command )
{
return send_generic(LCD_CMD, commands, len);
return send_generic( LCD_CMD, &command, 1 );
}
// Send data bytes
// This is used for printing data and for programming the user-defining chars
static int send_data(const char *data, int len)
static int send_data( const u8 *data, int len )
{
return send_generic(LCD_DATA, data, len);
return send_generic( LCD_DATA, data, len );
}
// Return the current value of the address counter.
static u8 recv_address_counter()
{
return recv_generic( LCD_GETPOS );
}
// *** Lua module functions begin... ***
// Return the current state of the buttons, a bit mask in the bottom 5 bits
// of a byte.
static u8 recv_buttons()
{
return recv_generic( LCD_BUTTONS );
}
// Turning the display on can only be achieved by simultaneously specifying the
// cursor type, so we have to remember what type of cursor they last set.
// Similarly, if they have turned the display off then set the cursor, this
// shouldn-t turn the display on.
// shouldn't turn the display on.
// Power-on setting is no cursor
#define DEFAULT_CURSOR_TYPE LCD_CMD_CURSOR_NONE
static char cursor_type = DEFAULT_CURSOR_TYPE;
static char display_is_off = 0; // Have they called display("off")?
static u8 cursor_type = DEFAULT_CURSOR_TYPE;
static u8 display_is_off = 0; // Have they called display("off")?
// Should we try to maintain the current cursor position across a definechar()?
// Unfortunately we can't read the current cursor position, and definechar()
// destroys it. The LCD controller does have a read-cursor-position primitive
// but the current PIC firmware doesn't pass this on as an I2C read.2
// So we have to track the cursor position. Yuk.
// The only relief is that we don't have to track the display scrolling.
// Adds 284 bytes of code to the executable.
//
// If, one day, we can read the LCD cursor position through the PIC firmware
// we can remove all this stuff.
#define KEEP_CURSOR_POSITION 1
#ifdef KEEP_CURSOR_POSITION
// Where is the cursor in the character memory? Required ONLY to be able to
// restore the cursor position when they define a character :-/
static int current_row = 0; // 0 or 1
static int current_column = 0; // 0-39 (though it over- and underflows)
static int current_direction = 1; // left-to-right. -1 is right-to-left
#endif
// *** Lua module functions begin... ***
// Lua: mizar32.disp.reset()
// Ensure the display is in a known initial state
static int lcd_reset( lua_State *L )
{
// Initialise the display to a known state
static const char reset[] = {
0 /* reset */
};
// Set the static variables
cursor_type = DEFAULT_CURSOR_TYPE;
display_is_off = 0;
#ifdef KEEP_CURSOR_POSITION
current_row = current_column = 0;
current_direction = 1;
#endif
return send_commands( reset, sizeof( reset ) );
return send_command( LCD_CMD_RESET );
}
// "Entry mode" function.
@ -147,52 +144,38 @@ static int lcd_setup( lua_State *L )
unsigned shift_display = lua_toboolean( L, 1 ); // Default: move cursor
unsigned right_to_left = lua_toboolean( L, 2 ); // Default: print left-to-right
#ifdef KEEP_CURSOR_POSITION
current_direction = right_to_left ? -1 : 1;
#endif
return send_command( LCD_CMD_ENTRYMODE + shift_display +
(!right_to_left) * 2 );
( ! right_to_left ) * 2 );
}
// Lua: mizar32.disp.clear()
// Clear the display, reset its shiftedness and put the cursor at 1,1
static int lcd_clear( lua_State *L )
{
#ifdef KEEP_CURSOR_POSITION
current_row = current_column = 0;
#endif
return send_command( LCD_CMD_CLEAR );
}
// Lua: mizar32.disp.home()
// Reset the display's shiftedness and put the cursor at 1,1
static int lcd_home(lua_State *L)
static int lcd_home( lua_State *L )
{
#ifdef KEEP_CURSOR_POSITION
current_row = current_column = 0;
#endif
return send_command( LCD_CMD_HOME );
}
// Lua: mizar32.disp.goto( row, col )
// Move the cursor to the specified row (1 or 2) and column (1-40)
// in the character memory.
static int lcd_goto(lua_State *L)
static int lcd_goto( lua_State *L )
{
unsigned row = luaL_checkinteger( L, 1 );
unsigned col = luaL_checkinteger( L, 2 );
int row = luaL_checkinteger( L, 1 );
int col = luaL_checkinteger( L, 2 );
unsigned address;
if ( row < 1 || row > 2 || col < 1 || col > 40 )
return luaL_error( L, "row/column must be 1-2 and 1-40" );
#ifdef KEEP_CURSOR_POSITION
current_row = row - 1;
current_column = col - 1;
#endif
address = ( row - 1 ) * 0x40 + ( col - 1 ) ;
return send_command( LCD_CMD_DDADDR + address );
return send_command( (u8) (LCD_CMD_DDADDR + address) );
}
// Lua: mizar32.disp.print( string )
@ -200,36 +183,19 @@ static int lcd_goto(lua_State *L)
// Usually this will be a string of text or a list of character codes.
// If they pass us integer values <0 or >255, we just use the bottom 8 bits.
#ifdef KEEP_CURSOR_POSITION
// Adjust current cursor position by N printed characters.
// Written for shortest code.
static void current_print(int n)
{
current_column += current_direction * n;
if (current_column < 0 || current_column >= 40) {
current_row = ! current_row;
current_column -= 40 * current_direction;
}
}
#endif
static int lcd_print(lua_State *L)
static int lcd_print( lua_State *L )
{
unsigned argc = lua_gettop( L ); // Number of parameters supplied
int argn;
for ( argn = 1; argn <= argc; argn ++ )
{
switch (lua_type( L, argn ) )
switch ( lua_type( L, argn ) )
{
case LUA_TNUMBER:
{
char byte = luaL_checkint( L, argn );
#ifdef KEEP_CURSOR_POSITION
current_print(1);
#endif
send_data(&byte, (size_t) 1);
u8 byte = luaL_checkint( L, argn );
send_data( &byte, 1 );
}
break;
@ -237,11 +203,7 @@ static int lcd_print(lua_State *L)
{
size_t len; // Number of chars in string
const char *str = luaL_checklstring( L, argn, &len );
#ifdef KEEP_CURSOR_POSITION
current_print(len);
#endif
send_data(str, len);
send_data( (u8 *) str, len );
}
break;
@ -252,18 +214,56 @@ static int lcd_print(lua_State *L)
return 0;
}
// Return the cursor position as row and column in the ranges 1-2 and 1-40
// The bottom 7-bits of addr are the contents of the address counter.
// The Ampire datasheet says:
// 0x00-0x0F for the first line of DDRAM (presumably 0..39 really),
// 0x40-0x4F for the second line of DDRAM (presumably 64..(64+39) really)
// The top bit (128) is the "Busy Flag", which should always be 0.
static int lcd_getpos( lua_State *L )
{
u8 addr = recv_address_counter();
lua_pushinteger( L, (lua_Integer) ( (addr & 0x40) ? 2 : 1 ) ); // row
lua_pushinteger( L, (lua_Integer) ( (addr & 0x3F) + 1 ) ); // column
return 2;
}
// Return the current state of the pressed buttons as a string containing
// a selection of the letters S, L, R, U, D or an empty string if none are
// currently held down.
static int lcd_buttons( lua_State *L )
{
u8 code; // bit code for buttons held
char string[6]; // Up to 5 buttons and a \0
char *stringp = string; // Where to write the next character;
code = recv_buttons();
if( code & LCD_BUTTON_SELECT ) *stringp++ = 'S';
if( code & LCD_BUTTON_LEFT ) *stringp++ = 'L';
if( code & LCD_BUTTON_RIGHT ) *stringp++ = 'R';
if( code & LCD_BUTTON_UP ) *stringp++ = 'U';
if( code & LCD_BUTTON_DOWN ) *stringp++ = 'D';
*stringp = '\0';
lua_pushstring( L, string );
return 1;
}
// "Display on/off control" functions
// Helper function to set a cursor type if the display is on,
// or to remember which cursor they asked for, to be able to set it
// when they turn the display on.
static int set_cursor( char command_byte )
static int set_cursor( u8 command_byte )
{
cursor_type = command_byte;
// Setting cursor type always turns the display on
if (display_is_off)
if ( display_is_off )
return 0;
else
return send_command( cursor_type );
@ -286,21 +286,9 @@ static int lcd_cursor( lua_State *L )
return set_cursor( LCD_CMD_CURSOR_LINE );
case 3:
#ifdef KEEP_CURSOR_POSITION
if (--current_column < 0) {
current_row = !current_row;
current_column = 39;
}
#endif
return send_command( LCD_CMD_SHIFT_CURSOR_LEFT );
case 4:
#ifdef KEEP_CURSOR_POSITION
if (++current_column >= 40) {
current_row = !current_row;
current_column = 0;
}
#endif
return send_command( LCD_CMD_SHIFT_CURSOR_RIGHT );
default: return luaL_argerror( L, 1, NULL );
@ -330,26 +318,25 @@ static int lcd_display( lua_State *L )
// glyph: a table of up to 8 numbers with values 0-31.
// If less than 8 are supplied, the bottom rows are blanked.
// If more than 8 are supplied, the extra are ignored.
// The current cursor position in the character display RAM is preserved.
static int lcd_definechar( lua_State *L ) {
int code; // The character code we are defining, 0-7
size_t datalen; // The number of elements in the glyph table
size_t line; // Which line of the char are we defining?
char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
#ifdef KEEP_CURSOR_POSITION
int old_column = current_column, old_row = current_row;
#endif
u8 data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int old_address; // The coded value for the current cursor position
// First parameter: glyph code to define
code = luaL_checkint( L, 1 );
if( code < 0 || code > 7 )
return luaL_error( L, "user-defined characters have codes 0-7");
return luaL_error( L, "user-defined characters have codes 0-7" );
// Second parameter: table of integer values to define the glyph
luaL_checktype( L, 2, LUA_TTABLE );
datalen = lua_objlen( L, 2 );
// Check all parameters before starting the I2C command.
if( datalen >= 8) datalen = 8; // Ignore extra parameters
if( datalen >= 8 ) datalen = 8; // Ignore extra parameters
for( line = 0; line < datalen; line ++ )
{
int value;
@ -359,18 +346,13 @@ static int lcd_definechar( lua_State *L ) {
data[line] = value;
}
send_command( LCD_CMD_CGADDR + code * 8 );
send_data( data, sizeof(data) );
old_address = recv_address_counter();
send_command( LCD_CMD_CGADDR + code * 8 );
send_data( data, sizeof( data ) );
#ifdef KEEP_CURSOR_POSITION
// Move back to where we were
current_row = old_row; current_column = old_column;
return send_command( LCD_CMD_DDADDR + current_row * 0x40 + current_column );
#else
// Sadly, we cannot save and restore the current cursor position
// so return to the home position.
return send_command( LCD_CMD_DDADDR );
#endif
return send_command( LCD_CMD_DDADDR + old_address );
}
#define MIN_OPT_LEVEL 2
@ -388,5 +370,7 @@ const LUA_REG_TYPE lcd_map[] =
{ LSTRKEY( "definechar" ), LFUNCVAL( lcd_definechar ) },
{ LSTRKEY( "cursor" ), LFUNCVAL( lcd_cursor ) },
{ LSTRKEY( "display" ), LFUNCVAL( lcd_display ) },
{ LSTRKEY( "getpos" ), LFUNCVAL( lcd_getpos ) } ,
{ LSTRKEY( "buttons" ), LFUNCVAL( lcd_buttons ) } ,
{ LNILKEY, LNILVAL }
};

View File

@ -12,14 +12,27 @@
#define LCD_BUS_FREQ 50000
// I2C slave addresses for command bytes and data strings
// Command address is followed by a dingle byte giving the command to perform
// Command address is followed by a single byte giving the command to perform
// Data address is followed by multiple bytes of ASCII data to display
// on the character display at the current cursor location.
#define LCD_CMD 0x7C
#define LCD_DATA 0x7E
#define LCD_CMD 0x7C // Send commands
#define LCD_GETPOS 0x7D // Read the cursor position
#define LCD_DATA 0x7E // Send data
#define LCD_BUTTONS 0x7F // Read the status of the buttons
// Bits indicating which buttons are held down in the reply to LCD_BUTTONS
#define LCD_BUTTON_SELECT 1
#define LCD_BUTTON_LEFT 2
#define LCD_BUTTON_RIGHT 4
#define LCD_BUTTON_UP 8
#define LCD_BUTTON_DOWN 16
// Command bytes
// Mizar32 LCD driver special: instead of being a NOP, 0 performs a
// reset of the LCD panel
#define LCD_CMD_RESET 0
// "Clear display: Write "20H" to DDRAM and set DDRAM address to "00H" from AC"
#define LCD_CMD_CLEAR 1

View File

@ -246,7 +246,6 @@ int platform_init()
// Setup virtual timers if needed
#if VTMR_NUM_TIMERS > 0
#define VTMR_CH 2
platform_cpu_set_interrupt( INT_TMR_MATCH, VTMR_CH, PLATFORM_CPU_ENABLE );
platform_timer_set_match_int( VTMR_CH, 1000000 / VTMR_FREQ_HZ, PLATFORM_TIMER_INT_CYCLIC );
#endif // #if VTMR_NUM_TIMERS > 0
@ -356,6 +355,13 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
opts.baudrate = baud;
// Set stopbits
#if PLATFORM_UART_STOPBITS_1 == USART_1_STOPBIT && \
PLATFORM_UART_STOPBITS_1_5 == USART_1_5_STOPBIT && \
PLATFORM_UART_STOPBITS_2 == USART_2_STOPBIT
// The AVR32 header values and the eLua values are the same (0, 1, 2)
if (stopbits > PLATFORM_UART_STOPBITS_2) return 0;
opts.stopbits = stopbits;
#else
switch (stopbits) {
case PLATFORM_UART_STOPBITS_1:
opts.stopbits = USART_1_STOPBIT;
@ -369,6 +375,7 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
default:
return 0;
}
#endif
// Set parity
switch (parity) {
@ -493,7 +500,7 @@ int platform_s_uart_set_flow_control( unsigned id, int type )
// Timer functions
static const u16 clkdivs[] = { 0xFFFF, 2, 8, 32, 128 };
u8 avr32_timer_int_periodic_flag[ 3 ];
u8 avr32_timer_int_periodic_flag[ TC_NUMBER_OF_CHANNELS ];
// Helper: get timer clock
static u32 platform_timer_get_clock( unsigned id )
@ -587,21 +594,21 @@ timer_data_type platform_s_timer_op( unsigned id, int op, timer_data_type data )
int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int type )
{
volatile avr32_tc_t *tc = &AVR32_TC;
u32 final;
u64 final;
if( period_us == 0 )
{
tc->channel[ id ].CMR.waveform.wavsel = TC_WAVEFORM_SEL_UP_MODE;
return PLATFORM_TIMER_INT_OK;
}
final = ( u32 )( ( u64 )( platform_timer_get_clock( id ) * period_us ) / 1000000 );
final = ( u64 )platform_timer_get_clock( id ) * period_us / 1000000;
if( final == 0 )
return PLATFORM_TIMER_INT_TOO_SHORT;
if( final > 0xFFFF )
return PLATFORM_TIMER_INT_TOO_LONG;
tc_stop( tc, id );
tc->channel[ id ].CMR.waveform.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER;
tc->channel[ id ].rc = final;
tc->channel[ id ].rc = ( u32 )final;
avr32_timer_int_periodic_flag[ id ] = type;
tc_start( tc, id );
return PLATFORM_TIMER_INT_OK;

View File

@ -61,14 +61,6 @@ __attribute__((__interrupt__)) static void uart3_rx_handler()
// ----------------------------------------------------------------------------
// TMR_MATCH interrupts
#ifndef VTMR_CH
#if VTMR_NUM_TIMERS > 0
#define VTMR_CH (2)
#else // #if VTMR_NUM_TIMERS > 0
#define VTMR_CH 0xFFFF
#endif // #if VTMR_NUM_TIMERS > 0
#endif // #ifndef VTMR_CH
extern void platform_eth_timer_handler();
static const int tmr_irqs[] = { AVR32_TC_IRQ0, AVR32_TC_IRQ1, AVR32_TC_IRQ2 };
extern u8 avr32_timer_int_periodic_flag[ 3 ];
@ -78,13 +70,16 @@ static void tmr_match_common_handler( int id )
volatile avr32_tc_t *tc = &AVR32_TC;
tc_read_sr( tc, id ); // clear interrupt
#if VTMR_NUM_TIMERS > 0
if( id == VTMR_CH )
{
cmn_virtual_timer_cb();
platform_eth_timer_handler();
}
else
#endif
cmn_int_handler( INT_TMR_MATCH, id );
if( avr32_timer_int_periodic_flag[ id ] != PLATFORM_TIMER_INT_CYCLIC )
{
tc->channel[ id ].IDR.cpcs = 1;

View File

@ -59,15 +59,11 @@ static void sdramc_ck_delay(unsigned long ck)
{
// Use the CPU cycle counter (CPU and HSB clocks are the same).
unsigned long delay_start_cycle = Get_system_register(AVR32_COUNT);
unsigned long delay_end_cycle = delay_start_cycle + ck;
// To be safer, the end of wait is based on an inequality test, so CPU cycle
// counter wrap around is checked.
if (delay_start_cycle > delay_end_cycle)
{
while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle);
}
while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle);
// at 60MHz the count register wraps every 71.68 secs, at 66MHz every 65s.
// The following unsigned arithmetic handles the wraparound condition.
while ((unsigned long)Get_system_register(AVR32_COUNT) - delay_start_cycle < ck)
/* wait */;
}

View File

@ -8,9 +8,9 @@
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
@ -66,7 +66,7 @@ __ASM uint32_t __get_PSP(void)
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
__ASM void __set_PSP(uint32_t topOfProcStack)
@ -94,7 +94,7 @@ __ASM uint32_t __get_MSP(void)
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
__ASM void __set_MSP(uint32_t mainStackPointer)
@ -224,7 +224,7 @@ __ASM void __set_FAULTMASK(uint32_t faultMask)
/**
* @brief Return the Control Register value
*
*
* @return Control value
*
* Return the content of the control register
@ -248,7 +248,7 @@ __ASM void __set_CONTROL(uint32_t control)
bx lr
}
#endif /* __ARMCC_VERSION */
#endif /* __ARMCC_VERSION */
@ -274,7 +274,7 @@ uint32_t __get_PSP(void)
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
@ -302,7 +302,7 @@ uint32_t __get_MSP(void)
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
@ -350,7 +350,7 @@ uint32_t __RBIT(uint32_t value)
uint8_t __LDREXB(uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
__ASM("bx lr");
__ASM("bx lr");
}
/**
@ -444,7 +444,7 @@ uint32_t __get_PSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, psp\n\t"
__ASM volatile ("MRS %0, psp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
@ -455,7 +455,7 @@ uint32_t __get_PSP(void)
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
@ -478,7 +478,7 @@ uint32_t __get_MSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, msp\n\t"
__ASM volatile ("MRS %0, msp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
@ -489,7 +489,7 @@ uint32_t __get_MSP(void)
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
@ -509,7 +509,7 @@ void __set_MSP(uint32_t topOfMainStack)
uint32_t __get_BASEPRI(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
@ -563,7 +563,7 @@ void __set_PRIMASK(uint32_t priMask)
uint32_t __get_FAULTMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
@ -582,7 +582,7 @@ void __set_FAULTMASK(uint32_t faultMask)
/**
* @brief Return the Control Register value
*
*
* @return Control value
*
* Return the content of the control register
@ -619,7 +619,7 @@ void __set_CONTROL(uint32_t control)
uint32_t __REV(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -635,7 +635,7 @@ uint32_t __REV(uint32_t value)
uint32_t __REV16(uint16_t value)
{
uint32_t result=0;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -651,7 +651,7 @@ uint32_t __REV16(uint16_t value)
int32_t __REVSH(int16_t value)
{
uint32_t result=0;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -667,7 +667,7 @@ int32_t __REVSH(int16_t value)
uint32_t __RBIT(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -683,7 +683,7 @@ uint32_t __RBIT(uint32_t value)
uint8_t __LDREXB(uint8_t *addr)
{
uint8_t result=0;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -699,7 +699,7 @@ uint8_t __LDREXB(uint8_t *addr)
uint16_t __LDREXH(uint16_t *addr)
{
uint16_t result=0;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -715,7 +715,7 @@ uint16_t __LDREXH(uint16_t *addr)
uint32_t __LDREXW(uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -731,8 +731,8 @@ uint32_t __LDREXW(uint32_t *addr)
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
//uint32_t result=0;
register uint32_t result asm ("r2");
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
@ -748,8 +748,8 @@ uint32_t __STREXB(uint8_t value, uint8_t *addr)
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
//uint32_t result=0;
register uint32_t result asm ("r2");
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
@ -766,7 +766,7 @@ uint32_t __STREXH(uint16_t value, uint16_t *addr)
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}

View File

@ -7,9 +7,9 @@
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
@ -67,7 +67,7 @@ __ASM uint32_t __get_PSP(void)
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
__ASM void __set_PSP(uint32_t topOfProcStack)
@ -97,7 +97,7 @@ __ASM uint32_t __get_MSP(void)
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
__ASM void __set_MSP(uint32_t mainStackPointer)
@ -237,7 +237,7 @@ __ASM void __set_FAULTMASK(uint32_t faultMask)
/**
* @brief Return the Control Register value
*
*
* @param none
* @return uint32_t Control value
*
@ -263,7 +263,7 @@ __ASM void __set_CONTROL(uint32_t control)
bx lr
}
#endif /* __ARMCC_VERSION */
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
@ -289,7 +289,7 @@ uint32_t __get_PSP(void)
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
@ -319,7 +319,7 @@ uint32_t __get_MSP(void)
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
@ -367,7 +367,7 @@ uint32_t __RBIT(uint32_t value)
uint8_t __LDREXB(uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
__ASM("bx lr");
__ASM("bx lr");
}
/**
@ -461,7 +461,7 @@ uint32_t __get_PSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, psp\n\t"
__ASM volatile ("MRS %0, psp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
@ -474,7 +474,7 @@ uint32_t __get_PSP(void)
* @param uint32_t Process Stack Pointer
* @return none
*
* Assign the value ProcessStackPointer to the MSP
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
@ -498,7 +498,7 @@ uint32_t __get_MSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, msp\n\t"
__ASM volatile ("MRS %0, msp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
@ -510,7 +510,7 @@ uint32_t __get_MSP(void)
* @param uint32_t Main Stack Pointer
* @return none
*
* Assign the value mainStackPointer to the MSP
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
@ -531,7 +531,7 @@ void __set_MSP(uint32_t topOfMainStack)
uint32_t __get_BASEPRI(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
@ -590,7 +590,7 @@ void __set_PRIMASK(uint32_t priMask)
uint32_t __get_FAULTMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
@ -619,7 +619,7 @@ void __set_FAULTMASK(uint32_t faultMask)
uint32_t __REV(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -635,7 +635,7 @@ uint32_t __REV(uint32_t value)
uint32_t __REV16(uint16_t value)
{
uint32_t result=0;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -651,7 +651,7 @@ uint32_t __REV16(uint16_t value)
int32_t __REVSH(int16_t value)
{
uint32_t result=0;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -667,7 +667,7 @@ int32_t __REVSH(int16_t value)
uint32_t __RBIT(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
@ -683,7 +683,7 @@ uint32_t __RBIT(uint32_t value)
uint8_t __LDREXB(uint8_t *addr)
{
uint8_t result=0;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -699,7 +699,7 @@ uint8_t __LDREXB(uint8_t *addr)
uint16_t __LDREXH(uint16_t *addr)
{
uint16_t result=0;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -715,7 +715,7 @@ uint16_t __LDREXH(uint16_t *addr)
uint32_t __LDREXW(uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
@ -731,25 +731,25 @@ uint32_t __LDREXW(uint32_t *addr)
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
//uint32_t result=0;
register uint32_t result asm ("r2");
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive
* @brief STR Exclusive (16 bit)
*
* @param uint16_t *address
* @param uint16_t value to store
* @return uint32_t successful / failed
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command
* Exclusive STR command for 16 bit values
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
//uint32_t result=0;
register uint32_t result asm ("r2");
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
@ -766,14 +766,14 @@ uint32_t __STREXH(uint16_t value, uint16_t *addr)
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief Return the Control Register value
*
*
* @param none
* @return uint32_t Control value
*

View File

@ -804,7 +804,7 @@ int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int
{
TIM_TypeDef* base = ( TIM_TypeDef* )timer[ id ];
u32 period, prescaler, freq;
timer_data_type final;
u64 final;
TIM_OCInitTypeDef TIM_OCInitStructure;
if( period_us == 0 )
@ -834,12 +834,12 @@ int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int
TIM_OCStructInit( &TIM_OCInitStructure );
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = final;
TIM_OCInitStructure.TIM_Pulse = ( u16 )final;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init( base, &TIM_OCInitStructure );
// Patch timer configuration to reload when period is reached
TIM_SetAutoreload( base, final );
TIM_SetAutoreload( base, ( u16 )final );
TIM_OC1PreloadConfig( base, TIM_OCPreload_Enable );

View File

@ -396,7 +396,7 @@ int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int
{
TIM_TypeDef* base = ( TIM_TypeDef* )str9_timer_data[ id ];
u32 freq;
timer_data_type final;
u64 final;
TIM_InitTypeDef TIM_InitStructure;
if( period_us == 0 )
@ -421,7 +421,7 @@ int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int
TIM_InitStructure.TIM_Clock_Source = TIM_CLK_APB;
TIM_InitStructure.TIM_Clock_Edge = TIM_CLK_EDGE_FALLING;
TIM_InitStructure.TIM_Prescaler = TIM_GetPrescalerValue( base );
TIM_InitStructure.TIM_Pulse_Length_1 = final;
TIM_InitStructure.TIM_Pulse_Length_1 = ( u16 )final;
TIM_Init( base, &TIM_InitStructure );
str9_timer_int_periodic_flag[ id ] = type;