mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
Merge branch 'master' into newsite
This commit is contained in:
commit
28d44765c3
@ -1,12 +1,15 @@
|
|||||||
eLua - Lua for microcontrollers
|
eLua - Lua for microcontrollers
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
*eLua* stands for *Embedded Lua* and the project aims to offer the full
|
*eLua* stands for *Embedded Lua* and the project aims to offer the
|
||||||
implementation of the http://www.lua.org[Lua Programming Language] to the
|
full implementation of the http://www.lua.org[Lua Programming
|
||||||
embedded world, extending it with specific features for efficient and portable
|
Language] to the embedded world, extending it with specific features
|
||||||
software embedded development. For more details please visit the link:http://www.eluaproject.net[project page].
|
for efficient and portable software embedded development. For more
|
||||||
|
details please visit the link:http://www.eluaproject.net[project
|
||||||
|
page].
|
||||||
|
|
||||||
If you've just downloaded *eLua* and are looking to get started check out link:http://www.eluaproject.net/en_using.html[using eLua].
|
If you've just downloaded *eLua* and are looking to get started check
|
||||||
|
out link:http://www.eluaproject.net/en_using.html[using eLua].
|
||||||
|
|
||||||
|
|
||||||
General Features
|
General Features
|
||||||
@ -63,6 +66,19 @@ Some aspects of eLua are:
|
|||||||
For more information about the functionality (implemented and planned) in eLua
|
For more information about the functionality (implemented and planned) in eLua
|
||||||
check link:http://www.eluaproject.net/en_status.html[our status page].
|
check link:http://www.eluaproject.net/en_status.html[our status page].
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Online documentation can be found on the web for the most recent
|
||||||
|
release version and development versions in the
|
||||||
|
link:http://www.eluaproject.net/get-better[get better] section of the
|
||||||
|
project website.
|
||||||
|
|
||||||
|
Project documentation can be generated for the version of the project
|
||||||
|
associated with this document by following the instructions in the
|
||||||
|
README.TXT file in the doc directory.
|
||||||
|
|
||||||
|
|
||||||
Contacts
|
Contacts
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ board_list = { 'SAM7-EX256' : [ 'AT91SAM7X256', 'AT91SAM7X512' ],
|
|||||||
'EAGLE-100' : [ 'LM3S6918' ],
|
'EAGLE-100' : [ 'LM3S6918' ],
|
||||||
'ELUA-PUC' : ['LPC2468' ],
|
'ELUA-PUC' : ['LPC2468' ],
|
||||||
'MBED' : ['LPC1768'],
|
'MBED' : ['LPC1768'],
|
||||||
'MIZAR32' : [ 'AT32UC3A0128', 'AT32UC3A0256', 'AT32UC3A0512', ],
|
'MIZAR32' : [ 'AT32UC3A0256', 'AT32UC3A0512', 'AT32UC3A0128' ],
|
||||||
'NETDUINO' : [ 'AT91SAM7X512' ],
|
'NETDUINO' : [ 'AT91SAM7X512' ],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +269,9 @@ if not GetOption( 'help' ):
|
|||||||
|
|
||||||
# CPU/allocator mapping (if allocator not specified)
|
# CPU/allocator mapping (if allocator not specified)
|
||||||
if comp['allocator'] == 'auto':
|
if comp['allocator'] == 'auto':
|
||||||
if comp['board'] in ['LPC-H2888', 'ATEVK1100', 'MBED']:
|
if comp['board'] in ['MIZAR32'] and comp['cpu'] in ['AT32UC3A0128']:
|
||||||
|
comp['allocator'] = 'simple'
|
||||||
|
elif comp['board'] in ['LPC-H2888', 'ATEVK1100', 'MIZAR32', 'MBED']:
|
||||||
comp['allocator'] = 'multiple'
|
comp['allocator'] = 'multiple'
|
||||||
else:
|
else:
|
||||||
comp['allocator'] = 'newlib'
|
comp['allocator'] = 'newlib'
|
||||||
|
@ -191,7 +191,7 @@ local board_list =
|
|||||||
[ 'EAGLE-100' ] = { 'LM3S6918' },
|
[ 'EAGLE-100' ] = { 'LM3S6918' },
|
||||||
[ 'ELUA-PUC' ] = { 'LPC2468' },
|
[ 'ELUA-PUC' ] = { 'LPC2468' },
|
||||||
[ 'MBED' ] = { 'LPC1768' },
|
[ 'MBED' ] = { 'LPC1768' },
|
||||||
[ 'MIZAR32' ] = { 'AT32UC3A0128', 'AT32UC3A0256', 'AT32UC3A0512' },
|
[ 'MIZAR32' ] = { 'AT32UC3A0256', 'AT32UC3A0512', 'AT32UC3A0128' },
|
||||||
[ 'NETDUINO' ] = { 'AT91SAM7X512' },
|
[ 'NETDUINO' ] = { 'AT91SAM7X512' },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +300,9 @@ end
|
|||||||
|
|
||||||
-- CPU/allocator mapping (if allocator not specified)
|
-- CPU/allocator mapping (if allocator not specified)
|
||||||
if comp.allocator == 'auto' then
|
if comp.allocator == 'auto' then
|
||||||
if utils.array_element_index( { 'LPC-H2888', 'ATEVK1100', 'MBED' }, comp.board:upper() ) then
|
if comp.board:upper() == 'MIZAR32' and comp.cpu:upper() == 'AT32UC3A0128' then
|
||||||
|
comp.allocator = 'simple'
|
||||||
|
elseif utils.array_element_index( { 'LPC-H2888', 'ATEVK1100', 'MIZAR32', 'MBED' }, comp.board:upper() ) then
|
||||||
comp.allocator = 'multiple'
|
comp.allocator = 'multiple'
|
||||||
else
|
else
|
||||||
comp.allocator = 'newlib'
|
comp.allocator = 'newlib'
|
||||||
|
@ -143,15 +143,15 @@ enum
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "timer_data_type #platform_timer_get_diff_us#( unsigned id, timer_data_type end, timer_data_type start );",
|
{ sig = "timer_data_type #platform_timer_get_diff_us#( unsigned id, timer_data_type start, timer_data_type end );",
|
||||||
desc = [[Return the time difference (in us) between two timer values (as returned by calling @refman_gen_tmr.html#platform_timer_op@platform_timer_op@ with $PLATFORM_TIMER_OP_READ$ or $PLATFORM_TIMER_OP_START$. This function
|
desc = [[Return the time difference (in us) between two timer values (as returned by calling @refman_gen_tmr.html#platform_timer_op@platform_timer_op@ with $PLATFORM_TIMER_OP_READ$ or $PLATFORM_TIMER_OP_START$. This function
|
||||||
is generic, thus it is implemented in %src/common.c%. <span class="warning">NOTE</span>: the order of $end$ and $start$ is important. $end$ must correspond to a moment in time which came after $start$. The function knows how to deal
|
is generic, thus it is implemented in %src/common.c%. <span class="warning">NOTE</span>: the order of $start$ and $end$ is important. $end$ must correspond to a moment in time which came after $start$. The function knows how to deal
|
||||||
with $a single$ timer overflow condition ($end$ is less than $start$); if the timer overflowed 2 or more times between $start$ and $end$ the result of this function will be incorrect.]],
|
with $a single$ timer overflow condition ($end$ is less than $start$); if the timer overflowed 2 or more times between $start$ and $end$ the result of this function will be incorrect.]],
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
"$id$ - the timer ID",
|
"$id$ - the timer ID",
|
||||||
"$end$ - the final counter value.",
|
|
||||||
"$start$ - the initial counter value.",
|
"$start$ - the initial counter value.",
|
||||||
|
"$end$ - the final counter value.",
|
||||||
},
|
},
|
||||||
ret = "the time difference (in microseconds)"
|
ret = "the time difference (in microseconds)"
|
||||||
},
|
},
|
||||||
|
@ -104,14 +104,14 @@ argument. The IP is given as a string.]],
|
|||||||
ret = "$err$ - the error code, as defined @#error_codes@here@."
|
ret = "$err$ - the error code, as defined @#error_codes@here@."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "socket, remoteip, err = #net.accept#( port, [timeout], [timer_id] )",
|
{ sig = "socket, remoteip, err = #net.accept#( port, [timer_id, timeout] )",
|
||||||
desc = "Accept a connection from a remote system with an optional timeout.",
|
desc = "Accept a connection from a remote system with an optional timeout.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
"$port$ - the port to wait for connections from the remote system.",
|
"$port$ - the port to wait for connections from the remote system.",
|
||||||
|
[[$timer_id (optional)$ - the ID of the timer used for measuring the timeout. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.]],
|
||||||
[[$timeout (optional)$ - timeout of the operation, can be either $net.NO_TIMEOUT$ or 0 for non-blocking operation, $net.INF_TIMEOUT$ for
|
[[$timeout (optional)$ - timeout of the operation, can be either $net.NO_TIMEOUT$ or 0 for non-blocking operation, $net.INF_TIMEOUT$ for
|
||||||
blocking operation, or a positive number that specifies the timeout in microseconds. The default value of this argument is $unet.INF_TIMEOUT$.]],
|
blocking operation, or a positive number that specifies the timeout in microseconds. The default value of this argument is $unet.INF_TIMEOUT$.]],
|
||||||
[[$timer_id (optional)$ - the ID of the timer used for measuring the timeout. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.]],
|
|
||||||
|
|
||||||
},
|
},
|
||||||
ret =
|
ret =
|
||||||
@ -136,7 +136,7 @@ blocking operation, or a positive number that specifies the timeout in microseco
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "res, err = #net.recv#( sock, format, [timeout], [timer_id] )",
|
{ sig = "res, err = #net.recv#( sock, format, [timer_id, timeout] )",
|
||||||
desc = "Read data from a socket.",
|
desc = "Read data from a socket.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
@ -146,9 +146,9 @@ blocking operation, or a positive number that specifies the timeout in microseco
|
|||||||
<li>$"*l"$: read a line (until the next '\n' character).</li>
|
<li>$"*l"$: read a line (until the next '\n' character).</li>
|
||||||
<li>$an integer$: read up to that many bytes.</li>
|
<li>$an integer$: read up to that many bytes.</li>
|
||||||
</ul>]],
|
</ul>]],
|
||||||
|
[[$timer_id (optional)$ - the ID of the timer used for measuring the timeout. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.]],
|
||||||
[[$timeout (optional)$ - timeout of the operation, can be either $net.NO_TIMEOUT$ or 0 for non-blocking operation, $net.INF_TIMEOUT$ for
|
[[$timeout (optional)$ - timeout of the operation, can be either $net.NO_TIMEOUT$ or 0 for non-blocking operation, $net.INF_TIMEOUT$ for
|
||||||
blocking operation, or a positive number that specifies the timeout in microseconds. The default value of this argument is $unet.INF_TIMEOUT$.]],
|
blocking operation, or a positive number that specifies the timeout in microseconds. The default value of this argument is $net.INF_TIMEOUT$.]],
|
||||||
[[$timer_id (optional)$ - the ID of the timer used for measuring the timeout. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.]],
|
|
||||||
},
|
},
|
||||||
ret =
|
ret =
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ data_en =
|
|||||||
timers with a single exception: you can't set the clock of a virtual timer (using @#tmr.setclock@tmr.setclock@). To use virtual timers with this
|
timers with a single exception: you can't set the clock of a virtual timer (using @#tmr.setclock@tmr.setclock@). To use virtual timers with this
|
||||||
module, specify $tmr.VIRTx$ as the timer ID instead of a number. For example, if the eLua image was configured to support 4 virtual timers, they will
|
module, specify $tmr.VIRTx$ as the timer ID instead of a number. For example, if the eLua image was configured to support 4 virtual timers, they will
|
||||||
be available by using $tmr.VIRT0$ to $tmr.VIRT3$ as timer IDs. The @arch_platform_timers.html#the_system_timer@system timer@ can also be used with
|
be available by using $tmr.VIRT0$ to $tmr.VIRT3$ as timer IDs. The @arch_platform_timers.html#the_system_timer@system timer@ can also be used with
|
||||||
any of these functions by ommiting the timer ID or specifying it as $tmr.SYS_TIMER$.</p>
|
any of these functions by omitting the timer ID or specifying it as $tmr.SYS_TIMER$.</p>
|
||||||
<p>All "time units" (delays, differences in time) in this module, as well as in other parts of eLua (timeouts) are expressed in microseconds. However,
|
<p>All "time units" (delays, differences in time) in this module, as well as in other parts of eLua (timeouts) are expressed in microseconds. However,
|
||||||
please keep in mind that the actual timer resolution depends on many factors. For example, it's very likely that the @#tmr.delay@tmr.delay@ function won't
|
please keep in mind that the actual timer resolution depends on many factors. For example, it's very likely that the @#tmr.delay@tmr.delay@ function won't
|
||||||
be able to delay for the exact amount you specify (in us), as the real delay depends on a number of variables, most notably the base clock of the timer
|
be able to delay for the exact amount you specify (in us), as the real delay depends on a number of variables, most notably the base clock of the timer
|
||||||
@ -28,45 +28,45 @@ data_en =
|
|||||||
-- Functions
|
-- Functions
|
||||||
funcs =
|
funcs =
|
||||||
{
|
{
|
||||||
{ sig = "#tmr.delay#( period, [id] )",
|
{ sig = "#tmr.delay#( id, period )",
|
||||||
desc = "Waits for the specified period, then returns.",
|
desc = "Waits for the specified period, then returns.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
|
"$id$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.",
|
||||||
"$period$ - how long to wait (in us).",
|
"$period$ - how long to wait (in us).",
|
||||||
"$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "counter = #tmr.read#( [id] )",
|
{ sig = "counter = #tmr.read#( [id] )",
|
||||||
desc= "Reads the timer counter register.",
|
desc= "Reads the timer counter register.",
|
||||||
args = "$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
args = "$id (optional)$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@. Defaults to $nil$ if not specified.",
|
||||||
ret = "The value of the timer counter register."
|
ret = "The value of the timer counter register."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "counter = #tmr.start#( [id] )",
|
{ sig = "counter = #tmr.start#( [id] )",
|
||||||
desc = "Starts the specified timer.",
|
desc = "Starts the specified timer.",
|
||||||
args = "$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
args = "$id (optional)$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@. Defaults to $nil$ if not specified.",
|
||||||
ret = "The value of the timer counter register when the timer started.",
|
ret = "The value of the timer counter register when the timer started.",
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "delta = #tmr.gettimediff#( end, start, [id] )",
|
{ sig = "delta = #tmr.gettimediff#( id, start, end )",
|
||||||
desc = [[Computes the time difference between two timer counter values (obtained by calling @#tmr.read@tmr.read@ or @#tmr.start@tmr.start@). <span class="warning">NOTE</span>: the order
|
desc = [[Computes the time difference between two timer counter values (obtained by calling @#tmr.read@tmr.read@ or @#tmr.start@tmr.start@). <span class="warning">NOTE</span>: the order
|
||||||
of $end$ and $start$ is important. $end$ must correspond to a moment in time which came after $start$. The function knows how to deal with $a single$ timer overflow condition ($end$ is less than $start$); if the timer overflowed 2 or more times between $start$ and $end$ the result of this function will be incorrect.]],
|
of $start$ and $end$ is important. $end$ must correspond to a moment in time which came after $start$. The function knows how to deal with $a single$ timer overflow condition ($end$ is less than $start$); if the timer overflowed 2 or more times between $start$ and $end$ the result of this function will be incorrect.]],
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
"$end$ - the final counter value.",
|
"$id$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.",
|
||||||
"$start$ - the initial counter value.",
|
"$start$ - the initial counter value.",
|
||||||
"$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
"$end$ - the final counter value.",
|
||||||
},
|
},
|
||||||
ret = "The time difference (in us)."
|
ret = "The time difference (in us)."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "delta = #tmr.getdiffnow#( start, [id] )",
|
{ sig = "delta = #tmr.getdiffnow#( id, start )",
|
||||||
desc = [[Computes the time difference between a counter value from the past (obtained by calling @#tmr.read@tmr.read@ or @#tmr.start@tmr.start@) and the counter value corresponding to the current time.]],
|
desc = [[Computes the time difference between a counter value from the past (obtained by calling @#tmr.read@tmr.read@ or @#tmr.start@tmr.start@) and the counter value corresponding to the current time.]],
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
|
"$id$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.",
|
||||||
"$start$ - the initial counter value.",
|
"$start$ - the initial counter value.",
|
||||||
"$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
|
||||||
},
|
},
|
||||||
ret = "The time difference (in us)."
|
ret = "The time difference (in us)."
|
||||||
},
|
},
|
||||||
@ -74,40 +74,40 @@ of $end$ and $start$ is important. $end$ must correspond to a moment in time whi
|
|||||||
|
|
||||||
{ sig = "mindelay = #tmr.getmindelay#( [id] )",
|
{ sig = "mindelay = #tmr.getmindelay#( [id] )",
|
||||||
desc = "Get the minimum achievable delay on the specified timer.",
|
desc = "Get the minimum achievable delay on the specified timer.",
|
||||||
args = "$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
args = "$id (optional)$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@. Defaults to $nil$ if not specified.",
|
||||||
ret = "The minimum achievable delay on the specified timer (in us)."
|
ret = "The minimum achievable delay on the specified timer (in us)."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "maxdelay = #tmr.getmaxdelay#( [id] )",
|
{ sig = "maxdelay = #tmr.getmaxdelay#( [id] )",
|
||||||
desc = "Get the maximum achievable delay on the specified timer.",
|
desc = "Get the maximum achievable delay on the specified timer.",
|
||||||
args = "$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
args = "$id (optional)$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@. Defaults to $nil$ if not specified.",
|
||||||
ret = "The maximum achievable delay on the specified timer (in us)."
|
ret = "The maximum achievable delay on the specified timer (in us)."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "clock = #tmr.setclock#( clock, [id] )",
|
{ sig = "clock = #tmr.setclock#( id, clock )",
|
||||||
desc = "Set the timer clock (the clock used to increment the timer counter register).",
|
desc = "Set the timer clock (the clock used to increment the timer counter register).",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
|
"$id$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@.",
|
||||||
"$clock$ - the timer clock (in Hz). ",
|
"$clock$ - the timer clock (in Hz). ",
|
||||||
"$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
|
||||||
},
|
},
|
||||||
ret = [[The actual clock set on the timer (in Hz). Depending on the hardware, this might have a different value than the $clock$ argument.
|
ret = [[The actual clock set on the timer (in Hz). Depending on the hardware, this might have a different value than the $clock$ argument.
|
||||||
$NOTE:$ this function does not work with virtual timers or with the system timer.]]
|
$NOTE:$ this function does not work with virtual timers or the system timer.]]
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "clock = #tmr.getclock#( [id] )",
|
{ sig = "clock = #tmr.getclock#( [id] )",
|
||||||
desc = "Get the timer clock (the clock used to increment the timer counter register).",
|
desc = "Get the timer clock (the clock used to increment the timer counter register).",
|
||||||
args = "$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@.",
|
args = "$id (optional)$ - the timer ID. Use $nil$ or $tmr.SYS_TIMER$ to specify the @arch_platform_timers.html#the_system_timer@system timer@. Defaults to $nil$ if not specified.",
|
||||||
ret = "The timer clock (in Hz)."
|
ret = "The timer clock (in Hz)."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "#tmr.set_match_int#( period, type, [id] )",
|
{ sig = "#tmr.set_match_int#( id, period, type )",
|
||||||
desc = "Setup the timer match interrupt. Only available if interrupt support is enabled, check @inthandlers.html@here@ for details.",
|
desc = "Setup the timer match interrupt. Only available if interrupt support is enabled, check @inthandlers.html@here@ for details.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
|
[[$id$ - the timer ID. If $nil$ it defaults to the @arch_platform_timers.html#the_system_timer@system timer@ (but note that this happens only for consistency, as the system timer can't generate interrupts).]],
|
||||||
"$period$ - the interrupt period in microseconds. Setting this to 0 disabled the timer match interrupt.",
|
"$period$ - the interrupt period in microseconds. Setting this to 0 disabled the timer match interrupt.",
|
||||||
"$type$ - $tmr.INT_ONESHOT$ to generate a single interrupt after *period* microseconds, or $tmr.INT_CYCLIC$ to generate interrupts every $period$ microseconds.",
|
"$type$ - $tmr.INT_ONESHOT$ to generate a single interrupt after $period$ microseconds, or $tmr.INT_CYCLIC$ to generate interrupts every $period$ microseconds.",
|
||||||
[[$id (optional)$ - the timer ID. If not specified it defaults to the @arch_platform_timers.html#the_system_timer@system timer@ (but note that this happens only for consistency, as the system timer can't generate interrupts).]],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
-- eLaa reference manual - platform data
|
-- eLua reference manual - platform data
|
||||||
|
|
||||||
data_en =
|
data_en =
|
||||||
{
|
{
|
||||||
@ -11,7 +11,7 @@ data_en =
|
|||||||
|
|
||||||
-- Overview
|
-- Overview
|
||||||
overview = [[This module contains functions to drive the two-line character LCD panel of the Mizar32 display module.</p>
|
overview = [[This module contains functions to drive the two-line character LCD panel of the Mizar32 display module.</p>
|
||||||
<p>Physically, the display has 16 characters per line but internally it has a 40 characters by two line memory. It displays 16 of those 40 columns at a time, with various ways to determine which of the 40 columns appear in the 16-column display. If you just want to display 16x2 characters, the $reset$, $goto$ and $print$ functions are enough to do this.]],
|
<p>Physically, the display has 16 characters per line but internally it has a 40 character by two line memory. It displays 16 of those 40 columns at a time, with various ways to determine which of the 40 columns appear in the 16-column display. If you just want to display 16x2 characters, the $reset$, $goto$ and $print$ functions are enough to do this.]],
|
||||||
|
|
||||||
-- Functions
|
-- Functions
|
||||||
funcs =
|
funcs =
|
||||||
@ -24,21 +24,21 @@ data_en =
|
|||||||
desc = "This can be used to set some of the stranger operating modes of the LCD display. Both parameters are optional and if you omit them, they default to $false$, which sets sensible mode.",
|
desc = "This can be used to set some of the stranger operating modes of the LCD display. Both parameters are optional and if you omit them, they default to $false$, which sets sensible mode.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
[[$display_shift$ - If $true$, then with each character you subsequently print, the cursor will move by one place in the character memory as usual but the display's contents will also move by one position horizontally so that the cursor remains in the same column of the physical display. This can be used to achieve "scrolling text" effects. Note, however, that when the cursor passes from column 40 to column 1 or vice versa, it flips over to the other row.]],
|
[[$display_shift$ - If $true$, then with each character you subsequently print, the cursor will move by one place in the character memory as usual but the display's contents will also move by one position horizontally in the opposite direction so that the cursor remains in the same column of the physical display. This can be used to achieve "scrolling text" effects. Note, however, that when the cursor passes from column 40 to column 1 or vice versa, it flips over to the other row.]],
|
||||||
"$right_to_left$ - If $true$, text will be printed right-to-left: the cursor will move one position to the left in the character memory and, if display shifting is also enabled, the display will shift so as to keep the cursor in the same column on the screen."
|
"$right_to_left$ - If $true$, text will be printed right-to-left: the cursor will move one position to the left in the character memory and, if display shifting is also enabled, the contents of the display will shift to the right so that the cursor stays in the same column on the screen."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "#mizar32.lcd.clear#()",
|
{ sig = "#mizar32.lcd.clear#()",
|
||||||
desc = "Clears the display, move the cursor to the top left (position 1,1) and reset the display shift to show columns 1-16."
|
desc = "Clears the display, moves the cursor to the top left (position 1,1) and resets the display shift to show columns 1 to 16."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "#mizar32.lcd.home#()",
|
{ sig = "#mizar32.lcd.home#()",
|
||||||
desc = "Moves the cursor to the top left (position 1,1) and reset the display shift."
|
desc = "Moves the cursor to the top left (position 1,1) and resets the display shift."
|
||||||
},
|
},
|
||||||
|
|
||||||
{ sig = "#mizar32.lcd.goto#( row, column )",
|
{ sig = "#mizar32.lcd.goto#( row, column )",
|
||||||
desc = "Move the cursor to the specified row and column.",
|
desc = "Moves the cursor to the specified row and column.",
|
||||||
args =
|
args =
|
||||||
{
|
{
|
||||||
"$row$ - A number (1 or 2) giving the row you want to move to.",
|
"$row$ - A number (1 or 2) giving the row you want to move to.",
|
||||||
@ -46,6 +46,15 @@ data_en =
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ sig = "#row, column = mizar32.lcd.getpos#()",
|
||||||
|
desc = "Returns the current cursor position.",
|
||||||
|
ret =
|
||||||
|
{
|
||||||
|
"$row$ - A number (1 or 2) giving the current row.",
|
||||||
|
"$column$ - A number (1 to 40) giving the current column in the character memory."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
{ sig = "#mizar32.lcd.print#( [data1] [, data2] ... [datan] )",
|
{ sig = "#mizar32.lcd.print#( [data1] [, data2] ... [datan] )",
|
||||||
desc = "Writes into the LCD character memory starting at the current cursor position. The cursor will advance by one position for each character printed. When it goes past column 40, it moves to column 1 of the other line, (and vice versa when printing right-to-left).",
|
desc = "Writes into the LCD character memory starting at the current cursor position. The cursor will advance by one position for each character printed. When it goes past column 40, it moves to column 1 of the other line, (and vice versa when printing right-to-left).",
|
||||||
args =
|
args =
|
||||||
@ -82,6 +91,14 @@ data_en =
|
|||||||
"$glyph$ - A table of up to eight numbers giving the bit-patterns for the eight rows of the character, in order from top to bottom. Each of these number is a value from 0 to 31, to define which of the 5 bits in the row should be black. The pixels' values from left to right are 16, 8, 4, 2 and 1. For example, { 1, 3, 7, 15, 31, 15, 7, 3, 1, 0 } would define a left-pointing solid triangle in the top 7 rows. Extra rows are ignored, and missing rows are blanked."
|
"$glyph$ - A table of up to eight numbers giving the bit-patterns for the eight rows of the character, in order from top to bottom. Each of these number is a value from 0 to 31, to define which of the 5 bits in the row should be black. The pixels' values from left to right are 16, 8, 4, 2 and 1. For example, { 1, 3, 7, 15, 31, 15, 7, 3, 1, 0 } would define a left-pointing solid triangle in the top 7 rows. Extra rows are ignored, and missing rows are blanked."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ sig = "#buttons = mizar32.lcd.buttons#()",
|
||||||
|
desc = "Tells which of the five user buttons are currently pressed.",
|
||||||
|
ret =
|
||||||
|
{
|
||||||
|
"$buttons$ - A string containing up to five of the characters $L$, $R$, $U$, $D$ and $S$ to say whether the Left, Right, Up, Down and Select buttons are currently held down. If none are pressed, an empty string is returned. The hardare allows Select to be detected reliably and up to two of the other four: if three of Left, Right, Up and Down are being held, all four are returned."
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ $$HEADER$$
|
|||||||
<h3>Using <b>eLua</b> with the AT91SAM7X CPUs from Atmel</h3>
|
<h3>Using <b>eLua</b> with the AT91SAM7X CPUs from Atmel</h3>
|
||||||
<p><a href="http://www.atmel.com">Atmel</a> is a company that doesn't need any kind of introduction :) Their huge product range include some quite nice ARM7TDMI core implementations.
|
<p><a href="http://www.atmel.com">Atmel</a> is a company that doesn't need any kind of introduction :) Their huge product range include some quite nice ARM7TDMI core implementations.
|
||||||
Among them are the <a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=3755">AT91SAM7X256</a> and
|
Among them are the <a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=3755">AT91SAM7X256</a> and
|
||||||
<a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=4104">AT91SAM7X512</a> CPUs. The only difference between them is the ammount of internal memory (256k Flash+64k RAM for
|
<a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=4104">AT91SAM7X512</a> CPUs. The only difference between them is the amount of internal memory (256k Flash+64k RAM for
|
||||||
AT91SAM7X256 vs. 512k Flash+128k RAM for AT91SAM7X512). Loaded with peripherals, and accompanied by a good support package, they make a perfect host for <b>eLua</b>. For this tutorial
|
AT91SAM7X256 vs. 512k Flash+128k RAM for AT91SAM7X512). Loaded with peripherals, and accompanied by a good support package, they make a perfect host for <b>eLua</b>. For this tutorial
|
||||||
I'm going to use the <a href="http://www.olimex.com/dev/sam7-ex256.html">SAM7-EX256</a> development board from <a href="http://www.olimex.com">Olimex</a>. It's quite a
|
I'm going to use the <a href="http://www.olimex.com/dev/sam7-ex256.html">SAM7-EX256</a> development board from <a href="http://www.olimex.com">Olimex</a>. It's quite a
|
||||||
decent board, and also reasonably priced, although it lacks a proper documentation package in my oppinion. It is equipped with an AT91SAM7X256 CPU. As much as I'd like to get
|
decent board, and also reasonably priced, although it lacks a proper documentation package in my oppinion. It is equipped with an AT91SAM7X256 CPU. As much as I'd like to get
|
||||||
|
@ -24,7 +24,7 @@ handler. After all the interrupts are handled and the queue is emptied, the hook
|
|||||||
C function that is executed for every VM instruction. If this function blocks for some reason, the VM instructions are not executed anymore. It's not hard to make
|
C function that is executed for every VM instruction. If this function blocks for some reason, the VM instructions are not executed anymore. It's not hard to make
|
||||||
this function block; for example, it blocks everytime the Lua code waits for some user input at the console, or when a link:refman_gen_tmr.html#tmr.delay[tmr.delay] is executed,
|
this function block; for example, it blocks everytime the Lua code waits for some user input at the console, or when a link:refman_gen_tmr.html#tmr.delay[tmr.delay] is executed,
|
||||||
or when link:refman_gen_uart.html#uart.read[uart.read] is called with an infinite or very large timeout; in general, any function from a Lua library that doesn't return
|
or when link:refman_gen_uart.html#uart.read[uart.read] is called with an infinite or very large timeout; in general, any function from a Lua library that doesn't return
|
||||||
immediately or after a short ammount of time will block the VM. Care must be taken to avoid such operations as much as possible, otherwise the interrupt support code won't run properly.
|
immediately or after a short amount of time will block the VM. Care must be taken to avoid such operations as much as possible, otherwise the interrupt support code won't run properly.
|
||||||
|
|
||||||
* There is a single interrupt handler per interrupt type in Lua (the same holds true for C interrupt support), as opposed to the many hardware interrupts
|
* There is a single interrupt handler per interrupt type in Lua (the same holds true for C interrupt support), as opposed to the many hardware interrupts
|
||||||
handlers usually found on the eLua targets. It is however easy to differentiate between different interrupt sources, as will be explained in the next
|
handlers usually found on the eLua targets. It is however easy to differentiate between different interrupt sources, as will be explained in the next
|
||||||
|
@ -32,7 +32,7 @@ void cmn_uart_setup_sermux();
|
|||||||
|
|
||||||
unsigned int intlog2( unsigned int v );
|
unsigned int intlog2( unsigned int v );
|
||||||
const char* cmn_str64( u64 x );
|
const char* cmn_str64( u64 x );
|
||||||
void cmn_get_timeout_data( lua_State *L, int pidx, timer_data_type *ptimeout, unsigned *pid );
|
void cmn_get_timeout_data( lua_State *L, int pidx, unsigned *pid, timer_data_type *ptimeout );
|
||||||
|
|
||||||
#endif // #ifndef __COMMON_H__
|
#endif // #ifndef __COMMON_H__
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ pio_type platform_pio_op( unsigned port, pio_type pinmask, int op );
|
|||||||
|
|
||||||
#if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_INTEGRAL_LONGLONG )
|
#if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_INTEGRAL_LONGLONG )
|
||||||
// Maximum values of the system timer
|
// Maximum values of the system timer
|
||||||
#define PLATFORM_TIMER_SYS_MAX ( ( 1LL << 32 ) - 2 )
|
#define PLATFORM_TIMER_SYS_MAX ( ( 1LL << 31 ) - 2 )
|
||||||
// Timer data type
|
// Timer data type
|
||||||
typedef u32 timer_data_type;
|
typedef u32 timer_data_type;
|
||||||
#else
|
#else
|
||||||
@ -122,7 +122,7 @@ timer_data_type platform_timer_op( unsigned id, int op, timer_data_type data );
|
|||||||
timer_data_type platform_s_timer_op( unsigned id, int op, timer_data_type data );
|
timer_data_type platform_s_timer_op( unsigned id, int op, timer_data_type data );
|
||||||
int platform_timer_set_match_int( unsigned id, timer_data_type period_us, int type );
|
int platform_timer_set_match_int( unsigned id, timer_data_type period_us, int type );
|
||||||
int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int type );
|
int platform_s_timer_set_match_int( unsigned id, timer_data_type period_us, int type );
|
||||||
timer_data_type platform_timer_get_diff_us( unsigned id, timer_data_type end, timer_data_type start );
|
timer_data_type platform_timer_get_diff_us( unsigned id, timer_data_type start, timer_data_type end );
|
||||||
// System timer functions
|
// System timer functions
|
||||||
timer_data_type platform_timer_read_sys();
|
timer_data_type platform_timer_read_sys();
|
||||||
int platform_timer_sys_available();
|
int platform_timer_sys_available();
|
||||||
@ -135,7 +135,7 @@ void platform_timer_sys_disable_int();
|
|||||||
// Convenience macros
|
// Convenience macros
|
||||||
#define platform_timer_read( id ) platform_timer_op( id, PLATFORM_TIMER_OP_READ, 0 )
|
#define platform_timer_read( id ) platform_timer_op( id, PLATFORM_TIMER_OP_READ, 0 )
|
||||||
#define platform_timer_start( id ) platform_timer_op( id, PLATFORM_TIMER_OP_START, 0 )
|
#define platform_timer_start( id ) platform_timer_op( id, PLATFORM_TIMER_OP_START, 0 )
|
||||||
#define platform_timer_get_diff_crt( id, v ) platform_timer_get_diff_us( id, platform_timer_read( id ), v )
|
#define platform_timer_get_diff_crt( id, v ) platform_timer_get_diff_us( id, v, platform_timer_read( id ) )
|
||||||
#define platform_timer_sys_delay( us ) platform_timer_delay( PLATFORM_TIMER_SYS_ID, us )
|
#define platform_timer_sys_delay( us ) platform_timer_delay( PLATFORM_TIMER_SYS_ID, us )
|
||||||
#define platform_timer_get_max_cnt( id ) platform_timer_op( id, PLATFORM_TIMER_OP_GET_MAX_CNT, 0 )
|
#define platform_timer_get_max_cnt( id ) platform_timer_op( id, PLATFORM_TIMER_OP_GET_MAX_CNT, 0 )
|
||||||
|
|
||||||
|
@ -112,6 +112,9 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
|
|||||||
termdata.c_iflag &= ~( IXON | IXOFF | IXANY );
|
termdata.c_iflag &= ~( IXON | IXOFF | IXANY );
|
||||||
termdata.c_iflag |= IGNBRK;
|
termdata.c_iflag |= IGNBRK;
|
||||||
|
|
||||||
|
// Disable input processing
|
||||||
|
termdata.c_iflag &= ~( INLCR | ICRNL | IGNCR );
|
||||||
|
|
||||||
// Raw input
|
// Raw input
|
||||||
termdata.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
|
termdata.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
|
||||||
|
|
||||||
@ -146,16 +149,21 @@ u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
|
|||||||
fd_set readfs;
|
fd_set readfs;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int retval;
|
int retval;
|
||||||
|
u32 readbytes = 0;
|
||||||
|
|
||||||
|
while( readbytes < maxsize )
|
||||||
|
{
|
||||||
FD_ZERO( &readfs );
|
FD_ZERO( &readfs );
|
||||||
FD_SET( ( int )id, &readfs );
|
FD_SET( ( int )id, &readfs );
|
||||||
tv.tv_sec = timeout / 1000;
|
tv.tv_sec = timeout / 1000;
|
||||||
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
tv.tv_usec = ( timeout % 1000 ) * 1000;
|
||||||
retval = select( ( int )id + 1, &readfs, NULL, NULL, timeout == SER_INF_TIMEOUT ? NULL : &tv );
|
retval = select( ( int )id + 1, &readfs, NULL, NULL, timeout == SER_INF_TIMEOUT ? NULL : &tv );
|
||||||
if( retval == -1 || retval == 0 )
|
if( retval == -1 || retval == 0 )
|
||||||
return 0;
|
break;
|
||||||
else
|
else
|
||||||
return ( u32 )read( id, dest, maxsize );
|
readbytes += ( u32 )read( id, dest + readbytes, maxsize - readbytes );
|
||||||
|
}
|
||||||
|
return readbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a single byte and return it (or -1 for error)
|
// Read a single byte and return it (or -1 for error)
|
||||||
|
17
src/common.c
17
src/common.c
@ -473,20 +473,21 @@ const char* cmn_str64( u64 x )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read a timeout spec from the user and return it
|
// Read a timeout spec from the user and return it
|
||||||
// The timeout spec has the format [timeout], [timer_id]. Both arguments are optional.
|
// The timeout spec has the format [timer_id, timeout]. Both arguments are optional:
|
||||||
// If none is specified -> defaults to infinite timeout
|
// If none is specified -> defaults to infinite timeout
|
||||||
// If timeout is PLATFORM_TIMER_INF_TIMEOUT -> also infinite timeout (see above)
|
// If timer_id is specified, but timeout is not specified -> defaults to infinite timeout
|
||||||
// If a timeout is specified -> timer_id might also be specified. If not, it defaults to
|
// If timeout is PLATFORM_TIMER_INF_TIMEOUT -> also infinite timeout (independent of timer_id)
|
||||||
// PLATFORM_TIMER_SYS_ID
|
// If both are specified -> wait the specified timeout on the specified timer_id
|
||||||
void cmn_get_timeout_data( lua_State *L, int pidx, timer_data_type *ptimeout, unsigned *pid )
|
// If timer_id is 'nil' the system timer will be used
|
||||||
|
void cmn_get_timeout_data( lua_State *L, int pidx, unsigned *pid, timer_data_type *ptimeout )
|
||||||
{
|
{
|
||||||
lua_Number tempn;
|
lua_Number tempn;
|
||||||
|
|
||||||
*ptimeout = PLATFORM_TIMER_INF_TIMEOUT;
|
*ptimeout = PLATFORM_TIMER_INF_TIMEOUT;
|
||||||
*pid = ( unsigned )luaL_optinteger( L, pidx + 1, PLATFORM_TIMER_SYS_ID );
|
*pid = ( unsigned )luaL_optinteger( L, pidx, PLATFORM_TIMER_SYS_ID );
|
||||||
if( lua_type( L, pidx ) == LUA_TNUMBER )
|
if( lua_type( L, pidx + 1 ) == LUA_TNUMBER )
|
||||||
{
|
{
|
||||||
tempn = lua_tonumber( L, pidx );
|
tempn = lua_tonumber( L, pidx + 1 );
|
||||||
if( tempn < 0 || tempn > PLATFORM_TIMER_INF_TIMEOUT )
|
if( tempn < 0 || tempn > PLATFORM_TIMER_INF_TIMEOUT )
|
||||||
luaL_error( L, "invalid timeout value" );
|
luaL_error( L, "invalid timeout value" );
|
||||||
*ptimeout = ( timer_data_type )tempn;
|
*ptimeout = ( timer_data_type )tempn;
|
||||||
|
@ -269,9 +269,9 @@ timer_data_type platform_timer_op( unsigned id, int op, timer_data_type data )
|
|||||||
{
|
{
|
||||||
// 'get min delay' and 'get max delay' are very common cases, handle them here
|
// 'get min delay' and 'get max delay' are very common cases, handle them here
|
||||||
if( op == PLATFORM_TIMER_OP_GET_MAX_DELAY )
|
if( op == PLATFORM_TIMER_OP_GET_MAX_DELAY )
|
||||||
return platform_timer_get_diff_us( id, platform_timer_get_max_cnt( id ), 0 );
|
return platform_timer_get_diff_us( id, 0, platform_timer_get_max_cnt( id ) );
|
||||||
else if( op == PLATFORM_TIMER_OP_GET_MIN_DELAY )
|
else if( op == PLATFORM_TIMER_OP_GET_MIN_DELAY )
|
||||||
return platform_timer_get_diff_us( id, 1, 0 );
|
return platform_timer_get_diff_us( id, 0, 1 );
|
||||||
else
|
else
|
||||||
return platform_s_timer_op( id, op, data );
|
return platform_s_timer_op( id, op, data );
|
||||||
}
|
}
|
||||||
@ -288,11 +288,11 @@ timer_data_type platform_timer_op( unsigned id, int op, timer_data_type data )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_MAX_DELAY:
|
case PLATFORM_TIMER_OP_GET_MAX_DELAY:
|
||||||
res = platform_timer_get_diff_us( id, 0xFFFFFFFF, 0 );
|
res = platform_timer_get_diff_us( id, 0, 0xFFFFFFFF );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_MIN_DELAY:
|
case PLATFORM_TIMER_OP_GET_MIN_DELAY:
|
||||||
res = platform_timer_get_diff_us( id, 1, 0 );
|
res = platform_timer_get_diff_us( id, 0, 1 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLATFORM_TIMER_OP_GET_MAX_CNT:
|
case PLATFORM_TIMER_OP_GET_MAX_CNT:
|
||||||
@ -308,7 +308,7 @@ timer_data_type platform_timer_op( unsigned id, int op, timer_data_type data )
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_data_type platform_timer_get_diff_us( unsigned id, timer_data_type end, timer_data_type start )
|
timer_data_type platform_timer_get_diff_us( unsigned id, timer_data_type start, timer_data_type end )
|
||||||
{
|
{
|
||||||
u32 freq;
|
u32 freq;
|
||||||
u64 tstart = ( u64 )start, tend = ( u64 )end;
|
u64 tstart = ( u64 )start, tend = ( u64 )end;
|
||||||
|
@ -193,6 +193,15 @@ int platform_uart_set_buffer( unsigned id, unsigned log2size )
|
|||||||
{
|
{
|
||||||
if( id >= SERMUX_SERVICE_ID_FIRST ) // Virtual UARTs need buffers no matter what
|
if( id >= SERMUX_SERVICE_ID_FIRST ) // Virtual UARTs need buffers no matter what
|
||||||
return PLATFORM_ERR;
|
return PLATFORM_ERR;
|
||||||
|
|
||||||
|
// Disable the UART interrupt if it was set
|
||||||
|
if( platform_cpu_get_interrupt( INT_UART_RX, id ) == PLATFORM_CPU_ENABLE )
|
||||||
|
platform_cpu_set_interrupt( INT_UART_RX, id, PLATFORM_CPU_DISABLE );
|
||||||
|
|
||||||
|
// If our C interrupt handler is installed, restore the previous one
|
||||||
|
if( elua_int_get_c_handler( INT_UART_RX ) == cmn_uart_rx_inthandler )
|
||||||
|
(void) elua_int_set_c_handler( INT_UART_RX, prev_uart_rx_handler );
|
||||||
|
|
||||||
// Disable buffering
|
// Disable buffering
|
||||||
buf_set( BUF_ID_UART, id, BUF_SIZE_NONE, BUF_DSIZE_U8 );
|
buf_set( BUF_ID_UART, id, BUF_SIZE_NONE, BUF_DSIZE_U8 );
|
||||||
}
|
}
|
||||||
@ -203,12 +212,13 @@ int platform_uart_set_buffer( unsigned id, unsigned log2size )
|
|||||||
return PLATFORM_ERR;
|
return PLATFORM_ERR;
|
||||||
if( id >= SERMUX_SERVICE_ID_FIRST ) // No need for aditional setup on virtual UARTs
|
if( id >= SERMUX_SERVICE_ID_FIRST ) // No need for aditional setup on virtual UARTs
|
||||||
return PLATFORM_OK;
|
return PLATFORM_OK;
|
||||||
// Enable UART RX interrupt
|
|
||||||
if( platform_cpu_set_interrupt( INT_UART_RX, id, PLATFORM_CPU_ENABLE ) != PLATFORM_INT_OK )
|
|
||||||
return PLATFORM_ERR;
|
|
||||||
// Setup our C handler
|
// Setup our C handler
|
||||||
if( elua_int_get_c_handler( INT_UART_RX ) != cmn_uart_rx_inthandler )
|
if( elua_int_get_c_handler( INT_UART_RX ) != cmn_uart_rx_inthandler )
|
||||||
prev_uart_rx_handler = elua_int_set_c_handler( INT_UART_RX, cmn_uart_rx_inthandler );
|
prev_uart_rx_handler = elua_int_set_c_handler( INT_UART_RX, cmn_uart_rx_inthandler );
|
||||||
|
|
||||||
|
// Enable UART RX interrupt
|
||||||
|
if( platform_cpu_set_interrupt( INT_UART_RX, id, PLATFORM_CPU_ENABLE ) < 0 )
|
||||||
|
return PLATFORM_ERR;
|
||||||
}
|
}
|
||||||
return PLATFORM_OK;
|
return PLATFORM_OK;
|
||||||
#else // BUF_ENABLE_UART
|
#else // BUF_ENABLE_UART
|
||||||
|
@ -706,6 +706,9 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
|
|||||||
if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */
|
if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */
|
||||||
luaC_fullgc(L);
|
luaC_fullgc(L);
|
||||||
if(nsize > osize && L != NULL) {
|
if(nsize > osize && L != NULL) {
|
||||||
|
#if defined(LUA_STRESS_EMERGENCY_GC)
|
||||||
|
luaC_fullgc(L);
|
||||||
|
#endif
|
||||||
if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize))
|
if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -556,6 +556,15 @@ static void atomic (lua_State *L) {
|
|||||||
g->estimate = g->totalbytes - udsize; /* first estimate */
|
g->estimate = g->totalbytes - udsize; /* first estimate */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sweepstrstep (global_State *g, lua_State *L) {
|
||||||
|
lu_mem old = g->totalbytes;
|
||||||
|
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
|
||||||
|
if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
|
||||||
|
g->gcstate = GCSsweep; /* end sweep-string phase */
|
||||||
|
lua_assert(old >= g->totalbytes);
|
||||||
|
g->estimate -= old - g->totalbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static l_mem singlestep (lua_State *L) {
|
static l_mem singlestep (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
@ -574,12 +583,7 @@ static l_mem singlestep (lua_State *L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case GCSsweepstring: {
|
case GCSsweepstring: {
|
||||||
lu_mem old = g->totalbytes;
|
sweepstrstep(g, L);
|
||||||
sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
|
|
||||||
if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
|
|
||||||
g->gcstate = GCSsweep; /* end sweep-string phase */
|
|
||||||
lua_assert(old >= g->totalbytes);
|
|
||||||
g->estimate -= old - g->totalbytes;
|
|
||||||
return GCSWEEPCOST;
|
return GCSWEEPCOST;
|
||||||
}
|
}
|
||||||
case GCSsweep: {
|
case GCSsweep: {
|
||||||
@ -641,6 +645,14 @@ void luaC_step (lua_State *L) {
|
|||||||
unset_block_gc(L);
|
unset_block_gc(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int luaC_sweepstrgc (lua_State *L) {
|
||||||
|
global_State *g = G(L);
|
||||||
|
if (g->gcstate == GCSsweepstring) {
|
||||||
|
sweepstrstep(g, L);
|
||||||
|
return (g->gcstate == GCSsweepstring) ? 1 : 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void luaC_fullgc (lua_State *L) {
|
void luaC_fullgc (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
|
@ -123,6 +123,7 @@ LUAI_FUNC void luaC_callGCTM (lua_State *L);
|
|||||||
LUAI_FUNC void luaC_freeall (lua_State *L);
|
LUAI_FUNC void luaC_freeall (lua_State *L);
|
||||||
LUAI_FUNC void luaC_step (lua_State *L);
|
LUAI_FUNC void luaC_step (lua_State *L);
|
||||||
LUAI_FUNC void luaC_fullgc (lua_State *L);
|
LUAI_FUNC void luaC_fullgc (lua_State *L);
|
||||||
|
LUAI_FUNC int luaC_sweepstrgc (lua_State *L);
|
||||||
LUAI_FUNC void luaC_marknew (lua_State *L, GCObject *o);
|
LUAI_FUNC void luaC_marknew (lua_State *L, GCObject *o);
|
||||||
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
|
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
|
||||||
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
|
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
|
||||||
|
@ -158,13 +158,22 @@ static int math_sqrt (lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LUA_NUMBER_INTEGRAL
|
#ifdef LUA_NUMBER_INTEGRAL
|
||||||
|
# define pow(a,b) luai_ipow(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
static int math_pow (lua_State *L) {
|
static int math_pow (lua_State *L) {
|
||||||
lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
|
lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LUA_NUMBER_INTEGRAL
|
||||||
|
# undef pow
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LUA_NUMBER_INTEGRAL
|
||||||
|
|
||||||
static int math_log (lua_State *L) {
|
static int math_log (lua_State *L) {
|
||||||
lua_pushnumber(L, log(luaL_checknumber(L, 1)));
|
lua_pushnumber(L, log(luaL_checknumber(L, 1)));
|
||||||
return 1;
|
return 1;
|
||||||
@ -306,6 +315,7 @@ const LUA_REG_TYPE math_map[] = {
|
|||||||
{LSTRKEY("floor"), LFUNCVAL(math_identity)},
|
{LSTRKEY("floor"), LFUNCVAL(math_identity)},
|
||||||
{LSTRKEY("max"), LFUNCVAL(math_max)},
|
{LSTRKEY("max"), LFUNCVAL(math_max)},
|
||||||
{LSTRKEY("min"), LFUNCVAL(math_min)},
|
{LSTRKEY("min"), LFUNCVAL(math_min)},
|
||||||
|
{LSTRKEY("pow"), LFUNCVAL(math_pow)},
|
||||||
{LSTRKEY("random"), LFUNCVAL(math_random)},
|
{LSTRKEY("random"), LFUNCVAL(math_random)},
|
||||||
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
|
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
|
||||||
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
|
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
|
||||||
|
@ -375,9 +375,9 @@ static void close_func (LexState *ls) {
|
|||||||
lua_assert(luaG_checkcode(f));
|
lua_assert(luaG_checkcode(f));
|
||||||
lua_assert(fs->bl == NULL);
|
lua_assert(fs->bl == NULL);
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
L->top -= 2; /* remove table and prototype from the stack */
|
|
||||||
/* last token read was anchored in defunct function; must reanchor it */
|
/* last token read was anchored in defunct function; must reanchor it */
|
||||||
if (fs) anchor_token(ls);
|
if (fs) anchor_token(ls);
|
||||||
|
L->top -= 2; /* remove table and prototype from the stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -385,14 +385,18 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
|
|||||||
struct LexState lexstate;
|
struct LexState lexstate;
|
||||||
struct FuncState *pfuncstate = (struct FuncState*)malloc(sizeof(struct FuncState));
|
struct FuncState *pfuncstate = (struct FuncState*)malloc(sizeof(struct FuncState));
|
||||||
Proto *res;
|
Proto *res;
|
||||||
|
TString *tname = luaS_new(L, name);
|
||||||
|
setsvalue2s(L, L->top, tname); /* protect name */
|
||||||
|
incr_top(L);
|
||||||
lexstate.buff = buff;
|
lexstate.buff = buff;
|
||||||
luaX_setinput(L, &lexstate, z, luaS_new(L, name));
|
luaX_setinput(L, &lexstate, z, tname);
|
||||||
open_func(&lexstate, pfuncstate);
|
open_func(&lexstate, pfuncstate);
|
||||||
pfuncstate->f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
|
pfuncstate->f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
|
||||||
luaX_next(&lexstate); /* read first token */
|
luaX_next(&lexstate); /* read first token */
|
||||||
chunk(&lexstate);
|
chunk(&lexstate);
|
||||||
check(&lexstate, TK_EOS);
|
check(&lexstate, TK_EOS);
|
||||||
close_func(&lexstate);
|
close_func(&lexstate);
|
||||||
|
L->top--; /* remove 'name' from stack */
|
||||||
lua_assert(pfuncstate->prev == NULL);
|
lua_assert(pfuncstate->prev == NULL);
|
||||||
lua_assert(pfuncstate->f->nups == 0);
|
lua_assert(pfuncstate->f->nups == 0);
|
||||||
lua_assert(lexstate.fs == NULL);
|
lua_assert(lexstate.fs == NULL);
|
||||||
|
@ -23,7 +23,7 @@ void luaS_resize (lua_State *L, int newsize) {
|
|||||||
stringtable *tb;
|
stringtable *tb;
|
||||||
int i;
|
int i;
|
||||||
tb = &G(L)->strt;
|
tb = &G(L)->strt;
|
||||||
if (G(L)->gcstate == GCSsweepstring || newsize == tb->size || is_resizing_strings_gc(L))
|
if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L))
|
||||||
return; /* cannot resize during GC traverse or doesn't need to be resized */
|
return; /* cannot resize during GC traverse or doesn't need to be resized */
|
||||||
set_resizing_strings_gc(L);
|
set_resizing_strings_gc(L);
|
||||||
if (newsize > tb->size) {
|
if (newsize > tb->size) {
|
||||||
|
@ -408,7 +408,13 @@
|
|||||||
*/
|
*/
|
||||||
#define LUA_COMPAT_OPENLIB
|
#define LUA_COMPAT_OPENLIB
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_STRESS_EMERGENCY_GC enables stress testing code for the Emergency GC.
|
||||||
|
** CHANGE it to defined if you want to test for Emergency GC related bugs.
|
||||||
|
** Note that this will make the Lua vm very slow, since it will force a
|
||||||
|
** full GC on every new allocation.
|
||||||
|
*/
|
||||||
|
#undef LUA_STRESS_EMERGENCY_GC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ luai_apicheck is the assert macro used by the Lua-C API.
|
@@ luai_apicheck is the assert macro used by the Lua-C API.
|
||||||
|
@ -171,6 +171,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
|||||||
L->top--;
|
L->top--;
|
||||||
unfixedstack(L);
|
unfixedstack(L);
|
||||||
setobj2t(L, oldval, val);
|
setobj2t(L, oldval, val);
|
||||||
|
((Table *)h)->flags = 0;
|
||||||
luaC_barriert(L, (Table*)h, val);
|
luaC_barriert(L, (Table*)h, val);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -28,12 +28,16 @@ static int adc_maxval( lua_State* L )
|
|||||||
// Lua: realclock = setclock( id, freq, [timer_id] )
|
// Lua: realclock = setclock( id, freq, [timer_id] )
|
||||||
static int adc_setclock( lua_State* L )
|
static int adc_setclock( lua_State* L )
|
||||||
{
|
{
|
||||||
|
s32 sfreq; // signed version for negative checking
|
||||||
u32 freq;
|
u32 freq;
|
||||||
unsigned id, timer_id = 0;
|
unsigned id, timer_id = 0;
|
||||||
|
|
||||||
id = luaL_checkinteger( L, 1 );
|
id = luaL_checkinteger( L, 1 );
|
||||||
MOD_CHECK_ID( adc, id );
|
MOD_CHECK_ID( adc, id );
|
||||||
freq = luaL_checkinteger( L, 2 );
|
sfreq = luaL_checkinteger( L, 2 );
|
||||||
|
if ( sfreq < 0 )
|
||||||
|
return luaL_error( L, "frequency must be 0 or positive" );
|
||||||
|
freq = ( u32 ) sfreq;
|
||||||
if ( freq > 0 )
|
if ( freq > 0 )
|
||||||
{
|
{
|
||||||
timer_id = luaL_checkinteger( L, 3 );
|
timer_id = luaL_checkinteger( L, 3 );
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "platform_conf.h"
|
#include "platform_conf.h"
|
||||||
#ifdef BUILD_UIP
|
#ifdef BUILD_UIP
|
||||||
|
|
||||||
// Lua: sock, remoteip, err = accept( port, [timeout], [timer_id] )
|
// Lua: sock, remoteip, err = accept( port, [timer_id, timeout] )
|
||||||
static int net_accept( lua_State *L )
|
static int net_accept( lua_State *L )
|
||||||
{
|
{
|
||||||
u16 port = ( u16 )luaL_checkinteger( L, 1 );
|
u16 port = ( u16 )luaL_checkinteger( L, 1 );
|
||||||
@ -24,7 +24,7 @@ static int net_accept( lua_State *L )
|
|||||||
elua_net_ip remip;
|
elua_net_ip remip;
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
cmn_get_timeout_data( L, 2, &timeout, &timer_id );
|
cmn_get_timeout_data( L, 2, &timer_id, &timeout );
|
||||||
lua_pushinteger( L, sock = elua_accept( port, timer_id, timeout, &remip ) );
|
lua_pushinteger( L, sock = elua_accept( port, timer_id, timeout, &remip ) );
|
||||||
lua_pushinteger( L, remip.ipaddr );
|
lua_pushinteger( L, remip.ipaddr );
|
||||||
lua_pushinteger( L, elua_net_get_last_err( sock ) );
|
lua_pushinteger( L, elua_net_get_last_err( sock ) );
|
||||||
@ -137,8 +137,8 @@ static int net_unpackip( lua_State *L )
|
|||||||
return luaL_error( L, "invalid format" );
|
return luaL_error( L, "invalid format" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: res, err = recv( sock, maxsize, [timeout], [timer_id] ) or
|
// Lua: res, err = recv( sock, maxsize, [timer_id, timeout] ) or
|
||||||
// res, err = recv( sock, "*l", [timeout], [timer_id] )
|
// res, err = recv( sock, "*l", [timer_id, timeout] )
|
||||||
static int net_recv( lua_State *L )
|
static int net_recv( lua_State *L )
|
||||||
{
|
{
|
||||||
int sock = ( int )luaL_checkinteger( L, 1 );
|
int sock = ( int )luaL_checkinteger( L, 1 );
|
||||||
@ -157,7 +157,7 @@ static int net_recv( lua_State *L )
|
|||||||
lastchar = '\n';
|
lastchar = '\n';
|
||||||
maxsize = BUFSIZ;
|
maxsize = BUFSIZ;
|
||||||
}
|
}
|
||||||
cmn_get_timeout_data( L, 3, &timeout, &timer_id );
|
cmn_get_timeout_data( L, 3, &timer_id, &timeout );
|
||||||
// Initialize buffer
|
// Initialize buffer
|
||||||
luaL_buffinit( L, &net_recv_buff );
|
luaL_buffinit( L, &net_recv_buff );
|
||||||
elua_net_recvbuf( sock, &net_recv_buff, maxsize, lastchar, timer_id, timeout );
|
elua_net_recvbuf( sock, &net_recv_buff, maxsize, lastchar, timer_id, timeout );
|
||||||
|
@ -28,15 +28,15 @@ static int tmrh_timer_op( lua_State* L, int op )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: delay( period, [id] )
|
// Lua: delay( id, period )
|
||||||
static int tmr_delay( lua_State* L )
|
static int tmr_delay( lua_State* L )
|
||||||
{
|
{
|
||||||
timer_data_type period;
|
timer_data_type period;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|
||||||
period = ( timer_data_type )luaL_checknumber( L, 1 );
|
id = ( unsigned )luaL_optinteger( L, 1, PLATFORM_TIMER_SYS_ID );
|
||||||
id = ( unsigned )luaL_optinteger( L, 2, PLATFORM_TIMER_SYS_ID );
|
|
||||||
MOD_CHECK_TIMER( id );
|
MOD_CHECK_TIMER( id );
|
||||||
|
period = ( timer_data_type )luaL_checknumber( L, 2 );
|
||||||
platform_timer_delay( id, period );
|
platform_timer_delay( id, period );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -53,30 +53,30 @@ static int tmr_start( lua_State* L )
|
|||||||
return tmrh_timer_op( L, PLATFORM_TIMER_OP_START );
|
return tmrh_timer_op( L, PLATFORM_TIMER_OP_START );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: time_us = gettimediff( end, start, [id] )
|
// Lua: time_us = gettimediff( id, start, end )
|
||||||
static int tmr_gettimediff( lua_State* L )
|
static int tmr_gettimediff( lua_State* L )
|
||||||
{
|
{
|
||||||
timer_data_type end, start, res;
|
timer_data_type start, end, res;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|
||||||
id = ( unsigned )luaL_optinteger( L, 3, PLATFORM_TIMER_SYS_ID );
|
id = ( unsigned )luaL_optinteger( L, 1, PLATFORM_TIMER_SYS_ID );
|
||||||
MOD_CHECK_TIMER( id );
|
MOD_CHECK_TIMER( id );
|
||||||
end = ( timer_data_type )luaL_checknumber( L, 1 );
|
|
||||||
start = ( timer_data_type )luaL_checknumber( L, 2 );
|
start = ( timer_data_type )luaL_checknumber( L, 2 );
|
||||||
res = platform_timer_get_diff_us( id, end, start );
|
end = ( timer_data_type )luaL_checknumber( L, 3 );
|
||||||
|
res = platform_timer_get_diff_us( id, start, end );
|
||||||
lua_pushnumber( L, ( lua_Number )res );
|
lua_pushnumber( L, ( lua_Number )res );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: time_us = getdiffnow( start, [id] )
|
// Lua: time_us = getdiffnow( id, start )
|
||||||
static int tmr_getdiffnow( lua_State *L )
|
static int tmr_getdiffnow( lua_State *L )
|
||||||
{
|
{
|
||||||
timer_data_type start, res;
|
timer_data_type start, res;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|
||||||
id = ( unsigned )luaL_optinteger( L, 2, PLATFORM_TIMER_SYS_ID );
|
id = ( unsigned )luaL_optinteger( L, 1, PLATFORM_TIMER_SYS_ID );
|
||||||
MOD_CHECK_TIMER( id );
|
MOD_CHECK_TIMER( id );
|
||||||
start = ( timer_data_type )luaL_checknumber( L, 1 );
|
start = ( timer_data_type )luaL_checknumber( L, 2 );
|
||||||
res = platform_timer_get_diff_crt( id, start );
|
res = platform_timer_get_diff_crt( id, start );
|
||||||
lua_pushnumber( L, ( lua_Number )res );
|
lua_pushnumber( L, ( lua_Number )res );
|
||||||
return 1;
|
return 1;
|
||||||
@ -108,15 +108,15 @@ static int tmr_getmaxdelay( lua_State* L )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: realclock = setclock( clock, [id] )
|
// Lua: realclock = setclock( id, clock )
|
||||||
static int tmr_setclock( lua_State* L )
|
static int tmr_setclock( lua_State* L )
|
||||||
{
|
{
|
||||||
u32 clock;
|
u32 clock;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
|
||||||
id = ( unsigned )luaL_optinteger( L, 2, PLATFORM_TIMER_SYS_ID );
|
id = ( unsigned )luaL_optinteger( L, 1, PLATFORM_TIMER_SYS_ID );
|
||||||
MOD_CHECK_TIMER( id );
|
MOD_CHECK_TIMER( id );
|
||||||
clock = ( u32 )luaL_checkinteger( L, 1 );
|
clock = ( u32 )luaL_checkinteger( L, 2 );
|
||||||
clock = platform_timer_op( id, PLATFORM_TIMER_OP_SET_CLOCK, clock );
|
clock = platform_timer_op( id, PLATFORM_TIMER_OP_SET_CLOCK, clock );
|
||||||
lua_pushinteger( L, clock );
|
lua_pushinteger( L, clock );
|
||||||
return 1;
|
return 1;
|
||||||
@ -136,15 +136,15 @@ static int tmr_getclock( lua_State* L )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_LUA_INT_HANDLERS
|
#ifdef BUILD_LUA_INT_HANDLERS
|
||||||
// Lua: set_match_int( timeout, type, [id] )
|
// Lua: set_match_int( id, timeout, type )
|
||||||
static int tmr_set_match_int( lua_State *L )
|
static int tmr_set_match_int( lua_State *L )
|
||||||
{
|
{
|
||||||
unsigned id;
|
unsigned id;
|
||||||
u32 res;
|
u32 res;
|
||||||
|
|
||||||
id = ( unsigned )luaL_optinteger( L, 3, PLATFORM_TIMER_SYS_ID );
|
id = ( unsigned )luaL_optinteger( L, 1, PLATFORM_TIMER_SYS_ID );
|
||||||
MOD_CHECK_TIMER( id );
|
MOD_CHECK_TIMER( id );
|
||||||
res = platform_timer_set_match_int( id, ( timer_data_type )luaL_checknumber( L, 1 ), ( int )luaL_checkinteger( L, 2 ) );
|
res = platform_timer_set_match_int( id, ( timer_data_type )luaL_checknumber( L, 2 ), ( int )luaL_checkinteger( L, 3 ) );
|
||||||
if( res == PLATFORM_TIMER_INT_TOO_SHORT )
|
if( res == PLATFORM_TIMER_INT_TOO_SHORT )
|
||||||
return luaL_error( L, "timer interval too small" );
|
return luaL_error( L, "timer interval too small" );
|
||||||
else if( res == PLATFORM_TIMER_INT_TOO_LONG )
|
else if( res == PLATFORM_TIMER_INT_TOO_LONG )
|
||||||
@ -200,6 +200,8 @@ const LUA_REG_TYPE tmr_map[] =
|
|||||||
#endif
|
#endif
|
||||||
#if VTMR_NUM_TIMERS > 0
|
#if VTMR_NUM_TIMERS > 0
|
||||||
{ LSTRKEY( "__index" ), LFUNCVAL( tmr_mt_index ) },
|
{ LSTRKEY( "__index" ), LFUNCVAL( tmr_mt_index ) },
|
||||||
|
#endif
|
||||||
|
#if LUA_OPTIMIZE_MEMORY > 0
|
||||||
{ LSTRKEY( "SYS_TIMER" ), LNUMVAL( PLATFORM_TIMER_SYS_ID ) },
|
{ LSTRKEY( "SYS_TIMER" ), LNUMVAL( PLATFORM_TIMER_SYS_ID ) },
|
||||||
#endif
|
#endif
|
||||||
#if LUA_OPTIMIZE_MEMORY > 0 && defined( BUILD_LUA_INT_HANDLERS )
|
#if LUA_OPTIMIZE_MEMORY > 0 && defined( BUILD_LUA_INT_HANDLERS )
|
||||||
|
@ -24,6 +24,27 @@ enum
|
|||||||
|
|
||||||
#define UART_INFINITE_TIMEOUT PLATFORM_TIMER_INF_TIMEOUT
|
#define UART_INFINITE_TIMEOUT PLATFORM_TIMER_INF_TIMEOUT
|
||||||
|
|
||||||
|
// Helper function, the same as cmn_get_timeout_data() but with the
|
||||||
|
// parameters in the order required by the uart module.
|
||||||
|
|
||||||
|
static void uart_get_timeout_data( lua_State *L, int pidx, timer_data_type *ptimeout, unsigned *pid )
|
||||||
|
{
|
||||||
|
lua_Number tempn;
|
||||||
|
|
||||||
|
*ptimeout = PLATFORM_TIMER_INF_TIMEOUT;
|
||||||
|
if( lua_type( L, pidx ) == LUA_TNUMBER )
|
||||||
|
{
|
||||||
|
tempn = lua_tonumber( L, pidx );
|
||||||
|
if( tempn < 0 || tempn > PLATFORM_TIMER_INF_TIMEOUT )
|
||||||
|
luaL_error( L, "invalid timeout value" );
|
||||||
|
*ptimeout = ( timer_data_type )tempn;
|
||||||
|
}
|
||||||
|
*pid = ( unsigned )luaL_optinteger( L, pidx + 1, PLATFORM_TIMER_SYS_ID );
|
||||||
|
if( *pid == PLATFORM_TIMER_SYS_ID && !platform_timer_sys_available() )
|
||||||
|
luaL_error( L, "the system timer is not implemented on this platform" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lua: actualbaud = setup( id, baud, databits, parity, stopbits )
|
// Lua: actualbaud = setup( id, baud, databits, parity, stopbits )
|
||||||
static int uart_setup( lua_State* L )
|
static int uart_setup( lua_State* L )
|
||||||
{
|
{
|
||||||
@ -108,7 +129,7 @@ static int uart_read( lua_State* L )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check timeout and timer id
|
// Check timeout and timer id
|
||||||
cmn_get_timeout_data( L, 3, &timeout, &timer_id );
|
uart_get_timeout_data( L, 3, &timeout, &timer_id );
|
||||||
|
|
||||||
// Read data
|
// Read data
|
||||||
luaL_buffinit( L, &b );
|
luaL_buffinit( L, &b );
|
||||||
@ -154,7 +175,7 @@ static int uart_getchar( lua_State* L )
|
|||||||
id = luaL_checkinteger( L, 1 );
|
id = luaL_checkinteger( L, 1 );
|
||||||
MOD_CHECK_ID( uart, id );
|
MOD_CHECK_ID( uart, id );
|
||||||
// Check timeout and timer id
|
// Check timeout and timer id
|
||||||
cmn_get_timeout_data( L, 2, &timeout, &timer_id );
|
uart_get_timeout_data( L, 2, &timeout, &timer_id );
|
||||||
res = platform_uart_recv( id, timer_id, timeout );
|
res = platform_uart_recv( id, timer_id, timeout );
|
||||||
if( res == -1 )
|
if( res == -1 )
|
||||||
lua_pushstring( L, "" );
|
lua_pushstring( L, "" );
|
||||||
@ -261,23 +282,18 @@ LUALIB_API int luaopen_uart( lua_State *L )
|
|||||||
#else // #if LUA_OPTIMIZE_MEMORY > 0
|
#else // #if LUA_OPTIMIZE_MEMORY > 0
|
||||||
luaL_register( L, AUXLIB_UART, uart_map );
|
luaL_register( L, AUXLIB_UART, uart_map );
|
||||||
|
|
||||||
// Add the stop bits and parity constants (for uart.setup)
|
|
||||||
MOD_REG_NUMBER( L, "PAR_EVEN", PLATFORM_UART_PARITY_EVEN );
|
MOD_REG_NUMBER( L, "PAR_EVEN", PLATFORM_UART_PARITY_EVEN );
|
||||||
MOD_REG_NUMBER( L, "PAR_ODD", PLATFORM_UART_PARITY_ODD );
|
MOD_REG_NUMBER( L, "PAR_ODD", PLATFORM_UART_PARITY_ODD );
|
||||||
MOD_REG_NUMBER( L, "PAR_NONE", PLATFORM_UART_PARITY_NONE );
|
MOD_REG_NUMBER( L, "PAR_NONE", PLATFORM_UART_PARITY_NONE );
|
||||||
MOD_REG_NUMBER( L, "STOP_1", PLATFORM_UART_STOPBITS_1 );
|
MOD_REG_NUMBER( L, "STOP_1", PLATFORM_UART_STOPBITS_1 );
|
||||||
MOD_REG_NUMBER( L, "STOP_1_5", PLATFORM_UART_STOPBITS_1_5 );
|
MOD_REG_NUMBER( L, "STOP_1_5", PLATFORM_UART_STOPBITS_1_5 );
|
||||||
MOD_REG_NUMBER( L, "STOP_2", PLATFORM_UART_STOPBITS_2 );
|
MOD_REG_NUMBER( L, "STOP_2", PLATFORM_UART_STOPBITS_2 );
|
||||||
|
|
||||||
// Add the "none" and "infinite" constant used in recv()
|
|
||||||
MOD_REG_NUMBER( L, "NO_TIMEOUT", 0 );
|
MOD_REG_NUMBER( L, "NO_TIMEOUT", 0 );
|
||||||
MOD_REG_NUMBER( L, "INF_TIMEOUT", UART_INFINITE_TIMEOUT );
|
MOD_REG_NUMBER( L, "INF_TIMEOUT", UART_INFINITE_TIMEOUT );
|
||||||
// Also add the system timer ID
|
MOD_REG_NUMBER( L, "FLOW_NONE", PLATFORM_UART_FLOW_NONE );
|
||||||
MOD_REG_NUMBER( L, "SYS_TIMER", PLATFORM_TIMER_SYS_ID );
|
|
||||||
|
|
||||||
// Add the UART flow constants
|
|
||||||
MOD_REG_NUMBER( L, "FLOW_RTS", PLATFORM_UART_FLOW_RTS );
|
MOD_REG_NUMBER( L, "FLOW_RTS", PLATFORM_UART_FLOW_RTS );
|
||||||
MOD_REG_NUMBER( L, "FLOW_CTS", PLATFORM_UART_FLOW_CTS );
|
MOD_REG_NUMBER( L, "FLOW_CTS", PLATFORM_UART_FLOW_CTS );
|
||||||
|
MOD_REG_NUMBER( L, "SYS_TIMER", PLATFORM_TIMER_SYS_ID );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
||||||
|
@ -43,15 +43,18 @@ static _ssize_t std_read( struct _reent *r, int fd, void* vptr, size_t len )
|
|||||||
i = 0;
|
i = 0;
|
||||||
while( i < len )
|
while( i < len )
|
||||||
{
|
{
|
||||||
|
// If we have a lookahead char from the previous run of std_read,
|
||||||
|
// process it now.
|
||||||
if( std_prev_char != -1 )
|
if( std_prev_char != -1 )
|
||||||
{
|
{
|
||||||
// We have a char from the previous run of std_read, so put it in the buffer
|
c = std_prev_char;
|
||||||
ptr[ i ++ ] = ( char )std_prev_char;
|
|
||||||
std_prev_char = -1;
|
std_prev_char = -1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if( ( c = std_get_char_func( STD_INFINITE_TIMEOUT ) ) == -1 )
|
if( ( c = std_get_char_func( STD_INFINITE_TIMEOUT ) ) == -1 )
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if( ( c == 8 ) || ( c == 0x7F ) ) // Backspace
|
if( ( c == 8 ) || ( c == 0x7F ) ) // Backspace
|
||||||
{
|
{
|
||||||
if( i > 0 )
|
if( i > 0 )
|
||||||
|
@ -182,7 +182,7 @@ _ssize_t _write_r( struct _reent *r, int file, const void *ptr, size_t len )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// Miscalenous functions
|
// Miscellaneous functions
|
||||||
|
|
||||||
int _isatty_r( struct _reent* r, int fd )
|
int _isatty_r( struct _reent* r, int fd )
|
||||||
{
|
{
|
||||||
@ -375,7 +375,7 @@ const DM_DEVICE* std_get_desc()
|
|||||||
#endif // #if !defined( BUILD_CON_GENERIC ) && !defined( BUILD_CON_TCP )
|
#endif // #if !defined( BUILD_CON_GENERIC ) && !defined( BUILD_CON_TCP )
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// memcpy is broken on AVR32's Newlib, so impolement a simple version here
|
// memcpy is broken on AVR32's Newlib, so implement a simple version here
|
||||||
// same goes for strcmp apparently
|
// same goes for strcmp apparently
|
||||||
#ifdef FORAVR32
|
#ifdef FORAVR32
|
||||||
void* memcpy( void *dst, const void* src, size_t len )
|
void* memcpy( void *dst, const void* src, size_t len )
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
// Virtual timers (0 if not used)
|
// Virtual timers (0 if not used)
|
||||||
#define VTMR_NUM_TIMERS 4
|
#define VTMR_NUM_TIMERS 4
|
||||||
#define VTMR_FREQ_HZ 10
|
#define VTMR_FREQ_HZ 10
|
||||||
|
#define VTMR_CH 2 // Which hardware timer to use for VTMR
|
||||||
|
|
||||||
// Number of resources (0 if not available/not implemented)
|
// Number of resources (0 if not available/not implemented)
|
||||||
#define NUM_PIO 4
|
#define NUM_PIO 4
|
||||||
@ -156,8 +157,16 @@
|
|||||||
|
|
||||||
// Allocator data: define your free memory zones here in two arrays
|
// Allocator data: define your free memory zones here in two arrays
|
||||||
// (start address and end address)
|
// (start address and end address)
|
||||||
|
#ifdef USE_MULTIPLE_ALLOCATOR
|
||||||
#define MEM_START_ADDRESS { ( void* )end, ( void* )SDRAM }
|
#define MEM_START_ADDRESS { ( void* )end, ( void* )SDRAM }
|
||||||
#define MEM_END_ADDRESS { ( void* )( 0x10000 - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
#define MEM_END_ADDRESS { ( void* )( 0x10000 - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
||||||
|
#else
|
||||||
|
// Newlib<1.19.0 has a bug in their dlmalloc that corrupts memory when there
|
||||||
|
// are multiple regions, and it appears that simple allocator also has problems.
|
||||||
|
// So with these allocators, only use a single region - the slower 32MB one.
|
||||||
|
#define MEM_START_ADDRESS { ( void* )SDRAM }
|
||||||
|
#define MEM_END_ADDRESS { ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
||||||
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
|
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
// Virtual timers (0 if not used)
|
// Virtual timers (0 if not used)
|
||||||
#define VTMR_NUM_TIMERS 4
|
#define VTMR_NUM_TIMERS 4
|
||||||
#define VTMR_FREQ_HZ 10
|
#define VTMR_FREQ_HZ 10
|
||||||
|
#define VTMR_CH 2 // Which hardware timer to use for VTMR
|
||||||
|
|
||||||
// Number of resources (0 if not available/not implemented)
|
// Number of resources (0 if not available/not implemented)
|
||||||
#define NUM_PIO 2
|
#define NUM_PIO 2
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
*/
|
*/
|
||||||
//! @{
|
//! @{
|
||||||
|
|
||||||
|
// Doesn't work yet in the hardware
|
||||||
|
//#define FOSC32 32768 //!< Osc32 frequency: Hz.
|
||||||
|
|
||||||
#define FOSC0 12000000 //!< Osc0 frequency: Hz.
|
#define FOSC0 12000000 //!< Osc0 frequency: Hz.
|
||||||
#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods.
|
#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods.
|
||||||
|
|
||||||
|
@ -9,20 +9,17 @@
|
|||||||
|
|
||||||
#include "sdramc.h"
|
#include "sdramc.h"
|
||||||
#include "sermux.h"
|
#include "sermux.h"
|
||||||
|
#include "usb-cdc.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
|
||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// Define here what components you want for this platform
|
// Define here what components you want for this platform
|
||||||
|
|
||||||
#define BUILD_MMCFS
|
#define BUILD_MMCFS
|
||||||
//#define BUILD_XMODEM
|
|
||||||
//#define BUILD_SHELL
|
|
||||||
//#define BUILD_ROMFS
|
//#define BUILD_ROMFS
|
||||||
#define BUILD_CON_GENERIC
|
#define BUILD_CON_GENERIC
|
||||||
//#define BUILD_RPC
|
//#define BUILD_RPC
|
||||||
#define BUF_ENABLE_UART
|
|
||||||
#define BUILD_C_INT_HANDLERS
|
#define BUILD_C_INT_HANDLERS
|
||||||
#define BUILD_LUA_INT_HANDLERS
|
|
||||||
//#define BUILD_RFS
|
//#define BUILD_RFS
|
||||||
//#define BUILD_SERMUX
|
//#define BUILD_SERMUX
|
||||||
|
|
||||||
@ -32,14 +29,18 @@
|
|||||||
#else
|
#else
|
||||||
// Build options for 256KB and 512KB flash
|
// Build options for 256KB and 512KB flash
|
||||||
# define RAM_SIZE 0x10000
|
# define RAM_SIZE 0x10000
|
||||||
|
# define BUILD_SHELL
|
||||||
|
# define BUILD_XMODEM
|
||||||
# define BUILD_ADC
|
# define BUILD_ADC
|
||||||
# define BUILD_LCD
|
# define BUILD_LCD
|
||||||
# define BUILD_TERM
|
# define BUILD_TERM
|
||||||
# define BUILD_UIP
|
# define BUILD_UIP
|
||||||
|
# define BUILD_LUA_INT_HANDLERS
|
||||||
|
# define BUILD_USB_CDC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_UIP
|
#ifdef BUILD_UIP
|
||||||
//#define BUILD_DHCPC
|
#define BUILD_DHCPC
|
||||||
#define BUILD_DNS
|
#define BUILD_DNS
|
||||||
//#define BUILD_CON_TCP
|
//#define BUILD_CON_TCP
|
||||||
#endif
|
#endif
|
||||||
@ -55,12 +56,21 @@
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// UART/Timer IDs configuration data (used in main.c)
|
// UART/Timer IDs configuration data (used in main.c)
|
||||||
|
|
||||||
#ifdef BUILD_SERMUX
|
#define BUF_ENABLE_UART
|
||||||
|
|
||||||
|
#ifdef BUILD_USB_CDC
|
||||||
|
# define CON_UART_ID CDC_UART_ID
|
||||||
|
#elif defined( BUILD_SERMUX )
|
||||||
# define CON_UART_ID ( SERMUX_SERVICE_ID_FIRST + 1 )
|
# define CON_UART_ID ( SERMUX_SERVICE_ID_FIRST + 1 )
|
||||||
#else
|
#else
|
||||||
# define CON_UART_ID 0
|
# define CON_UART_ID 0
|
||||||
#endif
|
|
||||||
# define CON_UART_SPEED 115200
|
# define CON_UART_SPEED 115200
|
||||||
|
// As flow control seems not to work, we use a large buffer so that people
|
||||||
|
// can copy/paste program fragments or data into the serial console.
|
||||||
|
// An 80x25 screenful is 2000 characters so we use 2048.
|
||||||
|
# define CON_BUF_SIZE BUF_SIZE_2048
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TERM_LINES 25
|
#define TERM_LINES 25
|
||||||
#define TERM_COLS 80
|
#define TERM_COLS 80
|
||||||
|
|
||||||
@ -122,6 +132,7 @@
|
|||||||
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
||||||
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
||||||
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||||
|
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -152,6 +163,7 @@
|
|||||||
// Virtual timers (0 if not used)
|
// Virtual timers (0 if not used)
|
||||||
#define VTMR_NUM_TIMERS 4
|
#define VTMR_NUM_TIMERS 4
|
||||||
#define VTMR_FREQ_HZ 10
|
#define VTMR_FREQ_HZ 10
|
||||||
|
#define VTMR_CH 2 // Which hardware timer to use for VTMR
|
||||||
|
|
||||||
// Number of resources (0 if not available/not implemented)
|
// Number of resources (0 if not available/not implemented)
|
||||||
#define NUM_PIO 4
|
#define NUM_PIO 4
|
||||||
@ -167,15 +179,10 @@
|
|||||||
#define NUM_ADC 8 // Though ADC3 pin is the Ethernet IRQ
|
#define NUM_ADC 8 // Though ADC3 pin is the Ethernet IRQ
|
||||||
#define NUM_CAN 0
|
#define NUM_CAN 0
|
||||||
|
|
||||||
// As flow control seems not to work, we use a large buffer so that people
|
|
||||||
// can copy/paste program fragments or data into the serial console.
|
|
||||||
// An 80x25 screenful is 2000 characters so we use 2048 and the buffer is
|
|
||||||
// allocated from the 32MB SDRAM so there is no effective limit.
|
|
||||||
#define CON_BUF_SIZE BUF_SIZE_2048
|
|
||||||
|
|
||||||
// RPC boot options
|
// RPC boot options
|
||||||
#define RPC_UART_ID CON_UART_ID
|
#define RPC_UART_ID 0
|
||||||
#define RPC_UART_SPEED CON_UART_SPEED
|
#define RPC_UART_SPEED 115200
|
||||||
|
|
||||||
// ADC Configuration Params
|
// ADC Configuration Params
|
||||||
#define ADC_BIT_RESOLUTION 10
|
#define ADC_BIT_RESOLUTION 10
|
||||||
@ -211,8 +218,16 @@
|
|||||||
|
|
||||||
// Allocator data: define your free memory zones here in two arrays
|
// Allocator data: define your free memory zones here in two arrays
|
||||||
// (start address and end address)
|
// (start address and end address)
|
||||||
|
#ifdef USE_MULTIPLE_ALLOCATOR
|
||||||
#define MEM_START_ADDRESS { ( void* )end, ( void* )( SDRAM + ELUA_FIRMWARE_SIZE ) }
|
#define MEM_START_ADDRESS { ( void* )end, ( void* )( SDRAM + ELUA_FIRMWARE_SIZE ) }
|
||||||
#define MEM_END_ADDRESS { ( void* )( RAM_SIZE - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
#define MEM_END_ADDRESS { ( void* )( RAM_SIZE - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
||||||
|
#else
|
||||||
|
// Newlib<1.19.0 has a bug in their dlmalloc that corrupts memory when there
|
||||||
|
// are multiple regions, and it appears that simple allocator also has problems.
|
||||||
|
// So with these allocators, only use a single region - the slower 32MB one.
|
||||||
|
#define MEM_START_ADDRESS { ( void* )( SDRAM + ELUA_FIRMWARE_SIZE ) }
|
||||||
|
#define MEM_END_ADDRESS { ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
||||||
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
|
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
|
||||||
|
@ -50,19 +50,66 @@
|
|||||||
#include <avr32/io.h>
|
#include <avr32/io.h>
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "platform_conf.h" // For REQ_PBA_FREQ
|
||||||
|
|
||||||
|
|
||||||
void adc_configure(volatile avr32_adc_t * adc)
|
void adc_configure(volatile avr32_adc_t * adc)
|
||||||
{
|
{
|
||||||
|
unsigned int prescal; // Value for ADC mode register's PRESCAL field
|
||||||
|
unsigned long ADCClock; // The ADC clock rate that we set
|
||||||
|
unsigned int shtim; // Value for ADC mode register's SHTIM field
|
||||||
|
unsigned long THAT; // Track-and-Hold Acquisition Time in nanoseconds
|
||||||
|
unsigned int startup; // Value for ADC mode register's START field
|
||||||
|
unsigned long StartupTime; // Startup time in microseconds
|
||||||
|
|
||||||
Assert( adc!=NULL );
|
Assert( adc!=NULL );
|
||||||
|
|
||||||
#ifdef USE_ADC_8_BITS
|
#ifdef USE_ADC_8_BITS
|
||||||
adc->mr |= 1<<AVR32_ADC_LOWRES_OFFSET;
|
adc->mr |= 1<<AVR32_ADC_LOWRES_OFFSET;
|
||||||
#endif
|
#endif
|
||||||
// set Sample/Hold time to max so that the ADC capacitor should be loaded entirely
|
|
||||||
adc->mr |= 0xF << AVR32_ADC_SHTIM_OFFSET;
|
// Ensure the ADC clock is within spec: 5MHz for 10-bit, 8MHz for 8-bit
|
||||||
// set Startup to max so that the ADC capacitor should be loaded entirely
|
// ADCClock = CLK_ADC / ((PRESCAL + 1) * 2)
|
||||||
adc->mr |= 0x1F << AVR32_ADC_STARTUP_OFFSET;
|
// PRESCAL is a 6-bit field with values up to 63.
|
||||||
|
prescal = 0;
|
||||||
|
do {
|
||||||
|
ADCClock = REQ_PBA_FREQ / ((prescal + 1) * 2);
|
||||||
|
} while ( ADCClock >
|
||||||
|
#ifdef USE_ADC_8_BITS
|
||||||
|
8000000
|
||||||
|
#else
|
||||||
|
5000000
|
||||||
|
#endif
|
||||||
|
&& ++prescal < 63);
|
||||||
|
adc->MR.prescal = prescal;
|
||||||
|
|
||||||
|
// Ensure the ADC sample-and-hold time is within spec: 600ns minimum.
|
||||||
|
|
||||||
|
// Track and Hold Acquisition Time ("THAT") = (SHTIM + 1) / ADCClock.
|
||||||
|
shtim = 0;
|
||||||
|
do {
|
||||||
|
// We want the result in nanoseconds, hence the 1000000000.
|
||||||
|
// However, with 32-bit ints, 1000000000*(shtim+1) overflows when
|
||||||
|
// shtim+1 > 4 and SHTIM is a 4-bit field so shtim+1 goes up to 16.
|
||||||
|
// So we divide top and bottom by 4 to avoid the overflow.
|
||||||
|
THAT = ((1000000000/4) * (shtim + 1)) / (ADCClock/4);
|
||||||
|
} while (THAT < 600 && ++shtim < 15);
|
||||||
|
adc->MR.shtim = shtim;
|
||||||
|
|
||||||
|
// Startup time should only happen when the ADC has SLEEP bit set in MR,
|
||||||
|
// but it does affect the performance, maybe because the current eLua code
|
||||||
|
// issues software resets to the ADC every time it requests samples.
|
||||||
|
// So we set it within spec anyway.
|
||||||
|
|
||||||
|
// Ensure the ADC startup time is within spec, which is 20us minimum.
|
||||||
|
// Startup = (START + 1) * 8 / ADCClock.
|
||||||
|
// START is a 5-bit field with values up to 31.
|
||||||
|
startup = 0;
|
||||||
|
do {
|
||||||
|
// We want the result in microseconds, hence the 1000000.
|
||||||
|
StartupTime = (1000000 * (startup + 1) * 8) / ADCClock;
|
||||||
|
} while (StartupTime < 20 && ++startup < 31);
|
||||||
|
adc->MR.startup = startup;
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_start(volatile avr32_adc_t * adc)
|
void adc_start(volatile avr32_adc_t * adc)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Configuration file for the AVR32 microcontrollers
|
# 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 i2c.c ethernet.c lcd.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 i2c.c ethernet.c lcd.c usb-cdc.c"
|
||||||
comp.Append(CPPDEFINES = 'FORAVR32')
|
comp.Append(CPPDEFINES = 'FORAVR32')
|
||||||
|
|
||||||
# See board.h for possible BOARD values.
|
# See board.h for possible BOARD values.
|
||||||
|
@ -302,19 +302,13 @@ unsigned char i2c_read_byte(int nack)
|
|||||||
// Pause for half an I2C bus clock cycle
|
// Pause for half an I2C bus clock cycle
|
||||||
static void I2CDELAY()
|
static void I2CDELAY()
|
||||||
{
|
{
|
||||||
// Code stolen from sdramc.c::sdramc_ck_delay()
|
|
||||||
|
|
||||||
// Use the CPU cycle counter (CPU and HSB clocks are the same).
|
// Use the CPU cycle counter (CPU and HSB clocks are the same).
|
||||||
u32 delay_start_cycle = Get_system_register(AVR32_COUNT);
|
u32 delay_start_cycle = Get_system_register(AVR32_COUNT);
|
||||||
u32 delay_end_cycle = delay_start_cycle + i2c_delay;
|
|
||||||
|
|
||||||
// To be safer, the end of wait is based on an inequality test, so CPU cycle
|
// at 60MHz the count register wraps every 71.68 secs, at 66MHz every 65s.
|
||||||
// counter wrap around is checked.
|
// The following unsigned arithmetic handles the wraparound condition.
|
||||||
if (delay_start_cycle > delay_end_cycle)
|
while( (u32)Get_system_register(AVR32_COUNT) - delay_start_cycle < i2c_delay )
|
||||||
{
|
/* wait */;
|
||||||
while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle);
|
|
||||||
}
|
|
||||||
while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set SCL as input and return current level of line
|
// Set SCL as input and return current level of line
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
|
|
||||||
// Since the LCD firmware currently only runs at up to 20kHz on the I2C bus,
|
// The LCD firmware only runs at up to 50kHz on the I2C bus, so
|
||||||
// we bracket all I2C packets to the LCD module with two functions
|
// we bracket all I2C packets to the LCD module with two functions
|
||||||
// to be able to save, change and restore the I2C clock rate to what it was
|
// to be able to save, change and restore the I2C clock rate to what it was
|
||||||
// before.
|
// before.
|
||||||
@ -41,100 +41,97 @@ static void lcd_stop()
|
|||||||
|
|
||||||
// Send a command or data packet.
|
// Send a command or data packet.
|
||||||
// "address" is LCD_CMD for LCD commands, LCD_DATA for LCD data.
|
// "address" is LCD_CMD for LCD commands, LCD_DATA for LCD data.
|
||||||
static int send_generic(char address, const char *data, int len)
|
static int send_generic( u8 address, const u8 *data, int len )
|
||||||
{
|
{
|
||||||
while (len > 0) {
|
|
||||||
int nbytes; // number of bytes sent in this I2C packet
|
|
||||||
|
|
||||||
lcd_start();
|
lcd_start();
|
||||||
i2c_start_cond();
|
i2c_start_cond();
|
||||||
i2c_write_byte( address );
|
i2c_write_byte( address );
|
||||||
// Mizar32 LCD module has a maximum of 31 bytes per data packet
|
while ( len > 0 ) {
|
||||||
nbytes = 0;
|
|
||||||
while ( len > 0 && nbytes < 31 ) {
|
|
||||||
i2c_write_byte( *data++ );
|
i2c_write_byte( *data++ );
|
||||||
nbytes++; len--;
|
len--;
|
||||||
}
|
}
|
||||||
i2c_stop_cond();
|
i2c_stop_cond();
|
||||||
lcd_stop();
|
lcd_stop();
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a single command byte
|
// Send an I2C read-data command and return the answer.
|
||||||
static int send_command(const char command)
|
// "address" is LCD_GETPOS to read the cursor position,
|
||||||
|
// LCD_BUTTONS for to read the buttons.
|
||||||
|
// The answer is always a single byte.
|
||||||
|
static u8 recv_generic( u8 address )
|
||||||
|
{
|
||||||
|
u8 retval;
|
||||||
|
|
||||||
|
lcd_start();
|
||||||
|
i2c_start_cond();
|
||||||
|
|
||||||
|
// Send the slave address.
|
||||||
|
if ( i2c_write_byte( address ) == 0 )
|
||||||
|
// NAK the single byte to signal end of transfer
|
||||||
|
retval = i2c_read_byte( TRUE );
|
||||||
|
else
|
||||||
|
// The address was not acknowledged, so no slave is present.
|
||||||
|
// There is no way to signal this to the Lua layer, so return a
|
||||||
|
// harmless value (meaning no buttons pressed or cursor at (1,1)).
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
i2c_stop_cond();
|
||||||
|
lcd_stop();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a command byte
|
||||||
|
static int send_command( const u8 command )
|
||||||
{
|
{
|
||||||
return send_generic( LCD_CMD, &command, 1 );
|
return send_generic( LCD_CMD, &command, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send multiple command bytes as one message
|
|
||||||
static int send_commands(const char *commands, int len)
|
|
||||||
{
|
|
||||||
return send_generic(LCD_CMD, commands, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send data bytes
|
// Send data bytes
|
||||||
// This is used for printing data and for programming the user-defining chars
|
// This is used for printing data and for programming the user-defining chars
|
||||||
static int send_data(const char *data, int len)
|
static int send_data( const u8 *data, int len )
|
||||||
{
|
{
|
||||||
return send_generic( LCD_DATA, data, len );
|
return send_generic( LCD_DATA, data, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the current value of the address counter.
|
||||||
|
static u8 recv_address_counter()
|
||||||
|
{
|
||||||
|
return recv_generic( LCD_GETPOS );
|
||||||
|
}
|
||||||
|
|
||||||
// *** Lua module functions begin... ***
|
// Return the current state of the buttons, a bit mask in the bottom 5 bits
|
||||||
|
// of a byte.
|
||||||
|
static u8 recv_buttons()
|
||||||
|
{
|
||||||
|
return recv_generic( LCD_BUTTONS );
|
||||||
|
}
|
||||||
|
|
||||||
// Turning the display on can only be achieved by simultaneously specifying the
|
// Turning the display on can only be achieved by simultaneously specifying the
|
||||||
// cursor type, so we have to remember what type of cursor they last set.
|
// cursor type, so we have to remember what type of cursor they last set.
|
||||||
// Similarly, if they have turned the display off then set the cursor, this
|
// Similarly, if they have turned the display off then set the cursor, this
|
||||||
// shouldn-t turn the display on.
|
// shouldn't turn the display on.
|
||||||
|
|
||||||
// Power-on setting is no cursor
|
// Power-on setting is no cursor
|
||||||
#define DEFAULT_CURSOR_TYPE LCD_CMD_CURSOR_NONE
|
#define DEFAULT_CURSOR_TYPE LCD_CMD_CURSOR_NONE
|
||||||
|
|
||||||
static char cursor_type = DEFAULT_CURSOR_TYPE;
|
static u8 cursor_type = DEFAULT_CURSOR_TYPE;
|
||||||
static char display_is_off = 0; // Have they called display("off")?
|
static u8 display_is_off = 0; // Have they called display("off")?
|
||||||
|
|
||||||
|
|
||||||
// Should we try to maintain the current cursor position across a definechar()?
|
// *** Lua module functions begin... ***
|
||||||
// Unfortunately we can't read the current cursor position, and definechar()
|
|
||||||
// destroys it. The LCD controller does have a read-cursor-position primitive
|
|
||||||
// but the current PIC firmware doesn't pass this on as an I2C read.2
|
|
||||||
// So we have to track the cursor position. Yuk.
|
|
||||||
// The only relief is that we don't have to track the display scrolling.
|
|
||||||
// Adds 284 bytes of code to the executable.
|
|
||||||
//
|
|
||||||
// If, one day, we can read the LCD cursor position through the PIC firmware
|
|
||||||
// we can remove all this stuff.
|
|
||||||
#define KEEP_CURSOR_POSITION 1
|
|
||||||
|
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
// Where is the cursor in the character memory? Required ONLY to be able to
|
|
||||||
// restore the cursor position when they define a character :-/
|
|
||||||
static int current_row = 0; // 0 or 1
|
|
||||||
static int current_column = 0; // 0-39 (though it over- and underflows)
|
|
||||||
static int current_direction = 1; // left-to-right. -1 is right-to-left
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Lua: mizar32.disp.reset()
|
// Lua: mizar32.disp.reset()
|
||||||
// Ensure the display is in a known initial state
|
// Ensure the display is in a known initial state
|
||||||
static int lcd_reset( lua_State *L )
|
static int lcd_reset( lua_State *L )
|
||||||
{
|
{
|
||||||
// Initialise the display to a known state
|
|
||||||
static const char reset[] = {
|
|
||||||
0 /* reset */
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set the static variables
|
// Set the static variables
|
||||||
cursor_type = DEFAULT_CURSOR_TYPE;
|
cursor_type = DEFAULT_CURSOR_TYPE;
|
||||||
display_is_off = 0;
|
display_is_off = 0;
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_row = current_column = 0;
|
|
||||||
current_direction = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return send_commands( reset, sizeof( reset ) );
|
return send_command( LCD_CMD_RESET );
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Entry mode" function.
|
// "Entry mode" function.
|
||||||
@ -147,10 +144,6 @@ static int lcd_setup( lua_State *L )
|
|||||||
unsigned shift_display = lua_toboolean( L, 1 ); // Default: move cursor
|
unsigned shift_display = lua_toboolean( L, 1 ); // Default: move cursor
|
||||||
unsigned right_to_left = lua_toboolean( L, 2 ); // Default: print left-to-right
|
unsigned right_to_left = lua_toboolean( L, 2 ); // Default: print left-to-right
|
||||||
|
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_direction = right_to_left ? -1 : 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return send_command( LCD_CMD_ENTRYMODE + shift_display +
|
return send_command( LCD_CMD_ENTRYMODE + shift_display +
|
||||||
( ! right_to_left ) * 2 );
|
( ! right_to_left ) * 2 );
|
||||||
}
|
}
|
||||||
@ -159,9 +152,6 @@ static int lcd_setup( lua_State *L )
|
|||||||
// Clear the display, reset its shiftedness and put the cursor at 1,1
|
// Clear the display, reset its shiftedness and put the cursor at 1,1
|
||||||
static int lcd_clear( lua_State *L )
|
static int lcd_clear( lua_State *L )
|
||||||
{
|
{
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_row = current_column = 0;
|
|
||||||
#endif
|
|
||||||
return send_command( LCD_CMD_CLEAR );
|
return send_command( LCD_CMD_CLEAR );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,9 +159,6 @@ static int lcd_clear( lua_State *L )
|
|||||||
// Reset the display's shiftedness and put the cursor at 1,1
|
// Reset the display's shiftedness and put the cursor at 1,1
|
||||||
static int lcd_home( lua_State *L )
|
static int lcd_home( lua_State *L )
|
||||||
{
|
{
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_row = current_column = 0;
|
|
||||||
#endif
|
|
||||||
return send_command( LCD_CMD_HOME );
|
return send_command( LCD_CMD_HOME );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,19 +167,15 @@ static int lcd_home(lua_State *L)
|
|||||||
// in the character memory.
|
// in the character memory.
|
||||||
static int lcd_goto( lua_State *L )
|
static int lcd_goto( lua_State *L )
|
||||||
{
|
{
|
||||||
unsigned row = luaL_checkinteger( L, 1 );
|
int row = luaL_checkinteger( L, 1 );
|
||||||
unsigned col = luaL_checkinteger( L, 2 );
|
int col = luaL_checkinteger( L, 2 );
|
||||||
unsigned address;
|
unsigned address;
|
||||||
|
|
||||||
if ( row < 1 || row > 2 || col < 1 || col > 40 )
|
if ( row < 1 || row > 2 || col < 1 || col > 40 )
|
||||||
return luaL_error( L, "row/column must be 1-2 and 1-40" );
|
return luaL_error( L, "row/column must be 1-2 and 1-40" );
|
||||||
|
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_row = row - 1;
|
|
||||||
current_column = col - 1;
|
|
||||||
#endif
|
|
||||||
address = ( row - 1 ) * 0x40 + ( col - 1 ) ;
|
address = ( row - 1 ) * 0x40 + ( col - 1 ) ;
|
||||||
return send_command( LCD_CMD_DDADDR + address );
|
return send_command( (u8) (LCD_CMD_DDADDR + address) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lua: mizar32.disp.print( string )
|
// Lua: mizar32.disp.print( string )
|
||||||
@ -200,19 +183,6 @@ static int lcd_goto(lua_State *L)
|
|||||||
// Usually this will be a string of text or a list of character codes.
|
// Usually this will be a string of text or a list of character codes.
|
||||||
// If they pass us integer values <0 or >255, we just use the bottom 8 bits.
|
// If they pass us integer values <0 or >255, we just use the bottom 8 bits.
|
||||||
|
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
// Adjust current cursor position by N printed characters.
|
|
||||||
// Written for shortest code.
|
|
||||||
static void current_print(int n)
|
|
||||||
{
|
|
||||||
current_column += current_direction * n;
|
|
||||||
if (current_column < 0 || current_column >= 40) {
|
|
||||||
current_row = ! current_row;
|
|
||||||
current_column -= 40 * current_direction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int lcd_print( lua_State *L )
|
static int lcd_print( lua_State *L )
|
||||||
{
|
{
|
||||||
unsigned argc = lua_gettop( L ); // Number of parameters supplied
|
unsigned argc = lua_gettop( L ); // Number of parameters supplied
|
||||||
@ -224,12 +194,8 @@ static int lcd_print(lua_State *L)
|
|||||||
{
|
{
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
{
|
{
|
||||||
char byte = luaL_checkint( L, argn );
|
u8 byte = luaL_checkint( L, argn );
|
||||||
|
send_data( &byte, 1 );
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_print(1);
|
|
||||||
#endif
|
|
||||||
send_data(&byte, (size_t) 1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -237,11 +203,7 @@ static int lcd_print(lua_State *L)
|
|||||||
{
|
{
|
||||||
size_t len; // Number of chars in string
|
size_t len; // Number of chars in string
|
||||||
const char *str = luaL_checklstring( L, argn, &len );
|
const char *str = luaL_checklstring( L, argn, &len );
|
||||||
|
send_data( (u8 *) str, len );
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
current_print(len);
|
|
||||||
#endif
|
|
||||||
send_data(str, len);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -252,13 +214,51 @@ static int lcd_print(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the cursor position as row and column in the ranges 1-2 and 1-40
|
||||||
|
// The bottom 7-bits of addr are the contents of the address counter.
|
||||||
|
// The Ampire datasheet says:
|
||||||
|
// 0x00-0x0F for the first line of DDRAM (presumably 0..39 really),
|
||||||
|
// 0x40-0x4F for the second line of DDRAM (presumably 64..(64+39) really)
|
||||||
|
// The top bit (128) is the "Busy Flag", which should always be 0.
|
||||||
|
|
||||||
|
static int lcd_getpos( lua_State *L )
|
||||||
|
{
|
||||||
|
u8 addr = recv_address_counter();
|
||||||
|
lua_pushinteger( L, (lua_Integer) ( (addr & 0x40) ? 2 : 1 ) ); // row
|
||||||
|
lua_pushinteger( L, (lua_Integer) ( (addr & 0x3F) + 1 ) ); // column
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the current state of the pressed buttons as a string containing
|
||||||
|
// a selection of the letters S, L, R, U, D or an empty string if none are
|
||||||
|
// currently held down.
|
||||||
|
|
||||||
|
static int lcd_buttons( lua_State *L )
|
||||||
|
{
|
||||||
|
u8 code; // bit code for buttons held
|
||||||
|
char string[6]; // Up to 5 buttons and a \0
|
||||||
|
char *stringp = string; // Where to write the next character;
|
||||||
|
|
||||||
|
code = recv_buttons();
|
||||||
|
if( code & LCD_BUTTON_SELECT ) *stringp++ = 'S';
|
||||||
|
if( code & LCD_BUTTON_LEFT ) *stringp++ = 'L';
|
||||||
|
if( code & LCD_BUTTON_RIGHT ) *stringp++ = 'R';
|
||||||
|
if( code & LCD_BUTTON_UP ) *stringp++ = 'U';
|
||||||
|
if( code & LCD_BUTTON_DOWN ) *stringp++ = 'D';
|
||||||
|
*stringp = '\0';
|
||||||
|
|
||||||
|
lua_pushstring( L, string );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// "Display on/off control" functions
|
// "Display on/off control" functions
|
||||||
|
|
||||||
// Helper function to set a cursor type if the display is on,
|
// Helper function to set a cursor type if the display is on,
|
||||||
// or to remember which cursor they asked for, to be able to set it
|
// or to remember which cursor they asked for, to be able to set it
|
||||||
// when they turn the display on.
|
// when they turn the display on.
|
||||||
static int set_cursor( char command_byte )
|
static int set_cursor( u8 command_byte )
|
||||||
{
|
{
|
||||||
cursor_type = command_byte;
|
cursor_type = command_byte;
|
||||||
|
|
||||||
@ -286,21 +286,9 @@ static int lcd_cursor( lua_State *L )
|
|||||||
return set_cursor( LCD_CMD_CURSOR_LINE );
|
return set_cursor( LCD_CMD_CURSOR_LINE );
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
if (--current_column < 0) {
|
|
||||||
current_row = !current_row;
|
|
||||||
current_column = 39;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return send_command( LCD_CMD_SHIFT_CURSOR_LEFT );
|
return send_command( LCD_CMD_SHIFT_CURSOR_LEFT );
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
if (++current_column >= 40) {
|
|
||||||
current_row = !current_row;
|
|
||||||
current_column = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return send_command( LCD_CMD_SHIFT_CURSOR_RIGHT );
|
return send_command( LCD_CMD_SHIFT_CURSOR_RIGHT );
|
||||||
|
|
||||||
default: return luaL_argerror( L, 1, NULL );
|
default: return luaL_argerror( L, 1, NULL );
|
||||||
@ -330,15 +318,14 @@ static int lcd_display( lua_State *L )
|
|||||||
// glyph: a table of up to 8 numbers with values 0-31.
|
// glyph: a table of up to 8 numbers with values 0-31.
|
||||||
// If less than 8 are supplied, the bottom rows are blanked.
|
// If less than 8 are supplied, the bottom rows are blanked.
|
||||||
// If more than 8 are supplied, the extra are ignored.
|
// If more than 8 are supplied, the extra are ignored.
|
||||||
|
// The current cursor position in the character display RAM is preserved.
|
||||||
|
|
||||||
static int lcd_definechar( lua_State *L ) {
|
static int lcd_definechar( lua_State *L ) {
|
||||||
int code; // The character code we are defining, 0-7
|
int code; // The character code we are defining, 0-7
|
||||||
size_t datalen; // The number of elements in the glyph table
|
size_t datalen; // The number of elements in the glyph table
|
||||||
size_t line; // Which line of the char are we defining?
|
size_t line; // Which line of the char are we defining?
|
||||||
char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
u8 data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
int old_address; // The coded value for the current cursor position
|
||||||
int old_column = current_column, old_row = current_row;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// First parameter: glyph code to define
|
// First parameter: glyph code to define
|
||||||
code = luaL_checkint( L, 1 );
|
code = luaL_checkint( L, 1 );
|
||||||
@ -359,18 +346,13 @@ static int lcd_definechar( lua_State *L ) {
|
|||||||
data[line] = value;
|
data[line] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_address = recv_address_counter();
|
||||||
|
|
||||||
send_command( LCD_CMD_CGADDR + code * 8 );
|
send_command( LCD_CMD_CGADDR + code * 8 );
|
||||||
send_data( data, sizeof( data ) );
|
send_data( data, sizeof( data ) );
|
||||||
|
|
||||||
#ifdef KEEP_CURSOR_POSITION
|
|
||||||
// Move back to where we were
|
// Move back to where we were
|
||||||
current_row = old_row; current_column = old_column;
|
return send_command( LCD_CMD_DDADDR + old_address );
|
||||||
return send_command( LCD_CMD_DDADDR + current_row * 0x40 + current_column );
|
|
||||||
#else
|
|
||||||
// Sadly, we cannot save and restore the current cursor position
|
|
||||||
// so return to the home position.
|
|
||||||
return send_command( LCD_CMD_DDADDR );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN_OPT_LEVEL 2
|
#define MIN_OPT_LEVEL 2
|
||||||
@ -388,5 +370,7 @@ const LUA_REG_TYPE lcd_map[] =
|
|||||||
{ LSTRKEY( "definechar" ), LFUNCVAL( lcd_definechar ) },
|
{ LSTRKEY( "definechar" ), LFUNCVAL( lcd_definechar ) },
|
||||||
{ LSTRKEY( "cursor" ), LFUNCVAL( lcd_cursor ) },
|
{ LSTRKEY( "cursor" ), LFUNCVAL( lcd_cursor ) },
|
||||||
{ LSTRKEY( "display" ), LFUNCVAL( lcd_display ) },
|
{ LSTRKEY( "display" ), LFUNCVAL( lcd_display ) },
|
||||||
|
{ LSTRKEY( "getpos" ), LFUNCVAL( lcd_getpos ) } ,
|
||||||
|
{ LSTRKEY( "buttons" ), LFUNCVAL( lcd_buttons ) } ,
|
||||||
{ LNILKEY, LNILVAL }
|
{ LNILKEY, LNILVAL }
|
||||||
};
|
};
|
||||||
|
@ -12,14 +12,27 @@
|
|||||||
#define LCD_BUS_FREQ 50000
|
#define LCD_BUS_FREQ 50000
|
||||||
|
|
||||||
// I2C slave addresses for command bytes and data strings
|
// I2C slave addresses for command bytes and data strings
|
||||||
// Command address is followed by a dingle byte giving the command to perform
|
// Command address is followed by a single byte giving the command to perform
|
||||||
// Data address is followed by multiple bytes of ASCII data to display
|
// Data address is followed by multiple bytes of ASCII data to display
|
||||||
// on the character display at the current cursor location.
|
// on the character display at the current cursor location.
|
||||||
#define LCD_CMD 0x7C
|
#define LCD_CMD 0x7C // Send commands
|
||||||
#define LCD_DATA 0x7E
|
#define LCD_GETPOS 0x7D // Read the cursor position
|
||||||
|
#define LCD_DATA 0x7E // Send data
|
||||||
|
#define LCD_BUTTONS 0x7F // Read the status of the buttons
|
||||||
|
|
||||||
|
// Bits indicating which buttons are held down in the reply to LCD_BUTTONS
|
||||||
|
#define LCD_BUTTON_SELECT 1
|
||||||
|
#define LCD_BUTTON_LEFT 2
|
||||||
|
#define LCD_BUTTON_RIGHT 4
|
||||||
|
#define LCD_BUTTON_UP 8
|
||||||
|
#define LCD_BUTTON_DOWN 16
|
||||||
|
|
||||||
// Command bytes
|
// Command bytes
|
||||||
|
|
||||||
|
// Mizar32 LCD driver special: instead of being a NOP, 0 performs a
|
||||||
|
// reset of the LCD panel
|
||||||
|
#define LCD_CMD_RESET 0
|
||||||
|
|
||||||
// "Clear display: Write "20H" to DDRAM and set DDRAM address to "00H" from AC"
|
// "Clear display: Write "20H" to DDRAM and set DDRAM address to "00H" from AC"
|
||||||
#define LCD_CMD_CLEAR 1
|
#define LCD_CMD_CLEAR 1
|
||||||
|
|
||||||
|
@ -41,6 +41,13 @@
|
|||||||
#include "pwm.h"
|
#include "pwm.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_USB_CDC
|
||||||
|
#if !defined( VTMR_NUM_TIMERS ) || VTMR_NUM_TIMERS == 0
|
||||||
|
# error "On AVR32, USB_CDC needs virtual timer support. Define VTMR_NUM_TIMERS > 0."
|
||||||
|
#endif
|
||||||
|
#include "usb-cdc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_UIP
|
#ifdef BUILD_UIP
|
||||||
|
|
||||||
// UIP sys tick data
|
// UIP sys tick data
|
||||||
@ -180,6 +187,10 @@ int platform_init()
|
|||||||
pm_enable_clk32_no_wait( &AVR32_PM, AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC );
|
pm_enable_clk32_no_wait( &AVR32_PM, AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_USB_CDC
|
||||||
|
pm_configure_usb_clock();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize external memory if any.
|
// Initialize external memory if any.
|
||||||
#ifdef AVR32_SDRAMC
|
#ifdef AVR32_SDRAMC
|
||||||
# ifndef BOOTLOADER_EMBLOD
|
# ifndef BOOTLOADER_EMBLOD
|
||||||
@ -246,11 +257,14 @@ int platform_init()
|
|||||||
|
|
||||||
// Setup virtual timers if needed
|
// Setup virtual timers if needed
|
||||||
#if VTMR_NUM_TIMERS > 0
|
#if VTMR_NUM_TIMERS > 0
|
||||||
#define VTMR_CH 2
|
|
||||||
platform_cpu_set_interrupt( INT_TMR_MATCH, VTMR_CH, PLATFORM_CPU_ENABLE );
|
platform_cpu_set_interrupt( INT_TMR_MATCH, VTMR_CH, PLATFORM_CPU_ENABLE );
|
||||||
platform_timer_set_match_int( VTMR_CH, 1000000 / VTMR_FREQ_HZ, PLATFORM_TIMER_INT_CYCLIC );
|
platform_timer_set_match_int( VTMR_CH, 1000000 / VTMR_FREQ_HZ, PLATFORM_TIMER_INT_CYCLIC );
|
||||||
#endif // #if VTMR_NUM_TIMERS > 0
|
#endif // #if VTMR_NUM_TIMERS > 0
|
||||||
|
|
||||||
|
#ifdef BUILD_USB_CDC
|
||||||
|
usb_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
cmn_platform_init();
|
cmn_platform_init();
|
||||||
|
|
||||||
// All done
|
// All done
|
||||||
@ -356,6 +370,13 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
|
|||||||
opts.baudrate = baud;
|
opts.baudrate = baud;
|
||||||
|
|
||||||
// Set stopbits
|
// Set stopbits
|
||||||
|
#if PLATFORM_UART_STOPBITS_1 == USART_1_STOPBIT && \
|
||||||
|
PLATFORM_UART_STOPBITS_1_5 == USART_1_5_STOPBIT && \
|
||||||
|
PLATFORM_UART_STOPBITS_2 == USART_2_STOPBIT
|
||||||
|
// The AVR32 header values and the eLua values are the same (0, 1, 2)
|
||||||
|
if (stopbits > PLATFORM_UART_STOPBITS_2) return 0;
|
||||||
|
opts.stopbits = stopbits;
|
||||||
|
#else
|
||||||
switch (stopbits) {
|
switch (stopbits) {
|
||||||
case PLATFORM_UART_STOPBITS_1:
|
case PLATFORM_UART_STOPBITS_1:
|
||||||
opts.stopbits = USART_1_STOPBIT;
|
opts.stopbits = USART_1_STOPBIT;
|
||||||
@ -369,6 +390,7 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
|
|||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set parity
|
// Set parity
|
||||||
switch (parity) {
|
switch (parity) {
|
||||||
@ -493,7 +515,7 @@ int platform_s_uart_set_flow_control( unsigned id, int type )
|
|||||||
// Timer functions
|
// Timer functions
|
||||||
|
|
||||||
static const u16 clkdivs[] = { 0xFFFF, 2, 8, 32, 128 };
|
static const u16 clkdivs[] = { 0xFFFF, 2, 8, 32, 128 };
|
||||||
u8 avr32_timer_int_periodic_flag[ 3 ];
|
u8 avr32_timer_int_periodic_flag[ TC_NUMBER_OF_CHANNELS ];
|
||||||
|
|
||||||
// Helper: get timer clock
|
// Helper: get timer clock
|
||||||
static u32 platform_timer_get_clock( unsigned id )
|
static u32 platform_timer_get_clock( unsigned id )
|
||||||
@ -1147,6 +1169,46 @@ void platform_eth_timer_handler()
|
|||||||
|
|
||||||
#endif // #ifdef BUILD_UIP
|
#endif // #ifdef BUILD_UIP
|
||||||
|
|
||||||
|
#ifdef BUILD_USB_CDC
|
||||||
|
|
||||||
|
void platform_usb_cdc_send( u8 data )
|
||||||
|
{
|
||||||
|
if (!Is_device_enumerated())
|
||||||
|
return;
|
||||||
|
while(!UsbCdcTxReady()); // "USART"-USB free ?
|
||||||
|
UsbCdcSendChar(data);
|
||||||
|
}
|
||||||
|
int platform_usb_cdc_recv( s32 timeout )
|
||||||
|
{
|
||||||
|
int data;
|
||||||
|
int read;
|
||||||
|
|
||||||
|
if (!Is_device_enumerated())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Try to read one byte from buffer, if none available return -1 or
|
||||||
|
// retry forever if timeout != 0 ( = PLATFORM_TIMER_INF_TIMEOUT)
|
||||||
|
do {
|
||||||
|
read = UsbCdcReadChar(&data);
|
||||||
|
} while( read == 0 && timeout != 0 );
|
||||||
|
|
||||||
|
if( read == 0 )
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_cdc_timer_handler()
|
||||||
|
{
|
||||||
|
usb_device_task();
|
||||||
|
UsbCdcFlush ();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void platform_cdc_timer_handler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif // #ifdef BUILD_USB_CDC
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
// Platform specific modules go here
|
// Platform specific modules go here
|
||||||
|
|
||||||
|
@ -61,15 +61,8 @@ __attribute__((__interrupt__)) static void uart3_rx_handler()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// TMR_MATCH interrupts
|
// TMR_MATCH interrupts
|
||||||
|
|
||||||
#ifndef VTMR_CH
|
|
||||||
#if VTMR_NUM_TIMERS > 0
|
|
||||||
#define VTMR_CH (2)
|
|
||||||
#else // #if VTMR_NUM_TIMERS > 0
|
|
||||||
#define VTMR_CH 0xFFFF
|
|
||||||
#endif // #if VTMR_NUM_TIMERS > 0
|
|
||||||
#endif // #ifndef VTMR_CH
|
|
||||||
|
|
||||||
extern void platform_eth_timer_handler();
|
extern void platform_eth_timer_handler();
|
||||||
|
extern void platform_cdc_timer_handler();
|
||||||
static const int tmr_irqs[] = { AVR32_TC_IRQ0, AVR32_TC_IRQ1, AVR32_TC_IRQ2 };
|
static const int tmr_irqs[] = { AVR32_TC_IRQ0, AVR32_TC_IRQ1, AVR32_TC_IRQ2 };
|
||||||
extern u8 avr32_timer_int_periodic_flag[ 3 ];
|
extern u8 avr32_timer_int_periodic_flag[ 3 ];
|
||||||
|
|
||||||
@ -78,13 +71,17 @@ static void tmr_match_common_handler( int id )
|
|||||||
volatile avr32_tc_t *tc = &AVR32_TC;
|
volatile avr32_tc_t *tc = &AVR32_TC;
|
||||||
|
|
||||||
tc_read_sr( tc, id ); // clear interrupt
|
tc_read_sr( tc, id ); // clear interrupt
|
||||||
|
#if VTMR_NUM_TIMERS > 0
|
||||||
if( id == VTMR_CH )
|
if( id == VTMR_CH )
|
||||||
{
|
{
|
||||||
cmn_virtual_timer_cb();
|
cmn_virtual_timer_cb();
|
||||||
platform_eth_timer_handler();
|
platform_eth_timer_handler();
|
||||||
|
platform_cdc_timer_handler();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
cmn_int_handler( INT_TMR_MATCH, id );
|
cmn_int_handler( INT_TMR_MATCH, id );
|
||||||
|
|
||||||
if( avr32_timer_int_periodic_flag[ id ] != PLATFORM_TIMER_INT_CYCLIC )
|
if( avr32_timer_int_periodic_flag[ id ] != PLATFORM_TIMER_INT_CYCLIC )
|
||||||
{
|
{
|
||||||
tc->channel[ id ].IDR.cpcs = 1;
|
tc->channel[ id ].IDR.cpcs = 1;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#define ASYNCHRONOUS_UPDATE 0
|
#define ASYNCHRONOUS_UPDATE 0
|
||||||
|
|
||||||
// Values to set into the CPD bit of the per-channel CMR registers
|
// Values to set into the CPD bit of the per-channel CMR registers
|
||||||
// to say whether we are updating the duty cycòle or the period.
|
// to say whether we are updating the duty cycle or the period.
|
||||||
// These values seem not to be defined anywhere in the avr32 headers.
|
// These values seem not to be defined anywhere in the avr32 headers.
|
||||||
#define AVR32_PWM_CMR_CPD_UPDATE_CDTY 0
|
#define AVR32_PWM_CMR_CPD_UPDATE_CDTY 0
|
||||||
#define AVR32_PWM_CMR_CPD_UPDATE_CPRD 1
|
#define AVR32_PWM_CMR_CPD_UPDATE_CPRD 1
|
||||||
@ -87,12 +87,10 @@ void pwm_init()
|
|||||||
// Set the two linear dividers' frequencies
|
// Set the two linear dividers' frequencies
|
||||||
void pwm_set_linear_divider( unsigned prea, unsigned diva )
|
void pwm_set_linear_divider( unsigned prea, unsigned diva )
|
||||||
{
|
{
|
||||||
avr32_pwm_mr_t mr; // Value for mode register
|
avr32_pwm_mr_t mr = AVR32_PWM.MR;
|
||||||
|
|
||||||
mr.prea = prea;
|
mr.prea = prea;
|
||||||
mr.diva = diva;
|
mr.diva = diva;
|
||||||
mr.preb = 0; // Turn clock B off
|
|
||||||
mr.divb = 0;
|
|
||||||
AVR32_PWM.MR = mr;
|
AVR32_PWM.MR = mr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,15 +59,11 @@ static void sdramc_ck_delay(unsigned long ck)
|
|||||||
{
|
{
|
||||||
// Use the CPU cycle counter (CPU and HSB clocks are the same).
|
// Use the CPU cycle counter (CPU and HSB clocks are the same).
|
||||||
unsigned long delay_start_cycle = Get_system_register(AVR32_COUNT);
|
unsigned long delay_start_cycle = Get_system_register(AVR32_COUNT);
|
||||||
unsigned long delay_end_cycle = delay_start_cycle + ck;
|
|
||||||
|
|
||||||
// To be safer, the end of wait is based on an inequality test, so CPU cycle
|
// at 60MHz the count register wraps every 71.68 secs, at 66MHz every 65s.
|
||||||
// counter wrap around is checked.
|
// The following unsigned arithmetic handles the wraparound condition.
|
||||||
if (delay_start_cycle > delay_end_cycle)
|
while ((unsigned long)Get_system_register(AVR32_COUNT) - delay_start_cycle < ck)
|
||||||
{
|
/* wait */;
|
||||||
while ((unsigned long)Get_system_register(AVR32_COUNT) > delay_end_cycle);
|
|
||||||
}
|
|
||||||
while ((unsigned long)Get_system_register(AVR32_COUNT) < delay_end_cycle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1205
src/platform/avr32/usb-cdc.c
Normal file
1205
src/platform/avr32/usb-cdc.c
Normal file
File diff suppressed because it is too large
Load Diff
792
src/platform/avr32/usb-cdc.h
Normal file
792
src/platform/avr32/usb-cdc.h
Normal file
@ -0,0 +1,792 @@
|
|||||||
|
/* 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 _USB_CDC_H_
|
||||||
|
#define _USB_CDC_H_
|
||||||
|
|
||||||
|
#include <avr32/io.h>
|
||||||
|
#include "compiler.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define USB_CONFIG_ATTRIBUTES_RESERVED 0x80
|
||||||
|
#define USB_CONFIG_BUSPOWERED (USB_CONFIG_ATTRIBUTES_RESERVED | 0x00)
|
||||||
|
#define USB_CONFIG_SELFPOWERED (USB_CONFIG_ATTRIBUTES_RESERVED | 0x40)
|
||||||
|
#define BUS_POWERED 0
|
||||||
|
#define SELF_POWERED 1
|
||||||
|
#define MSK_EP_DIR 0x80
|
||||||
|
#define MSK_EP_NBR 0x0F
|
||||||
|
|
||||||
|
#define DIRECTION_OUT AVR32_USBB_UECFG0_EPDIR_OUT
|
||||||
|
#define DIRECTION_IN AVR32_USBB_UECFG0_EPDIR_IN
|
||||||
|
#define SINGLE_BANK AVR32_USBB_UECFG0_EPBK_SINGLE
|
||||||
|
#define DOUBLE_BANK AVR32_USBB_UECFG0_EPBK_DOUBLE
|
||||||
|
#define TRIPLE_BANK AVR32_USBB_UECFG0_EPBK_TRIPLE
|
||||||
|
|
||||||
|
|
||||||
|
#define EVT_USB_POWERED 1 // USB plugged
|
||||||
|
#define EVT_USB_UNPOWERED 2 // USB unplugged
|
||||||
|
#define EVT_USB_DEVICE_FUNCTION 3 // USB in device
|
||||||
|
#define EVT_USB_HOST_FUNCTION 4 // USB in host
|
||||||
|
#define EVT_USB_SUSPEND 5 // USB suspend
|
||||||
|
#define EVT_USB_WAKE_UP 6 // USB wake-up
|
||||||
|
#define EVT_USB_RESUME 7 // USB resume
|
||||||
|
#define EVT_USB_RESET 8 // USB reset
|
||||||
|
#define EVT_HOST_SOF 9 // Host start-of-frame sent
|
||||||
|
#define EVT_HOST_HWUP 10 // Host wake-up detected
|
||||||
|
#define EVT_HOST_DISCONNECTION 11 // The target device is disconnected
|
||||||
|
|
||||||
|
#define NB_MS_BEFORE_FLUSH 1
|
||||||
|
|
||||||
|
#define AVR32_USBB_usbcon (AVR32_USBB.usbcon)
|
||||||
|
#define AVR32_USBB_udintclr (AVR32_USBB.udintclr)
|
||||||
|
#define AVR32_USBB_usbsta (AVR32_USBB.usbsta)
|
||||||
|
#define AVR32_USBB_usbstaclr (AVR32_USBB.usbstaclr)
|
||||||
|
#define AVR32_USBB_udint (AVR32_USBB.udint)
|
||||||
|
#define AVR32_USBB_udinte (AVR32_USBB.udinte)
|
||||||
|
#define AVR32_USBB_udinteclr (AVR32_USBB.udinteclr)
|
||||||
|
#define AVR32_USBB_udinteset (AVR32_USBB.udinteset)
|
||||||
|
#define AVR32_USBB_udcon (AVR32_USBB.udcon)
|
||||||
|
#define AVR32_USBB_uerst (AVR32_USBB.uerst)
|
||||||
|
#define AVR32_USBB_uecfgx(x) ((&AVR32_USBB.uecfg0)[(x)])
|
||||||
|
#define AVR32_USBB_uestax(x) ((&AVR32_USBB.uesta0)[(x)])
|
||||||
|
#define AVR32_USBB_ueconxset(x) ((&AVR32_USBB.uecon0set)[(x)])
|
||||||
|
#define AVR32_USBB_uestaxclr(x) ((&AVR32_USBB.uesta0clr)[(x)])
|
||||||
|
#define AVR32_USBB_ueconxclr(x) ((&AVR32_USBB.uecon0clr)[(x)])
|
||||||
|
#define AVR32_USBB_ueconx(x) ((&AVR32_USBB.uecon0)[(x)])
|
||||||
|
|
||||||
|
#define Usb_disable_id_pin() (Clr_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_UIDE_MASK))
|
||||||
|
#define Usb_ack_control_out_received_free() (AVR32_USBB_uestaxclr(EP_CONTROL) = AVR32_USBB_UESTA0CLR_RXOUTIC_MASK)
|
||||||
|
|
||||||
|
#define AVR32_USBB_FIFOX_DATA(x, scale) (((volatile TPASTE2(U, scale) (*)[0x10000 / ((scale) / 8)])AVR32_USBB_SLAVE)[(x)])
|
||||||
|
|
||||||
|
#define Usb_reset_endpoint_fifo_access(ep) \
|
||||||
|
(pep_fifo[(ep)].u64ptr = Usb_get_endpoint_fifo_access(ep, 64))
|
||||||
|
|
||||||
|
#define Usb_read_endpoint_data(ep, scale) \
|
||||||
|
(*pep_fifo[(ep)].TPASTE3(u, scale, ptr)\
|
||||||
|
TPASTE3(Pep_fifo_access_, scale, _post_inc)())
|
||||||
|
|
||||||
|
#define Usb_write_endpoint_data(ep, scale, data) \
|
||||||
|
(*pep_fifo[(ep)].TPASTE3(u, scale, ptr)\
|
||||||
|
TPASTE3(Pep_fifo_access_, scale, _post_inc)() = (data))
|
||||||
|
|
||||||
|
#define Usb_read_endpoint_indexed_data(ep, scale, index) \
|
||||||
|
(AVR32_USBB_FIFOX_DATA(ep, scale)[(index)])
|
||||||
|
|
||||||
|
#define Usb_write_endpoint_indexed_data(ep, scale, index, data) \
|
||||||
|
(AVR32_USBB_FIFOX_DATA(ep, scale)[(index)] = (data))
|
||||||
|
#define Usb_enable_endpoint_int_dis_hdma_req(ep) (AVR32_USBB_ueconxset(ep) = AVR32_USBB_UECONXSET_EPDISHDMAS_MASK)
|
||||||
|
#define Usb_disable_endpoint_int_dis_hdma_req(ep) (AVR32_USBB_ueconxclr(ep) = AVR32_USBB_UECONXCLR_EPDISHDMAC_MASK)
|
||||||
|
#define Is_usb_endpoint_int_dis_hdma_req_enabled(ep) (Tst_bits(AVR32_USBB_ueconx(ep), AVR32_USBB_UECON0_EPDISHDMA_MASK))
|
||||||
|
#define Usb_raise_endpoint_dma_interrupt(epdma) (AVR32_USBB_udintset = AVR32_USBB_UDINTSET_DMA1INTS_MASK << ((epdma) - 1))
|
||||||
|
#define Is_usb_endpoint_dma_interrupt(epdma) (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_DMA1INT_MASK << ((epdma) - 1)))
|
||||||
|
#define Usb_enable_endpoint_dma_interrupt(epdma) (AVR32_USBB_udinteset = AVR32_USBB_UDINTESET_DMA1INTES_MASK << ((epdma) - 1))
|
||||||
|
#define Usb_disable_endpoint_dma_interrupt(epdma) (AVR32_USBB_udinteclr = AVR32_USBB_UDINTECLR_DMA1INTEC_MASK << ((epdma) - 1))
|
||||||
|
#define Is_usb_endpoint_dma_interrupt_enabled(epdma) (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_DMA1INTE_MASK << ((epdma) - 1)))
|
||||||
|
#define Usb_ack_setup_received_free() (AVR32_USBB_uestaxclr(EP_CONTROL) = AVR32_USBB_UESTA0CLR_RXSTPIC_MASK)
|
||||||
|
#define Usb_send_in(ep) (Usb_ack_fifocon(ep))
|
||||||
|
#define Is_usb_out_received(ep) (Tst_bits(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_RXOUTI_MASK))
|
||||||
|
#define Is_usb_out_received_interrupt_enabled(ep) (Tst_bits(AVR32_USBB_ueconx(ep), AVR32_USBB_UECON0_RXOUTE_MASK))
|
||||||
|
#define Usb_ack_fifocon(ep) (AVR32_USBB_ueconxclr(ep) = AVR32_USBB_UECON0CLR_FIFOCONC_MASK)
|
||||||
|
#define Usb_ack_out_received_free(ep) (Usb_ack_out_received(ep), Usb_free_out(ep))
|
||||||
|
#define Usb_ack_out_received(ep) (AVR32_USBB_uestaxclr(ep) = AVR32_USBB_UESTA0CLR_RXOUTIC_MASK)
|
||||||
|
#define Is_usb_nak_out(ep) (Tst_bits(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_NAKOUTI_MASK))
|
||||||
|
#define Usb_enable_sof_interrupt() (AVR32_USBB_udinteset = AVR32_USBB_UDINTESET_SOFES_MASK)
|
||||||
|
#define Get_desc_ep_nbr(ep_addr) (Rd_bitfield(ep_addr, MSK_EP_NBR))
|
||||||
|
|
||||||
|
#define Is_usb_vbus_high() (Tst_bits(AVR32_USBB_usbsta, AVR32_USBB_USBSTA_VBUS_MASK))
|
||||||
|
#define Usb_detach() (Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_DETACH_MASK))
|
||||||
|
#define Usb_ack_sof() (AVR32_USBB_udintclr = AVR32_USBB_UDINTCLR_SOFC_MASK)
|
||||||
|
|
||||||
|
#define Usb_send_event(x) (Set_bits(g_usb_event, 1 << (x)))
|
||||||
|
#define Usb_ack_event(x) (Clr_bits(g_usb_event, 1 << (x)))
|
||||||
|
#define Is_usb_event(x) (Tst_bits(g_usb_event, 1 << (x)))
|
||||||
|
#define Usb_clear_all_event() (g_usb_event = 0x0000)
|
||||||
|
#define Is_device_enumerated() (usb_configuration_nb != 0)
|
||||||
|
#define Is_host_emergency_exit() (Is_usb_device() || Is_usb_event(EVT_HOST_DISCONNECTION) || Is_usb_event(EVT_USB_DEVICE_FUNCTION))
|
||||||
|
|
||||||
|
#define Is_usb_enabled() (Tst_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_USBE_MASK))
|
||||||
|
#define Is_usb_clock_frozen() (Tst_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_FRZCLK_MASK))
|
||||||
|
#define Usb_enable() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_USBE_MASK))
|
||||||
|
#define Usb_disable() (Clr_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_USBE_MASK))
|
||||||
|
#define Usb_attach() (Clr_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_DETACH_MASK))
|
||||||
|
#define Usb_enable_otg_pad() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_OTGPADE_MASK))
|
||||||
|
#define Usb_disable_otg_pad() (Clr_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_OTGPADE_MASK))
|
||||||
|
#define Usb_unfreeze_clock() (Clr_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_FRZCLK_MASK))
|
||||||
|
#define Usb_enable_vbus_interrupt() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_VBUSTE_MASK))
|
||||||
|
#define Usb_ack_suspend() (AVR32_USBB_udintclr = AVR32_USBB_UDINTCLR_SUSPC_MASK)
|
||||||
|
#define Is_usb_vbus_transition() (Tst_bits(AVR32_USBB_usbsta, AVR32_USBB_USBSTA_VBUSTI_MASK))
|
||||||
|
#define Is_usb_vbus_interrupt_enabled() (Tst_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_VBUSTE_MASK))
|
||||||
|
#define Usb_ack_vbus_transition() (AVR32_USBB_usbstaclr = AVR32_USBB_USBSTACLR_VBUSTIC_MASK)
|
||||||
|
#define Is_usb_sof_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_SOFE_MASK))
|
||||||
|
#define Is_usb_sof() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_SOF_MASK))
|
||||||
|
#define Usb_force_device_mode() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_UIMOD_MASK), Usb_disable_id_pin())
|
||||||
|
#define Is_usb_reset_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_EORSTE_MASK))
|
||||||
|
#define Is_usb_reset() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_EORST_MASK))
|
||||||
|
#define Is_usb_reset_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_EORSTE_MASK))
|
||||||
|
#define Is_usb_suspend() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_SUSP_MASK))
|
||||||
|
#define Usb_disable_resume_interrupt() (AVR32_USBB_udinteclr = AVR32_USBB_UDINTECLR_EORSMEC_MASK)
|
||||||
|
#define Usb_enable_suspend_interrupt() (AVR32_USBB_udinteset = AVR32_USBB_UDINTESET_SUSPES_MASK)
|
||||||
|
#define Usb_enable_reset_interrupt() (AVR32_USBB_udinteset = AVR32_USBB_UDINTESET_EORSTES_MASK)
|
||||||
|
#define Usb_force_full_speed_mode() (Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 3))
|
||||||
|
#define Is_usb_id_device() (Tst_bits(AVR32_USBB_usbsta, AVR32_USBB_USBSTA_ID_MASK))
|
||||||
|
#define Usb_ack_id_transition() (AVR32_USBB_usbstaclr = AVR32_USBB_USBSTACLR_IDTIC_MASK)
|
||||||
|
#define Usb_raise_id_transition() (AVR32_USBB_usbstaset = AVR32_USBB_USBSTASET_IDTIS_MASK)
|
||||||
|
#define Is_usb_id_transition() (Tst_bits(AVR32_USBB_usbsta, AVR32_USBB_USBSTA_IDTI_MASK))
|
||||||
|
#define Usb_enable_id_interrupt() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_IDTE_MASK))
|
||||||
|
#define Usb_disable_id_interrupt() (Clr_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_IDTE_MASK))
|
||||||
|
#define Is_usb_id_interrupt_enabled() (Tst_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_IDTE_MASK))
|
||||||
|
#define Usb_format_endpoint_size(size) (32 - clz(((U32)min(max(size, 8), 1024) << 1) - 1) - 1 - 3)
|
||||||
|
#define Is_usb_endpoint_configured(ep) (Tst_bits(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_CFGOK_MASK))
|
||||||
|
#define Usb_enable_endpoint(ep) (Set_bits(AVR32_USBB_uerst, AVR32_USBB_UERST_EPEN0_MASK << (ep)))
|
||||||
|
#define Usb_allocate_memory(ep) (Set_bits(AVR32_USBB_uecfgx(ep), AVR32_USBB_UECFG0_ALLOC_MASK))
|
||||||
|
#define Usb_get_endpoint_fifo_access(ep, scale) (AVR32_USBB_FIFOX_DATA(ep, scale))
|
||||||
|
#define Usb_byte_count(ep) (Rd_bitfield(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_BYCT_MASK))
|
||||||
|
#define Usb_free_out(ep) (Usb_ack_fifocon(ep))
|
||||||
|
#define Usb_get_dev_desc_length() (sizeof(usb_dev_desc))
|
||||||
|
#define Usb_configure_address(addr) (Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_UADD_MASK, addr))
|
||||||
|
#define Is_usb_control_in_ready() (Tst_bits(AVR32_USBB_uestax(EP_CONTROL), AVR32_USBB_UESTA0_TXINI_MASK))
|
||||||
|
#define Usb_ack_control_in_ready_send() (AVR32_USBB_uestaxclr(EP_CONTROL) = AVR32_USBB_UESTA0CLR_TXINIC_MASK)
|
||||||
|
#define Usb_ack_nak_out(ep) (AVR32_USBB_uestaxclr(ep) = AVR32_USBB_UESTA0CLR_NAKOUTIC_MASK)
|
||||||
|
#define Usb_get_endpoint_size(ep) (8 << Rd_bitfield(AVR32_USBB_uecfgx(ep), AVR32_USBB_UECFG0_EPSIZE_MASK))
|
||||||
|
#define Is_usb_control_out_received() (Tst_bits(AVR32_USBB_uestax(EP_CONTROL), AVR32_USBB_UESTA0_RXOUTI_MASK))
|
||||||
|
#define Usb_enable_address() (Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_ADDEN_MASK))
|
||||||
|
#define Usb_reset_data_toggle(ep) (AVR32_USBB_ueconxset(ep) = AVR32_USBB_UECON0SET_RSTDTS_MASK)
|
||||||
|
#define Is_usb_endpoint_stall_requested(ep) (Tst_bits(AVR32_USBB_ueconx(ep), AVR32_USBB_UECON0_STALLRQ_MASK))
|
||||||
|
|
||||||
|
#define Usb_format_mcu_to_usb_data(width, data) (TPASTE2(Swap, width)(data))
|
||||||
|
#define Usb_format_usb_to_mcu_data(width, data) (TPASTE2(Swap, width)(data))
|
||||||
|
#define usb_format_mcu_to_usb_data(width, data) (TPASTE2(swap, width)(data))
|
||||||
|
#define usb_format_usb_to_mcu_data(width, data) (TPASTE2(swap, width)(data))
|
||||||
|
|
||||||
|
|
||||||
|
//! configures selected endpoint in one step
|
||||||
|
#define Usb_configure_endpoint(ep, type, dir, size, bank) \
|
||||||
|
(\
|
||||||
|
Usb_enable_endpoint(ep),\
|
||||||
|
Wr_bits(AVR32_USBB_uecfgx(ep), AVR32_USBB_UECFG0_EPTYPE_MASK |\
|
||||||
|
AVR32_USBB_UECFG0_EPDIR_MASK |\
|
||||||
|
AVR32_USBB_UECFG0_EPSIZE_MASK |\
|
||||||
|
AVR32_USBB_UECFG0_EPBK_MASK, \
|
||||||
|
(((U32)(type) << AVR32_USBB_UECFG0_EPTYPE_OFFSET) & AVR32_USBB_UECFG0_EPTYPE_MASK) |\
|
||||||
|
(((U32)(dir ) << AVR32_USBB_UECFG0_EPDIR_OFFSET ) & AVR32_USBB_UECFG0_EPDIR_MASK ) |\
|
||||||
|
( (U32)Usb_format_endpoint_size(size) << AVR32_USBB_UECFG0_EPSIZE_OFFSET ) |\
|
||||||
|
(((U32)(bank) << AVR32_USBB_UECFG0_EPBK_OFFSET ) & AVR32_USBB_UECFG0_EPBK_MASK )),\
|
||||||
|
Usb_allocate_memory(ep),\
|
||||||
|
\
|
||||||
|
Is_usb_endpoint_configured(ep)\
|
||||||
|
)
|
||||||
|
|
||||||
|
#define Usb_reset_endpoint_fifo_access(ep) (pep_fifo[(ep)].u64ptr = Usb_get_endpoint_fifo_access(ep, 64))
|
||||||
|
|
||||||
|
|
||||||
|
#define Usb_wake_up_action()
|
||||||
|
#define Usb_resume_action()
|
||||||
|
#define Usb_suspend_action()
|
||||||
|
#define Usb_reset_action()
|
||||||
|
#define Usb_vbus_on_action()
|
||||||
|
#define Usb_vbus_off_action()
|
||||||
|
#define Usb_set_configuration_action() Usb_enable_sof_interrupt()
|
||||||
|
|
||||||
|
#define Usb_reset_endpoint(ep) (Set_bits(AVR32_USBB_uerst, AVR32_USBB_UERST_EPRST0_MASK << (ep)),\
|
||||||
|
Clr_bits(AVR32_USBB_uerst, AVR32_USBB_UERST_EPRST0_MASK << (ep)))
|
||||||
|
#define Is_usb_vbus_transition() (Tst_bits(AVR32_USBB_usbsta, AVR32_USBB_USBSTA_VBUSTI_MASK))
|
||||||
|
#define Is_usb_resume_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_EORSME_MASK))
|
||||||
|
#define Is_usb_wake_up() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_WAKEUP_MASK))
|
||||||
|
#define Is_usb_sof() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_SOF_MASK))
|
||||||
|
#define Is_usb_suspend_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_SUSPE_MASK))
|
||||||
|
#define Is_usb_endpoint_enabled(ep) (Tst_bits(AVR32_USBB_uerst, AVR32_USBB_UERST_EPEN0_MASK << (ep)))
|
||||||
|
#define Usb_ack_wake_up() (AVR32_USBB_udintclr = AVR32_USBB_UDINTCLR_WAKEUPC_MASK)
|
||||||
|
#define Is_usb_wake_up_interrupt_enabled() (Tst_bits(AVR32_USBB_udinte, AVR32_USBB_UDINTE_WAKEUPE_MASK))
|
||||||
|
#define Usb_enable_wake_up_interrupt() (AVR32_USBB_udinteset = AVR32_USBB_UDINTESET_WAKEUPES_MASK)
|
||||||
|
#define Usb_disable_wake_up_interrupt() (AVR32_USBB_udinteclr = AVR32_USBB_UDINTECLR_WAKEUPEC_MASK)
|
||||||
|
#define Usb_ack_resume() (AVR32_USBB_udintclr = AVR32_USBB_UDINTCLR_EORSMC_MASK)
|
||||||
|
#define Usb_freeze_clock() (Set_bits(AVR32_USBB_usbcon, AVR32_USBB_USBCON_FRZCLK_MASK))
|
||||||
|
#define Usb_ack_reset() (AVR32_USBB_udintclr = AVR32_USBB_UDINTCLR_EORSTC_MASK)
|
||||||
|
#define Is_usb_setup_received() (Tst_bits(AVR32_USBB_uestax(EP_CONTROL), AVR32_USBB_UESTA0_RXSTPI_MASK))
|
||||||
|
#define Usb_disable_stall_handshake(ep) (AVR32_USBB_ueconxclr(ep) = AVR32_USBB_UECON0CLR_STALLRQC_MASK)
|
||||||
|
|
||||||
|
#define Is_usb_resume() (Tst_bits(AVR32_USBB_udint, AVR32_USBB_UDINT_EORSM_MASK))
|
||||||
|
|
||||||
|
#define Usb_enable_stall_handshake(ep) (AVR32_USBB_ueconxset(ep) = AVR32_USBB_UECON0SET_STALLRQS_MASK)
|
||||||
|
#define Is_usb_write_enabled(ep) (Tst_bits(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_RWALL_MASK))
|
||||||
|
#define Usb_nb_busy_bank(ep) (Rd_bitfield(AVR32_USBB_uestax(ep), AVR32_USBB_UESTA0_NBUSYBK_MASK))
|
||||||
|
#define Usb_ack_in_ready_send(ep) (Usb_ack_in_ready(ep), Usb_send_in(ep))
|
||||||
|
#define Usb_ack_in_ready(ep) (AVR32_USBB_uestaxclr(ep) = AVR32_USBB_UESTA0CLR_TXINIC_MASK)
|
||||||
|
|
||||||
|
|
||||||
|
#define AVR32_USBB_IRQ 544
|
||||||
|
|
||||||
|
#define USB_SERIALPORT 0xE0
|
||||||
|
|
||||||
|
#define UART_USB_SUCCESS 0 //!< Successful completion.
|
||||||
|
#define UART_USB_FAILURE -1 //!< Failure because of some unspecified reason.
|
||||||
|
#define UART_USB_RX_EMPTY 3 //!< Nothing was received.
|
||||||
|
|
||||||
|
#define USART_1_STOPBIT AVR32_USART_MR_NBSTOP_1 //!< Use 1 stop bit.
|
||||||
|
#define USART_1_5_STOPBITS AVR32_USART_MR_NBSTOP_1_5 //!< Use 1.5 stop bits.
|
||||||
|
#define USART_2_STOPBITS AVR32_USART_MR_NBSTOP_2 //!< Use 2 stop bits (for more, just give the number of bits).
|
||||||
|
#define USART_NORMAL_CHMODE AVR32_USART_MR_CHMODE_NORMAL //!< Normal communication.
|
||||||
|
#define USART_AUTO_ECHO AVR32_USART_MR_CHMODE_ECHO //!< Echo data.
|
||||||
|
#define USART_LOCAL_LOOPBACK AVR32_USART_MR_CHMODE_LOCAL_LOOP //!< Local loopback.
|
||||||
|
#define USART_REMOTE_LOOPBACK AVR32_USART_MR_CHMODE_REMOTE_LOOP //!< Remote loopback.
|
||||||
|
#define USART_EVEN_PARITY AVR32_USART_MR_PAR_EVEN //!< Use even parity on character transmission.
|
||||||
|
#define USART_ODD_PARITY AVR32_USART_MR_PAR_ODD //!< Use odd parity on character transmission.
|
||||||
|
#define USART_SPACE_PARITY AVR32_USART_MR_PAR_SPACE //!< Use a space as parity bit.
|
||||||
|
#define USART_MARK_PARITY AVR32_USART_MR_PAR_MARK //!< Use a mark as parity bit.
|
||||||
|
#define USART_NO_PARITY AVR32_USART_MR_PAR_NONE //!< Don't use a parity bit.
|
||||||
|
#define USART_MULTIDROP_PARITY AVR32_USART_MR_PAR_MULTI //!< Parity bit is used to flag address characters.
|
||||||
|
|
||||||
|
#define EP_CONTROL 0
|
||||||
|
#define MAX_PEP_NB AVR32_USBB_EPT_NUM
|
||||||
|
#define TYPE_BULK AVR32_USBB_UECFG0_EPTYPE_BULK
|
||||||
|
#define TYPE_INTERRUPT AVR32_USBB_UECFG0_EPTYPE_INTERRUPT
|
||||||
|
|
||||||
|
#define ATMEL_VID 0x03EB
|
||||||
|
#define VENDOR_ID ATMEL_VID //! Atmel vendor ID
|
||||||
|
#define USB_SPECIFICATION 0x0200
|
||||||
|
#define CDC_COMM_CLASS 0x02
|
||||||
|
#define CDC_COMM_DEVICE_CLASS 0x02
|
||||||
|
#define CDC_DATA_CLASS 0x0A
|
||||||
|
|
||||||
|
#define SET_LINE_CODING 0x20
|
||||||
|
#define GET_LINE_CODING 0x21
|
||||||
|
#define SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define SEND_BREAK 0x23
|
||||||
|
#define SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define GET_ENCAPSULATED_COMMAND 0x01
|
||||||
|
|
||||||
|
#define Pep_fifo_access_64_post_inc()
|
||||||
|
#define Pep_fifo_access_32_post_inc()
|
||||||
|
#define Pep_fifo_access_16_post_inc() ++
|
||||||
|
#define Pep_fifo_access_8_post_inc() ++
|
||||||
|
|
||||||
|
#define TX_EP 0x01
|
||||||
|
#define RX_EP 0x02
|
||||||
|
#define INT_EP 0x03
|
||||||
|
#define GET_STATUS 0x00
|
||||||
|
#define GET_DEVICE 0x01
|
||||||
|
#define CLEAR_FEATURE 0x01
|
||||||
|
#define GET_STRING 0x03
|
||||||
|
#define SET_FEATURE 0x03
|
||||||
|
#define SET_ADDRESS 0x05
|
||||||
|
#define GET_DESCRIPTOR 0x06
|
||||||
|
#define SET_DESCRIPTOR 0x07
|
||||||
|
#define GET_CONFIGURATION 0x08
|
||||||
|
#define SET_CONFIGURATION 0x09
|
||||||
|
#define GET_INTERFACE 0x0A
|
||||||
|
#define SET_INTERFACE 0x0B
|
||||||
|
#define SYNCH_FRAME 0x0C
|
||||||
|
|
||||||
|
#define GET_DEVICE_DESCRIPTOR 1
|
||||||
|
#define GET_CONFIGURATION_DESCRIPTOR 4
|
||||||
|
|
||||||
|
#define REQUEST_DEVICE_STATUS 0x80
|
||||||
|
#define REQUEST_INTERFACE_STATUS 0x81
|
||||||
|
#define REQUEST_ENDPOINT_STATUS 0x82
|
||||||
|
#define DEVICE_TYPE 0x00
|
||||||
|
#define INTERFACE_TYPE 0x01
|
||||||
|
#define ENDPOINT_TYPE 0x02
|
||||||
|
|
||||||
|
// Descriptor Types
|
||||||
|
#define DEVICE_DESCRIPTOR 0x01
|
||||||
|
#define CONFIGURATION_DESCRIPTOR 0x02
|
||||||
|
#define STRING_DESCRIPTOR 0x03
|
||||||
|
#define INTERFACE_DESCRIPTOR 0x04
|
||||||
|
#define ENDPOINT_DESCRIPTOR 0x05
|
||||||
|
#define DEVICE_QUALIFIER_DESCRIPTOR 0x06
|
||||||
|
#define OTHER_SPEED_CONFIGURATION_DESCRIPTOR 0x07
|
||||||
|
|
||||||
|
// Standard Features
|
||||||
|
#define FEATURE_DEVICE_REMOTE_WAKEUP 0x01
|
||||||
|
#define FEATURE_ENDPOINT_HALT 0x00
|
||||||
|
#define FEATURE_TEST_MODE 0x02
|
||||||
|
|
||||||
|
|
||||||
|
/* usb_descriptors.h */
|
||||||
|
|
||||||
|
//_____ M A C R O S ________________________________________________________
|
||||||
|
|
||||||
|
#define Usb_unicode(c) (Usb_format_mcu_to_usb_data(16, (U16)(c)))
|
||||||
|
#define Usb_get_dev_desc_pointer() (&(usb_dev_desc.bLength))
|
||||||
|
#define Usb_get_dev_desc_length() (sizeof(usb_dev_desc))
|
||||||
|
#define Usb_get_conf_desc_pointer() (&(usb_conf_desc_fs.cfg.bLength))
|
||||||
|
#define Usb_get_conf_desc_length() (sizeof(usb_conf_desc_fs))
|
||||||
|
#define Usb_get_conf_desc_hs_pointer() (&(usb_conf_desc_hs.cfg.bLength))
|
||||||
|
#define Usb_get_conf_desc_hs_length() (sizeof(usb_conf_desc_hs))
|
||||||
|
#define Usb_get_conf_desc_fs_pointer() (&(usb_conf_desc_fs.cfg.bLength))
|
||||||
|
#define Usb_get_conf_desc_fs_length() (sizeof(usb_conf_desc_fs))
|
||||||
|
#define Usb_get_qualifier_desc_pointer() (&(usb_qualifier_desc.bLength))
|
||||||
|
#define Usb_get_qualifier_desc_length() (sizeof(usb_qualifier_desc))
|
||||||
|
|
||||||
|
|
||||||
|
//_____ U S B D E F I N E S _____________________________________________
|
||||||
|
|
||||||
|
// USB Device descriptor
|
||||||
|
#define USB_SPECIFICATION 0x0200
|
||||||
|
#define DEVICE_CLASS CDC_COMM_DEVICE_CLASS
|
||||||
|
#define DEVICE_SUB_CLASS 0 //! Each configuration has its own subclass
|
||||||
|
#define DEVICE_PROTOCOL 0 //! Each configuration has its own protocol
|
||||||
|
#define EP_CONTROL_LENGTH 64
|
||||||
|
#define VENDOR_ID ATMEL_VID //! Atmel vendor ID
|
||||||
|
#define CDC_EXAMPLE_PID 0x2307
|
||||||
|
#define PRODUCT_ID CDC_EXAMPLE_PID
|
||||||
|
#define RELEASE_NUMBER 0x1000
|
||||||
|
#define MAN_INDEX 0x01
|
||||||
|
#define PROD_INDEX 0x02
|
||||||
|
#define SN_INDEX 0x03
|
||||||
|
#define NB_CONFIGURATION 1
|
||||||
|
|
||||||
|
// CONFIGURATION
|
||||||
|
#define NB_INTERFACE 2 //! The number of interfaces for this configuration
|
||||||
|
#define CONF_NB 1 //! Number of this configuration
|
||||||
|
#define CONF_INDEX 0
|
||||||
|
#define CONF_ATTRIBUTES USB_CONFIG_BUSPOWERED
|
||||||
|
#define MAX_POWER 200 // 400 mA
|
||||||
|
|
||||||
|
// Interface 0 descriptor
|
||||||
|
#define INTERFACE_NB_0 0 //! The number of this interface
|
||||||
|
#define ALTERNATE_0 0 //! The alt setting nb of this interface
|
||||||
|
#define NB_ENDPOINT_0 1 //! The number of endpoints this interface has
|
||||||
|
#define INTERFACE_CLASS_0 CDC_COMM_CLASS //! CDC ACR Com Class
|
||||||
|
#define INTERFACE_SUB_CLASS_0 0x02
|
||||||
|
#define INTERFACE_PROTOCOL_0 0x01
|
||||||
|
#define INTERFACE_INDEX_0 0
|
||||||
|
|
||||||
|
// Interface 1 descriptor
|
||||||
|
#define INTERFACE_NB_1 1 //! The number of this interface
|
||||||
|
#define ALTERNATE_1 0 //! The alt setting nb of this interface
|
||||||
|
#define NB_ENDPOINT_1 2 //! The number of endpoints this interface has
|
||||||
|
#define INTERFACE_CLASS_1 CDC_DATA_CLASS //! CDC ACR Data Class
|
||||||
|
#define INTERFACE_SUB_CLASS_1 0
|
||||||
|
#define INTERFACE_PROTOCOL_1 0
|
||||||
|
#define INTERFACE_INDEX_1 0
|
||||||
|
|
||||||
|
// USB Endpoint 3 descriptor
|
||||||
|
// Interrupt IN
|
||||||
|
#define LANG_ID 0x00
|
||||||
|
#define ENDPOINT_NB_3 ( INT_EP | MSK_EP_DIR )
|
||||||
|
#define EP_ATTRIBUTES_3 TYPE_INTERRUPT
|
||||||
|
#define EP_IN_LENGTH_3 0x20
|
||||||
|
#define EP_SIZE_3 EP_IN_LENGTH_3
|
||||||
|
#define EP_INTERVAL_3 0xFF //! Interrupt polling interval from host
|
||||||
|
|
||||||
|
// USB Endpoint 1 descriptor
|
||||||
|
// Bulk IN
|
||||||
|
#define ENDPOINT_NB_1 ( TX_EP | MSK_EP_DIR )
|
||||||
|
#define EP_ATTRIBUTES_1 TYPE_BULK
|
||||||
|
#define EP_IN_LENGTH_1_FS 0x40
|
||||||
|
#define EP_SIZE_1_FS EP_IN_LENGTH_1_FS
|
||||||
|
#define EP_INTERVAL_1 0x00 //! Interrupt polling interval from host
|
||||||
|
|
||||||
|
// USB Endpoint 2 descriptor
|
||||||
|
// Bulk OUT
|
||||||
|
#define ENDPOINT_NB_2 RX_EP
|
||||||
|
#define EP_ATTRIBUTES_2 TYPE_BULK
|
||||||
|
#define EP_IN_LENGTH_2_FS 0x40
|
||||||
|
#define EP_SIZE_2_FS EP_IN_LENGTH_2_FS
|
||||||
|
#define EP_INTERVAL_2 0x00 //! Interrupt polling interval from host
|
||||||
|
|
||||||
|
|
||||||
|
#define DEVICE_STATUS SELF_POWERED
|
||||||
|
#define INTERFACE_STATUS 0x00 // TBD
|
||||||
|
|
||||||
|
#define LANG_ID 0x00
|
||||||
|
|
||||||
|
#define USB_MN_LENGTH 5
|
||||||
|
#define USB_MANUFACTURER_NAME \
|
||||||
|
{\
|
||||||
|
Usb_unicode('A'),\
|
||||||
|
Usb_unicode('T'),\
|
||||||
|
Usb_unicode('M'),\
|
||||||
|
Usb_unicode('E'),\
|
||||||
|
Usb_unicode('L') \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USB_PN_LENGTH 13
|
||||||
|
#define USB_PRODUCT_NAME \
|
||||||
|
{\
|
||||||
|
Usb_unicode('A'),\
|
||||||
|
Usb_unicode('V'),\
|
||||||
|
Usb_unicode('R'),\
|
||||||
|
Usb_unicode('3'),\
|
||||||
|
Usb_unicode('2'),\
|
||||||
|
Usb_unicode(' '),\
|
||||||
|
Usb_unicode('U'),\
|
||||||
|
Usb_unicode('C'),\
|
||||||
|
Usb_unicode('3'),\
|
||||||
|
Usb_unicode(' '),\
|
||||||
|
Usb_unicode('C'),\
|
||||||
|
Usb_unicode('D'),\
|
||||||
|
Usb_unicode('C') \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USB_SN_LENGTH 13
|
||||||
|
#define USB_SERIAL_NUMBER \
|
||||||
|
{\
|
||||||
|
Usb_unicode('1'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('0'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('0'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('0'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('0'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('0'),\
|
||||||
|
Usb_unicode('.'),\
|
||||||
|
Usb_unicode('A') \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LANGUAGE_ID 0x0409
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
U32 dwDTERate;
|
||||||
|
U8 bCharFormat;
|
||||||
|
U8 bParityType;
|
||||||
|
U8 bDataBits;
|
||||||
|
}S_line_coding;
|
||||||
|
|
||||||
|
//! USB Request
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bmRequestType; //!< Characteristics of the request
|
||||||
|
U8 bRequest; //!< Specific request
|
||||||
|
U16 wValue; //!< Field that varies according to request
|
||||||
|
U16 wIndex; //!< Field that varies according to request
|
||||||
|
U16 wLength; //!< Number of bytes to transfer if Data
|
||||||
|
} S_UsbRequest;
|
||||||
|
|
||||||
|
//! USB Device Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< DEVICE descriptor type
|
||||||
|
U16 bscUSB; //!< Binay Coded Decimal Spec. release
|
||||||
|
U8 bDeviceClass; //!< Class code assigned by the USB
|
||||||
|
U8 bDeviceSubClass; //!< Subclass code assigned by the USB
|
||||||
|
U8 bDeviceProtocol; //!< Protocol code assigned by the USB
|
||||||
|
U8 bMaxPacketSize0; //!< Max packet size for EP0
|
||||||
|
U16 idVendor; //!< Vendor ID. ATMEL = 0x03EB
|
||||||
|
U16 idProduct; //!< Product ID assigned by the manufacturer
|
||||||
|
U16 bcdDevice; //!< Device release number
|
||||||
|
U8 iManufacturer; //!< Index of manu. string descriptor
|
||||||
|
U8 iProduct; //!< Index of prod. string descriptor
|
||||||
|
U8 iSerialNumber; //!< Index of S.N. string descriptor
|
||||||
|
U8 bNumConfigurations; //!< Number of possible configurations
|
||||||
|
} S_usb_device_descriptor;
|
||||||
|
|
||||||
|
//! USB Configuration Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< CONFIGURATION descriptor type
|
||||||
|
U16 wTotalLength; //!< Total length of data returned
|
||||||
|
U8 bNumInterfaces; //!< Number of interfaces for this conf.
|
||||||
|
U8 bConfigurationValue; //!< Value for SetConfiguration resquest
|
||||||
|
U8 iConfiguration; //!< Index of string descriptor
|
||||||
|
U8 bmAttributes; //!< Configuration characteristics
|
||||||
|
U8 MaxPower; //!< Maximum power consumption
|
||||||
|
} S_usb_configuration_descriptor;
|
||||||
|
|
||||||
|
//! USB Interface Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< INTERFACE descriptor type
|
||||||
|
U8 bInterfaceNumber; //!< Number of interface
|
||||||
|
U8 bAlternateSetting; //!< Value to select alternate setting
|
||||||
|
U8 bNumEndpoints; //!< Number of EP except EP 0
|
||||||
|
U8 bInterfaceClass; //!< Class code assigned by the USB
|
||||||
|
U8 bInterfaceSubClass; //!< Subclass code assigned by the USB
|
||||||
|
U8 bInterfaceProtocol; //!< Protocol code assigned by the USB
|
||||||
|
U8 iInterface; //!< Index of string descriptor
|
||||||
|
} S_usb_interface_descriptor;
|
||||||
|
|
||||||
|
//! USB Endpoint Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< ENDPOINT descriptor type
|
||||||
|
U8 bEndpointAddress; //!< Address of the endpoint
|
||||||
|
U8 bmAttributes; //!< Endpoint's attributes
|
||||||
|
U16 wMaxPacketSize; //!< Maximum packet size for this EP
|
||||||
|
U8 bInterval; //!< Interval for polling EP in ms
|
||||||
|
} S_usb_endpoint_descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
//! USB Device Qualifier Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< Device Qualifier descriptor type
|
||||||
|
U16 bscUSB; //!< Binay Coded Decimal Spec. release
|
||||||
|
U8 bDeviceClass; //!< Class code assigned by the USB
|
||||||
|
U8 bDeviceSubClass; //!< Subclass code assigned by the USB
|
||||||
|
U8 bDeviceProtocol; //!< Protocol code assigned by the USB
|
||||||
|
U8 bMaxPacketSize0; //!< Max packet size for EP0
|
||||||
|
U8 bNumConfigurations; //!< Number of possible configurations
|
||||||
|
U8 bReserved; //!< Reserved for future use, must be zero
|
||||||
|
} S_usb_device_qualifier_descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! USB Language Descriptor
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< STRING descriptor type
|
||||||
|
U16 wlangid; //!< Language id
|
||||||
|
} S_usb_language_id;
|
||||||
|
|
||||||
|
|
||||||
|
//_____ U S B M A N U F A C T U R E R D E S C R I P T O R _______________
|
||||||
|
|
||||||
|
//! struct usb_st_manufacturer
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< STRING descriptor type
|
||||||
|
U16 wstring[USB_MN_LENGTH]; //!< Unicode characters
|
||||||
|
} S_usb_manufacturer_string_descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
//_____ U S B P R O D U C T D E S C R I P T O R _________________________
|
||||||
|
|
||||||
|
//! struct usb_st_product
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< STRING descriptor type
|
||||||
|
U16 wstring[USB_PN_LENGTH]; //!< Unicode characters
|
||||||
|
} S_usb_product_string_descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
//_____ U S B S E R I A L N U M B E R D E S C R I P T O R _____________
|
||||||
|
|
||||||
|
//! struct usb_st_serial_number
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
U8 bLength; //!< Size of this descriptor in bytes
|
||||||
|
U8 bDescriptorType; //!< STRING descriptor type
|
||||||
|
U16 wstring[USB_SN_LENGTH]; //!< Unicode characters
|
||||||
|
} S_usb_serial_number;
|
||||||
|
|
||||||
|
|
||||||
|
//_____ U S B D E V I C E C D C D E S C R I P T O R ___________________
|
||||||
|
|
||||||
|
typedef struct __attribute__((__packed__))
|
||||||
|
{
|
||||||
|
S_usb_configuration_descriptor cfg;
|
||||||
|
S_usb_interface_descriptor ifc0;
|
||||||
|
U8 CS_INTERFACE1[19];
|
||||||
|
S_usb_endpoint_descriptor ep3;
|
||||||
|
S_usb_interface_descriptor ifc1;
|
||||||
|
S_usb_endpoint_descriptor ep1;
|
||||||
|
S_usb_endpoint_descriptor ep2;
|
||||||
|
} S_usb_user_configuration_descriptor;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
// usb_user_device_descriptor
|
||||||
|
const S_usb_device_descriptor usb_dev_desc =
|
||||||
|
{
|
||||||
|
sizeof(S_usb_device_descriptor),
|
||||||
|
DEVICE_DESCRIPTOR,
|
||||||
|
Usb_format_mcu_to_usb_data(16, USB_SPECIFICATION),
|
||||||
|
DEVICE_CLASS,
|
||||||
|
DEVICE_SUB_CLASS,
|
||||||
|
DEVICE_PROTOCOL,
|
||||||
|
EP_CONTROL_LENGTH,
|
||||||
|
Usb_format_mcu_to_usb_data(16, VENDOR_ID),
|
||||||
|
Usb_format_mcu_to_usb_data(16, PRODUCT_ID),
|
||||||
|
Usb_format_mcu_to_usb_data(16, RELEASE_NUMBER),
|
||||||
|
MAN_INDEX,
|
||||||
|
PROD_INDEX,
|
||||||
|
SN_INDEX,
|
||||||
|
NB_CONFIGURATION
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// usb_user_configuration_descriptor FS
|
||||||
|
const S_usb_user_configuration_descriptor usb_conf_desc_fs =
|
||||||
|
{
|
||||||
|
{ sizeof(S_usb_configuration_descriptor)
|
||||||
|
, CONFIGURATION_DESCRIPTOR
|
||||||
|
, Usb_format_mcu_to_usb_data(16, sizeof(S_usb_user_configuration_descriptor))
|
||||||
|
, NB_INTERFACE
|
||||||
|
, CONF_NB
|
||||||
|
, CONF_INDEX
|
||||||
|
, CONF_ATTRIBUTES
|
||||||
|
, MAX_POWER
|
||||||
|
}
|
||||||
|
, { sizeof(S_usb_interface_descriptor)
|
||||||
|
, INTERFACE_DESCRIPTOR
|
||||||
|
, INTERFACE_NB_0
|
||||||
|
, ALTERNATE_0
|
||||||
|
, NB_ENDPOINT_0
|
||||||
|
, INTERFACE_CLASS_0
|
||||||
|
, INTERFACE_SUB_CLASS_0
|
||||||
|
, INTERFACE_PROTOCOL_0
|
||||||
|
, INTERFACE_INDEX_0
|
||||||
|
}
|
||||||
|
, { 0x05, // Size of structure
|
||||||
|
// -----------------
|
||||||
|
0x24, // CS_INTERFACE
|
||||||
|
0x00, // Header Functional Descriptor
|
||||||
|
0x10, 0x01, // USB Class Definitions for Communication Devices Specification release number in
|
||||||
|
// binary-coded decimal.
|
||||||
|
|
||||||
|
0x05, // Size of structure
|
||||||
|
// -----------------
|
||||||
|
0x24, // CS_INTERFACE
|
||||||
|
0x01, // Call Management Functional Descriptor
|
||||||
|
0x03, // The capabilities that this configuration supports:
|
||||||
|
// - Device handles call management itself.
|
||||||
|
// - Device can send/receive call management information over a Data Class interface.
|
||||||
|
0x01, // Interface number of Data Class interface optionally used for call management.
|
||||||
|
|
||||||
|
0x04, // Size of structure
|
||||||
|
// -----------------
|
||||||
|
0x24, // CS_INTERFACE
|
||||||
|
0x02, // Abstract Control Management Functional Descriptor.
|
||||||
|
0x06, // Abstract Control Management functional descriptor subtype:
|
||||||
|
// - Union Functional descriptor
|
||||||
|
|
||||||
|
0x05, // Size of structure
|
||||||
|
// -----------------
|
||||||
|
0x24, // CS_INTERFACE
|
||||||
|
0x06, // Union Functional descriptor
|
||||||
|
0x00, // The interface number of the Communication or Data Class interface, designated as
|
||||||
|
// the master or controlling interface for the union.
|
||||||
|
0x01 // Interface number of first slave or associated interface in the union.
|
||||||
|
}
|
||||||
|
, { sizeof(S_usb_endpoint_descriptor)
|
||||||
|
, ENDPOINT_DESCRIPTOR
|
||||||
|
, ENDPOINT_NB_3
|
||||||
|
, EP_ATTRIBUTES_3
|
||||||
|
, Usb_format_mcu_to_usb_data(16, EP_SIZE_3)
|
||||||
|
, EP_INTERVAL_3
|
||||||
|
}
|
||||||
|
, { sizeof(S_usb_interface_descriptor)
|
||||||
|
, INTERFACE_DESCRIPTOR
|
||||||
|
, INTERFACE_NB_1
|
||||||
|
, ALTERNATE_1
|
||||||
|
, NB_ENDPOINT_1
|
||||||
|
, INTERFACE_CLASS_1
|
||||||
|
, INTERFACE_SUB_CLASS_1
|
||||||
|
, INTERFACE_PROTOCOL_1
|
||||||
|
, INTERFACE_INDEX_1
|
||||||
|
}
|
||||||
|
, { sizeof(S_usb_endpoint_descriptor)
|
||||||
|
, ENDPOINT_DESCRIPTOR
|
||||||
|
, ENDPOINT_NB_1
|
||||||
|
, EP_ATTRIBUTES_1
|
||||||
|
, Usb_format_mcu_to_usb_data(16, EP_SIZE_1_FS)
|
||||||
|
, EP_INTERVAL_1
|
||||||
|
}
|
||||||
|
, { sizeof(S_usb_endpoint_descriptor)
|
||||||
|
, ENDPOINT_DESCRIPTOR
|
||||||
|
, ENDPOINT_NB_2
|
||||||
|
, EP_ATTRIBUTES_2
|
||||||
|
, Usb_format_mcu_to_usb_data(16, EP_SIZE_2_FS)
|
||||||
|
, EP_INTERVAL_2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// usb_user_language_id
|
||||||
|
const S_usb_language_id usb_user_language_id =
|
||||||
|
{
|
||||||
|
sizeof(S_usb_language_id),
|
||||||
|
STRING_DESCRIPTOR,
|
||||||
|
Usb_format_mcu_to_usb_data(16, LANGUAGE_ID)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// usb_user_manufacturer_string_descriptor
|
||||||
|
const S_usb_manufacturer_string_descriptor usb_user_manufacturer_string_descriptor =
|
||||||
|
{
|
||||||
|
sizeof(S_usb_manufacturer_string_descriptor),
|
||||||
|
STRING_DESCRIPTOR,
|
||||||
|
USB_MANUFACTURER_NAME
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// usb_user_product_string_descriptor
|
||||||
|
const S_usb_product_string_descriptor usb_user_product_string_descriptor =
|
||||||
|
{
|
||||||
|
sizeof(S_usb_product_string_descriptor),
|
||||||
|
STRING_DESCRIPTOR,
|
||||||
|
USB_PRODUCT_NAME
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// usb_user_serial_number
|
||||||
|
const S_usb_serial_number usb_user_serial_number =
|
||||||
|
{
|
||||||
|
sizeof(S_usb_serial_number),
|
||||||
|
STRING_DESCRIPTOR,
|
||||||
|
USB_SERIAL_NUMBER
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Bool usb_user_read_request(U8, U8);
|
||||||
|
extern Bool usb_user_get_descriptor(U8, U8);
|
||||||
|
void cdc_get_line_coding(void);
|
||||||
|
void cdc_set_line_coding(void);
|
||||||
|
void cdc_set_control_line_state (void);
|
||||||
|
|
||||||
|
__attribute__((__interrupt__)) void usb_general_interrupt(void);
|
||||||
|
//void usb_device_task_init(void);
|
||||||
|
void Usb_sof_action(void);
|
||||||
|
void usb_start_device(void);
|
||||||
|
void usb_process_request(void);
|
||||||
|
//void device_cdc_task_init(void);
|
||||||
|
void usb_init(void);
|
||||||
|
void usb_device_task(void);
|
||||||
|
Bool usb_user_get_descriptor(U8 type, U8 string);
|
||||||
|
Bool usb_user_read_request(U8 type, U8 request);
|
||||||
|
void usb_user_endpoint_init(U8 conf_nb);
|
||||||
|
|
||||||
|
extern Status_bool_t usb_init_device ( void );
|
||||||
|
extern U32 usb_set_ep_txpacket (U8, U8 , U32 );
|
||||||
|
extern U32 usb_write_ep_txpacket (U8, const void *, U32, const void **);
|
||||||
|
extern U32 usb_read_ep_rxpacket (U8, void *, U32, void **);
|
||||||
|
|
||||||
|
extern volatile U8 usb_configuration_nb;
|
||||||
|
|
||||||
|
void UsbCdcFlush (void);
|
||||||
|
int UsbCdcSendChar(int);
|
||||||
|
int UsbCdcReadChar( int *);
|
||||||
|
Bool UsbCdcTxReady(void);
|
||||||
|
Bool UsbCdcTestHit(void);
|
||||||
|
|
||||||
|
#endif
|
@ -731,8 +731,8 @@ uint32_t __LDREXW(uint32_t *addr)
|
|||||||
*/
|
*/
|
||||||
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
||||||
{
|
{
|
||||||
uint32_t result=0;
|
//uint32_t result=0;
|
||||||
|
register uint32_t result asm ("r2");
|
||||||
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
@ -748,8 +748,8 @@ uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
|||||||
*/
|
*/
|
||||||
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
||||||
{
|
{
|
||||||
uint32_t result=0;
|
//uint32_t result=0;
|
||||||
|
register uint32_t result asm ("r2");
|
||||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -731,25 +731,25 @@ uint32_t __LDREXW(uint32_t *addr)
|
|||||||
*/
|
*/
|
||||||
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
uint32_t __STREXB(uint8_t value, uint8_t *addr)
|
||||||
{
|
{
|
||||||
uint32_t result=0;
|
//uint32_t result=0;
|
||||||
|
register uint32_t result asm ("r2");
|
||||||
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief STR Exclusive
|
* @brief STR Exclusive (16 bit)
|
||||||
*
|
*
|
||||||
* @param uint16_t *address
|
* @param value value to store
|
||||||
* @param uint16_t value to store
|
* @param *addr address pointer
|
||||||
* @return uint32_t successful / failed
|
* @return successful / failed
|
||||||
*
|
*
|
||||||
* Exclusive STR command
|
* Exclusive STR command for 16 bit values
|
||||||
*/
|
*/
|
||||||
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
uint32_t __STREXH(uint16_t value, uint16_t *addr)
|
||||||
{
|
{
|
||||||
uint32_t result=0;
|
//uint32_t result=0;
|
||||||
|
register uint32_t result asm ("r2");
|
||||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ add_req_host_name(u8_t *optptr, const char* name)
|
|||||||
{
|
{
|
||||||
*optptr++ = DHCP_OPTION_HOST_NAME;
|
*optptr++ = DHCP_OPTION_HOST_NAME;
|
||||||
*optptr++ = (u8)strlen(name);
|
*optptr++ = (u8)strlen(name);
|
||||||
strcpy(optptr, name);
|
strcpy((char *)optptr, name);
|
||||||
return optptr + strlen(name);
|
return optptr + strlen(name);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user