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

added platform interface documentation for UART, SPI, timers and PWM

This commit is contained in:
James Snyder 2009-06-29 16:41:52 +00:00
parent 02fbbd2969
commit 58489cc1bf
8 changed files with 294 additions and 5 deletions

View File

@ -10,5 +10,10 @@
of all platforms supported by <b>eLua</b> in a common interface. For more details about the platform interface and the overall structure of
<b>eLua</b> in general, check <a href="arch_overview.html">this link</a>.<br>
The platform interface is defined in the <i>inc/platform.h</i> header file from the <b>eLua</b> source distribution. It is a collection of various
components (UART, SPI, timers ...), each of them is detailed in the next subsections.
components (UART, SPI, timers ...), each of them is detailed in the next subsections. Each such component has an <b>id</b> which is a number that
identifies that component in <b>eLua</b>. Generally, numbers are assigned to components in their "natural" order; for example, PORTA will have the id
0, PORTB will have 1 and so on. Similarly, the second SPI interface (SPI1) of the MCU will probably have an id equal to 1. However, this is not a strict
rule. The implementation of the platform interface might choose to expose only some of the peripherals (components) of the MCU, thus this rule might be
broken. For example, if a board has 3 UARTs, but for some reason the second UART (UART1) is dedicated and can't be touched by <b>eLua</b>, then UART0 will have the id 0 and UART2 will
have the id 1, so UART1 won't ever be accesible to the code. Such cases are documented in the <a href="">##specific usage notes</a> section.
</body></html>

View File

@ -29,14 +29,17 @@ This part of the platform interface deals with PIO (Programmable Input Output) o
};</code></pre></p></a>
<p>These are the operations that can be executed by the PIO subsystem on both ports and pins. They are given as arguments to the <a href="#platform_pio_op">platform_pio_op</a> function
shown below. ##TODO: document read in/read out if we keep that</p>
<p><pre><code>typedef u32 pio_type;</code></pre></p>
This is the type used for the actual I/O operations. Currently defined as an unsigned 32-bit type, thus no port can have more than 32 pins. If this happens, it should be possible to split it
in two or more parts and adding the new parts as "virtual ports" (logical ports that don't have a direct hardware equivalent). The "virtual port" technique is used in the AVR32 backend.</p>
<h3>Functions</h3>
<p><pre><code>int platform_pio_has_port( unsigned port );</code></pre></p>
<p>Returns 1 if the platform has the hardware port received as an argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_PIO</b> macro that must be defined in the
<p>Returns 1 if the platform has the hardware port sepcified as argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_PIO</b> macro that must be defined in the
platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details). For example:</p>
<p><code>#define NUM_PIO 4 <b>// The platform has 4 hardware ports</b></code></p>
<p><code>#define NUM_PIO 4 <b>// The platform has 4 hardware PIO ports</b></code></p>
<p><pre><code>int platform_pio_has_pin( unsigned port, unsigned pin );</code></pre></p>
<p>Returns 1 if the platform has the hardware port and pin specified as arguments, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_PIO</b> macro to check the validity
of the port and the <b>PIO_PINS_PER_PORT</b> or <b>PIO_PIN_ARRAY</b> macros to check the validity of the pin. The macros must be defined in the platform's <b>platform_conf.h</b> file
@ -47,6 +50,7 @@ of the port and the <b>PIO_PINS_PER_PORT</b> or <b>PIO_PIN_ARRAY</b> macros to c
<li>use <b>PIO_PIN_ARRAY</b> when different ports of the MCU have different number of pins. For example:
<p><code>#define PIO_PIN_ARRAY { 4, 4, 2, 6 } <b>// Port 0 has 4 pins, port 1 has 4 pins, port 2 has 2 pins, port 3 has 6 pins</b></code></p></li>
</ul></p>
<p><pre><code>const char* platform_pio_get_prefix( unsigned port );</code></pre></p>
<p>Get the port prefix. Used to establish if the port notation uses numbers (P0, P1, P2...) or letters (PA, PB, PC...). Implemented in <i>src/common.c</i> is uses the <b>PIO_PREFIX</b> macro
that must be defined in the platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details). The value of this macro can be either '0' (for

View File

@ -0,0 +1,45 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us"><title>eLua platform interface - PWM</title>
<link rel="stylesheet" type="text/css" href="../style.css"></head>
<body style="background-color: rgb(255, 255, 255);">
<h3>Overview</h3>
<p>
This part of the platform interface groups functions related to the PWM channel(s) of the MCU.
</p>
<h3>Data structures, constants and types</h3>
<a name="opval"><p><pre><code>// PWM operations
enum
{
PLATFORM_PWM_OP_START,
PLATFORM_PWM_OP_STOP,
PLATFORM_PWM_OP_SET_CLOCK,
PLATFORM_PWM_OP_GET_CLOCK
};</code></pre></p></a>
<p>This enum lists all the operations that can be executed on a given PWM channel.</p>
</p>
<h3>Functions</h3>
<a name="platform_pwm_setup"><p><pre><code>int platform_pwm_exists( unsigned id );</code></pre></p></a>
<p>Returns 1 if the platform has the PWM channel specified as argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_PWM</b> macro that must be defined in the
platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details). For example:</p>
<p><code>#define NUM_PWM 4 <b>// The platform has 4 PWM channels</b></code></p>
<p><pre><code>u32 platform_pwm_setup( unsigned id, u32 frequency, unsigned duty );</code></pre></p>
<p>Set up the PWM channel <b>id</b> to run at the given <b>frequency</b> (in hertz) with the specified <b>duty</b> cycle (specified as percent from 0 to 100). The function returns the
actual frequency set on the PWM channel, which might differ from <b>frequency</b> depending on the hardware. Also, some platforms don't allow the full range of 0%-100% duty cycle.</p>
<p><pre><code>u32 platform_pwm_op( unsigned id, int op, u32 data );</code></pre></p>
<p>Executes <b>op</b> on the given PWM <b>id</b>. <b>op</b> can take any value from <a href="#opval">this enum</a>, as follows:
<ul>
<li><b>PLATFORM_PWM_OP_START</b>: starts PWM generation on the specified channel. The return value is irrelevant.</li>
<li><b>PLATFORM_PWM_OP_STOP</b>: stops PWM generation on the specified channel. The return value is irrelevant.</li>
<li><b>PLATFORM_PWM_OP_SET_CLOCK</b>: sets the <b>base</b> clock of the specified PWM channel which will be used to generate the frequencies requested by
<a href="#platform_pwm_setup">platform_pwm_setup</a>) to <b>data</b> (in hertz). Returns the actual base clock set on the PWM channel, which might differ from <b>data</b>
depending on the hardware.</li>
<li><b>PLATFORM_PWM_OP_GET_CLOCK</b>: returns the <b>base</b> clock of the specified PWM channel.</li>
</ul></p>
</body></html>

View File

@ -0,0 +1,52 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us"><title>eLua platform interface - SPI</title>
<link rel="stylesheet" type="text/css" href="../style.css"></head>
<body style="background-color: rgb(255, 255, 255);">
<h3>Overview</h3>
<p>
This part of the platform interface groups functions related to the SPI interface(s) of the MCU.
</p>
<h3>Data structures and constants</h3>
<a name="modeval"><p><pre><code>// SPI mode
#define PLATFORM_SPI_MASTER 1
#define PLATFORM_SPI_SLAVE 0</code></pre></p></a>
<p>Constants used to specify the SPI mode (master or slave).</p>
<a name="selval"><p><pre><code>// SS values
#define PLATFORM_SPI_SELECT_ON 1
#define PLATFORM_SPI_SELECT_OFF 0</code></pre></p></a>
<p>Constants used to select/deselect the SPI SS pin (if applicable).</p>
<p><pre><code>typedef u32 spi_data_type;</code></pre></p>
<p>This is the type of a SPI data word, thus limiting the maximum size of a SPI data work to 32 bits (which should be enough for all practical purposes).</p>
<h3>Functions</h3>
<p><pre><code>int platform_spi_exists( unsigned id );</code></pre></p>
<p>Returns 1 if the platform has the hardware SPI specified as argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_SPI</b> macro that must be defined in the
platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details). For example:</p>
<p><code>#define NUM_SPI 1 <b>// The platform has 1 SPI interface</b></code></p>
<p><pre><code>u32 platform_spi_setup( unsigned id, int mode, u32 clock, unsigned cpol, unsigned cpha, unsigned databits );</code></pre></p>
<p>This function is used to initialize the parameters of the SPI interface.<br>
Arguments:
<ul>
<li><b>id</b>: the ID of the SPI interface.</li>
<li><b>mode</b>: SPI port mode (<b>PLATFORM_SPI_MASTER</b> or <b>PLATFORM_SPI_SLAVE</b>, see <a href="#modeval">here</a>).</li>
<li><b>clock</b>: clock speed for the SPI interface in master mode.</li>
<li><b>cpol</b>: clock polarity.</li>
<li><b>cpha</b>: clock phase.</li>
<li><b>databits</b>: length of the SPI data word in bits (usually 8, but configurable on some platforms).</li>
</ul></p>
<p>This function returns the actual clock set for the SPI interface. Depending on the hardware, this may have a different value than the <b>clock</b> argument.<br>
<font color="red"><b>NOTE</b>: currently, only master SPI mode is implemented in <b>eLua</b>.</font></p>
<p><pre><code>spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data );</code></pre></p>
<p>Executes a SPI read/write cycle by sending the data received in argument <b>data</b> and returning the data read from the SPI bus.</p>
<p><pre><code>void platform_spi_select( unsigned id, int is_select );</code></pre></p>
<p>For platforms that have a dedicated SS (Slave Select) pin in master SPI mode that be controlled manually, this function should enable or disable this pin on the SPI interface identified
by <b>id</b> depending on the value of the <b>is_select</b> argument (either <b>PLATFORM_SPI_SELECT_ON</b> or <b>PLATFORM_SPI_SELECT_OFF</b>, see <a href="#selval">here</a>). If this
functionality does not exist in hardware this function does nothing.</p>
</body></html>

View File

@ -9,7 +9,7 @@
<p>
Insert overview here.
</p>
<h3>Data structures and constants</h3>
<h3>Data structures, constants and types</h3>
<p>
Insert data structures and constants here.
</p>

View File

@ -0,0 +1,111 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us"><title>eLua platform interface - timers</title>
<link rel="stylesheet" type="text/css" href="../style.css"></head>
<body style="background-color: rgb(255, 255, 255);">
<h3>Overview</h3>
<p>
This part of the platform interface groups functions related to the timers of the MCU. It also makes provisions for using <b>virtual timers</b> on any platform, see <a href="#virtual">
this section</a> for details and kKeep in mind that in the following paragraphs an <b>id</b> can reffer to either a hardware timer or a virtual timer.
</p>
<h3>Data structures, constants and types</h3>
<p><pre><code>typedef u32 timer_data_type;</code></pre></p>
<p>This defines the data type used to specify delays and time intervals (which are always specifide in <b>microseconds</b>).</p>
<a name="opval"><p><pre><code>// Timer operations
enum
{
PLATFORM_TIMER_OP_START,
PLATFORM_TIMER_OP_READ,
PLATFORM_TIMER_OP_SET_CLOCK,
PLATFORM_TIMER_OP_GET_CLOCK,
PLATFORM_TIMER_OP_GET_MAX_DELAY,
PLATFORM_TIMER_OP_GET_MIN_DELAY
};</code></pre></p></a>
<p>This enum lists all the operations that can be executed on a given timer.</p>
<h3>Functions</h3>
<p><pre><code>int platform_timer_exists( unsigned id );</code></pre></p>
<p>Returns 1 if the platform has the timer specified as argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_TIMER</b> macro that must be defined in the
platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details) and the virtual timer configuration (see <a href="#virtual">here</a> for details).
For example:</p>
<p><code>#define NUM_TIMER 2 <b>// The platform has 2 hardware timers</b></code></p>
<p><pre><code>void platform_timer_delay( unsigned id, u32 delay_us );</code></pre></p>
<p>Waits for <b>delay_us</b> microseconds on timer <b>id</b>, then returns. This function is "split" in two parts: a platform-independent part implemented in <i>src/common.c</i> (that
handles virtual timers) and a platform-dependent part that must be implemented by each platform in a function named <b>platform_s_timer_delay</b> (see below). This function handles both
hardware timer IDs and virtual timer IDs.<br>
<b>IMPORTANT NOTE</b>: the real delay after executing this is a function of a number of variables, most notably the base clock of the timer and the size of the timer counter register
(32 bits on some platforms, 16 bits on most platforms, other values are less common). To ensure that the delay you're requesting is achievable, use
<a href="#platform_timer_op">platform_timer_op</a> with <b>platform_timer_op_get_max_delay</b> and <b>platform_timer_op_get_min_delay</b> to obtain the maximum and the minimum
achievable wait times on your timer, respectively. Even if your delay is within these limits, the <b>precision</b> of this function still varies a lot, mainly as a function of
the timer base clock.</p>
<p><pre><code>void platform_s_timer_delay( unsigned id, u32 delay_us );</code></pre></p>
<p>This function is identical in functionality to the one above (<b>platform_timer_delay</b>), but this is the function that must actually be implemented by a platform port, and it must never
handle virtual timer IDs, only hardware timer IDs.</p>
<a name="platform_timer_op"><p><pre><code>u32 platform_timer_op( unsigned id, int op, u32 data );</code></pre></p></a>
<p>Executes operation <b>op</b> on timer <b>id</b>. <b>op</b> can take any value from <a href="#opval">this enum</a>, as follows:
<ul>
<li><b>PLATFORM_TIMER_OP_START</b>: start the specified timeri by setting it to a predefined value which is returned.</li>
<li><b>PLATFORM_TIMER_OP_READ</b>: read the value of the specified timer and return it.</li>
<li><b>PLATFORM_TIMER_SET_CLOCK</b>: set the clock of the specified timer to <b>data</b> (in hertz). Returns the actual clock set on the timer, which might be different than <b>data</b>,
depending on the hardware. You can never set the clock of a virtual timer, which is set at compile time (intervals</li>
<li><b>PLATFORM_TIMER_GET_CLOCK</b>: return the clock of the specified timer.</li>
<li><b>PLATFORM_TIMER_OP_GET_MAX_DELAY</b>: return the maximum achievable timeout on the specified timer (in us).</li>
<li><b>PLATFORM_TIMER_OP_GET_MIN_DELAY</b>: return the minimum achievable timeout on the specified timer (in us).</li>
</ul></p>
<p>This function is "split" in two parts: a platform-independent part implemented in <i>src/common.c</i> (that handles virtual timers) and a platform-dependent part that must be implemented
by each platform in a function named <b>platform_s_timer_op</b> (see below). This function handles both hardware timer IDs and virtual timer IDs.</p>
<p><pre><code>u32 platform_s_timer_op( unsigned id, int op, u32 data );</code></pre></p>
<p>This function is identical in functionality to the one above (<b>platform_timer_op</b>), but this is the function that must actually be implemented by a platform port, and it must never
handle virtual timer IDs, only hardware timer IDs.</p>
<p><pre><code>u32 platform_timer_get_diff_us( unsigned id, timer_data_type end, timer_data_type start );</code></pre></p>
<p>Return the time difference (in us) betweeen the <b>end</b> and <b>start</b> timer values of timer <b>id</b>. This function is generic for all platforms, thus it is implemented in
<i>src/common.c</i>.</p>
<a name="virtual"><h3>Virtual timers</h3></a>
<p><b>Virtual timers</b> were added to <b>eLua</b> to overcome some limitations:
<ul>
<li>there are generally few hardware timers available, some of which might be dedicated (thus not usable directly by <b>eLua</b>).</li>
<li>many times it is difficult to share a hardware timer between different parts of an application because of conflicting requirements. Generally it's not possible to have timers that can
achieve long delays and high accuracy at the same time (this is especially true for systems that have 16 bit or even smaller timers).</li>
</ul></p>
<p>In this respect, <b>virtual timers</b> are a set of timers that share a single hardware timer. It is possible, in this way, to have a hardware timer that can implement 4, 8 or more hardware
timers. There are a few drawbacks to this approach:
<ul>
<li>the hardware timer used to implement the virtual timers must generally be dedicated. In fact in cat be still used in "read only mode", which means that the only operations that can
be executed on it are <b>PLATFORM_TIMER_OP_READ</b>, <b>PLATFORM_TIMER_GET_CLOCK</b>, <b>PLATFORM_TIMER_OP_GET_MAX_DELAY</b> and <b>PLATFORM_TIMER_OP_GET_MIN_DELAY</b>. However,
since the "read only mode" is not enforced by the code, it is advisable to treat this timer as a dedicated resource and thus make it invisible to <b>eLua</b> by not associating it with
an ID.</li>
<li>the number of virtual timers and their base frequency are fixed at compile time.</li>
<li>virtual timers are generally used for large delays with low accuracy, since their base frequency should be fairly low (see below).</li>
</ul></p>
<p>To <b>enable</b> virtual timers:
<ol>
<li>edit <b>platform_conf.h</b> (see <a href="arch_overview.html#platforms">here</a> for details) and set <b>VTMR_NUM_TIMERS</b> to the number of desired virtual timers and
<b>VTMR_FREQ_HZ</b> to the base frequency of the virtual timers (in hertz).For example:
<p><code>
#define VTMR_NUM_TIMERS 4 // we need 4 virtual timers<br>
#define VTMR_FREQ_HZ 4 // the base clock for the virtual timers is 4Hz</code></p></li>
<li>in your platform port setup a hardware timer to fire an interrupt at <b>VTMR_FREQ_HZ</b> and call the <b>cmn_virtual_timer_cb</b> function (defined in <i>src/common.c</i>) in the
timer interrupt handler. For example, if the the interrupt handler is called <b>timer_int_handler</b>, do this:
<p><code>void timer_int_handler( void )<br>
{<br>
&nbsp;&nbsp;// add code to clear the timer interrupt flag here if needed<br>
&nbsp;&nbsp;cmn_virtual_timer_cb();<br>
}<br>
</li>
</ol></p>
<p>Note that because of step 2 above you are limited by practical constraints on the value of <b>VTMR_FREQ_HZ</b>. If set too high, the timer interrupt will fire too often, thus taking too much
CPU time. The maximum value depends largely on the hardware and the desired behaviour of the virtual timers, but in practice values larger than 10 might visibly change the behaviour of your
system.</p>
<p>To <b>use</b> a virtua timers, identify it with the constant <b>VTMR_FIRST_ID</b> (defined in <i>inc/common.h</i>) plus an offset. For example, <b>VTMR_FIRST_ID+0</b> (or simply
<b>VTMR_FIRST_ID</b>) is the ID of the first virtual timer in the system, and <b>VTMR_FIRST_ID+2</b> is the ID of the third virtual timer in the system.</p>
</body></html>

View File

@ -0,0 +1,72 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Language" content="en-us"><title>eLua platform interface - UART</title>
<link rel="stylesheet" type="text/css" href="../style.css"></head>
<body style="background-color: rgb(255, 255, 255);">
<h3>Overview</h3>
<p>This part of the platform interface groups functions related to the UART interface(s) of the MCU.</p>
<h3>Data structures, constants and types</h3>
<a name="parval"><p><pre><code>// Parity
enum
{
PLATFORM_UART_PARITY_EVEN,
PLATFORM_UART_PARITY_ODD,
PLATFORM_UART_PARITY_NONE
};</code></pre></p></a>
<p>Constants used to specify the UART parity mode.</p>
<a name="stopval"><p><pre><code>// Stop bits
enum
{
PLATFORM_UART_STOPBITS_1,
PLATFORM_UART_STOPBITS_1_5,
PLATFORM_UART_STOPBITS_2
};</code></pre></p></a>
<p>Constants used to specify the number of UART stop bits.</p>
<a name="toinf"><p><pre><code>// "Infinite timeout" constant for recv
#define PLATFORM_UART_INFINITE_TIMEOUT (-1)</code></pre></p></a>
<p>This constant is used as a special timeout value (infinite timeout) in the UART functions that expect a timeout as argument.</p>
<h3>Functions</h3>
<p><pre><code>int platform_uart_exists( unsigned id );</code></pre></p>
<p>Returns 1 if the platform has the hardware UART specified as argument, 0 otherwise. Implemented in <i>src/common.c</i>, it uses the <b>NUM_UART</b> macro that must be defined in the
platform's <b>platform_conf.h</b> file (see <a href="arch_overview.html#platforms">here</a> for details). For example:</p>
<p><code>#define NUM_UART 2 <b>// The platform has 2 UART interfaces</b></code></p>
<p><pre><code>u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int stopbits );</code></pre></p>
<p>This function is used to initialize the parameters of the UART interface.<br>
Arguments:
<ul>
<li><b>id</b>: the ID of the UART interface.</li>
<li><b>baud</b>: baud rate.</li>
<li><b>databits</b>: number of data bits (maximum 8).</li>
<li><b>parity</b>: parity type (can be either <b>PLATFORM_UART_PARITY_EVEN</b>, <b>PLATFORM_UART_PARITY_ODD</b> or <b>PLATFORM_UART_PARITY_NONE</b>, see <a href="#parval">here</a>).</li>
<li><b>stopbits</b>: number of stop bits (can be either <b>PLATFORM_UART_STOPBITS_1</b>, <b>PLATFORM_UART_STOPBITS_1_5</b> or <b>PLATFORM_UART_STOPBITS_2</b>, see
<a href="#stopval">here</a>).</li>
</ul></p>
<p>This function returns the actual baud rate. Depending on the hardware, this may have a different value than the <b>baud</b> argument.</p>
<p><pre><code>void platform_uart_send( unsigned id, u8 data );</code></pre></p>
<p>Send the given <b>data</b> to the UART interface with the specified <b>id</b>. </p>
<p><pre><code>int platform_uart_recv( unsigned id, unsigned timer_id, s32 timeout );</code></pre></p>
<p>Receive a byte from the UART interface with the specified <b>id</b>. <b>timeout</b> specifies a timeout for the receive operation as follows:
<ul>
<li><b>timeout &gt; 0</b>: the timer with the specified <b>timer_id</b> (see <a href="arch_platform_timers.html">here</a>) will be used to timeout the receive operation after
<b>timeout</b> microseconds. If data from the UART is available before the timeout expires, the function returns it, otherwise it returns -1.</li>
<li><b>timeout = 0</b>: the function returns immediately with data from the UART if available or -1 if UART data is not available. In this mode, <b>timer_id</b> is ignored.</li>
<li><b>timeout = <a href="#toinf">PLATFORM_UART_INFINITE_TIMEOUT</a></b>: the function waits for UART data to be available and returns it. In this mode the function doesn't
time out, so -1 is never returned. In this mode, <b>timer_id</b> is ignored.</li>
</ul></p>
<p>This function is "split" in two parts: a platform-independent part that is implemented in <i>src/common.c</i>, and a platform-dependent part that must be implemented by each
platform in a function named <b>platform_s_uart_recv</b> (see below).</p>
<p><pre><code>int platform_s_uart_recv( unsigned id, s32 timeout );</code></pre></p>
<p>This is the platform-dependent part of the UART receive function <b>platform_uart_recv</b> (see above), and is in fact a "subset" of the full function (thus being easier to implement).
It receives a byte from the UART interface with the specified <b>id</b>. <b>timeout</b>
specifies a timeout for the receive operation that can be either 0 or PLATFORM_UART_INFINITE_TIMEOUT, see the <b>platform_uart_recv</b> function (above) for a full description of the
<b>timeout</b> argument. <b>NOTE</b>: this function doesn't have to deal with the <b>timeout &gt; 0</b> case, this is handled by the generic implementation in <i>src/common.c</i>.</p>
</body></html>

View File

@ -274,7 +274,7 @@ void cmn_virtual_timer_cb()
int platform_timer_exists( unsigned id )
{
#if VTMR_NUM_TIMERS > 0
if( TIMER_IS_VIRTUAL( id ) )
if( id >= VTMR_FIRST_ID )
return TIMER_IS_VIRTUAL( id );
else
#endif