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

- added support for the STR-E912 board from Olimex

- PWM module for STR9
- STR9 port fixes 
- STR9 platform-specific module: str9.pio (the STR9 GPIO subsystem is quite uncommon).
- small LM3S fixes
This commit is contained in:
Bogdan Marinescu 2009-10-18 01:27:33 +00:00
parent c404753efa
commit cf48728115
7 changed files with 276 additions and 42 deletions

View File

@ -7,6 +7,12 @@ toolchain = ARGUMENTS.get( 'toolchain', '')
optram = int( ARGUMENTS.get( 'optram', '1' ) )
boot = ARGUMENTS.get( 'boot', '').lower()
# Helper: "normalize" a name to make it a suitable C macro name
def cnorm( name ):
name = name.replace( '-', '' )
name = name.replace( ' ', '' )
return name.upper()
# List of toolchains
toolchain_list = {
'arm-gcc' : {
@ -34,6 +40,7 @@ toolchain_list = {
'compile' : 'avr32-gcc',
'link' : 'avr32-ld',
'asm' : 'avr32-as',
'bin' : 'avr32-objcopy',
'size' : 'avr32-size'
},
@ -71,6 +78,7 @@ board_list = { 'SAM7-EX256' : [ 'AT91SAM7X256', 'AT91SAM7X512' ],
'EK-LM3S6965' : [ 'LM3S6965' ],
'EK-LM3S9B92' : [ 'LM3S9B92' ],
'STR9-COMSTICK' : [ 'STR912FAW44' ],
'STR-E912' : [ 'STR912FAW44' ],
'PC' : [ 'I386' ],
'SIM' : [ 'LINUX' ],
'LPC-H2888' : [ 'LPC2888' ],
@ -111,6 +119,7 @@ file_list = { 'SAM7-EX256' : [ 'bisect', 'hangman' , 'led', 'piano', 'hello', 'i
'EK-LM3S6965' : [ 'bisect', 'hangman', 'lhttpd', 'pong', 'led', 'piano', 'pwmled', 'tvbgone', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'spaceship', 'tetrives' ],
'EK-LM3S9B92' : [ 'bisect', 'hangman', 'lhttpd', 'led', 'pwmled', 'hello', 'info', 'adcscope','adcpoll', 'life' ],
'STR9-COMSTICK' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
'STR-E912' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'piano' ],
'PC' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
'SIM' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
'LPC-H2888' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
@ -216,6 +225,8 @@ if not GetOption( 'clean' ):
output = 'elua_' + target + '_' + cputype.lower()
cdefs = '-DELUA_CPU=%s -DELUA_BOARD=%s -DELUA_PLATFORM=%s -D__BUFSIZ__=128' % ( cputype, boardname, platform.upper() )
# Also make the above into direct defines (to use in conditional C code)
cdefs = cdefs + " -DELUA_CPU_%s -DELUA_BOARD_%s -DELUA_PLATFORM_%s" % ( cnorm( cputype ), cnorm( boardname ), cnorm( platform ) )
if allocator == 'multiple':
cdefs = cdefs + " -DUSE_MULTIPLE_ALLOCATOR"
elif allocator == 'simple':

View File

@ -12,6 +12,10 @@ if pd.board() == "EK-LM3S8962" or pd.board() == "EK-LM3S6965" then
elseif pd.board() == "SAM7-EX256" then
pwmid, tmrid = 0, 1
tmr.setclock( 1, 1000000 )
elseif pd.board() == "STR-E912" then
local g = str9.pio
g.setpin( pio.P4_6, g.OUTPUT, g.OUTPUT_PUSHPULL, false, g.ALT_OUTPUT2 )
pwmid, tmrid = 3, 1
else
print( pd.board() .. " not supported with this example" )
return

View File

@ -966,9 +966,9 @@ LUALIB_API int luaopen_platform( lua_State *L )
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, PS_LIB_TABLE_NAME, luaopen_platform );
luaL_register( L, PS_LIB_TABLE_NAME, platform_map );
// Setup the new tables (pin and port) inside pio
// Setup the new tables inside platform table
lua_newtable( L );
luaL_register( L, NULL, disp_map );
lua_setfield( L, -2, "disp" );

View File

@ -2,7 +2,7 @@
cpumode = ARGUMENTS.get( 'cpumode', 'arm' ).lower()
specific_files = "startup912.s startup_generic.s platform.c 91x_scu.c 91x_fmi.c 91x_gpio.c 91x_uart.c 91x_tim.c 91x_vic.c interrupt.c"
specific_files = "startup912.s startup_generic.s platform.c 91x_scu.c 91x_fmi.c 91x_gpio.c 91x_uart.c 91x_tim.c 91x_vic.c interrupt.c str9_pio.c"
# Check CPU
if cputype == 'STR912FAW44':
@ -24,11 +24,16 @@ else:
specific_files = " ".join( [ "src/platform/%s/%s" % ( platform, f ) for f in specific_files.split() ] )
ldscript = "src/platform/%s/%s" % ( platform, ldscript )
# toolchain 'arm-gcc' requires '-mfpu=fpa' for some reason
auxm = ''
if toolchain == 'arm-gcc':
auxm = '-mfpu=fpa'
# Toolset data
tools[ 'str9' ] = {}
tools[ 'str9' ][ 'cccom' ] = "%s -mcpu=arm966e-s -mfpu=fpa %s $_CPPINCFLAGS %s -ffunction-sections -fdata-sections %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile'], opt, modeflag, cdefs )
tools[ 'str9' ][ 'linkcom' ] = "%s -mcpu=arm966e-s -mfpu=fpa -nostartfiles -nostdlib %s -T %s -Wl,--gc-sections -Wl,-e,_startup -Wl,--allow-multiple-definition -o $TARGET $SOURCES %s -lc -lgcc -lm" % ( toolset[ 'compile' ], modeflag, ldscript, local_libs )
tools[ 'str9' ][ 'ascom' ] = "%s -x assembler-with-cpp $_CPPINCFLAGS -mcpu=arm966e-s -mfpu=fpa %s %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], modeflag, cdefs )
tools[ 'str9' ][ 'cccom' ] = "%s -mcpu=arm966e-s %s %s $_CPPINCFLAGS %s -ffunction-sections -fdata-sections %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile'], auxm, opt, modeflag, cdefs )
tools[ 'str9' ][ 'linkcom' ] = "%s -mcpu=arm966e-s %s -nostartfiles -nostdlib %s -T %s -Wl,--gc-sections -Wl,-e,_startup -Wl,--allow-multiple-definition -o $TARGET $SOURCES %s -lc -lgcc -lm" % ( toolset[ 'compile' ], auxm, modeflag, ldscript, local_libs )
tools[ 'str9' ][ 'ascom' ] = "%s -x assembler-with-cpp $_CPPINCFLAGS %s -mfpu=fpa %s %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], auxm, modeflag, cdefs )
# Programming function for LPC2888
def progfunc_str9( target, source, env ):

View File

@ -18,13 +18,11 @@
#include "common.h"
#include "platform_conf.h"
#include "91x_vic.h"
// We define here the UART used by this porting layer
#define STR9_UART UART1
#include "lrotable.h"
// ****************************************************************************
// Platform initialization
static const GPIO_TypeDef* port_data[] = { GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9 };
const GPIO_TypeDef* port_data[] = { GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9 };
static const TIM_TypeDef* timer_data[] = { TIM0, TIM1, TIM2, TIM3 };
static void platform_config_scu()
@ -42,8 +40,8 @@ static void platform_config_scu()
/* Set the RCLK Clock divider to max speed*/
SCU_RCLKDivisorConfig(SCU_RCLK_Div1);
/* Set the PCLK Clock to MCLK/8 */
SCU_PCLKDivisorConfig(SCU_PCLK_Div8);
/* Set the PCLK Clock to MCLK/2 */
SCU_PCLKDivisorConfig(SCU_PCLK_Div2);
/* Set the HCLK Clock to MCLK */
SCU_HCLKDivisorConfig(SCU_HCLK_Div1);
@ -64,6 +62,37 @@ static void platform_config_scu()
SCU_APBPeriphClockConfig(__GPIO_ALL, ENABLE);
}
// Port/pin definitions of the eLua UART connection for different boards
#define UART_RX_IDX 0
#define UART_TX_IDX 1
#ifdef ELUA_BOARD_STRE912
static const GPIO_TypeDef* uart_port_data[] = { GPIO5, GPIO5 };
static const u8 uart_pin_data[] = { GPIO_Pin_1, GPIO_Pin_0 };
#else // STR9-comStick
static const GPIO_TypeDef* uart_port_data[] = { GPIO3, GPIO3 };
static const u8 uart_pin_data[] = { GPIO_Pin_2, GPIO_Pin_3 };
#endif
// Plaform specific GPIO UART setup
static void platform_gpio_uart_setup()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit( &GPIO_InitStructure );
// RX
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = uart_pin_data[ UART_RX_IDX ];
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;
GPIO_Init( ( GPIO_TypeDef* )uart_port_data[ UART_RX_IDX ], &GPIO_InitStructure );
// TX
GPIO_InitStructure.GPIO_Pin = uart_pin_data[ UART_TX_IDX ];
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt3 ;
GPIO_Init( ( GPIO_TypeDef* )uart_port_data[ UART_TX_IDX ], &GPIO_InitStructure );
}
int platform_init()
{
unsigned i;
@ -80,7 +109,8 @@ int platform_init()
// Initialize VIC
VIC_DeInit();
// UART setup (only STR9_UART is used in this example)
// UART setup
platform_gpio_uart_setup();
platform_uart_setup( CON_UART_ID, CON_UART_SPEED, 8, PLATFORM_UART_PARITY_NONE, PLATFORM_UART_STOPBITS_1 );
// Initialize timers
@ -159,25 +189,12 @@ pio_type platform_pio_op( unsigned port, pio_type pinmask, int op )
// ****************************************************************************
// UART
static const UART_TypeDef* uarts[] = { UART0, UART1, UART2 };
u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int stopbits )
{
UART_InitTypeDef UART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
id = id;
// First configure GPIO
// RX: GPIO3.2
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// TX: GPIO3.3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;
GPIO_Init (GPIO3, &GPIO_InitStructure);
UART_TypeDef* p_uart = ( UART_TypeDef* )uarts[ id ];
// Then configure UART parameters
switch( databits )
@ -212,33 +229,36 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
UART_InitStructure.UART_TxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */
UART_InitStructure.UART_RxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */
UART_DeInit(STR9_UART);
UART_Init(STR9_UART, &UART_InitStructure);
UART_Cmd(STR9_UART, ENABLE);
UART_DeInit( p_uart );
UART_Init( p_uart , &UART_InitStructure );
UART_Cmd( p_uart, ENABLE );
return baud;
}
void platform_uart_send( unsigned id, u8 data )
{
id = id;
UART_TypeDef* p_uart = ( UART_TypeDef* )uarts[ id ];
// while( UART_GetFlagStatus( STR9_UART, UART_FLAG_TxFIFOFull ) == SET );
UART_SendData( STR9_UART, data );
while( UART_GetFlagStatus( STR9_UART, UART_FLAG_TxFIFOFull ) != RESET );
UART_SendData( p_uart, data );
while( UART_GetFlagStatus( p_uart, UART_FLAG_TxFIFOFull ) != RESET );
}
int platform_s_uart_recv( unsigned id, s32 timeout )
{
UART_TypeDef* p_uart = ( UART_TypeDef* )uarts[ id ];
if( timeout == 0 )
{
// Return data only if already available
if( UART_GetFlagStatus( STR9_UART, UART_FLAG_RxFIFOEmpty ) != SET )
return UART_ReceiveData( STR9_UART );
if( UART_GetFlagStatus( p_uart, UART_FLAG_RxFIFOEmpty ) != SET )
return UART_ReceiveData( p_uart );
else
return -1;
}
while( UART_GetFlagStatus( STR9_UART, UART_FLAG_RxFIFOEmpty ) == SET );
return UART_ReceiveData( STR9_UART );
while( UART_GetFlagStatus( p_uart, UART_FLAG_RxFIFOEmpty ) == SET );
return UART_ReceiveData( p_uart );
}
// ****************************************************************************
@ -325,6 +345,66 @@ u32 platform_s_timer_op( unsigned id, int op, u32 data )
return res;
}
// ****************************************************************************
// PWM functions
u32 platform_pwm_setup( unsigned id, u32 frequency, unsigned duty )
{
TIM_TypeDef* p_timer = ( TIM_TypeDef* )timer_data[ id ];
u32 base = SCU_GetPCLKFreqValue() * 1000;
u32 div = ( base / 256 ) / frequency;
TIM_InitTypeDef tim;
TIM_DeInit( p_timer );
tim.TIM_Mode = TIM_PWM;
tim.TIM_Clock_Source = TIM_CLK_APB;
tim.TIM_Prescaler = 0xFF;
tim.TIM_Pulse_Level_1 = TIM_HIGH;
tim.TIM_Period_Level = TIM_LOW;
tim.TIM_Full_Period = div;
tim.TIM_Pulse_Length_1 = ( div * duty ) / 100;
TIM_Init( p_timer, &tim );
return base / div;
}
static u32 platform_pwm_set_clock( unsigned id, u32 clock )
{
TIM_TypeDef* p_timer = ( TIM_TypeDef* )timer_data[ id ];
u32 base = ( SCU_GetPCLKFreqValue() * 1000 );
u32 div = base / clock;
TIM_PrescalerConfig( p_timer, ( u8 )div - 1 );
return base / div;
}
u32 platform_pwm_op( unsigned id, int op, u32 data )
{
u32 res = 0;
TIM_TypeDef* p_timer = ( TIM_TypeDef* )timer_data[ id ];
switch( op )
{
case PLATFORM_PWM_OP_START:
TIM_CounterCmd( p_timer, TIM_START );
break;
case PLATFORM_PWM_OP_STOP:
TIM_CounterCmd( p_timer, TIM_STOP );
break;
case PLATFORM_PWM_OP_SET_CLOCK:
res = platform_pwm_set_clock( id, data );
break;
case PLATFORM_PWM_OP_GET_CLOCK:
res = ( SCU_GetPCLKFreqValue() * 1000 ) / ( TIM_GetPrescalerValue( p_timer ) + 1 );
break;
}
return res;
}
// ****************************************************************************
// CPU functions
@ -340,3 +420,35 @@ void platform_cpu_disable_interrupts()
{
disable_ints();
}
// ****************************************************************************
// Platform specific modules go here
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
extern const LUA_REG_TYPE str9_pio_map[];
const LUA_REG_TYPE platform_map[] =
{
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "pio" ), LROVAL( str9_pio_map ) },
#endif
{ LNILKEY, LNILVAL }
};
LUALIB_API int luaopen_platform( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else // #if LUA_OPTIMIZE_MEMORY > 0
luaL_register( L, PS_LIB_TABLE_NAME, platform_map );
// Setup the new tables inside platform table
lua_newtable( L );
luaL_register( L, NULL, str9_pio_map );
lua_setfield( L, -2, "pio" );
return 1;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}

View File

@ -19,7 +19,12 @@
// *****************************************************************************
// UART/Timer IDs configuration data (used in main.c)
#ifdef ELUA_BOARD_STRE912
#define CON_UART_ID 0
#else // STR9-comStick
#define CON_UART_ID 1
#endif
#define CON_UART_SPEED 115200
#define CON_TIMER_ID 0
#define TERM_LINES 25
@ -35,9 +40,9 @@
// Number of resources (0 if not available/not implemented)
#define NUM_PIO 10
#define NUM_SPI 0
#define NUM_UART 1
#define NUM_UART 3
#define NUM_TIMER 4
#define NUM_PWM 0
#define NUM_PWM 4
#define NUM_ADC 0
#define NUM_CAN 0
@ -63,6 +68,9 @@ u32 SCU_GetMCLKFreqValue();
// *****************************************************************************
// Auxiliary libraries that will be compiled for this platform
// The name of the platform specific libs table
#define PS_LIB_TABLE_NAME "str9"
#define LUA_PLATFORM_LIBS_ROM\
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
@ -72,6 +80,8 @@ u32 SCU_GetMCLKFreqValue();
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map)\
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map)\
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
_ROM( PS_LIB_TABLE_NAME, luaopen_platform, platform_map )
#endif // #ifndef __PLATFORM_CONF_H__

View File

@ -0,0 +1,92 @@
// STR9 specific PIO support
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "lrotable.h"
#include "platform_conf.h"
#include "91x_gpio.h"
#include "auxmods.h"
#define GPIO_DIR_INPUT GPIO_PinInput
#define GPIO_DIR_OUTPUT GPIO_PinOutput
#define GPIO_ALT_INPUT GPIO_InputAlt1
#define GPIO_ALT_OUTPUT1 GPIO_OutputAlt1
#define GPIO_ALT_OUTPUT2 GPIO_OutputAlt2
#define GPIO_ALT_OUTPUT3 GPIO_OutputAlt3
#define GPIO_OUTPUT_PP GPIO_Type_PushPull
#define GPIO_OUTPUT_OC GPIO_Type_OpenCollector
// Puin mappings (for GPIO lib)
static const unsigned str9_pins[] = { GPIO_Pin_0, GPIO_Pin_1, GPIO_Pin_2, GPIO_Pin_3, GPIO_Pin_4, GPIO_Pin_5, GPIO_Pin_6, GPIO_Pin_7 };
extern const GPIO_TypeDef* port_data[];
// Lua: str9.pio.set_input( pin, direction, type, ipconnected, alternate )
// direction: INPUT, OUTPUT
// type: OUTPUT_PUSHPULL, OUTPUT_OC
// ipconnected: true or false
// alternate: ALT_INPUT, ALT_OUTPUT1, ALT_OUTPUT2, ALT_OUTPUT3
static int setpin( lua_State *L )
{
pio_type v = ( pio_type )luaL_checkinteger( L, 1 );
int direction = luaL_checkinteger( L, 2 );
int type = luaL_checkinteger( L, 3 );
int ipconnected = lua_toboolean( L, 4 );
int alternate = luaL_checkinteger( L, 5 );
GPIO_InitTypeDef GPIO_InitStructure;
int port, pin;
port = PLATFORM_IO_GET_PORT( v );
pin = PLATFORM_IO_GET_PIN( v );
if( PLATFORM_IO_IS_PORT( v ) || !platform_pio_has_port( port ) || !platform_pio_has_pin( port, pin ) )
return luaL_error( L, "invalid pin" );
GPIO_StructInit( &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = str9_pins[ pin ];
GPIO_InitStructure.GPIO_Direction = direction;
GPIO_InitStructure.GPIO_Type = type;
GPIO_InitStructure.GPIO_IPConnected = ipconnected ? GPIO_IPConnected_Enable : GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = alternate;
GPIO_Init( ( GPIO_TypeDef* )port_data[ port ], &GPIO_InitStructure );
return 0;
}
// Module function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE str9_pio_map[] =
{
#if LUA_OPTIMIZE_MEMORY > 0
{ LSTRKEY( "INPUT" ), LNUMVAL( GPIO_DIR_INPUT ) },
{ LSTRKEY( "OUTPUT" ), LNUMVAL( GPIO_DIR_OUTPUT ) },
{ LSTRKEY( "ALT_INPUT" ), LNUMVAL( GPIO_ALT_INPUT ) },
{ LSTRKEY( "ALT_OUTPUT1" ), LNUMVAL( GPIO_ALT_OUTPUT1 ) },
{ LSTRKEY( "ALT_OUTPUT2" ), LNUMVAL( GPIO_ALT_OUTPUT2 ) },
{ LSTRKEY( "ALT_OUTPUT3" ), LNUMVAL( GPIO_ALT_OUTPUT3 ) },
{ LSTRKEY( "OUTPUT_PUSHPULL" ), LNUMVAL( GPIO_OUTPUT_PP ) },
{ LSTRKEY( "OUTPUT_OC" ), LNUMVAL( GPIO_OUTPUT_OC ) },
#endif
{ LSTRKEY( "setpin" ), LFUNCVAL( setpin) },
{ LNILKEY, LNILVAL }
};
LUALIB_API int luaopen_disp( lua_State *L )
{
#if LUA_OPTIMIZE_MEMORY > 0
return 0;
#else
luaL_register( L, PS_LIB_TABLE_NAME, str9_pio_map );
MOD_REG_NUMBER( L, "INPUT", GPIO_DIR_INPUT );
MOD_REG_NUMBER( L, "OUTPUT", GPIO_DIR_OUTPUT );
MOD_REG_NUMBER( L, "ALT_INPUT", GPIO_ALT_INPUT );
MOD_REG_NUMBER( L, "ALT_OUTPUT1", GPIO_ALT_OUTPUT1 );
MOD_REG_NUMBER( L, "ALT_OUTPUT2", GPIO_ALT_OUTPUT2 );
MOD_REG_NUMBER( L, "ALT_OUTPUT3", GPIO_ALT_OUTPUT3 );
MOD_REG_NUMBER( L, "OUTPUT_PUSHPULL", GPIO_OUTPUT_PP );
MOD_REG_NUMBER( L, "OUTPUT_OC", GPIO_OUTPUT_OC );
return 1;
#endif
}