1
0
mirror of https://github.com/elua/elua.git synced 2025-01-25 01:02:54 +08:00

Merge branch 'master' of github.com:elua/elua

This commit is contained in:
Martin Guy 2011-06-03 18:33:39 +02:00
commit 6877d642f1
40 changed files with 3345 additions and 790 deletions

4
.gitignore vendored
View File

@ -11,4 +11,8 @@ inc/romfiles.h
.sconf_temp/
.sconsign.dblite
config.log
mux*
rfs_server*
doc/dist
doc/cache

View File

@ -1,5 +1,6 @@
import os, sys, shutil, string
import platform as syspl
import platform as syspl
import glob
# Helper: "normalize" a name to make it a suitable C macro name
def cnorm( name ):
@ -116,89 +117,6 @@ board_list = { 'SAM7-EX256' : [ 'AT91SAM7X256', 'AT91SAM7X512' ],
cpu_list = sum([board_list[i] for i in board_list],[])
# ROMFS file list "groups"
# To include a file in a ROMFS build, include it in a group here (or create one
# if you need) and make sure the group is included on your platform's file_list
# definition (right after this).
# The following table will be left here just as an example
# eLua examples were removed from the distro since v0.8
#romfs = { 'bisect' : [ 'bisect.lua' ],
# 'hangman' : [ 'hangman.lua' ],
# 'lhttpd' : [ 'index.pht', 'lhttpd.lua', 'test.lua' ],
# 'led' : [ 'led.lua' ],
# 'piano' : [ 'piano.lua' ],
# 'pwmled' : [ 'pwmled.lua' ],
# 'tvbgone' : [ 'tvbgone.lua', 'codes.bin' ],
# 'hello' : [ 'hello.lua' ],
# 'info' : [ 'info.lua' ],
# 'morse' : [ 'morse.lua' ],
# 'dualpwm' : [ 'dualpwm.lua' ],
# 'adcscope' : [ 'adcscope.lua' ],
# 'adcpoll' : [ 'adcpoll.lua' ],
# 'life' : [ 'life.lua' ],
# 'logo' : ['logo.lua', 'logo.bin' ],
# 'pong' : [ 'pong.lua' ],
# 'spaceship' : [ 'spaceship.lua' ],
# 'tetrives' : [ 'tetrives.lua' ],
# 'snake' : [ 'snake.lua' ],
# 'dataflash' : [ 'dataflash.lua' ],
# 'pachube' : [ 'pachube_demo.lua' ],
# 'inttest' : [ 'inttest.lua' ]
# }
romfs = {
}
# List of board/romfs data combinations
# The following table will be left here just as an example
# eLua examples were removed from the distro since v0.8
#file_list = { 'SAM7-EX256' : [ 'bisect', 'hangman' , 'led', 'piano', 'hello', 'info', 'morse' ],
# 'EK-LM3S1968' : [ 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'spaceship', 'tetrives', 'snake' ],
# 'EK-LM3S8962' : [ 'lhttpd','bisect', 'led', 'pachube' ],
# 'EK-LM3S6965' : [ 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'tetrives' ],
# 'EK-LM3S9B92' : [ 'bisect', 'hangman', 'led', 'pwmled', 'hello', 'info', 'adcscope','adcpoll', 'life' ],
# 'STR9-COMSTICK' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
# 'STR-E912' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'piano', 'adcscope' ],
# 'PC' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
# 'SIM' : [ 'bisect', 'hello', 'info', 'life', 'hangman' ],
# 'LPC-H2888' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
# 'MOD711' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'dualpwm' ],
# 'STM3210E-EVAL' : [ 'bisect', 'hello', 'info' ],
# 'ATEVK1100' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'dataflash' ],
# 'ATEVK1101' : [ 'bisect', 'led', 'hello', 'info', 'dataflash' ],
# 'ET-STM32' : [ 't' ],
# 'EAGLE-100' : [ 'bisect', 'hangman', 'lhttpd', 'led', 'hello', 'info' ],
# 'ELUA-PUC' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'pwmled', 'adcscope', 'adcpoll', 'inttest' ],
# 'MBED' : [ 'bisect', 'hangman', 'hello', 'info', 'led', 'pwmled', 'dualpwm', 'life', 'adcscope', 'adcpoll' ],
# 'MIZAR32' : [ ],
# 'NETDUINO': [ ],
#}
file_list = { 'SAM7-EX256' : [ ],
'EK-LM3S1968' : [ ],
'EK-LM3S8962' : [ ],
'EK-LM3S6965' : [ ],
'EK-LM3S9B92' : [ ],
'STR9-COMSTICK' : [ ],
'STR-E912' : [ ],
'PC' : [ ],
'SIM' : [ ],
'LPC-H2888' : [ ],
'MOD711' : [ ],
'STM3210E-EVAL' : [ ],
'ATEVK1100' : [ ],
'ATEVK1101' : [ ],
'ET-STM32' : [ ],
'EAGLE-100' : [ ],
'ELUA-PUC' : [ ],
'MBED' : [ ],
'MIZAR32' : [ ],
'NETDUINO': [ ],
}
comp = Environment( tools = [],
OBJSUFFIX = ".o",
PROGSUFFIX = ".elf",
@ -469,12 +387,11 @@ if not GetOption( 'help' ):
# Make ROM File System first
if not GetOption( 'clean' ):
print "Building ROM File System..."
romdir = "romfs"
flist = []
for sample in file_list[ comp['board'] ]:
flist += romfs[ sample ]
for sample in glob.glob("romfs/*"):
flist += [ sample ]
import mkfs
mkfs.mkfs( romdir, "romfiles", flist, comp['romfs'], compcmd )
mkfs.mkfs( ".", "romfiles", flist, comp['romfs'], compcmd )
print
if os.path.exists( "inc/romfiles.h" ):
os.remove( "inc/romfiles.h" )

View File

@ -205,96 +205,6 @@ for k, v in pairs( board_list ) do
end
end
-- ROMFS file list "groups"
-- To include a file in a ROMFS build, include it in a group here (or create one
-- if you need) and make sure the group is included on your platform's file_list
-- definition (right after this).
-- The following table will be left here just as an example
-- eLua examples were removed from the distro since v0.8
--[[
local romfs =
{
bisect = { 'bisect.lua' },
hangman = { 'hangman.lua' },
lhttpd = { 'index.pht', 'lhttpd.lua', 'test.lua' },
led = { 'led.lua' },
piano = { 'piano.lua' },
pwmled = { 'pwmled.lua' },
tvbgone = { 'tvbgone.lua', 'codes.bin' },
hello = { 'hello.lua' },
info = { 'info.lua' },
morse = { 'morse.lua' },
dualpwm = { 'dualpwm.lua' },
adcscope = { 'adcscope.lua' },
adcpoll = { 'adcpoll.lua' },
life = { 'life.lua' },
logo = {'logo.lua', 'logo.bin' },
pong = { 'pong.lua' },
spaceship = { 'spaceship.lua' },
tetrives = { 'tetrives.lua' },
snake = { 'snake.lua' },
dataflash = { 'dataflash.lua' },
pachube = { 'pachube_demo.lua' },
inttest = { 'inttest.lua' }
}
--]]
local romfs = {}
-- List of board/romfs data combinations
-- The following table will be left here just as an example
-- eLua examples were removed from the distro since v0.8
--[[
local file_list =
{
[ 'SAM7-EX256' ] = { 'bisect', 'hangman' , 'led', 'piano', 'hello', 'info', 'morse' },
[ 'EK-LM3S1968' ] = { 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'spaceship', 'tetrives', 'snake' },
[ 'EK-LM3S8962' ] = { 'lhttpd','bisect', 'led', 'pachube' },
[ 'EK-LM3S6965' ] = { 'bisect', 'hangman', 'pong', 'led', 'piano', 'pwmled', 'hello', 'info', 'morse', 'adcscope', 'adcpoll', 'logo', 'tetrives' },
[ 'EK-LM3S9B92' ] = { 'bisect', 'hangman', 'led', 'pwmled', 'hello', 'info', 'adcscope','adcpoll', 'life' },
[ 'STR9-COMSTICK' ] = { 'bisect', 'hangman', 'led', 'hello', 'info' },
[ 'STR-E912' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'piano', 'adcscope' },
[ 'PC' ] = { 'bisect', 'hello', 'info', 'life', 'hangman' },
[ 'SIM' ] = { 'bisect', 'hello', 'info', 'life', 'hangman' },
[ 'LPC-H2888' ] = { 'bisect', 'hangman', 'led', 'hello', 'info' },
[ 'MOD711' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'dualpwm' },
[ 'STM3210E-EVAL' ] = { 'bisect', 'hello', 'info' },
[ 'ATEVK1100' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'dataflash' },
[ 'ATEVK1101' ] = { 'bisect', 'led', 'hello', 'info', 'dataflash' },
[ 'ET-STM32' ] = { 't' },
[ 'EAGLE-100' ] = { 'bisect', 'hangman', 'lhttpd', 'led', 'hello', 'info' },
[ 'ELUA-PUC' ] = { 'bisect', 'hangman', 'led', 'hello', 'info', 'pwmled', 'adcscope', 'adcpoll', 'inttest' },
[ 'MBED' ] = { 'bisect', 'hangman', 'hello', 'info', 'led', 'pwmled', 'dualpwm', 'life', 'adcscope', 'adcpoll' },
[ 'MIZAR32' ] = { },
[ 'NETDUINO' ] = { },
}
--]]
local file_list =
{
[ 'SAM7-EX256' ] = {},
[ 'EK-LM3S1968' ] = {},
[ 'EK-LM3S8962' ] = {},
[ 'EK-LM3S6965' ] = {},
[ 'EK-LM3S9B92' ] = {},
[ 'STR9-COMSTICK' ] = {},
[ 'STR-E912' ] = {},
[ 'PC' ] = {},
[ 'SIM' ] = {},
[ 'LPC-H2888' ] = {},
[ 'MOD711' ] = {},
[ 'STM3210E-EVAL' ] = {},
[ 'ATEVK1100' ] = {},
[ 'ATEVK1101' ] = {},
[ 'ET-STM32' ] = {},
[ 'EAGLE-100' ] = {},
[ 'ELUA-PUC' ] = {},
[ 'MBED' ] = {},
[ 'MIZAR32' ] = {},
[ 'NETDUINO'] = {},
}
builder:add_option( 'target', 'build "regular" float lua or integer-only "lualong"', 'lua', { 'lua', 'lualong' } )
builder:add_option( 'cpu', 'build for the specified CPU (board will be inferred, if possible)', 'auto', { cpu_list, 'auto' } )
builder:add_option( 'allocator', 'select memory allocator', 'auto', { 'newlib', 'multiple', 'simple', 'auto' } )
@ -489,13 +399,10 @@ source_files = source_files .. uip_files .. specific_files
-- ROM file system builder
local function make_romfs()
print "Building ROM file system ..."
local romdir = "romfs"
local flist = {}
for _, sample in pairs( file_list[ comp.board:upper() ] ) do
table.insert( flist, romfs[ sample ] )
end
flist = utils.string_to_table( utils.get_files( 'romfs', function( fname ) return not fname:find( "%.gitignore" ) end ) )
flist = utils.linearize_array( flist )
if not mkfs.mkfs( romdir, "romfiles", flist, comp.romfs, fscompcmd ) then return -1 end
if not mkfs.mkfs( ".", "romfiles", flist, comp.romfs, fscompcmd ) then return -1 end
if utils.is_file( "inc/romfiles.h" ) then
-- Read both the old and the new file
local oldfile = io.open( "inc/romfiles.h", "rb" )

View File

@ -10,7 +10,10 @@
#define LUARPC_ENABLE_SERIAL
#define LUA_PLATFORM_LIBS_ROM \
_ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
_ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )\
_ROM( AUXLIB_BITARRAY, luaopen_bitarray, bitarray_map )\
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )
#endif

View File

@ -6,13 +6,13 @@ builder:init( args )
builder:set_build_mode( builder.BUILD_DIR_LINEARIZED )
local flist = "main.c"
local rfs_flist = "main.c server.c log.c deskutils.c"
local rfs_flist = "main.c server.c log.c deskutils.c rfs_transports.c"
local cdefs = "RFS_UDP_TRANSPORT RFS_INSIDE_MUX_MODE"
local socklib
if utils.is_windows() then
cdefs = cdefs .. " WIN32_BUILD"
rfs_flist = rfs_flist .. " os_io_win32.c serial_win32.c net_win32.c"
exeprefix = "exe"
exeprefix = ".exe"
socklib = "ws2_32"
else
rfs_flist = rfs_flist .. " os_io_posix.c serial_posix.c net_posix.c"

2
mux.py
View File

@ -1,7 +1,7 @@
import os, sys, platform
flist = "main.c"
rfs_flist = "main.c server.c log.c deskutils.c"
rfs_flist = "main.c server.c log.c deskutils.c rfs_transports.c"
cdefs = "-DRFS_UDP_TRANSPORT -DRFS_INSIDE_MUX_MODE"
socklib = ''
ptlib = ''

View File

@ -145,7 +145,12 @@ static int parse_transport( const char* s )
#define FIRST_SERVICE_IDX 3
#define MIN_ARGC_COUNT 4
#ifdef _MSC_VER
#define strcasecmp _stricmp
int main( int argc, char *argv[] )
#else
int main( int argc, char **argv )
#endif
{
unsigned i;
SERVICE_DATA *tservice;
@ -165,9 +170,9 @@ int main( int argc, char **argv )
log_err( "Usage: %s <mode> <transport> <vcom1> [<vcom2>] ... [<vcomn>] [-v]\n", argv[ 0 ] );
log_err( " mode: \n" );
log_err( " 'mux': serial multiplexer mode\n" );
log_err( " 'rfsmux:<directory>: combined RFS and multiplexer mode.\n" );
log_err( " transport: '<port>,<baud>,<flow> ('flow' specifies the flow control type and can be 'none' or 'rtscts').\n" );
log_err( " vcom1, ..., vcomn: multiplexer serial ports." );
log_err( " 'rfsmux:<directory>': combined RFS and multiplexer mode.\n" );
log_err( " transport: '<port>,<baud>,<flow>' ('flow' specifies the flow control type and can be 'none' or 'rtscts').\n" );
log_err( " vcom1, ..., vcomn: multiplexer serial ports.\n" );
log_err( " Use '-v' for verbose output.\n" );
return 1;
}

107
mux_src/mux.vcxproj Normal file
View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\rfs_server_src\deskutils.h" />
<ClInclude Include="..\rfs_server_src\log.h" />
<ClInclude Include="..\rfs_server_src\net.h" />
<ClInclude Include="..\rfs_server_src\rfs.h" />
<ClInclude Include="..\rfs_server_src\rfs_transports.h" />
<ClInclude Include="..\rfs_server_src\serial.h" />
<ClInclude Include="..\rfs_server_src\server.h" />
<ClInclude Include="config.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\rfs_server_src\deskutils.c" />
<ClCompile Include="..\rfs_server_src\log.c" />
<ClCompile Include="..\rfs_server_src\net_win32.c" />
<ClCompile Include="..\rfs_server_src\os_io_win32.c" />
<ClCompile Include="..\rfs_server_src\rfs_transports.c" />
<ClCompile Include="..\rfs_server_src\serial_win32.c" />
<ClCompile Include="..\rfs_server_src\server.c" />
<ClCompile Include="..\src\eluarpc.c" />
<ClCompile Include="..\src\remotefs\remotefs.c" />
<ClCompile Include="main.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{68EE7183-C1E2-41A9-AADA-3456B4773685}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>mux</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\rfs_server_src;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\rfs_server_src;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32_BUILD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>
</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32_BUILD;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\rfs_server_src\deskutils.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\server.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\src\eluarpc.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\log.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="main.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\net_win32.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\os_io_win32.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\src\remotefs\remotefs.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\rfs_transports.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\rfs_server_src\serial_win32.c">
<Filter>source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="config.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\deskutils.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\log.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\net.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\rfs.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\rfs_transports.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\serial.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="..\rfs_server_src\server.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="source">
<UniqueIdentifier>{edd07642-0c4f-4725-9e8f-641858b5e631}</UniqueIdentifier>
</Filter>
<Filter Include="headers">
<UniqueIdentifier>{7234826d-2dcc-404c-9472-998da14f1314}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -20,12 +20,12 @@ if utils.is_windows() then
print "SIM target not supported under Windows"
os.exit( 1 )
end
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c"
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c rfs_transports.c"
cdefs = cdefs .. " WIN32_BUILD"
exeprefix = "exe"
exeprefix = ".exe"
socklib = 'ws2_32'
else
flist = mainname .. " server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c"
flist = mainname .. " server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c rfs_transports.c"
end
local output = sim == 0 and 'rfs_server' or 'rfs_sim_server'

View File

@ -13,12 +13,12 @@ if platform.system() == "Windows":
if sim == '1':
print "SIM target not supported under Windows"
os.exit( 1 )
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c"
flist = "main.c server.c os_io_win32.c log.c net_win32.c serial_win32.c deskutils.c rfs_transports.c"
cdefs = cdefs + " -DWIN32_BUILD"
exeprefix = ".exe"
socklib = '-lws2_32'
else:
flist = "%s server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c" % mainname
flist = "%s server.c os_io_posix.c log.c net_posix.c serial_posix.c deskutils.c rfs_transports.c" % mainname
exeprefix = ""
if sim == '0':

View File

@ -15,413 +15,7 @@
#include <string.h>
#include "rfs.h"
#include "deskutils.h"
// ****************************************************************************
// Local definitions
typedef void ( *p_read_request )( void );
typedef void ( *p_send_response )( void );
typedef void ( *p_cleanup )( void );
typedef struct
{
p_read_request f_read_request;
p_send_response f_send_response;
p_cleanup f_cleanup;
} RFS_TRANSPORT_DATA;
// ****************************************************************************
// Local variables
#define MAX_PACKET_SIZE 4096
static u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
static const RFS_TRANSPORT_DATA *p_transport_data;
// ****************************************************************************
// Serial transport implementation
static ser_handler ser;
static void flush_serial()
{
// Flush all data in serial port
while( ser_read_byte( ser, SER_NO_TIMEOUT ) != -1 );
}
// Read a packet from the serial port
static void ser_read_request_packet()
{
u16 temp16;
u32 readbytes;
while( 1 )
{
// First read the length
if( ( readbytes = ser_read( ser, rfs_buffer, ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != ELUARPC_START_OFFSET )
{
log_msg( "read_request_packet: ERROR reading packet length. Requested %d bytes, got %d bytes\n", ELUARPC_START_OFFSET, readbytes );
flush_serial();
continue;
}
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "read_request_packet: ERROR getting packet size.\n" );
flush_serial();
continue;
}
// Then the rest of the data
if( ( readbytes = ser_read( ser, rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != temp16 - ELUARPC_START_OFFSET )
{
log_msg( "read_request_packet: ERROR reading full packet, got %u bytes, expected %u bytes\n", ( unsigned )readbytes, ( unsigned )temp16 - ELUARPC_START_OFFSET );
flush_serial();
continue;
}
else
break;
}
}
// Send a packet to the serial port
static void ser_send_response_packet()
{
u16 temp16;
// Send request
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
ser_write( ser, rfs_buffer, temp16 );
}
}
static int ser_server_init( const char *portname, int serspeed, int flow )
{
// Setup serial port
if( ( ser = ser_open( portname ) ) == SER_HANDLER_INVALID )
{
log_err( "Cannot open port %s\n", portname );
return 0;
}
if( ser_setup( ser, ( u32 )serspeed, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1, flow ) != SER_OK )
{
log_err( "Unable to initialize serial port\n" );
return 0;
}
flush_serial();
// User report
log_msg( "Running RFS server on serial port %s (%u baud).\n", portname, ( unsigned )serspeed );
return 1;
}
static void ser_cleanup()
{
ser_close( ser );
}
static const RFS_TRANSPORT_DATA ser_transport_data = { ser_read_request_packet, ser_send_response_packet, ser_cleanup };
// ****************************************************************************
// UDP transport implementation
static NET_SOCKET trans_socket = INVALID_SOCKET_VALUE;
static struct sockaddr_in trans_from;
// Helper: read (blocking) the specified number of bytes
static void udp_read_helper( u8 *dest, u32 size )
{
socklen_t fromlen;
int readbytes;
while( size )
{
fromlen = sizeof( trans_from );
readbytes = net_recvfrom( trans_socket, ( char* )dest, size, 0, ( struct sockaddr* )&trans_from, &fromlen, NET_INF_TIMEOUT );
size -= readbytes;
if( size == 0 )
break;
dest += readbytes;
}
}
static void udp_read_request_packet()
{
u16 temp16;
while( 1 )
{
// First read the length
udp_read_helper( rfs_buffer, ELUARPC_START_OFFSET );
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "read_request_packet: ERROR getting packet size.\n" );
continue;
}
// Then the rest of the data
udp_read_helper( rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET );
break;
}
}
static void udp_send_response_packet()
{
u16 temp16;
// Send request
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
net_sendto( trans_socket, ( char* )rfs_buffer, temp16, 0, ( struct sockaddr* )&trans_from, sizeof( trans_from ) );
}
}
static int udp_server_init( unsigned server_port )
{
int length;
struct sockaddr_in server;
if( ( trans_socket = net_create_socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET_VALUE )
{
log_err( "Unable to create socket\n" );
return 1;
}
length = sizeof( server );
memset( &server, 0, sizeof( server ) );
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( server_port );
if( bind( net_socket( trans_socket ), ( struct sockaddr * )&server, length ) < 0 )
{
log_err( "Unable to bind socket\n" );
return 0;
}
log_msg( "Running RFS server on UDP port %u.\n", ( unsigned )server_port );
return 1;
}
static void udp_cleanup()
{
net_close( trans_socket );
}
static const RFS_TRANSPORT_DATA udp_transport_data = { udp_read_request_packet, udp_send_response_packet, udp_cleanup };
// ****************************************************************************
// Memory transport implementation
// Read state machine
enum
{
MEM_STATE_READ_LENGTH,
MEM_STATE_READ_REQUEST,
MEM_STATE_REQUEST_DONE
};
static int mem_read_len;
static int mem_expected_len;
static int mem_read_state;
static int mem_response_flag;
void rfs_mem_start_request()
{
mem_read_state = MEM_STATE_READ_LENGTH;
mem_read_len = mem_expected_len = 0;
mem_response_flag = 0;
}
int rfs_mem_read_request_packet( int c )
{
u16 temp16;
int res = 1;
if( c == -1 )
{
rfs_mem_start_request();
return 0;
}
switch( mem_read_state )
{
case MEM_STATE_READ_LENGTH:
rfs_buffer[ mem_read_len ++ ] = c;
if( mem_read_len == ELUARPC_START_OFFSET )
{
mem_read_len = 0;
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "RFS read_request_packet: ERROR getting packet size.\n" );
mem_read_state = MEM_STATE_REQUEST_DONE;
res = 0;
}
else
{
mem_read_state = MEM_STATE_READ_REQUEST;
mem_expected_len = temp16 - ELUARPC_START_OFFSET;
}
}
break;
case MEM_STATE_READ_REQUEST:
rfs_buffer[ ELUARPC_START_OFFSET + mem_read_len ] = c;
mem_read_len ++;
if( mem_read_len == mem_expected_len )
{
mem_read_state = MEM_STATE_REQUEST_DONE;
mem_response_flag = 1;
}
break;
}
return res;
}
int rfs_mem_has_response()
{
return mem_response_flag;
}
void rfs_mem_write_response( u16 *plen, u8 **pdata )
{
// Execute request
server_execute_request( rfs_buffer );
// Send response
if( eluarpc_get_packet_size( rfs_buffer, plen ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )*plen );
*pdata = rfs_buffer;
}
else
{
log_msg( "ERROR in send_response_packet!\n" );
*plen = 0;
}
}
static int mem_server_init()
{
rfs_mem_start_request();
log_msg( "RFS: using memory transport.\n" );
return 1;
}
static const RFS_TRANSPORT_DATA mem_transport_data = { NULL, NULL, NULL };
// ****************************************************************************
// Helper functions
// Transport parser
static int parse_transport_and_init( const char* s )
{
const char *c, *c2;
char *temps, *tempb;
long tempi;
int flow;
if( strstr( s, "ser:" ) == s )
{
p_transport_data = &ser_transport_data;
s += strlen( "ser:" );
if( ( c = strchr( s, ',' ) ) == NULL )
{
log_err( "Invalid serial transport syntax\n" );
return 0;
}
temps = l_strndup( s, c - s );
if( ( c2 = strchr( c + 1, ',' ) ) == NULL )
{
log_err( "Invalid serial transport syntax.\n" );
return 0;
}
tempb = l_strndup( c + 1, c2 - c - 1 );
if( secure_atoi( tempb, &tempi ) == 0 )
{
log_err( "Invalid port speed\n" );
return 0;
}
free( tempb );
if( !strcmp( c2 + 1, "none" ) )
flow = SER_FLOW_NONE;
else if( !strcmp( c2 + 1, "rtscts" ) )
flow = SER_FLOW_RTSCTS;
else
{
log_err( "Invalid flow control type.\n" );
return 0;
}
tempi = ser_server_init( temps, tempi, flow );
free( temps );
return tempi;
}
else if( strstr( s, "udp:" ) == s )
{
p_transport_data = &udp_transport_data;
s += strlen( "udp:" );
if( secure_atoi( s, &tempi ) == 0 )
{
log_err( "Invalid port number\n" );
return 0;
}
if( net_init() == 0 )
{
log_err( "Unable to initialize network\n" );
return 0;
}
return udp_server_init( tempi );
}
else if( !strcmp( s, "mem" ) )
{
// Direct memory transport, only used with mux in rfsmux mode
p_transport_data = &mem_transport_data;
return mem_server_init( tempi );
}
log_err( "Error: unsupported transport\n" );
return 0;
}
// *****************************************************************************
// Entry point
#define TRANSPORT_ARG_IDX 1
#define DIRNAME_ARG_IDX 2
#define VERBOSE_ARG_IDX 3
#define MIN_ARGC_COUNT 3
#define VERBOSE_ARGC_COUNT 4
int rfs_init( int argc, const char **argv )
{
setvbuf( stdout, NULL, _IONBF, 0 );
if( argc < MIN_ARGC_COUNT )
{
log_err( "Usage: %s <transport> <dirname> [-v]\n", argv[ 0 ] );
log_err( " Serial transport: 'ser:<sername>,<serspeed>,<flow> ('flow' defines the flow control and can be either 'none' or 'rtscts')\n" );
log_err( " UDP transport: 'udp:<port>'\n" );
log_err( "Use -v for verbose output.\n" );
return 1;
}
if( ( argc >= VERBOSE_ARGC_COUNT ) && !strcmp( argv[ VERBOSE_ARG_IDX ], "-v" ) )
log_init( LOG_ALL );
else
log_init( LOG_NONE );
if( !os_isdir( argv[ DIRNAME_ARG_IDX ] ) )
{
log_err( "Invalid directory %s\n", argv[ DIRNAME_ARG_IDX ] );
return 1;
}
if( parse_transport_and_init( argv[ TRANSPORT_ARG_IDX ] ) == 0 )
return 1;
// Setup RFS server
server_setup( argv[ DIRNAME_ARG_IDX ] );
log_msg( "Sharing directory %s\n", argv[ DIRNAME_ARG_IDX ] );
return 0;
}
#include "rfs_transports.h"
#ifdef RFS_STANDALONE_MODE
int main( int argc, const char **argv )

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\eluarpc.c" />
<ClCompile Include="..\src\remotefs\remotefs.c" />
<ClCompile Include="deskutils.c" />
<ClCompile Include="log.c" />
<ClCompile Include="main.c" />
<ClCompile Include="net_win32.c" />
<ClCompile Include="os_io_win32.c" />
<ClCompile Include="rfs_transports.c" />
<ClCompile Include="serial_win32.c" />
<ClCompile Include="server.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="deskutils.h" />
<ClInclude Include="log.h" />
<ClInclude Include="net.h" />
<ClInclude Include="rfs.h" />
<ClInclude Include="rfs_transports.h" />
<ClInclude Include="serial.h" />
<ClInclude Include="server.h" />
<ClInclude Include="type.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4A3A33C6-6A0C-4C82-8C07-A6896BAFB4FA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>rfs_server</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>.\;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>.\;..\inc;..\inc\remotefs;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>RFS_STANDALONE_MODE;WIN32_BUILD;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>RFS_STANDALONE_MODE;WIN32_BUILD;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="server.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="deskutils.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\src\eluarpc.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="log.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="main.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="net_win32.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="os_io_win32.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="..\src\remotefs\remotefs.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="rfs_transports.c">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="serial_win32.c">
<Filter>source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="deskutils.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="rfs_transports.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="serial.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="server.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="type.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="net.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="rfs.h">
<Filter>headers</Filter>
</ClInclude>
<ClInclude Include="log.h">
<Filter>headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="headers">
<UniqueIdentifier>{337cdfd6-7a94-45a7-9773-202c632d5000}</UniqueIdentifier>
</Filter>
<Filter Include="source">
<UniqueIdentifier>{ed41819a-7341-42c2-b1ee-525a54aeeee1}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -0,0 +1,413 @@
// Remote FS server
#include "net.h"
#include "remotefs.h"
#include "eluarpc.h"
#include "serial.h"
#include "server.h"
#include "type.h"
#include "log.h"
#include "os_io.h"
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "rfs.h"
#include "deskutils.h"
#include "rfs_transports.h"
// ****************************************************************************
// Local variables
u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
const RFS_TRANSPORT_DATA *p_transport_data;
// ****************************************************************************
// Serial transport implementation
static ser_handler ser;
static void flush_serial()
{
// Flush all data in serial port
while( ser_read_byte( ser, SER_NO_TIMEOUT ) != -1 );
}
// Read a packet from the serial port
static void ser_read_request_packet()
{
u16 temp16;
u32 readbytes;
while( 1 )
{
// First read the length
if( ( readbytes = ser_read( ser, rfs_buffer, ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != ELUARPC_START_OFFSET )
{
log_msg( "read_request_packet: ERROR reading packet length. Requested %d bytes, got %d bytes\n", ELUARPC_START_OFFSET, readbytes );
flush_serial();
continue;
}
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "read_request_packet: ERROR getting packet size.\n" );
flush_serial();
continue;
}
// Then the rest of the data
if( ( readbytes = ser_read( ser, rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET, SER_INF_TIMEOUT ) ) != temp16 - ELUARPC_START_OFFSET )
{
log_msg( "read_request_packet: ERROR reading full packet, got %u bytes, expected %u bytes\n", ( unsigned )readbytes, ( unsigned )temp16 - ELUARPC_START_OFFSET );
flush_serial();
continue;
}
else
break;
}
}
// Send a packet to the serial port
static void ser_send_response_packet()
{
u16 temp16;
// Send request
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
ser_write( ser, rfs_buffer, temp16 );
}
}
static int ser_server_init( const char *portname, int serspeed, int flow )
{
// Setup serial port
if( ( ser = ser_open( portname ) ) == SER_HANDLER_INVALID )
{
log_err( "Cannot open port %s\n", portname );
return 0;
}
if( ser_setup( ser, ( u32 )serspeed, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1, flow ) != SER_OK )
{
log_err( "Unable to initialize serial port\n" );
return 0;
}
flush_serial();
// User report
log_msg( "Running RFS server on serial port %s (%u baud).\n", portname, ( unsigned )serspeed );
return 1;
}
static void ser_cleanup()
{
ser_close( ser );
}
const RFS_TRANSPORT_DATA ser_transport_data = { ser_read_request_packet, ser_send_response_packet, ser_cleanup };
// ****************************************************************************
// UDP transport implementation
static NET_SOCKET trans_socket = INVALID_SOCKET_VALUE;
static struct sockaddr_in trans_from;
// Helper: read (blocking) the specified number of bytes
static void udp_read_helper( u8 *dest, u32 size )
{
socklen_t fromlen;
int readbytes;
while( size )
{
fromlen = sizeof( trans_from );
readbytes = net_recvfrom( trans_socket, ( char* )dest, size, 0, ( struct sockaddr* )&trans_from, &fromlen, NET_INF_TIMEOUT );
size -= readbytes;
if( size == 0 )
break;
dest += readbytes;
}
}
static void udp_read_request_packet()
{
u16 temp16;
while( 1 )
{
// First read the length
udp_read_helper( rfs_buffer, ELUARPC_START_OFFSET );
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "read_request_packet: ERROR getting packet size.\n" );
continue;
}
// Then the rest of the data
udp_read_helper( rfs_buffer + ELUARPC_START_OFFSET, temp16 - ELUARPC_START_OFFSET );
break;
}
}
static void udp_send_response_packet()
{
u16 temp16;
// Send request
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )temp16 );
net_sendto( trans_socket, ( char* )rfs_buffer, temp16, 0, ( struct sockaddr* )&trans_from, sizeof( trans_from ) );
}
}
static int udp_server_init( unsigned server_port )
{
int length;
struct sockaddr_in server;
if( ( trans_socket = net_create_socket( AF_INET, SOCK_DGRAM, 0 ) ) == INVALID_SOCKET_VALUE )
{
log_err( "Unable to create socket\n" );
return 1;
}
length = sizeof( server );
memset( &server, 0, sizeof( server ) );
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( server_port );
if( bind( net_socket( trans_socket ), ( struct sockaddr * )&server, length ) < 0 )
{
log_err( "Unable to bind socket\n" );
return 0;
}
log_msg( "Running RFS server on UDP port %u.\n", ( unsigned )server_port );
return 1;
}
static void udp_cleanup()
{
net_close( trans_socket );
}
const RFS_TRANSPORT_DATA udp_transport_data = { udp_read_request_packet, udp_send_response_packet, udp_cleanup };
// ****************************************************************************
// Memory transport implementation
// Read state machine
enum
{
MEM_STATE_READ_LENGTH,
MEM_STATE_READ_REQUEST,
MEM_STATE_REQUEST_DONE
};
static int mem_read_len;
static int mem_expected_len;
static int mem_read_state;
static int mem_response_flag;
void rfs_mem_start_request()
{
mem_read_state = MEM_STATE_READ_LENGTH;
mem_read_len = mem_expected_len = 0;
mem_response_flag = 0;
}
int rfs_mem_read_request_packet( int c )
{
u16 temp16;
int res = 1;
if( c == -1 )
{
rfs_mem_start_request();
return 0;
}
switch( mem_read_state )
{
case MEM_STATE_READ_LENGTH:
rfs_buffer[ mem_read_len ++ ] = c;
if( mem_read_len == ELUARPC_START_OFFSET )
{
mem_read_len = 0;
if( eluarpc_get_packet_size( rfs_buffer, &temp16 ) == ELUARPC_ERR )
{
log_msg( "RFS read_request_packet: ERROR getting packet size.\n" );
mem_read_state = MEM_STATE_REQUEST_DONE;
res = 0;
}
else
{
mem_read_state = MEM_STATE_READ_REQUEST;
mem_expected_len = temp16 - ELUARPC_START_OFFSET;
}
}
break;
case MEM_STATE_READ_REQUEST:
rfs_buffer[ ELUARPC_START_OFFSET + mem_read_len ] = c;
mem_read_len ++;
if( mem_read_len == mem_expected_len )
{
mem_read_state = MEM_STATE_REQUEST_DONE;
mem_response_flag = 1;
}
break;
}
return res;
}
int rfs_mem_has_response()
{
return mem_response_flag;
}
void rfs_mem_write_response( u16 *plen, u8 **pdata )
{
// Execute request
server_execute_request( rfs_buffer );
// Send response
if( eluarpc_get_packet_size( rfs_buffer, plen ) != ELUARPC_ERR )
{
log_msg( "send_response_packet: sending response packet of %u bytes\n", ( unsigned )*plen );
*pdata = rfs_buffer;
}
else
{
log_msg( "ERROR in send_response_packet!\n" );
*plen = 0;
}
}
static int mem_server_init()
{
rfs_mem_start_request();
log_msg( "RFS: using memory transport.\n" );
return 1;
}
const RFS_TRANSPORT_DATA mem_transport_data = { NULL, NULL, NULL };
// ****************************************************************************
// Helper functions
// Transport parser
static int parse_transport_and_init( const char* s )
{
const char *c, *c2;
char *temps, *tempb;
long tempi = 0;
int flow;
if( strstr( s, "ser:" ) == s )
{
p_transport_data = &ser_transport_data;
s += strlen( "ser:" );
if( ( c = strchr( s, ',' ) ) == NULL )
{
log_err( "Invalid serial transport syntax\n" );
return 0;
}
temps = l_strndup( s, c - s );
if( ( c2 = strchr( c + 1, ',' ) ) == NULL )
{
log_err( "Invalid serial transport syntax.\n" );
return 0;
}
tempb = l_strndup( c + 1, c2 - c - 1 );
if( secure_atoi( tempb, &tempi ) == 0 )
{
log_err( "Invalid port speed\n" );
return 0;
}
free( tempb );
if( !strcmp( c2 + 1, "none" ) )
flow = SER_FLOW_NONE;
else if( !strcmp( c2 + 1, "rtscts" ) )
flow = SER_FLOW_RTSCTS;
else
{
log_err( "Invalid flow control type.\n" );
return 0;
}
tempi = ser_server_init( temps, tempi, flow );
free( temps );
return tempi;
}
else if( strstr( s, "udp:" ) == s )
{
p_transport_data = &udp_transport_data;
s += strlen( "udp:" );
if( secure_atoi( s, &tempi ) == 0 )
{
log_err( "Invalid port number\n" );
return 0;
}
if( net_init() == 0 )
{
log_err( "Unable to initialize network\n" );
return 0;
}
return udp_server_init( tempi );
}
else if( !strcmp( s, "mem" ) )
{
// Direct memory transport, only used with mux in rfsmux mode
p_transport_data = &mem_transport_data;
return mem_server_init( tempi );
}
log_err( "Error: unsupported transport\n" );
return 0;
}
// *****************************************************************************
// Entry point
#define TRANSPORT_ARG_IDX 1
#define DIRNAME_ARG_IDX 2
#define VERBOSE_ARG_IDX 3
#define MIN_ARGC_COUNT 3
#define VERBOSE_ARGC_COUNT 4
int rfs_init( int argc, const char **argv )
{
setvbuf( stdout, NULL, _IONBF, 0 );
if( argc < MIN_ARGC_COUNT )
{
log_err( "Usage: %s <transport> <dirname> [-v]\n", argv[ 0 ] );
log_err( " Serial transport: 'ser:<sername>,<serspeed>,<flow> ('flow' defines the flow control and can be either 'none' or 'rtscts')\n" );
log_err( " UDP transport: 'udp:<port>'\n" );
log_err( "Use -v for verbose output.\n" );
return 1;
}
if( ( argc >= VERBOSE_ARGC_COUNT ) && !strcmp( argv[ VERBOSE_ARG_IDX ], "-v" ) )
log_init( LOG_ALL );
else
log_init( LOG_NONE );
if( !os_isdir( argv[ DIRNAME_ARG_IDX ] ) )
{
log_err( "Invalid directory %s\n", argv[ DIRNAME_ARG_IDX ] );
return 1;
}
if( parse_transport_and_init( argv[ TRANSPORT_ARG_IDX ] ) == 0 )
return 1;
// Setup RFS server
server_setup( argv[ DIRNAME_ARG_IDX ] );
log_msg( "Sharing directory %s\n", argv[ DIRNAME_ARG_IDX ] );
return 0;
}

View File

@ -0,0 +1,22 @@
#ifndef _RFS_TRANSPORTS_H
#define _RFS_TRANSPORTS_H
typedef void ( *p_read_request )( void );
typedef void ( *p_send_response )( void );
typedef void ( *p_cleanup )( void );
typedef struct
{
p_read_request f_read_request;
p_send_response f_send_response;
p_cleanup f_cleanup;
} RFS_TRANSPORT_DATA;
#define MAX_PACKET_SIZE 4096
extern const RFS_TRANSPORT_DATA *p_transport_data;
extern const RFS_TRANSPORT_DATA mem_transport_data;
extern const RFS_TRANSPORT_DATA udp_transport_data;
extern const RFS_TRANSPORT_DATA ser_transport_data;
extern u8 rfs_buffer[ MAX_PACKET_SIZE + ELUARPC_WRITE_REQUEST_EXTRA ];
#endif

View File

@ -8,17 +8,24 @@
#include "serial.h"
#define WIN_ERROR ( HANDLE )-1
#define WIN_MAX_PORT_NAME 1024
#define WIN_MAX_PORT_NAME MAX_PATH
#define MAX_HANDLES 1024
static HANDLE sel_handlers[ MAX_HANDLES ];
static int sel_handler_map[ MAX_HANDLES ];
static HANDLE sel_handlers[ MAX_HANDLES ]; // XXX: consider making this an static variable of ser_select_byte
static int sel_handler_map[ MAX_HANDLES ]; // XXX: consider making this an static variable of ser_select_byte
static void init_ov( OVERLAPPED* o )
{
HANDLE temp = o->hEvent;
memset( o, 0, sizeof( OVERLAPPED ) );
o->hEvent = temp;
}
// Helper: set timeout
static int ser_win32_set_timeouts( HANDLE hComm, DWORD ri, DWORD rtm, DWORD rtc, DWORD wtm, DWORD wtc )
{
{
COMMTIMEOUTS timeouts;
if( GetCommTimeouts( hComm, &timeouts ) == FALSE )
{
CloseHandle( hComm );
@ -29,18 +36,18 @@ static int ser_win32_set_timeouts( HANDLE hComm, DWORD ri, DWORD rtm, DWORD rtc,
timeouts.ReadTotalTimeoutMultiplier = rtc;
timeouts.WriteTotalTimeoutConstant = wtm;
timeouts.WriteTotalTimeoutMultiplier = wtc;
if( SetCommTimeouts( hComm, &timeouts ) == FALSE )
{
CloseHandle( hComm );
return SER_ERR;
}
if( SetCommTimeouts( hComm, &timeouts ) == FALSE )
{
CloseHandle( hComm );
return SER_ERR;
}
return SER_OK;
}
// Helper: set communication timeout
static int ser_set_timeout_ms( HANDLE hComm, u32 timeout )
{
{
if( timeout == SER_NO_TIMEOUT )
return ser_win32_set_timeouts( hComm, MAXDWORD, 0, 0, 0, 0 );
else if( timeout == SER_INF_TIMEOUT )
@ -55,8 +62,8 @@ ser_handler ser_open( const char* sername )
char portname[ WIN_MAX_PORT_NAME + 1 ];
HANDLE hComm;
ser_handler hnd;
portname[ 0 ] = portname[ WIN_MAX_PORT_NAME ] = '\0';
portname[ WIN_MAX_PORT_NAME ] = '\0';
_snprintf( portname, WIN_MAX_PORT_NAME, "\\\\.\\%s", sername );
hComm = CreateFile( portname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 );
if( hComm == INVALID_HANDLE_VALUE )
@ -70,10 +77,17 @@ ser_handler ser_open( const char* sername )
memset( hnd, 0, sizeof( SERIAL_DATA ) );
hnd->hnd = hComm;
hnd->fWaitingOnRead = FALSE;
if( ( hnd->o.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
if( ( hnd->o.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
{
free( hnd );
return SER_HANDLER_INVALID;
if( ( hnd->o_wr.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
return SER_HANDLER_INVALID;
}
if( ( hnd->o_wr.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
{
free( hnd );
CloseHandle( hnd->o.hEvent );
return SER_HANDLER_INVALID;
}
return hnd;
}
@ -81,7 +95,7 @@ ser_handler ser_open( const char* sername )
void ser_close( ser_handler id )
{
CloseHandle( id->o.hEvent );
CloseHandle( id->o_wr.hEvent );
CloseHandle( id->o_wr.hEvent );
CloseHandle( id->hnd );
free( id );
}
@ -90,12 +104,13 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
{
HANDLE hComm = id->hnd;
DCB dcb;
if( GetCommState( hComm, &dcb ) == FALSE )
{
CloseHandle( hComm );
return SER_ERR;
}
dcb.DCBlength = sizeof(DCB);
if( GetCommState( hComm, &dcb ) == FALSE )
{
CloseHandle( hComm );
return SER_ERR;
}
dcb.BaudRate = baud;
dcb.ByteSize = databits;
dcb.Parity = parity == SER_PARITY_NONE ? NOPARITY : ( parity == SER_PARITY_EVEN ? EVENPARITY : ODDPARITY );
@ -120,59 +135,63 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutxCtsFlow = TRUE;
}
if( SetCommState( hComm, &dcb ) == 0 )
if( SetCommState( hComm, &dcb ) == FALSE )
{
CloseHandle( hComm );
return SER_ERR;
}
if( ser_win32_set_timeouts( hComm, 0, 0, 0, 0, 0 ) == SER_ERR )
{
CloseHandle( hComm );
return SER_ERR;
}
FlushFileBuffers( hComm );
return SER_OK;
}
// Read up to the specified number of bytes, return bytes actually read
u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
static u32 ser_read_internal( ser_handler id, u32 timeout )
{
HANDLE hComm = id->hnd;
DWORD readbytes = 0;
if( !id->fWaitingOnRead )
DWORD dwRes = WaitForSingleObject( id->o.hEvent, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
if( dwRes == WAIT_OBJECT_0 )
{
if( ReadFile( hComm, dest, maxsize, &readbytes, &id->o ) == FALSE )
{
if( GetLastError() != ERROR_IO_PENDING )
return 0;
else
id->fWaitingOnRead = TRUE;
}
else
return readbytes;
if( !GetOverlappedResult( hComm, &id->o, &readbytes, TRUE ) )
readbytes = 0;
}
else if( dwRes == WAIT_TIMEOUT )
{
CancelIo( hComm );
GetOverlappedResult( hComm, &id->o, &readbytes, TRUE );
readbytes = 0;
}
ResetEvent( id->o.hEvent );
return readbytes;
}
// Read up to the specified number of bytes, return bytes actually read
u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
{
DWORD readbytes = 0;
if( id->fWaitingOnRead )
{
DWORD dwRes = WaitForSingleObject( id->o.hEvent, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
if( dwRes == WAIT_OBJECT_0 )
{
if( !GetOverlappedResult( hComm, &id->o, &readbytes, TRUE ) )
readbytes = 0;
}
else if( dwRes == WAIT_TIMEOUT )
{
CancelIo( hComm );
GetOverlappedResult( hComm, &id->o, &readbytes, TRUE );
readbytes = 0;
}
ResetEvent( id->o.hEvent );
}
id->fWaitingOnRead = FALSE;
readbytes = ser_read_internal( id, timeout );
dest[0] = id->databuf;
}
else
{
init_ov( &id->o );
if( ReadFile( id->hnd, dest, maxsize, &readbytes, &id->o ) )
return readbytes;
if( GetLastError() != ERROR_IO_PENDING )
return 0;
id->fWaitingOnRead = TRUE; // XXX: consider removing statement
readbytes = ser_read_internal( id, timeout );
}
id->fWaitingOnRead = FALSE;
return readbytes;
}
@ -180,41 +199,25 @@ u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
int ser_read_byte( ser_handler id, u32 timeout )
{
u8 data;
int res = ser_read( id, &data, 1, timeout );
return res == 1 ? data : -1;
return ser_read( id, &data, 1, timeout ) == 1 ? data : -1;
}
// Write up to the specified number of bytes, return bytes actually written
u32 ser_write( ser_handler id, const u8 *src, u32 size )
{
HANDLE hComm = id->hnd;
DWORD written = 0;
BOOL fWaitingOnWrite = FALSE;
HANDLE temp = id->o_wr.hEvent;
memset( &id->o_wr, 0, sizeof( OVERLAPPED ) );
id->o_wr.hEvent = temp;
if( WriteFile( hComm, src, size, &written, &id->o_wr ) == FALSE )
{
if( GetLastError() != ERROR_IO_PENDING )
return 0;
else
fWaitingOnWrite = TRUE;
}
else
DWORD written;
init_ov( &id->o_wr );
if( WriteFile( hComm, src, size, &written, &id->o_wr ) )
return written;
if( GetLastError() != ERROR_IO_PENDING )
return 0;
if( !GetOverlappedResult( hComm, &id->o_wr, &written, TRUE ) )
written = 0;
ResetEvent( id->o_wr.hEvent );
if( fWaitingOnWrite )
{
DWORD dwRes = WaitForSingleObject( id->o_wr.hEvent, INFINITE );
if( dwRes == WAIT_OBJECT_0 )
if( !GetOverlappedResult( hComm, &id->o_wr, &written, FALSE ) )
written = 0;
ResetEvent( id->o_wr.hEvent );
}
return written;
return written;
}
// Write a byte to the serial port
@ -228,73 +231,57 @@ u32 ser_write_byte( ser_handler id, u8 data )
// otherwise
int ser_select_byte( ser_handler *pobjects, unsigned nobjects, int timeout )
{
int i, idx;
DWORD readbytes;
int i;
DWORD readbytes, dwRes;
int res = -1;
unsigned num_wait = 0;
ser_handler hnd;
HANDLE temp;
if( nobjects >= MAXIMUM_WAIT_OBJECTS )
return -1;
// Try to read directly first
for( i = 0; i < nobjects; i ++ )
{
temp = pobjects[ i ]->o.hEvent;
memset( &pobjects[ i ]->o, 0, sizeof( OVERLAPPED ) );
pobjects[ i ]->o.hEvent = temp;
{
if( !pobjects[ i ]->fWaitingOnRead )
{
if( ReadFile( pobjects[ i ]->hnd, &pobjects[ i ]->databuf, 1, &readbytes, &pobjects[ i ]->o ) == FALSE )
{
if( GetLastError() != ERROR_IO_PENDING )
return -1;
else
{
pobjects[ i ]->fWaitingOnRead = TRUE;
sel_handler_map[ num_wait ] = i;
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
}
}
else
{
if( readbytes == 1 )
return pobjects[ i ]->databuf | ( i << 8 );
else
return -1;
}
}
else
{
sel_handler_map[ num_wait ] = i;
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
}
init_ov( &pobjects[ i ]->o );
if( ReadFile( pobjects[ i ]->hnd, &pobjects[ i ]->databuf, 1, &readbytes, &pobjects[ i ]->o ) )
return readbytes != 1 ? -1 : pobjects[ i ]->databuf | ( i << 8 );
if( GetLastError() != ERROR_IO_PENDING )
return -1;
pobjects[ i ]->fWaitingOnRead = TRUE;
}
sel_handler_map[ num_wait ] = i;
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
}
if( num_wait > 0 )
if( num_wait == 0 )
return -1;
dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
if( dwRes >= WAIT_OBJECT_0 && dwRes < WAIT_OBJECT_0 + num_wait )
{
idx = -1;
DWORD dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
if( dwRes >= WAIT_OBJECT_0 && dwRes < WAIT_OBJECT_0 + num_wait )
i = dwRes - WAIT_OBJECT_0;
hnd = pobjects[ sel_handler_map[ i ] ];
hnd->fWaitingOnRead = FALSE;
if( GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE ) && readbytes == 1 )
res = hnd->databuf | ( sel_handler_map[ i ] << 8 );
ResetEvent( hnd->o.hEvent );
}
else if( dwRes == WAIT_TIMEOUT )
{
for( i = 0; i < num_wait; i ++ )
{
i = idx = dwRes - WAIT_OBJECT_0;
hnd = pobjects[ sel_handler_map[ i ] ];
hnd->fWaitingOnRead = FALSE;
if( GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE ) && readbytes == 1 )
res = hnd->databuf | ( sel_handler_map[ i ] << 8 );
ResetEvent( hnd->o.hEvent );
CancelIo( hnd->hnd );
}
else if( dwRes == WAIT_TIMEOUT )
{
for( i = 0; i < num_wait; i ++ )
{
hnd = pobjects[ sel_handler_map[ i ] ];
hnd->fWaitingOnRead = FALSE;
CancelIo( hnd->hnd );
GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE );
ResetEvent( hnd->o.hEvent );
}
}
}
return res;
WaitForMultipleObjects( num_wait, sel_handlers, TRUE, INFINITE );
for( i = 0; i < num_wait; i ++ )
ResetEvent( pobjects[ sel_handler_map[ i ] ]->o.hEvent );
}
return res;
}

3
romfs/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*
!.gitignore

View File

@ -1,33 +1,35 @@
import os, sys, platform
output = 'luarpc'
cdefs = ['-DLUA_CROSS_COMPILER','-DLUA_RPC']
cdefs = "-DLUA_CROSS_COMPILER -DLUA_RPC"
# Lua source files and include path
lua_files = """lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c
lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c
ldblib.c liolib.c lmathlib.c loslib.c ltablib.c lstrlib.c loadlib.c linit.c lua.c print.c lrotable.c"""
lua_full_files = " " + " ".join( [ "src/lua/%s" % name for name in lua_files.split() ] )
lua_full_files += " src/modules/luarpc.c src/luarpc_desktop_serial.c "
lua_full_files += " src/modules/luarpc.c src/modules/lpack.c src/modules/bitarray.c src/modules/bit.c src/luarpc_desktop_serial.c "
external_libs = ['m']
external_libs = '-lm'
if platform.system() == "Windows":
lua_full_files += " src/serial/serial_win32.c"
cdefs.append("-DWIN32_BUILD")
cdefs += " -DWIN32_BUILD"
else:
lua_full_files += " src/serial/serial_posix.c"
external_libs += ['readline']
cdefs.append("-DLUA_USE_READLINE")
external_libs += " -lreadline"
cdefs += " -DLUA_USE_READLINE"
local_include = ['src/lua', 'inc', 'src/modules', 'inc/desktop'];
local_include = "-Isrc/lua -Iinc -Isrc/modules -Iinc/desktop"
# Compiler/linker options
cccom = "gcc -O2 -g %s -Wall %s -c $SOURCE -o $TARGET" % ( local_include, cdefs )
linkcom = "gcc -o $TARGET $SOURCES %s" % external_libs
# Env for building the program
comp = Environment( CPPPATH = local_include,
CCFLAGS = cdefs,
comp = Environment( CCCOM = cccom,
LINKCOM = linkcom,
ENV = os.environ )
# Debug
comp.PrependUnique(CCFLAGS=['-g'])
Decider( 'MD5-timestamp' )
Default( comp.Program( output, Split( lua_full_files ), LIBS=external_libs ) )
Default( comp.Program( output, Split( lua_full_files ) ) )

View File

@ -147,10 +147,15 @@ void platform_uart_send( unsigned id, u8 data )
static elua_int_c_handler prev_uart_rx_handler;
static void cmn_uart_rx_inthandler( elua_int_resnum resnum )
{
{
int data;
if( buf_is_enabled( BUF_ID_UART, resnum ) || resnum == SERMUX_PHYS_ID )
cmn_rx_handler( resnum, platform_s_uart_recv( resnum, 0 ) );
{
while( -1 != ( data = platform_s_uart_recv( resnum, 0 ) ) )
cmn_rx_handler( resnum, ( u8 )data );
}
// Chain to previous handler
if( prev_uart_rx_handler != NULL )
prev_uart_rx_handler( resnum );

View File

@ -40,13 +40,7 @@ static u32 periodic_timer, arp_timer;
static void device_driver_send()
{
if( uip_len <= TOTAL_HEADER_LENGTH )
platform_eth_send_packet( uip_buf, uip_len );
else
{
platform_eth_send_packet( uip_buf, TOTAL_HEADER_LENGTH );
platform_eth_send_packet( ( u8* )uip_appdata, uip_len - TOTAL_HEADER_LENGTH );
}
platform_eth_send_packet( uip_buf, uip_len );
}
// This gets called on both Ethernet RX interrupts and timer requests,
@ -202,7 +196,7 @@ static int elua_uip_telnet_socket = -1;
// Utility function for TELNET: parse input buffer, skipping over
// TELNET specific sequences
// Returns the length of the buffer after processing
static void elua_uip_telnet_handle_input( struct elua_uip_state* s )
static void elua_uip_telnet_handle_input( volatile struct elua_uip_state* s )
{
u8 *dptr = ( u8* )uip_appdata;
char *orig = ( char* )s->ptr;
@ -272,7 +266,7 @@ volatile static elua_net_ip elua_uip_accept_remote;
void elua_uip_appcall()
{
struct elua_uip_state *s;
volatile struct elua_uip_state *s;
elua_net_size temp;
int sockno;

View File

@ -41,7 +41,7 @@ void transport_open( Transport *tpt, const char *path )
}
ser_setup( tpt->fd, 115200, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1 );
ser_set_timeout_ms( tpt->fd, 1000 );
ser_set_timeout_ms( tpt->fd, 10000 );
}
// Open Listener / Server

View File

@ -3,7 +3,7 @@
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "type.h"
#include "auxmods.h"
#include "lrotable.h"
#include <string.h>
@ -175,15 +175,15 @@ static int bitarray_set( lua_State *L )
switch( pa->elsize )
{
case 8:
pa->values[ idx ] = val;;
pa->values[ idx ] = ( u8 )newval;
break;
case 16:
*( ( u16* )pa->values + idx ) = val;
*( ( u16* )pa->values + idx ) = ( u16 )newval;
break;
case 32:
*( ( u32* )pa->values + idx ) = val;
*( ( u32* )pa->values + idx ) = ( u32 )newval;
break;
}
return 0;

View File

@ -58,7 +58,7 @@ static int spi_rw_helper( lua_State *L, int withread )
{
spi_data_type value;
const char *sval;
int total = lua_gettop( L ), i, id;
int total = lua_gettop( L ), i, j, id;
size_t len, residx = 1;
id = luaL_checkinteger( L, 1 );
@ -79,9 +79,9 @@ static int spi_rw_helper( lua_State *L, int withread )
else if( lua_isstring( L, i ) )
{
sval = lua_tolstring( L, i, &len );
for( i = 0; i < len; i ++ )
for( j = 0; j < len; j ++ )
{
value = platform_spi_send_recv( id, sval[ i ] );
value = platform_spi_send_recv( id, sval[ j ] );
if( withread )
{
lua_pushnumber( L, value );

View File

@ -23,6 +23,10 @@
//#define BUILD_SERMUX
#define BUILD_ADC
#define BUILD_UIP
//#define BUILD_DHCPC
#define BUILD_DNS
// *****************************************************************************
// UART/Timer IDs configuration data (used in main.c)
@ -66,6 +70,11 @@
#else
#define ADCLINE
#endif
#ifdef BUILD_UIP
#define NETLINE _ROM( AUXLIB_NET, luaopen_net, net_map )
#else
#define NETLINE
#endif
#if defined( BUILD_RPC )
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
@ -80,8 +89,9 @@
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
_ROM( AUXLIB_SPI, luaopen_spi, spi_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
ADCLINE\
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
ADCLINE\
NETLINE\
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
RPCLINE\
@ -174,4 +184,26 @@
// *****************************************************************************
// CPU constants that should be exposed to the eLua "cpu" module
// Static TCP/IP configuration
#define ELUA_CONF_IPADDR0 192
#define ELUA_CONF_IPADDR1 168
#define ELUA_CONF_IPADDR2 1
#define ELUA_CONF_IPADDR3 10
#define ELUA_CONF_NETMASK0 255
#define ELUA_CONF_NETMASK1 255
#define ELUA_CONF_NETMASK2 255
#define ELUA_CONF_NETMASK3 0
#define ELUA_CONF_DEFGW0 192
#define ELUA_CONF_DEFGW1 168
#define ELUA_CONF_DEFGW2 1
#define ELUA_CONF_DEFGW3 1
#define ELUA_CONF_DNS0 192
#define ELUA_CONF_DNS1 168
#define ELUA_CONF_DNS2 1
#define ELUA_CONF_DNS3 1
#endif // #ifndef __EVK1100_CONF_H__

View File

@ -8,6 +8,7 @@
#define __MIZAR32_CONF_H__
#include "sdramc.h"
#include "sermux.h"
#include "buf.h"
// *****************************************************************************
@ -15,18 +16,27 @@
#define BUILD_MMCFS
//#define BUILD_XMODEM
//#define BUILD_SHELL
//#define BUILD_ROMFS
#define BUILD_SHELL
#define BUILD_ROMFS
//#define BUILD_TERM
#define BUILD_CON_GENERIC
//#define BUILD_CON_GENERIC
//#define BUILD_RPC
#define BUF_ENABLE_UART
#define BUILD_C_INT_HANDLERS
//#define BUILD_ADC
#define BUILA_LUA_INT_HANDLERS
//#define BUILD_RFS
//#define BUILD_SERMUX
#define BUILD_UIP
//#define BUILD_DHCPC
#define BUILD_DNS
#define BUILD_CON_TCP
// *****************************************************************************
// UART/Timer IDs configuration data (used in main.c)
//#define CON_UART_ID ( SERMUX_SERVICE_ID_FIRST + 1 )
#define CON_UART_ID 0
#define CON_UART_SPEED 115200
#define CON_TIMER_ID 0
@ -65,6 +75,11 @@
#else
#define ADCLINE
#endif
#ifdef BUILD_UIP
#define NETLINE _ROM( AUXLIB_NET, luaopen_net, net_map )
#else
#define NETLINE
#endif
#if defined( BUILD_RPC )
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
@ -77,8 +92,9 @@
_ROM( AUXLIB_UART, luaopen_uart, uart_map )\
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
_ROM( AUXLIB_SPI, luaopen_spi, spi_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
NETLINE\
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
ADCLINE\
@ -87,11 +103,14 @@
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
#if MINIMAL_ROM_MODULES_TO_FIT_IN_120KB
/* Minimal ROM modules, to fit in 120KB */
#undef LUA_PLATFORM_LIBS_ROM
#define LUA_PLATFORM_LIBS_ROM\
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
NETLINE
#endif
// *****************************************************************************
// Configuration data
@ -165,12 +184,49 @@
// Interrupt queue size
#define PLATFORM_INT_QUEUE_LOG_SIZE 5
#define RFS_BUFFER_SIZE BUF_SIZE_512
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
#define RFS_TIMER_ID 0
#define RFS_TIMEOUT 100000
#define RFS_UART_SPEED 115200
//#define SERMUX_PHYS_ID 0
//#define SERMUX_PHYS_SPEED 115200
//#define SERMUX_NUM_VUART 2
//#define SERMUX_BUFFER_SIZES { RFS_BUFFER_SIZE, CON_BUF_SIZE }
// Interrupt list
#define INT_UART_RX ELUA_INT_FIRST_ID
#define INT_ELUA_LAST INT_UART_RX
#define PLATFORM_CPU_CONSTANTS\
_C( INT_UART_RX )
// *****************************************************************************
// CPU constants that should be exposed to the eLua "cpu" module
// Static TCP/IP configuration
#define ELUA_CONF_IPADDR0 192
#define ELUA_CONF_IPADDR1 168
#define ELUA_CONF_IPADDR2 1
#define ELUA_CONF_IPADDR3 10
#define ELUA_CONF_NETMASK0 255
#define ELUA_CONF_NETMASK1 255
#define ELUA_CONF_NETMASK2 255
#define ELUA_CONF_NETMASK3 0
#define ELUA_CONF_DEFGW0 192
#define ELUA_CONF_DEFGW1 168
#define ELUA_CONF_DEFGW2 1
#define ELUA_CONF_DEFGW3 1
#define ELUA_CONF_DNS0 192
#define ELUA_CONF_DNS1 168
#define ELUA_CONF_DNS2 1
#define ELUA_CONF_DNS3 1
#endif // #ifndef __MIZAR32_CONF_H__

View File

@ -1,6 +1,6 @@
-- Configuration file for the AVR32 microcontrollers
specific_files = "crt0.s trampoline.s platform.c exception.s intc.c pm.c flashc.c pm_conf_clocks.c usart.c gpio.c tc.c spi.c platform_int.c adc.c pwm.c"
specific_files = "crt0.s trampoline.s platform.c exception.s intc.c pm.c flashc.c pm_conf_clocks.c usart.c gpio.c tc.c spi.c platform_int.c adc.c pwm.c ethernet.c"
addm( "FORAVR32" )
-- See board.h for possible BOARD values.

View File

@ -1,6 +1,6 @@
# Configuration file for the AVR32 microcontrollers
specific_files = "crt0.s trampoline.s platform.c exception.s intc.c pm.c flashc.c pm_conf_clocks.c usart.c gpio.c tc.c spi.c platform_int.c adc.c pwm.c"
specific_files = "crt0.s trampoline.s platform.c exception.s intc.c pm.c flashc.c pm_conf_clocks.c usart.c gpio.c tc.c spi.c platform_int.c adc.c pwm.c ethernet.c"
comp.Append(CPPDEFINES = 'FORAVR32')
# See board.h for possible BOARD values.

View File

@ -0,0 +1,814 @@
/* This source file is part of the ATMEL AVR32-UC3-SoftwareFramework-1.6.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief MACB driver for EVK1100 board.
*
* This file defines a useful set of functions for the MACB interface on
* AVR32 devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a MACB module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an Atmel
* AVR product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*
*/
/*
* ported on elua world by nuccio raciti <raciti.nuccio@gmail.com>, enjoy.
*/
#include <stdio.h>
#include <string.h>
#include <avr32/io.h>
#include "compiler.h"
#include "platform_conf.h"
#ifdef BUILD_UIP
#include "ethernet.h"
/* Size of each receive buffer - DO NOT CHANGE. */
#define RX_BUFFER_SIZE 128
/* The buffer addresses written into the descriptors must be aligned so the
last two bits are zero. These bits have special meaning for the MACB
peripheral and cannot be used as part of the address. */
#define ADDRESS_MASK ( ( unsigned long ) 0xFFFFFFFC )
/* Bit used within the address stored in the descriptor to mark the last
descriptor in the array. */
#define RX_WRAP_BIT ( ( unsigned long ) 0x02 )
/* A short delay is used to wait for a buffer to become available, should
one not be immediately available when trying to transmit a frame. */
#define BUFFER_WAIT_DELAY ( 2 )
#include "ethernet.h"
#include "intc.h"
#include "elua_uip.h"
#ifndef FREERTOS_USED
#define portENTER_CRITICAL Disable_global_interrupt
#define portEXIT_CRITICAL Enable_global_interrupt
#define portENTER_SWITCHING_ISR()
#define portEXIT_SWITCHING_ISR()
#endif
#define TIMEOUT 500
/* Buffer written to by the MACB DMA. Must be aligned as described by the
comment above the ADDRESS_MASK definition. */
static volatile char pcRxBuffer[ ETHERNET_CONF_NB_RX_BUFFERS * RX_BUFFER_SIZE ] __attribute__ ((aligned (4)));
/* Buffer read by the MACB DMA. Must be aligned as described by the comment
above the ADDRESS_MASK definition. */
static volatile char pcTxBuffer[ ETHERNET_CONF_NB_TX_BUFFERS * ETHERNET_CONF_TX_BUFFER_SIZE ] __attribute__ ((aligned (4)));
/* Descriptors used to communicate between the program and the MACB peripheral.
These descriptors hold the locations and state of the Rx and Tx buffers.
Alignment value chosen from RBQP and TBQP registers description in datasheet. */
static volatile AVR32_TxTdDescriptor xTxDescriptors[ ETHERNET_CONF_NB_TX_BUFFERS ] __attribute__ ((aligned (8)));
static volatile AVR32_RxTdDescriptor xRxDescriptors[ ETHERNET_CONF_NB_RX_BUFFERS ] __attribute__ ((aligned (8)));
/* The IP and Ethernet addresses are read from the header files. */
unsigned char cMACAddress[ 6 ] = { ETHERNET_CONF_ETHADDR0,ETHERNET_CONF_ETHADDR1,ETHERNET_CONF_ETHADDR2,ETHERNET_CONF_ETHADDR3,ETHERNET_CONF_ETHADDR4,ETHERNET_CONF_ETHADDR5 };
/*-----------------------------------------------------------*/
/* See the header file for descriptions of public functions. */
/*
* Prototype for the MACB interrupt function - called by the asm wrapper.
*/
__attribute__((__interrupt__)) void vMACB_ISR(void);
/*
* Initialise both the Tx and Rx descriptors used by the MACB.
*/
static void prvSetupDescriptors(volatile avr32_macb_t *macb);
//
// Restore ownership of all Rx buffers to the MACB.
//
static void vResetMacbRxFrames( void );
/*
* Write our MAC address into the MACB.
*/
static void prvSetupMACAddress(volatile avr32_macb_t *macb);
/*
* Configure the MACB for interrupts.
*/
static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb);
/*
* Some initialisation functions.
*/
static Bool prvProbePHY(volatile avr32_macb_t *macb);
static unsigned long ulReadMDIO(volatile avr32_macb_t *macb, unsigned short usAddress);
static void vWriteMDIO(volatile avr32_macb_t *macb, unsigned short usAddress, unsigned short usValue);
/* Holds the index to the next buffer from which data will be read. */
volatile unsigned long ulNextRxBuffer = 0;
long lMACBSend(volatile avr32_macb_t *macb, const void *pvFrom, unsigned long ulLength, long lEndOfFrame)
{
const unsigned char *pcFrom = pvFrom;
static unsigned long uxTxBufferIndex = 0;
void *pcBuffer;
unsigned long ulLastBuffer, ulDataBuffered = 0, ulDataRemainingToSend, ulLengthToSend;
/* If the length of data to be transmitted is greater than each individual
transmit buffer then the data will be split into more than one buffer.
Loop until the entire length has been buffered. */
while( ulDataBuffered < ulLength )
{
// Is a buffer available ?
while( !( xTxDescriptors[ uxTxBufferIndex ].U_Status.status & AVR32_TRANSMIT_OK ) )
{
// There is no room to write the Tx data to the Tx buffer.
// Wait a short while, then try again.
__asm__ __volatile__ ("nop");
}
portENTER_CRITICAL();
{
// Get the address of the buffer from the descriptor,
// then copy the data into the buffer.
pcBuffer = ( void * ) xTxDescriptors[ uxTxBufferIndex ].addr;
// How much can we write to the buffer ?
ulDataRemainingToSend = ulLength - ulDataBuffered;
if( ulDataRemainingToSend <= ETHERNET_CONF_TX_BUFFER_SIZE )
{
// We can write all the remaining bytes.
ulLengthToSend = ulDataRemainingToSend;
}
else
{
// We can't write more than ETH_TX_BUFFER_SIZE in one go.
ulLengthToSend = ETHERNET_CONF_TX_BUFFER_SIZE;
}
// Copy the data into the buffer.
memcpy( pcBuffer, &( pcFrom[ ulDataBuffered ] ), ulLengthToSend );
ulDataBuffered += ulLengthToSend;
// Is this the last data for the frame ?
if( lEndOfFrame && ( ulDataBuffered >= ulLength ) )
{
// No more data remains for this frame so we can start the transmission.
ulLastBuffer = AVR32_LAST_BUFFER;
}
else
{
// More data to come for this frame.
ulLastBuffer = 0;
}
// Fill out the necessary in the descriptor to get the data sent,
// then move to the next descriptor, wrapping if necessary.
if( uxTxBufferIndex >= ( ETHERNET_CONF_NB_TX_BUFFERS - 1 ) )
{
xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned long ) AVR32_LENGTH_FRAME )
| ulLastBuffer
| AVR32_TRANSMIT_WRAP;
uxTxBufferIndex = 0;
} else
{
xTxDescriptors[ uxTxBufferIndex ].U_Status.status = ( ulLengthToSend & ( unsigned long ) AVR32_LENGTH_FRAME )
| ulLastBuffer;
uxTxBufferIndex++;
}
/* If this is the last buffer to be sent for this frame we can
start the transmission. */
if( ulLastBuffer )
macb->ncr |= AVR32_MACB_TSTART_MASK;
}
portEXIT_CRITICAL();
}
return PASS;
}
unsigned long ulMACBInputLength(void)
{
register unsigned long ulIndex , ulLength = 0;
unsigned int uiTemp;
volatile unsigned long ulEventStatus;
// Check if the MACB encountered a problem.
ulEventStatus = AVR32_MACB.rsr;
if( ulEventStatus & AVR32_MACB_RSR_BNA_MASK )
{ // MACB couldn't get ownership of a buffer. This could typically
// happen if the total numbers of Rx buffers is tailored too small
// for a noisy network with big frames.
// We might as well restore ownership of all buffers to the MACB to
// restart from a clean state.
vResetMacbRxFrames();
return( ulLength );
}
// Skip any fragments. We are looking for the first buffer that contains
// data and has the SOF (start of frame) bit set.
while( ( xRxDescriptors[ ulNextRxBuffer ].addr & AVR32_OWNERSHIP_BIT )
&& !( xRxDescriptors[ ulNextRxBuffer ].U_Status.status & AVR32_SOF ) )
{
// Ignoring this buffer. Mark it as free again.
uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
ulNextRxBuffer++;
if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS )
{
ulNextRxBuffer = 0;
}
}
// We are going to walk through the descriptors that make up this frame,
// but don't want to alter ulNextRxBuffer as this would prevent vMACBRead()
// from finding the data. Therefore use a copy of ulNextRxBuffer instead.
ulIndex = ulNextRxBuffer;
// Walk through the descriptors until we find the last buffer for this frame.
// The last buffer will give us the length of the entire frame.
while ( xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT )
{
ulLength = xRxDescriptors[ ulIndex ].U_Status.status & AVR32_LENGTH_FRAME;
if (ulLength) break; //return ulLength
// Increment to the next buffer, wrapping if necessary.
if( ++ulIndex >= ETHERNET_CONF_NB_RX_BUFFERS ) ulIndex = 0;
// Is the descriptor valid?
if (!(xRxDescriptors[ ulIndex ].addr & AVR32_OWNERSHIP_BIT)) break; //return 0
// Is it a SOF? If so, the head packet is bad and should be discarded
if (xRxDescriptors[ ulIndex ].U_Status.status & AVR32_SOF)
{
// Mark the buffers of the CURRENT, FAULTY packet available.
unsigned int i = ulNextRxBuffer;
do{
// Ignore the faulty frame. Mark its buffers as owned by the MACB.
uiTemp = xRxDescriptors[ i ].addr;
xRxDescriptors[ i ].addr = uiTemp & ~(AVR32_OWNERSHIP_BIT);
if (++i>=ETHERNET_CONF_NB_RX_BUFFERS) i=0;
}while (i!=ulIndex);
ulNextRxBuffer=ulIndex;
// We have the start of a new packet, look at that one instead.
}
}
return ulLength;
}
/*-----------------------------------------------------------*/
void vMACBRead(void *pvTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength)
{
unsigned char *pcTo = pvTo;
static unsigned long ulSectionBytesReadSoFar = 0, ulBufferPosition = 0, ulFrameBytesReadSoFar = 0;
static const unsigned char *pcSource;
register unsigned long ulBytesRemainingInBuffer, ulRemainingSectionBytes;
unsigned int uiTemp;
// Read ulSectionLength bytes from the Rx buffers.
// This is not necessarily any correspondence between the length of our Rx buffers,
// and the length of the data we are returning or the length of the data being requested.
// Therefore, between calls we have to remember not only which buffer we are currently
// processing, but our position within that buffer.
// This would be greatly simplified if PBUF_POOL_BUFSIZE could be guaranteed to be greater
// than the size of each Rx buffer, and that memory fragmentation did not occur.
// This function should only be called after a call to ulMACBInputLength().
// This will ensure ulNextRxBuffer is set to the correct buffer. */
// vMACBRead is called with pcTo set to NULL to indicate that we are about
// to read a new frame. Any fragments remaining in the frame we were
// processing during the last call should be dropped.
if( pcTo == NULL )
{
// How many bytes are indicated as being in this buffer?
// If none then the buffer is completely full and the frame is contained within more
// than one buffer.
// Reset our state variables ready for the next read from this buffer.
pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK );
ulFrameBytesReadSoFar = ( unsigned long ) 0;
ulBufferPosition = ( unsigned long ) 0;
}
else
{
// Loop until we have obtained the required amount of data.
ulSectionBytesReadSoFar = 0;
while( ulSectionBytesReadSoFar < ulSectionLength )
{
// We may have already read some data from this buffer.
// How much data remains in the buffer?
ulBytesRemainingInBuffer = ( RX_BUFFER_SIZE - ulBufferPosition );
// How many more bytes do we need to read before we have the
// required amount of data?
ulRemainingSectionBytes = ulSectionLength - ulSectionBytesReadSoFar;
// Do we want more data than remains in the buffer?
if( ulRemainingSectionBytes > ulBytesRemainingInBuffer )
{
// We want more data than remains in the buffer so we can
// write the remains of the buffer to the destination, then move
// onto the next buffer to get the rest.
memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulBytesRemainingInBuffer );
ulSectionBytesReadSoFar += ulBytesRemainingInBuffer;
ulFrameBytesReadSoFar += ulBytesRemainingInBuffer;
// Mark the buffer as free again.
uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
// Move onto the next buffer.
ulNextRxBuffer++;
if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS )
{
ulNextRxBuffer = ( unsigned long ) 0;
}
// Reset the variables for the new buffer.
pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK );
ulBufferPosition = ( unsigned long ) 0;
}
else
{
// We have enough data in this buffer to send back.
// Read out enough data and remember how far we read up to.
memcpy( &( pcTo[ ulSectionBytesReadSoFar ] ), &( pcSource[ ulBufferPosition ] ), ulRemainingSectionBytes );
// There may be more data in this buffer yet.
// Increment our position in this buffer past the data we have just read.
ulBufferPosition += ulRemainingSectionBytes;
ulSectionBytesReadSoFar += ulRemainingSectionBytes;
ulFrameBytesReadSoFar += ulRemainingSectionBytes;
// Have we now finished with this buffer?
if( ( ulBufferPosition >= RX_BUFFER_SIZE ) || ( ulFrameBytesReadSoFar >= ulTotalFrameLength ) )
{
// Mark the buffer as free again.
uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
// Move onto the next buffer.
ulNextRxBuffer++;
if( ulNextRxBuffer >= ETHERNET_CONF_NB_RX_BUFFERS )
{
ulNextRxBuffer = 0;
}
pcSource = ( unsigned char * )( xRxDescriptors[ ulNextRxBuffer ].addr & ADDRESS_MASK );
ulBufferPosition = 0;
}
}
}
}
}
/*-----------------------------------------------------------*/
void vMACBFlushCurrentPacket(unsigned long ulTotalFrameLength)
{
unsigned int uiTemp;
long int lTotalFrameLen = (long int)ulTotalFrameLength;
while( lTotalFrameLen > 0 )
{
// Ignoring this buffer. Mark it as free again.
uiTemp = xRxDescriptors[ ulNextRxBuffer ].addr;
xRxDescriptors[ ulNextRxBuffer ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
// Move on to the next buffer.
ulNextRxBuffer++;
ulNextRxBuffer = ulNextRxBuffer%ETHERNET_CONF_NB_RX_BUFFERS;
lTotalFrameLen -= RX_BUFFER_SIZE;
}
}
/*-----------------------------------------------------------*/
void vMACBSetMACAddress(const unsigned char *MACAddress)
{
memcpy(cMACAddress, MACAddress, sizeof(cMACAddress));
}
Bool xMACBInit(volatile avr32_macb_t *macb)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
volatile unsigned long status;
//vDisableMACBOperations(macb);
// set up registers
macb->ncr = 0;
macb->tsr = ~0UL;
macb->rsr = ~0UL;
if (global_interrupt_enabled) Disable_global_interrupt();
macb->idr = ~0UL;
status = macb->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
// RMII used, set 0 to the USRIO Register
macb->usrio &= ~AVR32_MACB_RMII_MASK;
// Load our MAC address into the MACB.
prvSetupMACAddress(macb);
// Setup the buffers and descriptors.
prvSetupDescriptors(macb);
#if ETHERNET_CONF_SYSTEM_CLOCK <= 20000000
macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV8 << AVR32_MACB_NCFGR_CLK_OFFSET);
#elif ETHERNET_CONF_SYSTEM_CLOCK <= 40000000
macb->ncfgr |= (AVR32_MACB_NCFGR_CLK_DIV16 << AVR32_MACB_NCFGR_CLK_OFFSET);
#elif ETHERNET_CONF_SYSTEM_CLOCK <= 80000000
macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV32 << AVR32_MACB_NCFGR_CLK_OFFSET;
#elif ETHERNET_CONF_SYSTEM_CLOCK <= 160000000
macb->ncfgr |= AVR32_MACB_NCFGR_CLK_DIV64 << AVR32_MACB_NCFGR_CLK_OFFSET;
#else
# error System clock too fast
#endif
// Are we connected?
if( prvProbePHY(macb) == TRUE )
{
// Enable the interrupt!
portENTER_CRITICAL();
{
prvSetupMACBInterrupt(macb);
}
portEXIT_CRITICAL();
// Enable Rx and Tx, plus the stats register.
macb->ncr = AVR32_MACB_NCR_TE_MASK | AVR32_MACB_NCR_RE_MASK;
return (TRUE);
}
return (FALSE);
}
void vDisableMACBOperations (volatile avr32_macb_t *macb)
{
Bool global_interrupt_enabled = Is_global_interrupt_enabled();
// write the MACB control register : disable Tx & Rx
macb->ncr &= ~((1 << AVR32_MACB_RE_OFFSET) | (1 << AVR32_MACB_TE_OFFSET));
// We no more want to interrupt on Rx and Tx events.
if (global_interrupt_enabled) Disable_global_interrupt();
macb->idr = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK;
macb->isr;
if (global_interrupt_enabled) Enable_global_interrupt();
}
void vClearMACBTxBuffer(void)
{
static unsigned long uxNextBufferToClear = 0;
// Called on Tx interrupt events to set the AVR32_TRANSMIT_OK bit in each
// Tx buffer within the frame just transmitted. This marks all the buffers
// as available again.
// The first buffer in the frame should have the bit set automatically. */
if( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_TRANSMIT_OK )
{
// Loop through the other buffers in the frame.
while( !( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_LAST_BUFFER ) )
{
uxNextBufferToClear++;
if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
{
uxNextBufferToClear = 0;
}
xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK;
}
// Start with the next buffer the next time a Tx interrupt is called.
uxNextBufferToClear++;
// Do we need to wrap back to the first buffer?
if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
{
uxNextBufferToClear = 0;
}
}
}
static void prvSetupDescriptors(volatile avr32_macb_t *macb)
{
unsigned long xIndex;
unsigned long ulAddress;
// Initialise xRxDescriptors descriptor.
for( xIndex = 0; xIndex < ETHERNET_CONF_NB_RX_BUFFERS; ++xIndex )
{
// Calculate the address of the nth buffer within the array.
ulAddress = ( unsigned long )( pcRxBuffer + ( xIndex * RX_BUFFER_SIZE ) );
// Write the buffer address into the descriptor.
// The DMA will place the data at this address when this descriptor is being used.
// No need to mask off the bottom bits of the address (these have special meaning
// for the MACB) because pcRxBuffer is 4Bytes-aligned.
xRxDescriptors[ xIndex ].addr = ulAddress;
}
// The last buffer has the wrap bit set so the MACB knows to wrap back
// to the first buffer.
xRxDescriptors[ ETHERNET_CONF_NB_RX_BUFFERS - 1 ].addr |= RX_WRAP_BIT;
// Initialise xTxDescriptors.
for( xIndex = 0; xIndex < ETHERNET_CONF_NB_TX_BUFFERS; ++xIndex )
{
// Calculate the address of the nth buffer within the array.
ulAddress = ( unsigned long )( pcTxBuffer + ( xIndex * ETHERNET_CONF_TX_BUFFER_SIZE ) );
// Write the buffer address into the descriptor.
// The DMA will read data from here when the descriptor is being used.
xTxDescriptors[ xIndex ].addr = ulAddress;
xTxDescriptors[ xIndex ].U_Status.status = AVR32_TRANSMIT_OK;
}
// The last buffer has the wrap bit set so the MACB knows to wrap back
// to the first buffer.
xTxDescriptors[ ETHERNET_CONF_NB_TX_BUFFERS - 1 ].U_Status.status = AVR32_TRANSMIT_WRAP | AVR32_TRANSMIT_OK;
// Tell the MACB where to find the descriptors.
macb->rbqp = ( unsigned long )xRxDescriptors;
macb->tbqp = ( unsigned long )xTxDescriptors;
// Do not copy the FCS field of received frames to memory.
macb->ncfgr |= ( AVR32_MACB_NCFGR_DRFCS_MASK );
}
//!
//! \brief Restore ownership of all Rx buffers to the MACB.
//!
static void vResetMacbRxFrames( void )
{
register unsigned long ulIndex;
unsigned int uiTemp;
// Disable MACB frame reception.
AVR32_MACB.ncr &= ~(AVR32_MACB_NCR_RE_MASK);
// Restore ownership of all Rx buffers to the MACB.
for( ulIndex = 0; ulIndex < ETHERNET_CONF_NB_RX_BUFFERS; ++ulIndex )
{
// Mark the buffer as owned by the MACB.
uiTemp = xRxDescriptors[ ulIndex ].addr;
xRxDescriptors[ ulIndex ].addr = uiTemp & ~( AVR32_OWNERSHIP_BIT );
}
// Reset the Buffer-not-available bit and the overrun bit.
AVR32_MACB.rsr = AVR32_MACB_RSR_BNA_MASK | AVR32_MACB_RSR_OVR_MASK; // Clear
AVR32_MACB.rsr; // We read to force the previous operation.
// Reset the MACB starting point.
AVR32_MACB.rbqp = ( unsigned long )xRxDescriptors;
// Reset the index to the next buffer from which data will be read.
ulNextRxBuffer = 0;
// Enable MACB frame reception.
AVR32_MACB.ncr |= AVR32_MACB_NCR_RE_MASK;
}
static void prvSetupMACAddress(volatile avr32_macb_t *macb)
{
// Must be written SA1L then SA1H.
macb->sa1b = ( ( unsigned long ) cMACAddress[ 3 ] << 24 ) |
( ( unsigned long ) cMACAddress[ 2 ] << 16 ) |
( ( unsigned long ) cMACAddress[ 1 ] << 8 ) |
cMACAddress[ 0 ];
macb->sa1t = ( ( unsigned long ) cMACAddress[ 5 ] << 8 ) |
cMACAddress[ 4 ];
}
static void prvSetupMACBInterrupt(volatile avr32_macb_t *macb)
{
// Setup the interrupt for MACB.
// Register the interrupt handler to the interrupt controller at interrupt level 2
INTC_register_interrupt((__int_handler)&vMACB_ISR, AVR32_MACB_IRQ, AVR32_INTC_INT2);
// We want to interrupt on Rx and Tx events
macb->ier = AVR32_MACB_IER_RCOMP_MASK | AVR32_MACB_IER_TCOMP_MASK ;
}
/*! Read a register on MDIO bus (access to the PHY)
* This function is looping until PHY gets ready
*
* \param macb Input. instance of the MACB to use
* \param usAddress Input. register to set.
*
* \return unsigned long data that has been read
*/
static unsigned long ulReadMDIO(volatile avr32_macb_t *macb, unsigned short usAddress)
{
unsigned long value, status;
u16 timeout = 0;
// initiate transaction : enable management port
macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
// Write the PHY configuration frame to the MAN register
macb->man = (AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET)) // SOF
| (2 << AVR32_MACB_CODE_OFFSET) // Code
| (2 << AVR32_MACB_RW_OFFSET) // Read operation
| ((ETHERNET_CONF_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET) // Phy Add
| (usAddress << AVR32_MACB_REGA_OFFSET); // Reg Add
// wait for PHY to be ready
do {
status = macb->nsr;
} while (!(status & AVR32_MACB_NSR_IDLE_MASK) && (timeout++ < TIMEOUT));
// read the register value in maintenance register
value = macb->man & 0x0000ffff;
// disable management port
macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
// return the read value
return (value);
}
/*! Write a given value to a register on MDIO bus (access to the PHY)
* This function is looping until PHY gets ready
*
* \param *macb Input. instance of the MACB to use
* \param usAddress Input. register to set.
* \param usValue Input. value to write.
*
*/
static void vWriteMDIO(volatile avr32_macb_t *macb, unsigned short usAddress, unsigned short usValue)
{
unsigned long status;
u16 timeout = 0;
// initiate transaction : enable management port
macb->ncr |= AVR32_MACB_NCR_MPE_MASK;
// Write the PHY configuration frame to the MAN register
macb->man = (( AVR32_MACB_SOF_MASK & (0x01<<AVR32_MACB_SOF_OFFSET)) // SOF
| (2 << AVR32_MACB_CODE_OFFSET) // Code
| (1 << AVR32_MACB_RW_OFFSET) // Write operation
| ((ETHERNET_CONF_PHY_ADDR & 0x1f) << AVR32_MACB_PHYA_OFFSET) // Phy Add
| (usAddress << AVR32_MACB_REGA_OFFSET)) // Reg Add
| (usValue & 0xffff); // Data
// wait for PHY to be ready
do {
status = macb->nsr;
} while (!(status & AVR32_MACB_NSR_IDLE_MASK) && (timeout++ < TIMEOUT));
// disable management port
macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
}
static Bool prvProbePHY(volatile avr32_macb_t *macb)
{
volatile unsigned long mii_status, phy_ctrl;
volatile unsigned long config;
unsigned long upper, lower, mode, advertise, lpa;
volatile unsigned long physID;
// Read Phy Identifier register 1 & 2
lower = ulReadMDIO(macb, PHY_PHYSID2);
upper = ulReadMDIO(macb, PHY_PHYSID1);
// get Phy ID, ignore Revision
physID = ((upper << 16) & 0xFFFF0000) | (lower & 0xFFF0);
// check if it match config
if (physID == ETHERNET_CONF_PHY_ID)
{
// read RBR
mode = ulReadMDIO(macb, PHY_RBR);
// set RMII mode if not done
if ((mode & RBR_RMII) != RBR_RMII)
{
// force RMII flag if strap options are wrong
mode |= RBR_RMII;
vWriteMDIO(macb, PHY_RBR, mode);
}
advertise = ADVERTISE_CSMA | ADVERTISE_ALL;
// write advertise register
vWriteMDIO(macb, PHY_ADVERTISE, advertise);
// read Control register
config = ulReadMDIO(macb, PHY_BMCR);
// read Phy Control register
phy_ctrl = ulReadMDIO(macb, PHY_PHYCR);
// enable Auto MDIX
phy_ctrl |= PHYCR_MDIX_EN;
// reset auto-negociation capability
config |= (BMCR_ANRESTART | BMCR_ANENABLE);
// update Phy ctrl register
vWriteMDIO(macb, PHY_PHYCR, phy_ctrl);
// update ctrl register
vWriteMDIO(macb, PHY_BMCR, config);
// loop while link status isn't OK
do {
mii_status = ulReadMDIO(macb, PHY_BMSR);
} while (!(mii_status & BMSR_LSTATUS));
// read the LPA configuration of the PHY
lpa = ulReadMDIO(macb, PHY_LPA);
// read the MACB config register
config = AVR32_MACB.ncfgr;
// if 100MB needed
if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL))
config |= AVR32_MACB_SPD_MASK;
else
config &= ~(AVR32_MACB_SPD_MASK);
// if FULL DUPLEX needed
if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL))
config |= AVR32_MACB_FD_MASK;
else
config &= ~(AVR32_MACB_FD_MASK);
// write the MACB config register
macb->ncfgr = config;
return TRUE;
}
return FALSE;
}
/*
* The MACB ISR. Handles both Tx and Rx complete interrupts.
*/
__attribute__((__interrupt__)) void vMACB_ISR(void)
{
// Variable definitions can be made now.
volatile unsigned long ulIntStatus, ulEventStatus;
// Find the cause of the interrupt.
ulIntStatus = AVR32_MACB.isr;
ulEventStatus = AVR32_MACB.rsr;
if( ( ulIntStatus & AVR32_MACB_IDR_RCOMP_MASK ) || ( ulEventStatus & AVR32_MACB_REC_MASK ) )
{
// A frame has been received, signal the IP task so it can process
// the Rx descriptors.
elua_uip_mainloop();
AVR32_MACB.rsr = AVR32_MACB_REC_MASK; // Clear
AVR32_MACB.rsr; // Read to force the previous write
}
if( ulIntStatus & AVR32_MACB_TCOMP_MASK )
{
// A frame has been transmitted. Mark all the buffers used by the
// frame just transmitted as free again.
vClearMACBTxBuffer();
AVR32_MACB.tsr = AVR32_MACB_TSR_COMP_MASK; // Clear
AVR32_MACB.tsr; // Read to force the previous write
}
}
#endif

View File

@ -0,0 +1,492 @@
/* This header file is part of the ATMEL AVR32-UC3-SoftwareFramework-1.6.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief MACB driver.
*
* This file defines a useful set of functions for the MACB interface on
* AVR32 devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a MACB module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an Atmel
* AVR product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
*
*/
#ifndef AVR32_ETHERNET_H
#define AVR32_ETHERNET_H
#include <avr32/io.h>
#include "compiler.h"
/*! \name Rx Ring descriptor flags
*/
//! @{
#define AVR32_MACB_RX_USED_OFFSET 0
#define AVR32_MACB_RX_USED_SIZE 1
#define AVR32_MACB_RX_WRAP_OFFSET 1
#define AVR32_MACB_RX_WRAP_SIZE 1
#define AVR32_MACB_RX_LEN_OFFSET 0
#define AVR32_MACB_RX_LEN_SIZE 12
#define AVR32_MACB_RX_OFFSET_OFFSET 12
#define AVR32_MACB_RX_OFFSET_SIZE 2
#define AVR32_MACB_RX_SOF_OFFSET 14
#define AVR32_MACB_RX_SOF_SIZE 1
#define AVR32_MACB_RX_EOF_OFFSET 15
#define AVR32_MACB_RX_EOF_SIZE 1
#define AVR32_MACB_RX_CFI_OFFSET 16
#define AVR32_MACB_RX_CFI_SIZE 1
//! @}
/*! \name Tx Ring descriptor flags
*/
//! @{
#define AVR32_MACB_TX_LEN_OFFSET 0
#define AVR32_MACB_TX_LEN_SIZE 11
#define AVR32_MACB_TX_EOF_OFFSET 15
#define AVR32_MACB_TX_EOF_SIZE 1
#define AVR32_MACB_TX_NOCRC_OFFSET 16
#define AVR32_MACB_TX_NOCRC_SIZE 1
#define AVR32_MACB_TX_EMF_OFFSET 27
#define AVR32_MACB_TX_EMF_SIZE 1
#define AVR32_MACB_TX_UNR_OFFSET 28
#define AVR32_MACB_TX_UNR_SIZE 1
#define AVR32_MACB_TX_MAXRETRY_OFFSET 29
#define AVR32_MACB_TX_MAXRETRY_SIZE 1
#define AVR32_MACB_TX_WRAP_OFFSET 30
#define AVR32_MACB_TX_WRAP_SIZE 1
#define AVR32_MACB_TX_USED_OFFSET 31
#define AVR32_MACB_TX_USED_SIZE 1
//! @}
/*! \name Generic MII registers.
*/
//! @{
#define PHY_BMCR 0x00 //!< Basic mode control register
#define PHY_BMSR 0x01 //!< Basic mode status register
#define PHY_PHYSID1 0x02 //!< PHYS ID 1
#define PHY_PHYSID2 0x03 //!< PHYS ID 2
#define PHY_ADVERTISE 0x04 //!< Advertisement control reg
#define PHY_LPA 0x05 //!< Link partner ability reg
//! @}
#define PHY_RBR 0x17 //!< RMII Bypass reg
#define PHY_MICR 0x11 //!< Interrupt Control reg
#define PHY_MISR 0x12 //!< Interrupt Status reg
#define PHY_PHYCR 0x19 //!< Phy CTRL reg
/*! \name Basic mode control register.
*/
//! @{
#define BMCR_RESV 0x007f //!< Unused...
#define BMCR_CTST 0x0080 //!< Collision test
#define BMCR_FULLDPLX 0x0100 //!< Full duplex
#define BMCR_ANRESTART 0x0200 //!< Auto negotiation restart
#define BMCR_ISOLATE 0x0400 //!< Disconnect PHY from MII
#define BMCR_PDOWN 0x0800 //!< Powerdown the PHY
#define BMCR_ANENABLE 0x1000 //!< Enable auto negotiation
#define BMCR_SPEED100 0x2000 //!< Select 100Mbps
#define BMCR_LOOPBACK 0x4000 //!< TXD loopback bits
#define BMCR_RESET 0x8000 //!< Reset the PHY
//! @}
/*! \name Basic mode status register.
*/
//! @{
#define BMSR_ERCAP 0x0001 //!< Ext-reg capability
#define BMSR_JCD 0x0002 //!< Jabber detected
#define BMSR_LSTATUS 0x0004 //!< Link status
#define BMSR_ANEGCAPABLE 0x0008 //!< Able to do auto-negotiation
#define BMSR_RFAULT 0x0010 //!< Remote fault detected
#define BMSR_ANEGCOMPLETE 0x0020 //!< Auto-negotiation complete
#define BMSR_RESV 0x00c0 //!< Unused...
#define BMSR_ESTATEN 0x0100 //!< Extended Status in R15
#define BMSR_100FULL2 0x0200 //!< Can do 100BASE-T2 HDX
#define BMSR_100HALF2 0x0400 //!< Can do 100BASE-T2 FDX
#define BMSR_10HALF 0x0800 //!< Can do 10mbps, half-duplex
#define BMSR_10FULL 0x1000 //!< Can do 10mbps, full-duplex
#define BMSR_100HALF 0x2000 //!< Can do 100mbps, half-duplex
#define BMSR_100FULL 0x4000 //!< Can do 100mbps, full-duplex
#define BMSR_100BASE4 0x8000 //!< Can do 100mbps, 4k packets
//! @}
/*! \name Advertisement control register.
*/
//! @{
#define ADVERTISE_SLCT 0x001f //!< Selector bits
#define ADVERTISE_CSMA 0x0001 //!< Only selector supported
#define ADVERTISE_10HALF 0x0020 //!< Try for 10mbps half-duplex
#define ADVERTISE_1000XFULL 0x0020 //!< Try for 1000BASE-X full-duplex
#define ADVERTISE_10FULL 0x0040 //!< Try for 10mbps full-duplex
#define ADVERTISE_1000XHALF 0x0040 //!< Try for 1000BASE-X half-duplex
#define ADVERTISE_100HALF 0x0080 //!< Try for 100mbps half-duplex
#define ADVERTISE_1000XPAUSE 0x0080 //!< Try for 1000BASE-X pause
#define ADVERTISE_100FULL 0x0100 //!< Try for 100mbps full-duplex
#define ADVERTISE_1000XPSE_ASYM 0x0100 //!< Try for 1000BASE-X asym pause
#define ADVERTISE_100BASE4 0x0200 //!< Try for 100mbps 4k packets
#define ADVERTISE_PAUSE_CAP 0x0400 //!< Try for pause
#define ADVERTISE_PAUSE_ASYM 0x0800 //!< Try for asymetric pause
#define ADVERTISE_RESV 0x1000 //!< Unused...
#define ADVERTISE_RFAULT 0x2000 //!< Say we can detect faults
#define ADVERTISE_LPACK 0x4000 //!< Ack link partners response
#define ADVERTISE_NPAGE 0x8000 //!< Next page bit
//! @}
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | ADVERTISE_CSMA)
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
ADVERTISE_100HALF | ADVERTISE_100FULL)
/*! \name Link partner ability register.
*/
//! @{
#define LPA_SLCT 0x001f //!< Same as advertise selector
#define LPA_10HALF 0x0020 //!< Can do 10mbps half-duplex
#define LPA_1000XFULL 0x0020 //!< Can do 1000BASE-X full-duplex
#define LPA_10FULL 0x0040 //!< Can do 10mbps full-duplex
#define LPA_1000XHALF 0x0040 //!< Can do 1000BASE-X half-duplex
#define LPA_100HALF 0x0080 //!< Can do 100mbps half-duplex
#define LPA_1000XPAUSE 0x0080 //!< Can do 1000BASE-X pause
#define LPA_100FULL 0x0100 //!< Can do 100mbps full-duplex
#define LPA_1000XPAUSE_ASYM 0x0100 //!< Can do 1000BASE-X pause asym
#define LPA_100BASE4 0x0200 //!< Can do 100mbps 4k packets
#define LPA_PAUSE_CAP 0x0400 //!< Can pause
#define LPA_PAUSE_ASYM 0x0800 //!< Can pause asymetrically
#define LPA_RESV 0x1000 //!< Unused...
#define LPA_RFAULT 0x2000 //!< Link partner faulted
#define LPA_LPACK 0x4000 //!< Link partner acked us
#define LPA_NPAGE 0x8000 //!< Next page bit
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
//! @}
/*! RMII Bypass Register */
#define RBR_RMII 0x0020 //!< RMII Mode
/*! \name Interrupt Ctrl Register.
*/
//! @{
#define MICR_INTEN 0x0002 //!< Enable interrupts
#define MICR_INTOE 0x0001 //!< Enable INT output
//! @}
/*! \name Interrupt Status Register.
*/
//! @{
#define MISR_ED_INT_EN 0x0040 //!< Energy Detect enabled
#define MISR_LINK_INT_EN 0x0020 //!< Link status change enabled
#define MISR_SPD_INT_EN 0x0010 //!< Speed change enabled
#define MISR_DP_INT_EN 0x0008 //!< Duplex mode change enabled
#define MISR_ANC_INT_EN 0x0004 //!< Auto-Neg complete enabled
#define MISR_FHF_INT_EN 0x0002 //!< False Carrier enabled
#define MISR_RHF_INT_EN 0x0001 //!< Receive Error enabled
#define MISR_ED_INT 0x4000 //!< Energy Detect
#define MISR_LINK_INT 0x2000 //!< Link status change
#define MISR_SPD_INT 0x1000 //!< Speed change
#define MISR_DP_INT 0x0800 //!< Duplex mode change
#define MISR_ANC_INT 0x0400 //!< Auto-Neg complete
#define MISR_FHF_INT 0x0200 //!< False Carrier
#define MISR_RHF_INT 0x0100 //!< Receive Error
//! @}
/*! \name Phy Ctrl Register.
*/
//! @{
#define PHYCR_MDIX_EN 0x8000 //!< Enable Auto MDIX
#define PHYCR_MDIX_FORCE 0x4000 //!< Force MDIX crossed
//! @}
/* Size of each receive buffer - DO NOT CHANGE. */
#define RX_BUFFER_SIZE 128
/* The buffer addresses written into the descriptors must be aligned so the
last two bits are zero. These bits have special meaning for the MACB
peripheral and cannot be used as part of the address. */
#define ADDRESS_MASK ( ( unsigned long ) 0xFFFFFFFC )
/* Bit used within the address stored in the descriptor to mark the last
descriptor in the array. */
#define RX_WRAP_BIT ( ( unsigned long ) 0x02 )
/* A short delay is used to wait for a buffer to become available, should
one not be immediately available when trying to transmit a frame. */
#define BUFFER_WAIT_DELAY ( 2 )
/*! location of net config file on the file system */
#define ETHERNET_CONFIG_FILE "A:/CFG/net.txt"
/*! Phy Address (set through strap options) */
#define ETHERNET_CONF_PHY_ADDR 0x01
#define ETHERNET_CONF_PHY_ID 0x20005C90
/*! Number of receive buffers. Max ethernet frame size is 1526. A Rx buffer is
128 Bytes long. So 12 Rx buffers are necessary to store one max sized frame.
Multiply that by 2 for performance. */
#define ETHERNET_CONF_NB_RX_BUFFERS 24
/*! USE_RMII_INTERFACE must be defined as 1 to use an RMII interface, or 0
to use an MII interface. */
#define ETHERNET_CONF_USE_RMII_INTERFACE 1
/*! Number of Transmit buffers */
#define ETHERNET_CONF_NB_TX_BUFFERS 10
/*! Size of each Transmit buffer. */
#define ETHERNET_CONF_TX_BUFFER_SIZE 512
/*! Clock definition */
#define ETHERNET_CONF_SYSTEM_CLOCK 60000000
/*! Allow Auto Negociation */
#define ETHERNET_CONF_AN_ENABLE 1
/*! Use auto cross capability. Used by default. */
#define ETHERNET_CONF_AUTO_CROSS_ENABLE 1
/*! Use direct cable. Ignored when ETHERNET_CONF_AN_ENABLE and
ETHERNET_CONF_AUTO_CROSS_ENABLE are enabled. */
#define ETHERNET_CONF_CROSSED_LINK 0
/* ethernet default parameters */
/*! MAC address definition. The MAC address must be unique on the network. */
#define ETHERNET_CONF_ETHADDR0 0x00
#define ETHERNET_CONF_ETHADDR1 0x04
#define ETHERNET_CONF_ETHADDR2 0x25
#define ETHERNET_CONF_ETHADDR3 0x00
#define ETHERNET_CONF_ETHADDR4 0x01
#define ETHERNET_CONF_ETHADDR5 0x02
/*! set to 1 if Phy status changes handle an interrupt */
#define ETHERNET_CONF_USE_PHY_IT 0
/*! Packet structure.
*/
//! @{
typedef struct
{
unsigned char *data;
unsigned int len;
} macb_packet_t;
//! @}
/*! Receive Transfer descriptor structure.
*/
//! @{
typedef struct _AVR32_RxTdDescriptor {
unsigned int addr;
union
{
unsigned int status;
struct {
unsigned int BroadCast:1;
unsigned int MultiCast:1;
unsigned int UniCast:1;
unsigned int ExternalAdd:1;
unsigned int Res1:1;
unsigned int Sa1Match:1;
unsigned int Sa2Match:1;
unsigned int Sa3Match:1;
unsigned int Sa4Match:1;
unsigned int TypeID:1;
unsigned int VlanTag:1;
unsigned int PriorityTag:1;
unsigned int VlanPriority:3;
unsigned int Cfi:1;
unsigned int EndOfFrame:1;
unsigned int StartOfFrame:1;
unsigned int Rxbuf_off:2;
unsigned int Res0:1;
unsigned int Length:11;
}S_Status;
}U_Status;
}AVR32_RxTdDescriptor, *AVR32P_RxTdDescriptor;
//! @}
/*! Transmit Transfer descriptor structure.
*/
//! @{
typedef struct _AVR32_TxTdDescriptor {
unsigned int addr;
union
{
unsigned int status;
struct {
unsigned int BuffUsed:1;
unsigned int Wrap:1;
unsigned int TransmitError:1;
unsigned int TransmitUnderrun:1;
unsigned int BufExhausted:1;
unsigned int Res1:10;
unsigned int NoCrc:1;
unsigned int LastBuff:1;
unsigned int Res0:4;
unsigned int Length:11;
}S_Status;
}U_Status;
}AVR32_TxTdDescriptor, *AVR32P_TxTdDescriptor;
//! @}
/*! Mask for frame used. */
#define AVR32_OWNERSHIP_BIT 0x00000001
/*! Receive status defintion.
*/
//! @{
#define AVR32_BROADCAST_ADDR ((unsigned int) (1 << 31)) //* Broadcat address detected
#define AVR32_MULTICAST_HASH ((unsigned int) (1 << 30)) //* MultiCast hash match
#define AVR32_UNICAST_HASH ((unsigned int) (1 << 29)) //* UniCast hash match
#define AVR32_EXTERNAL_ADDR ((unsigned int) (1 << 28)) //* External Address match
#define AVR32_SA1_ADDR ((unsigned int) (1 << 26)) //* Specific address 1 match
#define AVR32_SA2_ADDR ((unsigned int) (1 << 25)) //* Specific address 2 match
#define AVR32_SA3_ADDR ((unsigned int) (1 << 24)) //* Specific address 3 match
#define AVR32_SA4_ADDR ((unsigned int) (1 << 23)) //* Specific address 4 match
#define AVR32_TYPE_ID ((unsigned int) (1 << 22)) //* Type ID match
#define AVR32_VLAN_TAG ((unsigned int) (1 << 21)) //* VLAN tag detected
#define AVR32_PRIORITY_TAG ((unsigned int) (1 << 20)) //* PRIORITY tag detected
#define AVR32_VLAN_PRIORITY ((unsigned int) (7 << 17)) //* PRIORITY Mask
#define AVR32_CFI_IND ((unsigned int) (1 << 16)) //* CFI indicator
#define AVR32_EOF ((unsigned int) (1 << 15)) //* EOF
#define AVR32_SOF ((unsigned int) (1 << 14)) //* SOF
#define AVR32_RBF_OFFSET ((unsigned int) (3 << 12)) //* Receive Buffer Offset Mask
#define AVR32_LENGTH_FRAME ((unsigned int) 0x0FFF) //* Length of frame
//! @}
/* Transmit Status definition */
//! @{
#define AVR32_TRANSMIT_OK ((unsigned int) (1 << 31)) //*
#define AVR32_TRANSMIT_WRAP ((unsigned int) (1 << 30)) //* Wrap bit: mark the last descriptor
#define AVR32_TRANSMIT_ERR ((unsigned int) (1 << 29)) //* RLE:transmit error
#define AVR32_TRANSMIT_UND ((unsigned int) (1 << 28)) //* Transmit Underrun
#define AVR32_BUF_EX ((unsigned int) (1 << 27)) //* Buffers exhausted in mid frame
#define AVR32_TRANSMIT_NO_CRC ((unsigned int) (1 << 16)) //* No CRC will be appended to the current frame
#define AVR32_LAST_BUFFER ((unsigned int) (1 << 15)) //*
//! @}
/**
* \brief Initialise the MACB driver.
*
* \param *macb Base address of the MACB
*
* \return TRUE if success, FALSE otherwise.
*/
extern Bool xMACBInit(volatile avr32_macb_t *macb);
/**
* \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
* MACB Tx buffers, then indicates to the MACB that the buffer is ready.
* If lEndOfFrame is true then the data being copied is the end of the frame
* and the frame can be transmitted.
*
* \param *macb Base address of the MACB
* \param *pvFrom Address of the data buffer
* \param ulLength Length of the frame
* \param lEndOfFrame Flag for End Of Frame
*
* \return length sent.
*/
extern long lMACBSend(volatile avr32_macb_t *macb, const void *pvFrom, unsigned long ulLength, long lEndOfFrame);
/**
* \brief Frames can be read from the MACB in multiple sections.
* Read ulSectionLength bytes from the MACB receive buffers to pcTo.
* ulTotalFrameLength is the size of the entire frame. Generally vMACBRead
* will be repetedly called until the sum of all the ulSectionLenths totals
* the value of ulTotalFrameLength.
*
* \param *pvTo Address of the buffer
* \param ulSectionLength Length of the buffer
* \param ulTotalFrameLength Length of the frame
*/
extern void vMACBRead(void *pvTo, unsigned long ulSectionLength, unsigned long ulTotalFrameLength);
/**
* \brief Flush the current received packet.
*
* \param ulTotalFrameLength Length of the packet to flush
*/
extern void vMACBFlushCurrentPacket(unsigned long ulTotalFrameLength);
/**
* \brief Called by the Tx interrupt, this function traverses the buffers used to
* hold the frame that has just completed transmission and marks each as
* free again.
*/
extern void vClearMACBTxBuffer(void);
/**
* \brief Suspend on a semaphore waiting either for the semaphore to be obtained
* or a timeout. The semaphore is used by the MACB ISR to indicate that
* data has been received and is ready for processing.
*
* \param ulTimeOut time to wait for an input
*
*/
extern void vMACBWaitForInput(unsigned long ulTimeOut);
/**
* \brief Function to get length of the next frame in the receive buffers
*
* \return the length of the next frame in the receive buffers.
*/
extern unsigned long ulMACBInputLength(void);
/**
* \brief Set the MACB Physical address (SA1B & SA1T registers).
*
* \param *MACAddress the MAC address to set.
*/
extern void vMACBSetMACAddress(const unsigned char *MACAddress);
/**
* \brief Disable MACB operations (Tx and Rx).
*
* \param *macb Base address of the MACB
*/
extern void vDisableMACBOperations(volatile avr32_macb_t *macb);
#endif

View File

@ -15,6 +15,17 @@
#include "platform_conf.h"
#include "common.h"
#include "buf.h"
#include "spi.h"
#ifdef BUILD_MMCFS
#include "diskio.h"
#endif
#ifdef BUILD_UIP
#include "ethernet.h"
#include "uip_arp.h"
#include "elua_uip.h"
#include "uip-conf.h"
#endif
// Platform-specific includes
#include <avr32/io.h>
@ -30,8 +41,21 @@
#include "adc.h"
#include "pwm.h"
// UIP sys tick data
// NOTE: when using virtual timers, SYSTICKHZ and VTMR_FREQ_HZ should have the
// same value, as they're served by the same timer (the systick)
#define SYSTICKHZ 4
#define SYSTICKMS (1000 / SYSTICKHZ)
#ifdef BUILD_UIP
static int eth_timer_fired;
#endif
// ****************************************************************************
// Platform initialization
#ifdef BUILD_UIP
u32 platform_ethernet_setup(void);
#endif
extern int pm_configure_clocks( pm_freq_param_t *param );
@ -51,7 +75,20 @@ __attribute__((__interrupt__)) static void tmr_int_handler()
tc_read_sr( tc, VTMR_CH );
cmn_virtual_timer_cb();
}
#ifdef BUILD_MMCFS
disk_timerproc();
#endif
#ifdef BUILD_UIP
// Indicate that a SysTick interrupt has occurred.
eth_timer_fired = 1;
// Generate a fake Ethernet interrupt. This will perform the actual work
// of incrementing the timers and taking the appropriate actions.
platform_eth_force_interrupt();
#endif
}
#endif
const u32 uart_base_addr[ ] = {
@ -188,6 +225,11 @@ int platform_init()
pwm_init();
#endif
#ifdef BUILD_UIP
platform_ethernet_setup();
#endif
#ifdef ELUA_BOARD_MIZAR32
// If BUF_ENABLE_UART is enabled on Mizar32 (which it is by default) but the
// serial board is not plugged in, we get an infinite number of interrupts
@ -814,7 +856,6 @@ int platform_adc_start_sequence( )
#endif
// ****************************************************************************
// PWM functions
@ -964,3 +1005,87 @@ u32 platform_pwm_op( unsigned id, int op, u32 data)
}
return 0;
}
// ****************************************************************************
// Network support
#ifdef BUILD_UIP
static const gpio_map_t MACB_GPIO_MAP =
{
{AVR32_MACB_MDC_0_PIN, AVR32_MACB_MDC_0_FUNCTION },
{AVR32_MACB_MDIO_0_PIN, AVR32_MACB_MDIO_0_FUNCTION },
{AVR32_MACB_RXD_0_PIN, AVR32_MACB_RXD_0_FUNCTION },
{AVR32_MACB_TXD_0_PIN, AVR32_MACB_TXD_0_FUNCTION },
{AVR32_MACB_RXD_1_PIN, AVR32_MACB_RXD_1_FUNCTION },
{AVR32_MACB_TXD_1_PIN, AVR32_MACB_TXD_1_FUNCTION },
{AVR32_MACB_TX_EN_0_PIN, AVR32_MACB_TX_EN_0_FUNCTION },
{AVR32_MACB_RX_ER_0_PIN, AVR32_MACB_RX_ER_0_FUNCTION },
{AVR32_MACB_RX_DV_0_PIN, AVR32_MACB_RX_DV_0_FUNCTION },
{AVR32_MACB_TX_CLK_0_PIN, AVR32_MACB_TX_CLK_0_FUNCTION}
};
u32 platform_ethernet_setup()
{
static struct uip_eth_addr sTempAddr;
// Assign GPIO to MACB
gpio_enable_module(MACB_GPIO_MAP, sizeof(MACB_GPIO_MAP) / sizeof(MACB_GPIO_MAP[0]));
// initialize MACB & Phy Layers
if (xMACBInit(&AVR32_MACB) == FALSE ) {
return PLATFORM_ERR;
}
sTempAddr.addr[0] = ETHERNET_CONF_ETHADDR0;
sTempAddr.addr[1] = ETHERNET_CONF_ETHADDR1;
sTempAddr.addr[2] = ETHERNET_CONF_ETHADDR2;
sTempAddr.addr[3] = ETHERNET_CONF_ETHADDR3;
sTempAddr.addr[4] = ETHERNET_CONF_ETHADDR4;
sTempAddr.addr[5] = ETHERNET_CONF_ETHADDR5;
// Initialize the eLua uIP layer
elua_uip_init( &sTempAddr );
return PLATFORM_OK;
}
void platform_eth_send_packet( const void* src, u32 size )
{
lMACBSend(&AVR32_MACB,src, size, TRUE);
}
u32 platform_eth_get_packet_nb( void* buf, u32 maxlen )
{
u32 len;
/* Obtain the size of the packet. */
len = ulMACBInputLength();
if (len > maxlen) {
return 0;
}
if( len ) {
/* Let the driver know we are going to read a new packet. */
vMACBRead( NULL, 0, len );
vMACBRead( buf, len, len );
}
return len;
}
void platform_eth_force_interrupt()
{
elua_uip_mainloop();
}
u32 platform_eth_get_elapsed_time()
{
if( eth_timer_fired )
{
eth_timer_fired = 0;
return SYSTICKMS;
}
else
return 0;
}
#endif

View File

@ -0,0 +1,137 @@
//*****************************************************************************
//
// uip-conf.h - uIP Project Specific Configuration File
//
//*****************************************************************************
#ifndef __UIP_AVR32_CONF_H__
#define __UIP_AVR32_CONF_H__
#include "platform_conf.h"
//
// 8 bit datatype
// This typedef defines the 8-bit type used throughout uIP.
//
typedef unsigned char u8_t;
//
// 16 bit datatype
// This typedef defines the 16-bit type used throughout uIP.
//
typedef unsigned short u16_t;
//
// Statistics datatype
// This typedef defines the dataype used for keeping statistics in
// uIP.
//
typedef unsigned short uip_stats_t;
//
// Ping IP address assignment
// Use first incoming "ping" packet to derive host IP address
//
#define UIP_CONF_PINGADDRCONF 0
//
// TCP support on or off
//
#define UIP_CONF_TCP 1
//
// UDP support on or off
//
#define UIP_CONF_UDP 1
//
// UDP checksums on or off
// (not currently supported ... should be 0)
//
#define UIP_CONF_UDP_CHECKSUMS 1
//
// UDP Maximum Connections
//
#define UIP_CONF_UDP_CONNS 4
//
// Maximum number of TCP connections.
//
#define UIP_CONF_MAX_CONNECTIONS 4
//
// Maximum number of listening TCP ports.
//
#define UIP_CONF_MAX_LISTENPORTS 4
//
// Size of advertised receiver's window
//
//#define UIP_CONF_RECEIVE_WINDOW 400
//
// Size of ARP table
//
#define UIP_CONF_ARPTAB_SIZE 4
//
// uIP buffer size.
//
#define UIP_CONF_BUFFER_SIZE 1024
//
// uIP statistics on or off
//
#define UIP_CONF_STATISTICS 0
//
// Logging on or off
//
#define UIP_CONF_LOGGING 0
//
// Broadcast Support
//
#define UIP_CONF_BROADCAST 1
//
// Link-Level Header length
//
#define UIP_CONF_LLH_LEN 14
//
// CPU byte order.
//
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
//
// Here we include the header file for the application we are using in
// this example
#include "elua_uip.h"
#include "dhcpc.h"
//
// Define the uIP Application State type (both TCP and UDP)
//
typedef struct elua_uip_state uip_tcp_appstate_t;
typedef struct dhcpc_state uip_udp_appstate_t;
//
// UIP_APPCALL: the name of the application function. This function
// must return void and take no arguments (i.e., C type "void
// appfunc(void)").
//
#ifndef UIP_APPCALL
#define UIP_APPCALL elua_uip_appcall
#endif
#ifndef UIP_ADP_APPCALL
#define UIP_UDP_APPCALL elua_uip_udp_appcall
#endif
// Added for eLua: DHCP TIMER ID
#define ELUA_DHCP_TIMER_ID 1
#define CLOCK_SECOND 1000000UL
#endif // __UIP_CONF_H_

View File

@ -16,7 +16,7 @@
#define BUILD_CON_GENERIC
#define BUILD_ADC
#define BUILD_SEMIFS
#define BUILD_LUARPC
#define BUILD_RPC
// *****************************************************************************
// UART/Timer IDs configuration data (used in main.c)
@ -36,6 +36,13 @@
#define ADCLINE
#endif
// RPC
#if defined( BUILD_RPC )
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
#else
#define RPCLINE
#endif
// The name of the platform specific libs table
#define PS_LIB_TABLE_NAME "mbed"
@ -50,6 +57,7 @@
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
RPCLINE\
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
_ROM( PS_LIB_TABLE_NAME, luaopen_platform, platform_map )

466
src/platform/str9/91x_ssp.c Normal file
View File

@ -0,0 +1,466 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : 91x_ssp.c
* Author : MCD Application Team
* Version : V2.1
* Date : 12/22/2008
* Description : This file provides all the SSP firmware functions.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "91x_ssp.h"
#include "91x_scu.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* SSP peripheral Enable */
#define SSP_Enable 0x0002
#define SSP_Disable 0xFFFD
/* SSP Loop Back Mode Enable */
#define SSP_LoopBackMode_Enable 0x0001
#define SSP_LoopBackMode_Disable 0xFFFE
/* SSP Flag Mask */
#define SSP_Flag_Mask 0x001F
/* SSP DMA transmit/ receive enable/disable Masks */
#define SSP_DMA_TransmitEnable 0x0002
#define SSP_DMA_TransmitDisable 0xFFFD
#define SSP_DMA_ReceiveEnable 0x0001
#define SSP_DMA_ReceiveDisable 0xFFFE
/* SSP Masks */
#define SSP_FrameFormat_Mask 0xFFCF
#define SSP_DataSize_Mask 0xFFF0
#define SSP_ClockRate_Mask 0x00FF
#define SSP_ClockPrescaler_Mask 0xFF00
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : SSP_DeInit
* Description : Deinitializes the SSPx peripheral registers to their default
* reset values.
* Input : SSPx: where x can be 0 or 1 to select the SSP peripheral.
* Output : None
* Return : None
*******************************************************************************/
void SSP_DeInit(SSP_TypeDef* SSPx)
{
if(SSPx == SSP0)
{
/* Reset the SSP0 registers values*/
SCU_APBPeriphReset(__SSP0,ENABLE);
SCU_APBPeriphReset(__SSP0,DISABLE);
}
else if (SSPx == SSP1)
{
/* Reset the SSP1 registers values*/
SCU_APBPeriphReset(__SSP1,ENABLE);
SCU_APBPeriphReset(__SSP1,DISABLE);
}
}
/*******************************************************************************
* Function Name : SSP_Init
* Description : Initializes the SSPx peripheral according to the specified
* parameters in the SSP_InitTypeDef structure.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_InitStruct: pointer to a SSP_InitTypeDef structure that
* contains the configuration information for the specified SSP
* peripheral.
* Output : None
* Return : None
*******************************************************************************/
void SSP_Init(SSP_TypeDef* SSPx, SSP_InitTypeDef* SSP_InitStruct)
{
if(SSP_InitStruct->SSP_FrameFormat == SSP_FrameFormat_Motorola)
{
/* Set the Motorola frame format */
SSPx->CR0 &= SSP_FrameFormat_Motorola;
/* Configure the Clock polarity */
if(SSP_InitStruct->SSP_CPOL == SSP_CPOL_High)
{
/* SCK is held high when no data is being transfered */
SSPx->CR0 |= SSP_CPOL_High;
}
else
{
/* SCK is held low when no data is being transfered */
SSPx->CR0 &= SSP_CPOL_Low;
}
/* Configure the Clock Phase */
if(SSP_InitStruct->SSP_CPHA == SSP_CPHA_2Edge)
{
/* Data captured on second clock edge */
SSPx->CR0 |= SSP_CPHA_2Edge;
}
else
{
/* Data captured on first clock edge */
SSPx->CR0 &= SSP_CPHA_1Edge;
}
}
/* Configure the Frame format */
else
{
/* Clear the FRF[1:0] bits */
SSPx->CR0 &= SSP_FrameFormat_Mask;
/* Set the TI frame format */
SSPx->CR0 |= SSP_InitStruct->SSP_FrameFormat;
}
/* Configure the Mode */
if(SSP_InitStruct->SSP_Mode == SSP_Mode_Slave)
{
/* Set the slave mode */
SSPx->CR1 |= SSP_Mode_Slave;
/* Configure the Slave output */
if(SSP_InitStruct->SSP_SlaveOutput == SSP_SlaveOutput_Disable)
{
/* Slave output disabled */
SSPx->CR1 |= SSP_SlaveOutput_Disable;
}
else
{
/* Slave output enabled */
SSPx->CR1 &= SSP_SlaveOutput_Enable;
}
}
else
{
/* Set the master mode */
SSPx->CR1 &= SSP_Mode_Master;
/* Clear clock rate SCR[7:0] bits */
SSPx->CR0 &= SSP_ClockRate_Mask;
/* Set the serial clock rate */
SSPx->CR0 |= (SSP_InitStruct->SSP_ClockRate<<8);
/* Clear clock prescaler CPSDVSR[7:0] bits */
SSPx->PR &= SSP_ClockPrescaler_Mask;
/* Set the serial clock prescaler */
SSPx->PR |= SSP_InitStruct->SSP_ClockPrescaler;
}
/* Clear data size DSS[3:0] bits */
SSPx->CR0 &= SSP_DataSize_Mask;
/* Set the data size */
SSPx->CR0 |= SSP_InitStruct->SSP_DataSize;
}
/*******************************************************************************
* Function Name : SSP_StructInit
* Description : Fills in a SSP_InitTypeDef structure with the reset value of
* each parameter.
* Input : SSP_InitStruct : pointer to a SSP_InitTypeDef structure
which will be initialized.
* Output : None
* Return : None
*******************************************************************************/
void SSP_StructInit(SSP_InitTypeDef* SSP_InitStruct)
{
/* Initialize the SSP_FrameFormat member */
SSP_InitStruct->SSP_FrameFormat = SSP_FrameFormat_Motorola;
/* Initialize the SSP_Mode member */
SSP_InitStruct->SSP_Mode = SSP_Mode_Master;
/* Initialize the SSP_CPOL member */
SSP_InitStruct->SSP_CPOL = SSP_CPOL_Low;
/* Initialize the SSP_CPHA member */
SSP_InitStruct->SSP_CPHA = SSP_CPHA_1Edge;
/* Initialize the SSP_DataSize member */
SSP_InitStruct->SSP_DataSize = SSP_DataSize_8b;
/* Initialize the SSP_SlaveOutput member */
SSP_InitStruct->SSP_SlaveOutput = SSP_SlaveOutput_Enable;
/* Initialize the SSP_ClockRate member */
SSP_InitStruct->SSP_ClockRate = 0;
/* Initialize the SSP_ClockPrescaler member */
SSP_InitStruct->SSP_ClockPrescaler = 0;
}
/*******************************************************************************
* Function Name : SSP_Cmd
* Description : Enables or disables the specified SSP peripheral.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - NewState: new state of the SSPx peripheral. This parameter
* can be: ENABLE or DISABLE.
* Output : None
* Return : None
*******************************************************************************/
void SSP_Cmd(SSP_TypeDef* SSPx, FunctionalState NewState)
{
if(NewState == ENABLE)
{
/* Enable the SSP peripheral */
SSPx->CR1 |= SSP_Enable;
}
else
{
/* Disable the SSP peripheral */
SSPx->CR1 &= SSP_Disable;
}
}
/*******************************************************************************
* Function Name : SSP_ITConfig
* Description : Enables or disables the specified SSP interrupts.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_IT: specifies the SSP interrupts sources to be enabled
* or disabled. This parameter can be any combination of the
* following values:
* - SSP_IT_TxFifo: Transmit FIFO half empty or less interrupt
* - SSP_IT_RxFifo: Receive FIFO half full or less interrupt
* - SSP_IT_RxTimeOut: Receive timeout interrupt
* - SSP_IT_RxOverrun: Receive overrun interrupt
* - NewState: new state of the specified SSP interrupts.
* This parameter can be: ENABLE or DISABLE.
* Output : None
* Return : None
*******************************************************************************/
void SSP_ITConfig(SSP_TypeDef* SSPx, u16 SSP_IT, FunctionalState NewState)
{
if(NewState == ENABLE)
{
/* Enable the selected SSP interrupts */
SSPx->IMSCR |= SSP_IT;
}
else
{
/* Disable the selected SSP interrupts */
SSPx->IMSCR &= ~SSP_IT;
}
}
/*******************************************************************************
* Function Name : SSP_DMACmd
* Description : Configures the SSP0 DMA interface.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_DMATransfert : specifies the DMA transfert to be
* enabled or disabled. This parameter can be one of the
* following values:
* - SSP_DMA_Transmit: transmit Fifo DMA transfert
* - SSP_DMA_Receive : receive Fifo DMA transfert
* - NewState: new state of the DMA transfert.
* This parameter can be: ENABLE or DISABLE.
* Output : None
* Return : None
*******************************************************************************/
void SSP_DMACmd(SSP_TypeDef* SSPx, u16 SSP_DMATransfert, FunctionalState NewState)
{
if(NewState == ENABLE)
{
if(SSP_DMATransfert == SSP_DMA_Transmit)
{
/* Enable DMA for the transmit FIFO */
SSPx->DMACR |= SSP_DMA_TransmitEnable;
}
else
{
/* Enable DMA for the receive FIFO */
SSPx->DMACR |= SSP_DMA_ReceiveEnable;
}
}
else
{
if(SSP_DMATransfert == SSP_DMA_Transmit)
{
/* Disable DMA for the transmit FIFO */
SSPx->DMACR &= SSP_DMA_TransmitDisable;
}
else
{
/* Disable DMA for the receive FIFO */
SSPx->DMACR &= SSP_DMA_ReceiveDisable;
}
}
}
/*******************************************************************************
* Function Name : SSP_SendData.
* Description : Transmits a Data through the SSP peripheral.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - Data : Data to be transmitted.
* Output : None
* Return : None
*******************************************************************************/
void SSP_SendData(SSP_TypeDef* SSPx, u16 Data)
{
/* Write in the DR register the data to be sent */
SSPx->DR = Data;
}
/*******************************************************************************
* Function Name : SSP_ReceiveData.
* Description : Returns the most recent received data by the SSP peripheral.
* Input : SSPx: where x can be 0 or 1 to select the SSP peripheral.
* Output : None
* Return : The value of the received data.
*******************************************************************************/
u16 SSP_ReceiveData(SSP_TypeDef* SSPx)
{
/* Return the data in the DR register */
return SSPx->DR;
}
/*******************************************************************************
* Function Name : SSP_LoopBackConfig
* Description : Enable or disable the Loop back mode for the selected SSPx peripheral.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - NewState: new state of the Loop Back mode.
* This parameter can be: ENABLE or DISABLE.
* Output : None
* Return : None.
*******************************************************************************/
void SSP_LoopBackConfig(SSP_TypeDef* SSPx, FunctionalState NewState)
{
if(NewState == ENABLE)
{
/* Enable loop back mode */
SSPx->CR1 |= SSP_LoopBackMode_Enable;
}
else
{
/* Disable loop back mode */
SSPx->CR1 &= SSP_LoopBackMode_Disable;
}
}
/*******************************************************************************
* Function Name : SSP_GetFlagStatus
* Description : Checks whether the specified SSP flag is set or not.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_FLAG: flag to check. This parameter can be one of the
* following values:
* - SSP_FLAG_Busy: busy flag
* - SSP_FLAG_RxFifoFull: Receive FIFO full flag
* - SSP_FLAG_RxFifoNotEmpty: Receive FIFO not empty flag
* - SSP_FLAG_TxFifoNotFull: Transmit FIFO not full flag
* - SSP_FLAG_TxFifoEmpty: Transmit FIFO empty flag
* - SSP_FLAG_TxFifo: Transmit FIFO half empty or less flag
* - SSP_FLAG_RxFifo: Receive FIFO half full or less flag
* - SSP_FLAG_RxTimeOut: Receive timeout flag
* - SSP_FLAG_RxOverrun: Receive overrun flag
* Output : None
* Return : The new state of SSP_Flag (SET or RESET).
*******************************************************************************/
FlagStatus SSP_GetFlagStatus(SSP_TypeDef* SSPx, u16 SSP_FLAG)
{
u32 SSPReg = 0, FlagPos = 0;
u32 StatusReg = 0;
/* Get the SSP register index */
SSPReg = SSP_FLAG >> 5;
/* Get the flag position */
FlagPos = SSP_FLAG & SSP_Flag_Mask;
/* Find the register of the flag to check */
if(SSPReg == 1)
{
/* The flag to check is in SR register */
StatusReg = SSPx->SR;
}
else if (SSPReg == 2)
{
/* The flag to check is in RISR register */
StatusReg = SSPx->RISR;
}
/* Check the status of the specified SSP flag */
if((StatusReg & (1 << FlagPos)) != RESET)
{
/* Return SET if the SSP flag is set */
return SET;
}
else
{
/* Return RESET if the SSP flag is reset */
return RESET;
}
}
/*******************************************************************************
* Function Name : SSP_ClearFlag
* Description : Clears the SSPx flags.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_FLAG: flags to clear. This parameter one of the
* following values:
* - SSP_FLAG_RxTimeOut: Receive timeout flag
* - SSP_FLAG_RxOverrun: Receive overrun flag
* Output : None
* Return : None
*******************************************************************************/
void SSP_ClearFlag(SSP_TypeDef* SSPx, u16 SSP_FLAG)
{
u8 FlagPos = 0;
/* Get the flag position */
FlagPos = SSP_FLAG & SSP_Flag_Mask;
/* Clear the selected SSP flag */
SSPx->ICR = (1 << FlagPos);
}
/*******************************************************************************
* Function Name : SSP_GetITStatus
* Description : Checks whether the specified SSP interrupt flag is set or not.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_IT: interrupt flag to check. This parameter can be one
* of the following values:
* - SSP_IT_TxFifo: Transmit FIFO half empty or less interrupt
* - SSP_IT_RxFifo: Receive FIFO half full or less interrupt
* - SSP_IT_RxTimeOut: Receive timeout interrupt
* - SSP_IT_RxOverrun: Receive overrun interrupt
* Output : None
* Return : The new state of SSP_IT flag (SET or RESET).
*******************************************************************************/
ITStatus SSP_GetITStatus(SSP_TypeDef* SSPx, u16 SSP_IT)
{
/* Check the status of the specified interrupt flag */
if((SSPx->MISR & SSP_IT) != RESET)
{
/* Return SET if the SSP interrupt flag is set */
return SET;
}
else
{
/* Return RESET if SSP interrupt flag is reset */
return RESET;
}
}
/*******************************************************************************
* Function Name : SSP_ClearITPendingBit
* Description : Clears the pending interrupt flags.
* Input : - SSPx: where x can be 0 or 1 to select the SSP peripheral.
* - SSP_IT: interrupts pending bits to clear. This parameter
* can be any combination of the following values:
* - SSP_IT_RxTimeOut: Receive timeout interrupt
* - SSP_IT_RxOverrun: Receive overrun interrupt
* Output : None
* Return : None
*******************************************************************************/
void SSP_ClearITPendingBit(SSP_TypeDef* SSPx, u16 SSP_IT)
{
/* Clear the selected SSP interrupts pending bits */
SSPx->ICR = SSP_IT;
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

116
src/platform/str9/91x_ssp.h Normal file
View File

@ -0,0 +1,116 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : 91x_ssp.h
* Author : MCD Application Team
* Version : V2.1
* Date : 12/22/2008
* Description : This file contains all the functions prototypes for the
* SSP firmware library.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __91x_SSP_H
#define __91x_SSP_H
/* Includes ------------------------------------------------------------------*/
#include "91x_map.h"
/* Exported types ------------------------------------------------------------*/
/* SSP Init structure definition */
typedef struct
{
u16 SSP_FrameFormat ;
u16 SSP_Mode ;
u16 SSP_CPOL ;
u16 SSP_CPHA ;
u16 SSP_DataSize ;
u16 SSP_SlaveOutput ;
u8 SSP_ClockRate ;
u8 SSP_ClockPrescaler ;
}SSP_InitTypeDef;
/* Exported constants --------------------------------------------------------*/
/* SSP Frame Format Select */
#define SSP_FrameFormat_TI 0x0010
#define SSP_FrameFormat_Motorola 0xFFCF
#define SSP_FrameFormat_Microwire 0x0020
/* SSP Master/Slave Select */
#define SSP_Mode_Master 0xFFFB
#define SSP_Mode_Slave 0x0004
/* SSP Clock Polarity */
#define SSP_CPOL_Low 0xFFBF
#define SSP_CPOL_High 0x0040
/* SSP Clock Phase */
#define SSP_CPHA_1Edge 0xFF7F
#define SSP_CPHA_2Edge 0x0080
/* SSP Data Size */
#define SSP_DataSize_16b 0x000F
#define SSP_DataSize_15b 0x000E
#define SSP_DataSize_14b 0x000D
#define SSP_DataSize_13b 0x000C
#define SSP_DataSize_12b 0x000B
#define SSP_DataSize_11b 0x000A
#define SSP_DataSize_10b 0x0009
#define SSP_DataSize_9b 0x0008
#define SSP_DataSize_8b 0x0007
#define SSP_DataSize_7b 0x0006
#define SSP_DataSize_6b 0x0005
#define SSP_DataSize_5b 0x0004
#define SSP_DataSize_4b 0x0003
/* SSP Slave output config */
#define SSP_SlaveOutput_Enable 0xFFF7
#define SSP_SlaveOutput_Disable 0x0008
/* SSP Interrupts */
#define SSP_IT_TxFifo 0x0008
#define SSP_IT_RxFifo 0x0004
#define SSP_IT_RxTimeOut 0x0002
#define SSP_IT_RxOverrun 0x0001
/* SSP Flags */
#define SSP_FLAG_Busy 0x0024
#define SSP_FLAG_RxFifoFull 0x0023
#define SSP_FLAG_RxFifoNotEmpty 0x0022
#define SSP_FLAG_TxFifoNotFull 0x0021
#define SSP_FLAG_TxFifoEmpty 0x0020
#define SSP_FLAG_TxFifo 0x0043
#define SSP_FLAG_RxFifo 0x0042
#define SSP_FLAG_RxTimeOut 0x0041
#define SSP_FLAG_RxOverrun 0x0040
/* SSP DMA Requests */
#define SSP_DMA_Transmit 0x0002
#define SSP_DMA_Receive 0x0001
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void SSP_DeInit(SSP_TypeDef* SSPx);
void SSP_Init(SSP_TypeDef* SSPx, SSP_InitTypeDef* SSP_InitStruct);
void SSP_StructInit(SSP_InitTypeDef* SSP_InitStruct);
void SSP_Cmd(SSP_TypeDef* SSPx, FunctionalState NewState);
void SSP_ITConfig(SSP_TypeDef* SSPx, u16 SSP_IT, FunctionalState NewState);
void SSP_DMACmd(SSP_TypeDef* SSPx, u16 SSP_DMATransfert, FunctionalState NewState);
void SSP_SendData(SSP_TypeDef* SSPx, u16 Data);
u16 SSP_ReceiveData(SSP_TypeDef* SSPx);
void SSP_LoopBackConfig(SSP_TypeDef* SSPx, FunctionalState NewState);
FlagStatus SSP_GetFlagStatus(SSP_TypeDef* SSPx, u16 SSP_FLAG);
void SSP_ClearFlag(SSP_TypeDef* SSPx, u16 SSP_FLAG);
ITStatus SSP_GetITStatus(SSP_TypeDef* SSPx, u16 SSP_IT);
void SSP_ClearITPendingBit(SSP_TypeDef* SSPx, u16 SSP_IT);
#endif /* __91x_SSP_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -2,7 +2,7 @@
local cpumode = ( builder:get_option( 'cpumode' ) or '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 str9_pio.c 91x_i2c.c 91x_wiu.c 91x_adc.c platform_int.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 91x_i2c.c 91x_wiu.c 91x_adc.c platform_int.c 91x_ssp.c"
local ldscript = "str912fw44.lds"

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 str9_pio.c 91x_i2c.c 91x_wiu.c 91x_adc.c platform_int.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 91x_i2c.c 91x_wiu.c 91x_adc.c platform_int.c 91x_ssp.c"
# Check CPU
if comp[ 'cpu' ] == 'STR912FAW44':

View File

@ -24,6 +24,8 @@
#include "buf.h"
#include "elua_adc.h"
#include "91x_adc.h"
#include "91x_ssp.h"
#include "utils.h"
// ****************************************************************************
// Platform initialization
@ -51,6 +53,8 @@ static void platform_config_scu()
SCU_PCLKDivisorConfig(SCU_PCLK_Div2);
/* Set the HCLK Clock to MCLK */
SCU_HCLKDivisorConfig(SCU_HCLK_Div1);
/* Set the BRCLK Clock to MCLK */
SCU_BRCLKDivisorConfig(SCU_BRCLK_Div1);
// Enable VIC clock
SCU_AHBPeriphClockConfig(__VIC, ENABLE);
@ -80,6 +84,12 @@ static void platform_config_scu()
// Enable the ADC clocks
SCU_APBPeriphClockConfig(__ADC, ENABLE);
// Enable the SSP clocks
SCU_APBPeriphClockConfig(__SSP0,ENABLE);
SCU_APBPeriphReset(__SSP0,DISABLE);
SCU_APBPeriphClockConfig(__SSP1,ENABLE);
SCU_APBPeriphReset(__SSP1,DISABLE);
}
// Port/pin definitions of the eLua UART connection for different boards
@ -142,12 +152,13 @@ int platform_init()
TIM_CounterCmd( base, TIM_START );
}
cmn_platform_init();
#ifdef BUILD_ADC
// Setup ADCs
platform_setup_adcs();
#endif
cmn_platform_init();
#ifdef VTMR_TIMER_ID
platform_s_timer_set_match_int( VTMR_TIMER_ID, 1000000 / VTMR_FREQ_HZ, PLATFORM_TIMER_INT_CYCLIC );
#endif
@ -785,6 +796,99 @@ int platform_i2c_recv_byte( unsigned id, int ack )
return I2C_ReceiveData( pi2c );
}
// ****************************************************************************
// SPI
#define SPI_MAX_PRESCALER ( 254 * 256 )
#define SPI_MIN_PRESCALER 2
u32 platform_spi_setup( unsigned id, int mode, u32 clock, unsigned cpol, unsigned cpha, unsigned databits )
{
const u32 basefreq = CPU_FREQUENCY;
u32 prescaler, divider = 1, temp, mindiff = 0xFFFFFFFF, minp;
GPIO_InitTypeDef GPIO_InitStructure;
SSP_InitTypeDef SSP_InitStructure;
clock = UMIN( clock, basefreq >> 1 );
prescaler = UMIN( basefreq / clock, SPI_MAX_PRESCALER );
if( basefreq / prescaler > clock )
prescaler ++;
if( prescaler & 1 )
prescaler ++;
if( prescaler > 254 )
{
temp = prescaler;
for( prescaler = minp = 2; prescaler <= 254; prescaler += 2 )
{
divider = temp / prescaler;
if( divider <= 255 )
{
if( ABSDIFF( divider * prescaler, temp ) < mindiff )
{
mindiff = ABSDIFF( divider * prescaler, temp );
minp = prescaler;
if( mindiff == 0 )
break;
}
}
}
prescaler = minp;
divider = temp / prescaler;
}
// GPIO setup
// Fixed assignment:
// P5.4 - SCLK
// P5.5 - MOSI
// P5.6 - MISO
// P5.7 - CS (not explicitly handled by the SPI module)
GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2 ;
GPIO_Init(GPIO5, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Enable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1 ;
GPIO_Init(GPIO5, &GPIO_InitStructure);
// Actual SPI setup
SSP_DeInit(SSP0);
SSP_InitStructure.SSP_FrameFormat = SSP_FrameFormat_Motorola;
SSP_InitStructure.SSP_Mode = SSP_Mode_Master;
SSP_InitStructure.SSP_CPOL = cpol == 0 ? SSP_CPOL_Low : SSP_CPOL_High;
SSP_InitStructure.SSP_CPHA = cpha == 0 ? SSP_CPHA_1Edge : SSP_CPHA_2Edge;
SSP_InitStructure.SSP_DataSize = databits - 1;
SSP_InitStructure.SSP_ClockRate = divider - 1;
SSP_InitStructure.SSP_ClockPrescaler = prescaler;
SSP_Init(SSP0, &SSP_InitStructure);
// Enable peripheral
SSP_Cmd(SSP0, ENABLE);
// All done
return basefreq / ( prescaler * divider );
}
spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
{
// Send byte through the SSP0 peripheral
SSP0->DR = data;
// Loop while Transmit FIFO is full
while(SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoEmpty) == RESET);
// Loop while Receive FIFO is empty
while(SSP_GetFlagStatus(SSP0, SSP_FLAG_RxFifoNotEmpty) == RESET);
// Return the byte read from the SSP bus
return SSP0->DR;
}
void platform_spi_select( unsigned id, int is_select )
{
id = id;
is_select = is_select;
}
// ****************************************************************************
// Platform specific modules go here
@ -811,7 +915,6 @@ LUALIB_API int luaopen_platform( lua_State *L )
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

@ -46,7 +46,7 @@
// Number of resources (0 if not available/not implemented)
#define NUM_PIO 10
#define NUM_SPI 0
#define NUM_SPI 1
#define NUM_UART 3
#define NUM_PWM 4
#define NUM_ADC 8
@ -130,6 +130,8 @@ u32 SCU_GetMCLKFreqValue();
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map)\
_ROM( AUXLIB_CPU, luaopen_elua, elua_map)\
_ROM( AUXLIB_I2C, luaopen_i2c, i2c_map)\
_ROM( AUXLIB_SPI, luaopen_spi, spi_map)\
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map)\
RPCLINE\
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map)\
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\

View File

@ -135,8 +135,6 @@ DAbt_Handler: B DAbt_Handler
IRQ_Handler: B ASM_IRQ_Handler /* should never get here as IRQ is via VIC slot... */
FIQ_Handler: B FIQ_Handler
.text
# Generic IRQ handler
ASM_IRQ_Handler:
sub lr, lr ,#4