mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
Merge branch 'master' of https://github.com/elua/elua
This commit is contained in:
commit
a637578dc6
@ -17,7 +17,7 @@ data_en =
|
||||
be available by using $tmr.VIRT0$ to $tmr.VIRT3$ as timer IDs.</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 ona number of variables, most notably the base clock of the timer
|
||||
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
|
||||
and the size of the timer counter register (32 bits on some platforms, 16 bits on most platforms, other values are less common). To ensure that the delay
|
||||
you're requesting is achievable, use @#tmr.getmindelay@tmr.getmindelay@ and @#tmr.getmaxdelay@tmr.getmaxdelay@ to obtain the maximum and the minimum
|
||||
achievable wait times on your timer, respectively. Even if your delay is within these limits, the $precision$ of this function still varies a lot,
|
||||
@ -59,13 +59,13 @@ data_en =
|
||||
},
|
||||
|
||||
{ sig = "mindelay = #tmr.getmindelay#( id )",
|
||||
desc = "Get the minimum achieavable delay on the specified timer.",
|
||||
desc = "Get the minimum achievable delay on the specified timer.",
|
||||
args = "$id$ - the timer ID.",
|
||||
ret = "The minimum achievable delay on the specified timer (in us)."
|
||||
},
|
||||
|
||||
{ sig = "maxdelay = #tmr.getmaxdelay#( id )",
|
||||
desc = "Get the maximum achieavable delay on the specified timer.",
|
||||
desc = "Get the maximum achievable delay on the specified timer.",
|
||||
args = "$id$ - the timer ID.",
|
||||
ret = "The maximum achievable delay on the specified timer (in us)."
|
||||
},
|
||||
|
@ -3,9 +3,9 @@ $$HEADER$$
|
||||
<p>The EGC (Emergency Garbage Collector) patch was originally written for Lua by Robert Jakabosky, who was kind enough to port it to <b>eLua</b>. You can find the author's detailed
|
||||
description of the patch <a href="http://lua-users.org/wiki/EmergencyGarbageCollector">here</a>. In short, what it does is that it lets you run a garbage collection cycle in Lua in a low memory
|
||||
situation, from inside Lua's memory allocation function (something that the current version of Lua can't do out of the box). By forcing a garbage collection cycle, Lua can reclaim memory that's
|
||||
not in use anymore, thus making more memory available for your program. The downside is reduced execution speed, as a direct result of running the gargabe collector when needed. For some
|
||||
not in use any more, thus making more memory available for your program. The downside is reduced execution speed, as a direct result of running the garbage collector when needed. For some
|
||||
applications, reducing the execution speed to fit the application in memory might be acceptable, and for other applications it might not. As usual, it all depends on your application. As a generic
|
||||
guideline, if your application isn't concerned with realtime processing, you should be fine with sacrifing execution speed to get more memory in many real life scenarios.</p>
|
||||
guideline, if your application isn't concerned with realtime processing, you should be fine with sacrificing execution speed to get more memory in many real life scenarios.</p>
|
||||
<p>In <b>eLua</b>, the EGC patch can be configured to run in 4 different modes:</p>
|
||||
<ol>
|
||||
<li><b>disabled</b>: EGC inactive, no collection cycle will be forced in low memory situations.</li>
|
||||
|
@ -80,7 +80,7 @@ static _ssize_t std_read( struct _reent *r, int fd, void* vptr, size_t len )
|
||||
}
|
||||
ptr[ i ++ ] = c;
|
||||
}
|
||||
return len;
|
||||
return i;
|
||||
}
|
||||
|
||||
// 'write'
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define BUILD_CON_GENERIC
|
||||
//#define BUILD_RPC
|
||||
#define BUILD_C_INT_HANDLERS
|
||||
#define BUILA_LUA_INT_HANDLERS
|
||||
#define BUILD_LUA_INT_HANDLERS
|
||||
//#define BUILD_RFS
|
||||
//#define BUILD_SERMUX
|
||||
#define BUILD_ADC
|
||||
@ -161,6 +161,9 @@
|
||||
//#define SERMUX_NUM_VUART 2
|
||||
//#define SERMUX_BUFFER_SIZES { RFS_BUFFER_SIZE, CON_BUF_SIZE }
|
||||
|
||||
// Interrupt queue size
|
||||
#define PLATFORM_INT_QUEUE_LOG_SIZE 5
|
||||
|
||||
// Interrupt list
|
||||
#define INT_UART_RX ELUA_INT_FIRST_ID
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
@ -114,6 +114,9 @@
|
||||
#define MEM_START_ADDRESS { ( void* )end }
|
||||
#define MEM_END_ADDRESS { ( void* )( AVR32_SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
||||
|
||||
// Interrupt queue size
|
||||
#define PLATFORM_INT_QUEUE_LOG_SIZE 5
|
||||
|
||||
// Interrupt list
|
||||
#define INT_UART_RX ELUA_INT_FIRST_ID
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
@ -22,6 +22,7 @@
|
||||
//#define BUILD_RPC
|
||||
#define BUF_ENABLE_UART
|
||||
#define BUILD_C_INT_HANDLERS
|
||||
//#define BUILD_ADC
|
||||
|
||||
// *****************************************************************************
|
||||
// UART/Timer IDs configuration data (used in main.c)
|
||||
@ -59,6 +60,12 @@
|
||||
#define BUILD_RPC
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_ADC
|
||||
#define ADCLINE _ROM( AUXLIB_ADC, luaopen_adc, adc_map )
|
||||
#else
|
||||
#define ADCLINE
|
||||
#endif
|
||||
|
||||
#if defined( BUILD_RPC )
|
||||
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
|
||||
#else
|
||||
@ -74,6 +81,7 @@
|
||||
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
|
||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
ADCLINE\
|
||||
RPCLINE\
|
||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||
@ -102,7 +110,7 @@
|
||||
#define NUM_TIMER 3
|
||||
#endif
|
||||
#define NUM_PWM 7 // PWM7 is on GPIO50
|
||||
#define NUM_ADC 0
|
||||
#define NUM_ADC 8 // Though ADC3 pin is the Ethernet IRQ
|
||||
#define NUM_CAN 0
|
||||
|
||||
// As flow control seems not to work, we use a large buffer so that people
|
||||
@ -116,6 +124,15 @@
|
||||
#define RPC_TIMER_ID CON_TIMER_ID
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
|
||||
// ADC Configuration Params
|
||||
#define ADC_BIT_RESOLUTION 10
|
||||
#define BUF_ENABLE_ADC
|
||||
#define ADC_BUF_SIZE BUF_SIZE_2
|
||||
|
||||
// These should be adjusted to support multiple ADC devices
|
||||
#define ADC_TIMER_FIRST_ID 0
|
||||
#define ADC_NUM_TIMERS 0
|
||||
|
||||
// SD/MMC Filesystem Setup
|
||||
#define MMCFS_TICK_HZ 10
|
||||
#define MMCFS_TICK_MS ( 1000 / MMCFS_TICK_HZ )
|
||||
@ -145,6 +162,9 @@
|
||||
#define MEM_START_ADDRESS { ( void* )end, ( void* )( SDRAM + ELUA_FIRMWARE_SIZE ) }
|
||||
#define MEM_END_ADDRESS { ( void* )( 0x8000 - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
||||
|
||||
// Interrupt queue size
|
||||
#define PLATFORM_INT_QUEUE_LOG_SIZE 5
|
||||
|
||||
// Interrupt list
|
||||
#define INT_UART_RX ELUA_INT_FIRST_ID
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
@ -37,7 +37,7 @@ extern int pm_configure_clocks( pm_freq_param_t *param );
|
||||
|
||||
static u32 platform_timer_set_clock( unsigned id, u32 clock );
|
||||
|
||||
#if NUM_ADC > 0
|
||||
#ifdef BUILD_ADC
|
||||
__attribute__((__interrupt__)) static void adc_int_handler();
|
||||
#endif
|
||||
|
||||
@ -176,7 +176,7 @@ int platform_init()
|
||||
|
||||
#endif
|
||||
|
||||
#if NUM_ADC > 0
|
||||
#ifdef BUILD_ADC
|
||||
(&AVR32_ADC)->ier = AVR32_ADC_DRDY_MASK;
|
||||
INTC_register_interrupt( &adc_int_handler, AVR32_ADC_IRQ, AVR32_INTC_INT0);
|
||||
|
||||
@ -348,27 +348,42 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
|
||||
opts.baudrate = baud;
|
||||
|
||||
// Set stopbits
|
||||
if( stopbits == PLATFORM_UART_STOPBITS_1 )
|
||||
switch (stopbits) {
|
||||
case PLATFORM_UART_STOPBITS_1:
|
||||
opts.stopbits = USART_1_STOPBIT;
|
||||
else if( stopbits == PLATFORM_UART_STOPBITS_1_5 )
|
||||
break;
|
||||
case PLATFORM_UART_STOPBITS_1_5:
|
||||
opts.stopbits = USART_1_5_STOPBITS;
|
||||
else
|
||||
break;
|
||||
case PLATFORM_UART_STOPBITS_2:
|
||||
opts.stopbits = USART_2_STOPBITS;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set parity
|
||||
if( parity == PLATFORM_UART_PARITY_EVEN )
|
||||
switch (parity) {
|
||||
case PLATFORM_UART_PARITY_EVEN:
|
||||
opts.paritytype = USART_EVEN_PARITY;
|
||||
else if( parity == PLATFORM_UART_PARITY_ODD )
|
||||
break;
|
||||
case PLATFORM_UART_PARITY_ODD:
|
||||
opts.paritytype = USART_ODD_PARITY;
|
||||
else
|
||||
break;
|
||||
case PLATFORM_UART_PARITY_NONE:
|
||||
opts.paritytype = USART_NO_PARITY;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set actual interface
|
||||
gpio_enable_module(uart_pins + id * 2, 2 );
|
||||
usart_init_rs232( pusart, &opts, REQ_PBA_FREQ );
|
||||
if ( usart_init_rs232( pusart, &opts, REQ_PBA_FREQ ) != USART_SUCCESS )
|
||||
return 0;
|
||||
|
||||
// [TODO] Return actual baud here
|
||||
return baud;
|
||||
// Return actual baud here
|
||||
return usart_get_async_baudrate(pusart, REQ_PBA_FREQ);
|
||||
}
|
||||
|
||||
void platform_s_uart_send( unsigned id, u8 data )
|
||||
@ -564,6 +579,11 @@ u32 platform_s_timer_op( unsigned id, int op, u32 data )
|
||||
return res;
|
||||
}
|
||||
|
||||
int platform_s_timer_set_match_int( unsigned id, u32 period_us, int type )
|
||||
{
|
||||
return PLATFORM_TIMER_INT_INVALID_ID;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// SPI functions
|
||||
|
||||
|
@ -111,6 +111,60 @@ static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Return the actual baud rate set into the USART
|
||||
*
|
||||
* Baud rate calculation:
|
||||
* \f$ Baudrate = \frac{SelectedClock}{Over \times (CD + \frac{FP}{8})} \f$, \e Over being 16 or 8.
|
||||
*
|
||||
* \param usart Base address of the USART instance.
|
||||
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
|
||||
*
|
||||
* \retval baudrate The closest integer to the actual baud rate
|
||||
* \retval 0 UART clock is off or there was some error on our part
|
||||
*/
|
||||
unsigned int usart_get_async_baudrate(volatile avr32_usart_t *usart, unsigned long pba_hz)
|
||||
{
|
||||
unsigned int clock; // Master clock frequency
|
||||
unsigned int over; // divisor of 8 or 16
|
||||
unsigned int cd; // clock divider (0-65535)
|
||||
unsigned int fp; // fractional part of clock divider (0-7)
|
||||
unsigned int divisor; // What the master clock is divided by to get
|
||||
// the final baud rate
|
||||
|
||||
// Find
|
||||
switch ((usart->mr & AVR32_USART_MR_USCLKS_MASK) >> AVR32_USART_MR_USCLKS_OFFSET)
|
||||
{
|
||||
case AVR32_USART_MR_USCLKS_MCK:
|
||||
clock = pba_hz;
|
||||
break;
|
||||
|
||||
case AVR32_USART_MR_USCLKS_MCK_DIV:
|
||||
// I can't figure out where the divider is defined. The datasheet
|
||||
// section 26.7.1 says it is "product dependent, but generally set to 8".
|
||||
// Fortunately, the code above always selects MCK.
|
||||
case AVR32_USART_MR_USCLKS_SCK:
|
||||
// If we have an external clock, we don't know its frequency here.
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
over = usart->mr & AVR32_USART_MR_OVER_MASK;
|
||||
cd = (usart->brgr & AVR32_USART_BRGR_CD_MASK) >> AVR32_USART_BRGR_CD_OFFSET;
|
||||
fp = (usart->brgr & AVR32_USART_BRGR_FP_MASK) >> AVR32_USART_BRGR_FP_OFFSET;
|
||||
|
||||
// if CD==0, no baud rate is generated.
|
||||
// if CD==1, the clock divider and fractional part are bypassed.
|
||||
if (cd == 0) return 0;
|
||||
if (cd == 1) fp = 0;
|
||||
|
||||
// Rewriting "divisor = 8 * (2 - over) * (cd + fp/8)" for integer math:
|
||||
divisor = (2 - over) * (8 * cd + fp);
|
||||
|
||||
// Round to the integer that is closest to the actual result
|
||||
return (clock + divisor/2) / divisor;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Calculates a clock divider (\e CD) for the USART synchronous master
|
||||
* modes to generate a baud rate as close as possible to the baud rate
|
||||
* set point.
|
||||
@ -288,7 +342,11 @@ void usart_reset(volatile avr32_usart_t *usart)
|
||||
int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz)
|
||||
{
|
||||
// Reset the USART and shutdown TX and RX.
|
||||
// This is too brutal for eLua, for which the power-on reset state is OK.
|
||||
// Otherwise a buffered serial port stops receiving when you change baud rate.
|
||||
#ifndef ELUA_PLATFORM
|
||||
usart_reset(usart);
|
||||
#endif
|
||||
|
||||
// Check input values.
|
||||
if (!opt || // Null pointer.
|
||||
@ -844,7 +902,12 @@ int usart_read_char(volatile avr32_usart_t *usart, int *c)
|
||||
if (usart->csr & (AVR32_USART_CSR_OVRE_MASK |
|
||||
AVR32_USART_CSR_FRAME_MASK |
|
||||
AVR32_USART_CSR_PARE_MASK))
|
||||
{
|
||||
// Clear the error flag
|
||||
usart->cr = AVR32_USART_CR_RSTSTA_MASK;
|
||||
// Signal failure
|
||||
return USART_RX_ERROR;
|
||||
}
|
||||
|
||||
// No error; if we really did receive a char, read it and return SUCCESS.
|
||||
if (usart_test_hit(usart))
|
||||
|
@ -230,6 +230,16 @@ extern void usart_reset(volatile avr32_usart_t *usart);
|
||||
*/
|
||||
extern int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
|
||||
|
||||
/*! \brief Returns the actual baud rate set into the USART in async mode
|
||||
*
|
||||
* \param usart Base address of the USART instance.
|
||||
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
|
||||
*
|
||||
* \retval baudrate The nearest integer to the actual baud rate
|
||||
* \retval 0 No baudrate is being generated or some error
|
||||
*/
|
||||
extern unsigned int usart_get_async_baudrate(volatile avr32_usart_t *usart, unsigned long pba_hz);
|
||||
|
||||
/*! \brief Sets up the USART to use the standard RS232 protocol in TX-only mode.
|
||||
*
|
||||
* Compared to \ref usart_init_rs232, this function allows very high baud rates
|
||||
|
Loading…
x
Reference in New Issue
Block a user