From 5cb0a63beecaa9ff78b2ee9126ff56a02faf38e9 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Thu, 21 Apr 2011 19:09:19 +0200 Subject: [PATCH 01/15] Fix defines so that inclusion of ADC code is controlled by BUILD_ADC (previously, if NUM_ADC>0 but !BUILD_ADC, compilation failed with unresolved symbols) --- src/platform/avr32/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/avr32/platform.c b/src/platform/avr32/platform.c index bd65c6d4..7b71f06a 100644 --- a/src/platform/avr32/platform.c +++ b/src/platform/avr32/platform.c @@ -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); From eed1f7492d182313761af535d7be252d7a83bf6e Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Thu, 21 Apr 2011 19:34:09 +0200 Subject: [PATCH 02/15] Prepare Mizar32 platform conf for support of ADC module (disabled by default) --- src/platform/avr32/MIZAR32/mizar32_conf.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/platform/avr32/MIZAR32/mizar32_conf.h b/src/platform/avr32/MIZAR32/mizar32_conf.h index 52ff7e36..fc652c80 100644 --- a/src/platform/avr32/MIZAR32/mizar32_conf.h +++ b/src/platform/avr32/MIZAR32/mizar32_conf.h @@ -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 ) From b49a11f4a29bee3a9f1f7c31948175acaf6e7899 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Thu, 21 Apr 2011 20:48:04 +0200 Subject: [PATCH 03/15] Fix typos in documentation --- doc/en/elua_egc.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/elua_egc.html b/doc/en/elua_egc.html index be61645b..8e17701d 100644 --- a/doc/en/elua_egc.html +++ b/doc/en/elua_egc.html @@ -3,9 +3,9 @@ $$HEADER$$

The EGC (Emergency Garbage Collector) patch was originally written for Lua by Robert Jakabosky, who was kind enough to port it to eLua. You can find the author's detailed description of the patch here. 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.

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

In eLua, the EGC patch can be configured to run in 4 different modes:

  1. disabled: EGC inactive, no collection cycle will be forced in low memory situations.
  2. From 35c0b09875f92adcff5ac3edcbafd9e6b4b2c54a Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 18:02:47 +0200 Subject: [PATCH 04/15] When the UART gets a receive error, clear the error flag to avoid infinite repetition of the error state. --- src/platform/avr32/usart.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/avr32/usart.c b/src/platform/avr32/usart.c index dc2ff7a3..0948cd49 100644 --- a/src/platform/avr32/usart.c +++ b/src/platform/avr32/usart.c @@ -844,7 +844,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)) From 3b17c330027418a28f7df26efdcb6138f789f64a Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 18:03:51 +0200 Subject: [PATCH 05/15] When there is an error reading a line of input, return the actual number of characters received before the error (not a whole buffer full of junk!) --- src/newlib/genstd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/newlib/genstd.c b/src/newlib/genstd.c index 6a49c5a7..1e57c103 100644 --- a/src/newlib/genstd.c +++ b/src/newlib/genstd.c @@ -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' From a836ebeaaee9b3a84096f6f72213fa4a9d9f725a Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 18:05:50 +0200 Subject: [PATCH 06/15] Allow enabling/disabling of console buffer bu changing only BUF_ENABLE_CON (before, you had to change BUF_ENABLE_CON and CON_BUF_SIZE in parallel). --- inc/validate.h | 16 ++++++---------- src/common.c | 9 ++++----- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/inc/validate.h b/inc/validate.h index 0e7d3889..201791b2 100644 --- a/inc/validate.h +++ b/inc/validate.h @@ -59,6 +59,12 @@ // For BUF_ENABLE_UART we also need C interrupt handlers support and specific INT_UART_RX support #if defined( BUF_ENABLE_UART ) + #if !defined( CON_BUF_SIZE ) + #error "To enable console buffering you also need to define CON_BUF_SIZE" + #endif + #if !defined( CON_UART_ID ) + #error "Console buffering needs CON_UART_ID defined to the UART ID of the console device" + #endif #if !defined( BUILD_C_INT_HANDLERS ) #error "Buffering support on UART neeeds C interrupt handlers support, define BUILD_C_INT_HANDLERS in your platform_conf.h" #endif @@ -74,15 +80,5 @@ #endif #endif -// CON_BUF_SIZE needs BUF_ENABLE_UART and CON_UART_ID -#if defined( CON_BUF_SIZE ) - #if !defined( BUF_ENABLE_UART ) - #error "Console buffering needs BUF_ENABLE_UART" - #endif - #if !defined( CON_UART_ID ) - #error "Console buffering needs CON_UART_ID defined to the UART ID of the console device" - #endif -#endif - #endif // #ifndef __VALIDATE_H__ diff --git a/src/common.c b/src/common.c index 4902a05d..87dc4dac 100644 --- a/src/common.c +++ b/src/common.c @@ -33,11 +33,6 @@ extern const elua_int_descriptor elua_int_table[ INT_ELUA_LAST ]; #define VTMR_NUM_TIMERS 0 #endif // #ifndef VTMR_NUM_TIMERS -// [TODO] the new builder should automatically do this -#ifndef CON_BUF_SIZE -#define CON_BUF_SIZE 0 -#endif // #ifndef CON_BUF_SIZE - // [TODO] the new builder should automatically do this #ifndef SERMUX_FLOW_TYPE #define SERMUX_FLOW_TYPE PLATFORM_UART_FLOW_NONE @@ -205,7 +200,11 @@ void cmn_platform_init() // Setup console UART platform_uart_setup( CON_UART_ID, CON_UART_SPEED, 8, PLATFORM_UART_PARITY_NONE, PLATFORM_UART_STOPBITS_1 ); platform_uart_set_flow_control( CON_UART_ID, CON_FLOW_TYPE ); +#ifdef BUF_ENABLE_UART platform_uart_set_buffer( CON_UART_ID, CON_BUF_SIZE ); +#else + platform_uart_set_buffer( CON_UART_ID, 0 ); +#endif #endif // #if defined( CON_UART_ID ) && CON_UART_ID < SERMUX_SERVICE_ID_FIRST // Set the send/recv functions From 593b4b92327622b62f262d3c333e93d914d4ff72 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 18:20:15 +0200 Subject: [PATCH 07/15] Remove printing of internal code values from "Buffer overflow" message so that the relatively common UART input buffer overflow condition just says "[ERROR] Buffer overflow." without the inscrutable "resid=0 resnum=0" numbers. --- src/buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buf.c b/src/buf.c index 1391f189..e0286a2f 100644 --- a/src/buf.c +++ b/src/buf.c @@ -123,7 +123,7 @@ int buf_write( unsigned resid, unsigned resnum, t_buf_data *data ) return PLATFORM_ERR; if( pbuf->count > BUF_REALSIZE( pbuf ) ) { - fprintf( stderr, "[ERROR] Buffer overflow on resid=%d, resnum=%d!\n", resid, resnum ); + fprintf( stderr, "[ERROR] Buffer overflow.\n"); return PLATFORM_ERR; } DUFF_DEVICE_8( BUF_REALDSIZE( pbuf ), *d++ = *s++ ); From f49b44eae64c4cf4d9e7b251a49866729509be64 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 18:56:41 +0200 Subject: [PATCH 08/15] Fix typos in en_refman_gen_tmr doc --- doc/eluadoc/refman_gen_tmr.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/eluadoc/refman_gen_tmr.lua b/doc/eluadoc/refman_gen_tmr.lua index bee583e1..4d8a4713 100644 --- a/doc/eluadoc/refman_gen_tmr.lua +++ b/doc/eluadoc/refman_gen_tmr.lua @@ -17,7 +17,7 @@ data_en = be available by using $tmr.VIRT0$ to $tmr.VIRT3$ as timer IDs.

    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)." }, From 0a89dae26b3ed117f1518c58454f5614c40be946 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Sat, 23 Apr 2011 19:15:17 +0200 Subject: [PATCH 09/15] Revert "Remove printing of internal code values from "Buffer overflow" message" This reverts commit 593b4b92327622b62f262d3c333e93d914d4ff72. As requested by Bogdan --- src/buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buf.c b/src/buf.c index e0286a2f..1391f189 100644 --- a/src/buf.c +++ b/src/buf.c @@ -123,7 +123,7 @@ int buf_write( unsigned resid, unsigned resnum, t_buf_data *data ) return PLATFORM_ERR; if( pbuf->count > BUF_REALSIZE( pbuf ) ) { - fprintf( stderr, "[ERROR] Buffer overflow.\n"); + fprintf( stderr, "[ERROR] Buffer overflow on resid=%d, resnum=%d!\n", resid, resnum ); return PLATFORM_ERR; } DUFF_DEVICE_8( BUF_REALDSIZE( pbuf ), *d++ = *s++ ); From c0119c0908dfceb9a33beac5c8051516307941b2 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 13:52:10 +0200 Subject: [PATCH 10/15] Revert "Allow enabling/disabling of console buffer bu changing only BUF_ENABLE_CON" This reverts commit a836ebeaaee9b3a84096f6f72213fa4a9d9f725a. As requested by Bogdan --- inc/validate.h | 16 ++++++++++------ src/common.c | 9 +++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/inc/validate.h b/inc/validate.h index 201791b2..0e7d3889 100644 --- a/inc/validate.h +++ b/inc/validate.h @@ -59,12 +59,6 @@ // For BUF_ENABLE_UART we also need C interrupt handlers support and specific INT_UART_RX support #if defined( BUF_ENABLE_UART ) - #if !defined( CON_BUF_SIZE ) - #error "To enable console buffering you also need to define CON_BUF_SIZE" - #endif - #if !defined( CON_UART_ID ) - #error "Console buffering needs CON_UART_ID defined to the UART ID of the console device" - #endif #if !defined( BUILD_C_INT_HANDLERS ) #error "Buffering support on UART neeeds C interrupt handlers support, define BUILD_C_INT_HANDLERS in your platform_conf.h" #endif @@ -80,5 +74,15 @@ #endif #endif +// CON_BUF_SIZE needs BUF_ENABLE_UART and CON_UART_ID +#if defined( CON_BUF_SIZE ) + #if !defined( BUF_ENABLE_UART ) + #error "Console buffering needs BUF_ENABLE_UART" + #endif + #if !defined( CON_UART_ID ) + #error "Console buffering needs CON_UART_ID defined to the UART ID of the console device" + #endif +#endif + #endif // #ifndef __VALIDATE_H__ diff --git a/src/common.c b/src/common.c index 87dc4dac..4902a05d 100644 --- a/src/common.c +++ b/src/common.c @@ -33,6 +33,11 @@ extern const elua_int_descriptor elua_int_table[ INT_ELUA_LAST ]; #define VTMR_NUM_TIMERS 0 #endif // #ifndef VTMR_NUM_TIMERS +// [TODO] the new builder should automatically do this +#ifndef CON_BUF_SIZE +#define CON_BUF_SIZE 0 +#endif // #ifndef CON_BUF_SIZE + // [TODO] the new builder should automatically do this #ifndef SERMUX_FLOW_TYPE #define SERMUX_FLOW_TYPE PLATFORM_UART_FLOW_NONE @@ -200,11 +205,7 @@ void cmn_platform_init() // Setup console UART platform_uart_setup( CON_UART_ID, CON_UART_SPEED, 8, PLATFORM_UART_PARITY_NONE, PLATFORM_UART_STOPBITS_1 ); platform_uart_set_flow_control( CON_UART_ID, CON_FLOW_TYPE ); -#ifdef BUF_ENABLE_UART platform_uart_set_buffer( CON_UART_ID, CON_BUF_SIZE ); -#else - platform_uart_set_buffer( CON_UART_ID, 0 ); -#endif #endif // #if defined( CON_UART_ID ) && CON_UART_ID < SERMUX_SERVICE_ID_FIRST // Set the send/recv functions From dfcde5bb47c569eff3f017dc2504b25cc0d67fa6 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 16:32:00 +0200 Subject: [PATCH 11/15] Starting to fix AVR32 UARt code: - Check for error return values and return errors when they happen - Return error value when invalid parameters are passed - uart.setup(): return the actual baud rate set. --- src/platform/avr32/platform.c | 33 +++++++++++++++------ src/platform/avr32/usart.c | 54 +++++++++++++++++++++++++++++++++++ src/platform/avr32/usart.h | 10 +++++++ 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/platform/avr32/platform.c b/src/platform/avr32/platform.c index 7b71f06a..a0c8f2fa 100644 --- a/src/platform/avr32/platform.c +++ b/src/platform/avr32/platform.c @@ -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 ) diff --git a/src/platform/avr32/usart.c b/src/platform/avr32/usart.c index 0948cd49..4641ff26 100644 --- a/src/platform/avr32/usart.c +++ b/src/platform/avr32/usart.c @@ -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. diff --git a/src/platform/avr32/usart.h b/src/platform/avr32/usart.h index c066cdcc..d095713a 100644 --- a/src/platform/avr32/usart.h +++ b/src/platform/avr32/usart.h @@ -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 From 02cc57c53822d6aec3f55cca15c6f1f2f3c4cad7 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 17:16:05 +0200 Subject: [PATCH 12/15] Put more SERMUX code under #ifdef BUILD_SERMUX Saves 184 bytes in code segment when !BUILD_SERMUX by replacing constant runtime checks with compile-time ones. --- src/common_uart.c | 32 +++++++++++++++++++++++++------- src/modules/uart.c | 4 ++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/common_uart.c b/src/common_uart.c index 5ea7ee40..6202aa9a 100644 --- a/src/common_uart.c +++ b/src/common_uart.c @@ -16,8 +16,6 @@ int uart_service_id_out = -1; u8 uart_got_esc = 0; int uart_last_sent = -1; // [TODO] add interrupt support for virtual UARTs -#else // #ifdef BUILD_SERMUX -#define SERMUX_PHYS_ID ( 0xFFFF ) #endif // #ifdef BUILD_SERMUX // The platform UART functions @@ -148,7 +146,11 @@ static elua_int_c_handler prev_uart_rx_handler; static void cmn_uart_rx_inthandler( elua_int_resnum resnum ) { - if( buf_is_enabled( BUF_ID_UART, resnum ) || resnum == SERMUX_PHYS_ID ) + if( buf_is_enabled( BUF_ID_UART, resnum ) +#ifdef BUILD_SERMUX + || resnum == SERMUX_PHYS_ID +#endif // #ifdef BUILD_SERMUX + ) cmn_rx_handler( resnum, platform_s_uart_recv( resnum, 0 ) ); // Chain to previous handler @@ -159,13 +161,21 @@ static void cmn_uart_rx_inthandler( elua_int_resnum resnum ) int platform_uart_set_buffer( unsigned id, unsigned log2size ) { - if( id == SERMUX_PHYS_ID ) // mere mortals aren't allowed to mess with VUART physical interface buffering +#ifdef BUILD_SERMUX + // mere mortals aren't allowed to mess with VUART physical interface buffering + if( id == SERMUX_PHYS_ID ) return PLATFORM_ERR; +#endif // #ifdef BUILD_SERMUX + #ifdef BUF_ENABLE_UART if( log2size == 0 ) { - if( id >= SERMUX_SERVICE_ID_FIRST ) // Virtual UARTs need buffers no matter what +#ifdef BUILD_SERMUX + // Virtual UARTs need buffers no matter what + if( id >= SERMUX_SERVICE_ID_FIRST ) return PLATFORM_ERR; +#endif // #ifdef BUILD_SERMUX + // Disable buffering buf_set( BUF_ID_UART, id, BUF_SIZE_NONE, BUF_DSIZE_U8 ); } @@ -174,11 +184,17 @@ int platform_uart_set_buffer( unsigned id, unsigned log2size ) // Enable buffering if( buf_set( BUF_ID_UART, id, log2size, BUF_DSIZE_U8 ) == PLATFORM_ERR ) return PLATFORM_ERR; - if( id >= SERMUX_SERVICE_ID_FIRST ) // No need for aditional setup on virtual UARTs + +#ifdef BUILD_SERMUX + // No need for additional setup on virtual UARTs + if( id >= SERMUX_SERVICE_ID_FIRST ) return PLATFORM_OK; +#endif // #ifdef BUILD_SERMUX + // Enable UART RX interrupt if( platform_cpu_set_interrupt( INT_UART_RX, id, PLATFORM_CPU_ENABLE ) != PLATFORM_INT_OK ) return PLATFORM_ERR; + // Setup our C handler if( elua_int_get_c_handler( INT_UART_RX ) != cmn_uart_rx_inthandler ) prev_uart_rx_handler = elua_int_set_c_handler( INT_UART_RX, cmn_uart_rx_inthandler ); @@ -207,8 +223,10 @@ void cmn_uart_setup_sermux() int platform_uart_set_flow_control( unsigned id, int type ) { +#ifdef BUILD_SERMUX if( id >= SERMUX_SERVICE_ID_FIRST ) return PLATFORM_ERR; +#endif // #ifdef BUILD_SERMUX + return platform_s_uart_set_flow_control( id, type ); } - diff --git a/src/modules/uart.c b/src/modules/uart.c index b9138a11..62bcfcb6 100644 --- a/src/modules/uart.c +++ b/src/modules/uart.c @@ -30,8 +30,10 @@ static int uart_setup( lua_State* L ) id = luaL_checkinteger( L, 1 ); MOD_CHECK_ID( uart, id ); +#ifdef BUILD_SERMUX if( id >= SERMUX_SERVICE_ID_FIRST ) return luaL_error( L, "uart.setup can't be called on virtual UARTs" ); +#endif baud = luaL_checkinteger( L, 2 ); databits = luaL_checkinteger( L, 3 ); parity = luaL_checkinteger( L, 4 ); @@ -187,8 +189,10 @@ static int uart_set_buffer( lua_State *L ) MOD_CHECK_ID( uart, id ); if( size && ( size & ( size - 1 ) ) ) return luaL_error( L, "the buffer size must be a power of 2 or 0" ); +#ifdef BUILD_SERMUX if( size == 0 && id >= SERMUX_SERVICE_ID_FIRST ) return luaL_error( L, "disabling buffers on virtual UARTs is not allowed" ); +#endif if( platform_uart_set_buffer( id, intlog2( size ) ) == PLATFORM_ERR ) return luaL_error( L, "unable to set UART buffer" ); return 0; From 53efb1b4c8bb177c41d3bb28d8f8c10ab472f836 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 17:46:22 +0200 Subject: [PATCH 13/15] Add code to allow compilation with BUILD_LUA_INT_HANDLERS on avr32 platforms --- src/platform/avr32/EVK1100/evk1100_conf.h | 5 ++++- src/platform/avr32/EVK1101/evk1101_conf.h | 3 +++ src/platform/avr32/MIZAR32/mizar32_conf.h | 3 +++ src/platform/avr32/platform.c | 5 +++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/platform/avr32/EVK1100/evk1100_conf.h b/src/platform/avr32/EVK1100/evk1100_conf.h index 5fa6f788..61acf6a6 100644 --- a/src/platform/avr32/EVK1100/evk1100_conf.h +++ b/src/platform/avr32/EVK1100/evk1100_conf.h @@ -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 diff --git a/src/platform/avr32/EVK1101/evk1101_conf.h b/src/platform/avr32/EVK1101/evk1101_conf.h index d6dffb1c..f659fd47 100644 --- a/src/platform/avr32/EVK1101/evk1101_conf.h +++ b/src/platform/avr32/EVK1101/evk1101_conf.h @@ -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 diff --git a/src/platform/avr32/MIZAR32/mizar32_conf.h b/src/platform/avr32/MIZAR32/mizar32_conf.h index fc652c80..8ae33a1d 100644 --- a/src/platform/avr32/MIZAR32/mizar32_conf.h +++ b/src/platform/avr32/MIZAR32/mizar32_conf.h @@ -162,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 diff --git a/src/platform/avr32/platform.c b/src/platform/avr32/platform.c index a0c8f2fa..67a63ffa 100644 --- a/src/platform/avr32/platform.c +++ b/src/platform/avr32/platform.c @@ -579,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 From 27d0ed361e749d82311234cb9c959202ad8b009d Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 21:26:19 +0200 Subject: [PATCH 14/15] Revert "Put more SERMUX code under #ifdef BUILD_SERMUX" This reverts commit 02cc57c53822d6aec3f55cca15c6f1f2f3c4cad7. Objected to by Bogdan. --- src/common_uart.c | 32 +++++++------------------------- src/modules/uart.c | 4 ---- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/common_uart.c b/src/common_uart.c index 6202aa9a..5ea7ee40 100644 --- a/src/common_uart.c +++ b/src/common_uart.c @@ -16,6 +16,8 @@ int uart_service_id_out = -1; u8 uart_got_esc = 0; int uart_last_sent = -1; // [TODO] add interrupt support for virtual UARTs +#else // #ifdef BUILD_SERMUX +#define SERMUX_PHYS_ID ( 0xFFFF ) #endif // #ifdef BUILD_SERMUX // The platform UART functions @@ -146,11 +148,7 @@ static elua_int_c_handler prev_uart_rx_handler; static void cmn_uart_rx_inthandler( elua_int_resnum resnum ) { - if( buf_is_enabled( BUF_ID_UART, resnum ) -#ifdef BUILD_SERMUX - || resnum == SERMUX_PHYS_ID -#endif // #ifdef BUILD_SERMUX - ) + if( buf_is_enabled( BUF_ID_UART, resnum ) || resnum == SERMUX_PHYS_ID ) cmn_rx_handler( resnum, platform_s_uart_recv( resnum, 0 ) ); // Chain to previous handler @@ -161,21 +159,13 @@ static void cmn_uart_rx_inthandler( elua_int_resnum resnum ) int platform_uart_set_buffer( unsigned id, unsigned log2size ) { -#ifdef BUILD_SERMUX - // mere mortals aren't allowed to mess with VUART physical interface buffering - if( id == SERMUX_PHYS_ID ) + if( id == SERMUX_PHYS_ID ) // mere mortals aren't allowed to mess with VUART physical interface buffering return PLATFORM_ERR; -#endif // #ifdef BUILD_SERMUX - #ifdef BUF_ENABLE_UART if( log2size == 0 ) { -#ifdef BUILD_SERMUX - // Virtual UARTs need buffers no matter what - if( id >= SERMUX_SERVICE_ID_FIRST ) + if( id >= SERMUX_SERVICE_ID_FIRST ) // Virtual UARTs need buffers no matter what return PLATFORM_ERR; -#endif // #ifdef BUILD_SERMUX - // Disable buffering buf_set( BUF_ID_UART, id, BUF_SIZE_NONE, BUF_DSIZE_U8 ); } @@ -184,17 +174,11 @@ int platform_uart_set_buffer( unsigned id, unsigned log2size ) // Enable buffering if( buf_set( BUF_ID_UART, id, log2size, BUF_DSIZE_U8 ) == PLATFORM_ERR ) return PLATFORM_ERR; - -#ifdef BUILD_SERMUX - // No need for additional setup on virtual UARTs - if( id >= SERMUX_SERVICE_ID_FIRST ) + if( id >= SERMUX_SERVICE_ID_FIRST ) // No need for aditional setup on virtual UARTs return PLATFORM_OK; -#endif // #ifdef BUILD_SERMUX - // Enable UART RX interrupt if( platform_cpu_set_interrupt( INT_UART_RX, id, PLATFORM_CPU_ENABLE ) != PLATFORM_INT_OK ) return PLATFORM_ERR; - // Setup our C handler if( elua_int_get_c_handler( INT_UART_RX ) != cmn_uart_rx_inthandler ) prev_uart_rx_handler = elua_int_set_c_handler( INT_UART_RX, cmn_uart_rx_inthandler ); @@ -223,10 +207,8 @@ void cmn_uart_setup_sermux() int platform_uart_set_flow_control( unsigned id, int type ) { -#ifdef BUILD_SERMUX if( id >= SERMUX_SERVICE_ID_FIRST ) return PLATFORM_ERR; -#endif // #ifdef BUILD_SERMUX - return platform_s_uart_set_flow_control( id, type ); } + diff --git a/src/modules/uart.c b/src/modules/uart.c index 62bcfcb6..b9138a11 100644 --- a/src/modules/uart.c +++ b/src/modules/uart.c @@ -30,10 +30,8 @@ static int uart_setup( lua_State* L ) id = luaL_checkinteger( L, 1 ); MOD_CHECK_ID( uart, id ); -#ifdef BUILD_SERMUX if( id >= SERMUX_SERVICE_ID_FIRST ) return luaL_error( L, "uart.setup can't be called on virtual UARTs" ); -#endif baud = luaL_checkinteger( L, 2 ); databits = luaL_checkinteger( L, 3 ); parity = luaL_checkinteger( L, 4 ); @@ -189,10 +187,8 @@ static int uart_set_buffer( lua_State *L ) MOD_CHECK_ID( uart, id ); if( size && ( size & ( size - 1 ) ) ) return luaL_error( L, "the buffer size must be a power of 2 or 0" ); -#ifdef BUILD_SERMUX if( size == 0 && id >= SERMUX_SERVICE_ID_FIRST ) return luaL_error( L, "disabling buffers on virtual UARTs is not allowed" ); -#endif if( platform_uart_set_buffer( id, intlog2( size ) ) == PLATFORM_ERR ) return luaL_error( L, "unable to set UART buffer" ); return 0; From e1b80e55bbcc5580ea376f92b1885bc24bde6715 Mon Sep 17 00:00:00 2001 From: Martin Guy Date: Mon, 25 Apr 2011 21:27:50 +0200 Subject: [PATCH 15/15] Fix bug #221 --- src/platform/avr32/usart.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/avr32/usart.c b/src/platform/avr32/usart.c index 4641ff26..b0c35242 100644 --- a/src/platform/avr32/usart.c +++ b/src/platform/avr32/usart.c @@ -342,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.