0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-06-19 22:58:04 +03:00

Initial commit

This commit is contained in:
OneOfEleven
2023-09-09 08:03:56 +01:00
parent 92305117f1
commit 54441e27d9
3388 changed files with 582553 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
/**
\defgroup common_drv_gr Common Driver Definitions
\brief Definitions common in all driver interfaces (%Driver_Common.h)
\details
The following definitions are common in all CMSIS-Driver interfaces. Refer to \ref DriverFunctions
for a general overview.
@{
*/
/**
\enum ARM_POWER_STATE
\details
The access structure of each CMSIS-Driver provides the function \b PowerControl, which handles the power
profile for a peripheral using the parameter \ref ARM_POWER_STATE. Depending on this parameter,
the peripheral will operate at full speed, detect just events, or is completely un-powered.
Refer to \ref CallSequence for more information.
*/
/**
\struct ARM_DRIVER_VERSION
\details
The access structure of each CMSIS-Driver provides the function \b GetVersion, which returns in the struct ARM_DRIVER_VERSION:
- API version, which is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version, which is the source code version of the actual driver implementation.
The version is encoded as 16-bit unsigned value (uint16_t) with:
- high-byte: major version.
- low-byte: minor version.
For example, version 1.12 is encoded as 0x10C.
\defgroup execution_status Status Error Codes
\ingroup common_drv_gr
\brief Negative return values of functions indicate errors occurred during execution.
\details
Most functions return a status information using negative return values.
The following list provides the status error codes that are common in all drivers.
The drivers may return also status error codes that are specific to the peripheral.
\sa
\ref spi_execution_status for SPI driver;
\ref usart_execution_status for USART driver;
\ref nand_execution_status for NAND driver;
@{
\def ARM_DRIVER_OK
The value 0 or positive values indicate that the function execution is completed without any errors.
Note that positive values are used to provide for example the number of data items.
\def ARM_DRIVER_ERROR
The function did not execute correct and an unspecified error occurred during execution.
\def ARM_DRIVER_ERROR_BUSY
The function cannot be executed because the driver is busy with the execution of a conflicting operation.
\def ARM_DRIVER_ERROR_TIMEOUT
The function execution is terminated because a peripheral did not react within a specific timeout limit.
\def ARM_DRIVER_ERROR_UNSUPPORTED
The function requested an operation (for example by using an illegal control code) that is not supported.
\def ARM_DRIVER_ERROR_PARAMETER
A function parameter is incorrect.
\def ARM_DRIVER_ERROR_SPECIFIC
This value indicates the start of status error codes that are specific to the peripheral driver.
\sa
\ref spi_execution_status for SPI driver;
\ref usart_execution_status for USART driver;
@}
*/
/**
@}
*/

View File

@ -0,0 +1,224 @@
/**
\defgroup eth_interface_gr Ethernet Interface
\brief Ethernet common definitions (%Driver_ETH.h)
\details
<b>Ethernet</b> is a networking technology for exchanging data packages between computer systems. Several microcontrollers integrate
an Ethernet MAC (Media Access Control) data-link layer that interfaces to an Ethernet PHY (Physical Interface Transceiver).
Wikipedia offers more information about
the <a href="http://en.wikipedia.org/wiki/Ethernet" target="_blank"><b>Ethernet</b></a>.
<b>Block Diagram</b>
The Ethernet PHY connects typically to the Ethernet MAC using an MII (Media Independent Interface) or RMII (Reduced Media Independent Interface).
\n
\image html EthernetSchematic.png "Block Diagram of a typical Ethernet Interface"
<b>Ethernet API</b>
The following header files define the Application Programming Interface (API) for the <b>Ethernet</b> interface:
- \b %Driver_ETH.h : Common definitions of the Ethernet PHY and MAC part
- \b %Driver_ETH_MAC.h : API for the Ethernet MAC
- \b %Driver_ETH_PHY.h : API for the Ethernet PHY
The driver implementation of the Ethernet MAC is a typical part of a Device Family Pack (DFP) that supports the peripherals of the microcontroller family.
The driver implementation of the Ethernet PHY is a typical part of a \b Network Software Pack, since PHY is typically not integrated into the microcontroller.
\note
For parameters, the value marked with (default) is the setting after the driver initialization.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_ETH_MAC : access struct for <b>Ethernet MAC</b> driver functions.
- \ref ARM_DRIVER_ETH_PHY : access struct for <b>Ethernet PHY</b> driver functions.
Both drivers are used in combination and usually the Ethernet MAC provides a media interface to the Ethernet PHY.
A typical setup sequence for the drivers is shown below:
<b>Example Code</b>
The following example code shows the usage of the Ethernet interface.
\code
extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0;
static ARM_DRIVER_ETH_MAC *mac;
static ARM_DRIVER_ETH_PHY *phy;
static ARM_ETH_MAC_ADDR own_mac_address;
static ARM_ETH_MAC_CAPABILITIES capabilities;
void ethernet_mac_notify (uint32_t event) {
switch (event) {
:
}
}
void initialize_ethernet_interface (void) {
mac = &Driver_ETH_MAC0;
phy = &Driver_ETH_PHY0;
// Initialize Media Access Controller
capabilities = mac->GetCapabilities ();
mac->Initialize (ethernet_mac_notify);
mac->PowerControl (ARM_POWER_FULL);
if (capabilities.mac_address == 0) {
// populate own_mac_address with the address to use
mac->SetMacAddress(&own_mac_address);
}
else {
mac->GetMacAddress(&own_mac_address);
}
// Initialize Physical Media Interface
if (phy->Initialize (mac->PHY_Read, mac->PHY_Write) == ARM_DRIVER_OK) {
phy->PowerControl (ARM_POWER_FULL);
phy->SetInterface (capabilities.media_interface);
phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE);
}
:
:
}
static ARM_ETH_LINK_STATE ethernet_link; // current link status
void ethernet_check_link_status (void) {
ARM_ETH_LINK_STATE link;
link = phy->GetLinkState ();
if (link == ethernet_link) {
return; // link state unchanged
}
// link state changed
ethernet_link = link;
if (link == ARM_ETH_LINK_UP) { // start transfer
ARM_ETH_LINK_INFO info = phy->GetLinkInfo ();
mac->Control(ARM_ETH_MAC_CONFIGURE,
info.speed << ARM_ETH_MAC_SPEED_Pos |
info.duplex << ARM_ETH_MAC_DUPLEX_Pos |
ARM_ETH_MAC_ADDRESS_BROADCAST);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 1);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 1);
}
else { // stop transfer
mac->Control(ARM_ETH_MAC_FLUSH, ARM_ETH_MAC_FLUSH_TX | ARM_ETH_MAC_FLUSH_RX);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 0);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 0);
}
}
\endcode
*/
/**
\defgroup eth_interface_gr Ethernet Interface
@{
*/
/**
\cond
*/
/**
\enum ARM_ETH_INTERFACE
\details
Encodes the supported media interface between Ethernet MAC and Ethernet PHY.
The function \ref ARM_ETH_MAC_GetCapabilities retrieves the media interface type encoded in the data field \b media_interface of the struct
\ref ARM_ETH_MAC_CAPABILITIES.
<b>Parameter for:</b>
- \ref ARM_ETH_PHY_SetInterface
*/
/**
\enum ARM_ETH_DUPLEX
\details
Lists the supported duplex operating types for MAC.
<b>Parameter for:</b>
- \ref ARM_ETH_MAC_SetMode
*/
/**
\typedef ARM_ETH_SPEED
\details
Lists the supported operating speeds for MAC.
<b>Parameter for:</b>
- \ref ARM_ETH_MAC_SetMode
*/
/**
\endcond
*/
/**
\typedef ARM_ETH_LINK_STATE
\details
The Ethernet Link status shows if the communication is currently established (up) or interrupted (down).
<b>Returned by:</b>
- \ref ARM_ETH_PHY_GetLinkState
*/
/**
\struct ARM_ETH_LINK_INFO
\details
The Ethernet Link information provides parameters about the current established communication.
<b>Returned by:</b>
- \ref ARM_ETH_PHY_GetLinkInfo
*/
/**
\struct ARM_ETH_MAC_ADDR
\details
Stores the MAC Address of the Ethernet interface as defined by IEEE 802. Wikipedia offers more information about
the <a href="http://en.wikipedia.org/wiki/MAC_address" target="_blank"><b>MAC Address</b></a>.
<b>Parameter for:</b>
- \ref ARM_ETH_MAC_GetMacAddress, \ref ARM_ETH_MAC_SetMacAddress, \ref ARM_ETH_MAC_SetAddressFilter
*/
/**
@}
*/
// End ETH Interface
/**
\defgroup eth_interface_types1 Media Interface Types
\ingroup eth_interface_gr
\brief Ethernet Media Interface type
\details
Encodes the supported media interface between Ethernet MAC and Ethernet PHY.
The function \ref ARM_ETH_MAC_GetCapabilities retrieves the media interface type encoded in the data field \b media_interface of the struct
\ref ARM_ETH_MAC_CAPABILITIES.
<b>Parameter for:</b>
- \ref ARM_ETH_PHY_SetInterface
@{
\def ARM_ETH_INTERFACE_MII
\sa ARM_ETH_PHY_SetInterface
\def ARM_ETH_INTERFACE_RMII
\sa ARM_ETH_PHY_SetInterface
\def ARM_ETH_INTERFACE_SMII
\sa ARM_ETH_PHY_SetInterface
@}
*/

View File

@ -0,0 +1,641 @@
/**
\defgroup eth_mac_interface_gr Ethernet MAC Interface
\ingroup eth_interface_gr
\brief Driver API for Ethernet MAC Peripheral (%Driver_ETH_MAC.h)
\details
The following section describes the Ethernet MAC Interface as defined in the %Driver_ETH_MAC.h header file.
@{
*/
/**
\struct ARM_ETH_MAC_CAPABILITIES
\details
An Ethernet MAC driver can be implemented with different capabilities.
The data fields of this struct encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_ETH_MAC_GetCapabilities
*/
/**
\struct ARM_DRIVER_ETH_MAC
\details
The functions of the Ethernet MAC are accessed by function pointers. Refer to \ref DriverFunctions for
overview information.
Each instance of an Ethernet MAC provides such an access struct. The instance is indicated by
a postfix in the symbol name of the access struct, for example:
- \b Driver_ETH_MAC0 is the name of the access struct of the first instance (no. 0).
- \b Driver_ETH_MAC1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_ETH_MAC<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*/
/**
\struct ARM_ETH_MAC_TIME
\details
The two members of this struct provide fields to encode time values in the order \token{Nano seconds} and \token{seconds}.
The member \em ns is also used as a correction factor for \ref ARM_ETH_MAC_TIMER_ADJUST_CLOCK.
<b>Used in:</b>
- \ref ARM_ETH_MAC_GetRxFrameTime
- \ref ARM_ETH_MAC_GetTxFrameTime
- \ref ARM_ETH_MAC_ControlTimer
*******************************************************************************************************************/
/**
\typedef ARM_ETH_MAC_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_ETH_MAC_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_ETH_MAC_Initialize
*******************************************************************************************************************/
/**
\defgroup ETH_MAC_events Ethernet MAC Events
\ingroup eth_mac_interface_gr
\brief The Ethernet MAC driver generates call back events that are notified via the function \ref ARM_ETH_MAC_SignalEvent.
\details
This section provides the event values for the \ref ARM_ETH_MAC_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_ETH_MAC_EVENT_RX_FRAME
\def ARM_ETH_MAC_EVENT_TX_FRAME
\def ARM_ETH_MAC_EVENT_WAKEUP
\def ARM_ETH_MAC_EVENT_TIMER_ALARM
@}
*/
//
// Function documentation
//
ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void) {
;
}
/**
\fn ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void);
\details
The function \b ARM_ETH_MAC_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
ARM_DRIVER_ETH_MAC *mac;
void setup_ethernet (void) {
ARM_DRIVER_VERSION version;
mac = &Driver_ETH_MAC0;
version = mac->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*******************************************************************************************************************/
ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void) {
;
}
/**
\fn ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void)
\details
The function \b ARM_ETH_MAC_GetCapabilities retrieves information about capabilities in this driver implementation.
The data fields of the struct \ref ARM_ETH_MAC_CAPABILITIES encode various capabilities, for example
if a hardware is capable to create checksums in hardware or signal events using the \ref ARM_ETH_MAC_SignalEvent
callback function.
Example:
\code
extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
ARM_DRIVER_ETH_MAC *mac;
void read_capabilities (void) {
ARM_ETH_MAC_CAPABILITIES mac_capabilities;
mac = &Driver_ETH_MAC0;
mac_capabilities = mac->GetCapabilities ();
// interrogate capabilities
}
\endcode
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) {
}
/**
\fn int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event)
\details
The function \b ARM_ETH_MAC_Initialize initializes the Ethernet MAC interface.
It is called when the middleware component starts operation.
The \ref ARM_ETH_MAC_Initialize function performs the following operations:
- Initializes the resources needed for the Ethernet MAC peripheral.
- Registers the \ref ARM_ETH_MAC_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_ETH_MAC_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_Uninitialize (void) {
}
/**
\fn int32_t ARM_ETH_MAC_Uninitialize (void)
\details
The function \b ARM_ETH_MAC_Uninitialize de-initializes the resources of Ethernet MAC interface.
It is called when the middleware component stops operation and releases the software resources
used by the interface.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state) {
}
/**
\fn int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_ETH_MAC_PowerControl allows you to configure the power modes of the Ethernet MAC interface.
The parameter \em state can be:
- ARM_POWER_OFF: Ethernet MAC peripheral is turned off.
- ARM_POWER_FULL: Ethernet MAC peripheral is turned on and fully operational.
If power \em state specifies an unsupported mode, the function returns \ref ARM_DRIVER_ERROR_UNSUPPORTED as status information
and the previous power state of the peripheral is unchanged. Multiple calls with the same \em state generate no
error.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) {
}
/**
\fn int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr)
\details
The function \b ARM_ETH_MAC_GetMacAddress retrieves the Ethernet MAC own address from the driver.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) {
}
/**
\fn int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr)
\details
The function \b ARM_ETH_MAC_SetMacAddress configures Ethernet MAC own address.
The Ethernet MAC accepts packets <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frames</b></a> which contains
a MAC destination address that matches the address specified with \em ptr_addr.
The Ethernet MAC receiver will accept also packets with addresses configured by \ref ARM_ETH_MAC_SetAddressFilter function.
MAC receiver can be configured to accept also packets with broadcast address, any multicast address or even all packets regardless of address (Promiscuity Mode).
This is configured by function \ref ARM_ETH_MAC_Control with \ref ARM_ETH_MAC_CONFIGURE as control parameter.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr) {
}
/**
\fn int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr)
\details
The function \b ARM_ETH_MAC_SetAddressFilter configures Ethernet MAC receiver address filtering.
The Ethernet MAC accepts packets <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frames</b></a> which contains
a MAC destination address of the list supplied with \em ptr_addr. The parameter \em ptr_addr provides and array of Ethernet MAC addresses. The number of addresses
is supplied by \em num_addr. Specifying \em num_adr = 0 disables address filtering previously set with this function.
The Ethernet MAC receiver will accept packets addressed to its own address and packets with addresses configured by this function.
MAC receiver can be configured to accept also packets with broadcast address, any multicast address or even all packets regardless of address (Promiscuity Mode).
This is configured by function \ref ARM_ETH_MAC_Control with \ref ARM_ETH_MAC_CONFIGURE as control parameter.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) {
}
/**
\fn int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
\details
The function \b ARM_ETH_MAC_SendFrame writes an <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frame</b></a> to the Ethernet MAC transmit buffer.
The Ethernet MAC transmit engine must be enabled by using the function \ref ARM_ETH_MAC_Control (ARM_ETH_MAC_CONTROL_TX, 1) before a call to this function.
The frame data addressed by \em buf starts with MAC destination and ends with the last Payload data byte. The frame data is copied into
the transmit buffer of the Ethernet MAC interface. The function does not wait until the transmission over the Ethernet is complete,
however the memory addressed by \em buf is available for the next Ethernet frame after return.
The maximum value for \em len is implied by the size restrictions of the Ethernet frame but is not verified.
Using an invalid value for \em len may generate unpredicted results.
The parameter \em flags specifies additional attributes for the function as shown in the following table. Multiple flags can be combined, for example:
ARM_ETH_MAC_TX_FRAME_EVENT | ARM_ETH_MAC_TX_FRAME_TIMESTAMP.
Flag bit | Description
:--------------------------------------|:-----------------------------------------
\ref ARM_ETH_MAC_TX_FRAME_FRAGMENT | Indicates that it is a fragment of the frame. allows you to collect multiple fragments before the frame is sent.
\ref ARM_ETH_MAC_TX_FRAME_EVENT | \ref ARM_ETH_MAC_SignalEvent with \em event bit \ref ARM_ETH_MAC_EVENT_TX_FRAME set will be called when frame send is complete.
\ref ARM_ETH_MAC_TX_FRAME_TIMESTAMP | Capture the time stamp of the frame. The time stamp can be obtained using the function \ref ARM_ETH_MAC_GetTxFrameTime.
\b Example:
\code
status = mac->SendFrame (&frame->data[0], frame->length, 0);
if (status != ARM_DRIVER_OK) {
// error handling
}
\endcode
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len) {
}
/**
\fn int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len)
\details
The function \b ARM_ETH_MAC_ReadFrame reads an <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frame</b></a> from the Ethernet MAC receive buffer.
The Ethernet MAC receive engine must be enabled using the function \ref ARM_ETH_MAC_Control (ARM_ETH_MAC_CONTROL_RX , 1) before a call to this function.
The \em len of the Ethernet frame can be checked using the function \ref ARM_ETH_MAC_GetRxFrameSize.
The frame data addressed by \em buf starts with MAC destination and ends with the last Payload data byte. The frame data is read from
the receive buffer of the Ethernet MAC interface and the number of bytes written into the memory addressed by \em buf is returned.
A negative return value indicates an error whereby the status code is defined with driver common return codes.
The function \ref ARM_ETH_MAC_ReadFrame may be called with \em buf = NULL and \em len = 0 to discard or release an frame. This is useful when an incorrect frame has been received or
no memory is available to hold the Ethernet frame.
\b Example:
\code
size = mac->GetRxFrameSize ();
if ((size < 14) || (size > 1514)) { // frame excludes CRC
mac->ReadFrame (NULL, 0); // Frame error, release it
}
len = mac->ReadFrame (&frame->data[0], size);
if (len < 0) {
// error handling
}
\endcode
*******************************************************************************************************************/
uint32_t ARM_ETH_MAC_GetRxFrameSize (void) {
}
/**
\fn uint32_t ARM_ETH_MAC_GetRxFrameSize (void)
\details
The function \b ARM_ETH_MAC_GetRxFrameSize returns the size of a received
<a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frame</b></a>.
This function is called before \ref ARM_ETH_MAC_ReadFrame and supplies the value \em len.
The frame size includes MAC destination and ends with the last Payload data byte.
Value \em 0 indicates that no Ethernet frame is available in the receive buffer.
Values smaller than minimum size of Ethernet frame or larger than maximum size of Ethernet frame
indicate an invalid frame which needs to be discarded by calling \ref ARM_ETH_MAC_ReadFrame.
\b Example:
- see \ref ARM_ETH_MAC_ReadFrame
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time) {
}
/**
\fn int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time)
\details
Retrieve time stamp of a received <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frame</b></a>.
This function must be called before the frame is read using \ref ARM_ETH_MAC_ReadFrame.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time) {
}
/**
\fn int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time)
\details
The function \b returns the time stamp of a transmitted <a href="http://en.wikipedia.org/wiki/Ethernet_frame" target="_blank"><b>Ethernet frame</b></a>.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg) {
}
/**
\fn int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg)
\details
The function \b ARM_ETH_MAC_Control controls the Ethernet MAC interface and executes various operations.
After initialization, the Ethernet transceiver and receiver are disabled.
The parameter \em control specifies an operation as defined in the table <b>Parameter \em control</b>. \n
The parameter \em arg provides, depending on the operation, additional information or values.
The table lists values for the parameter \em control.
Parameter \em control | Operation
:----------------------------------------------------|:--------------------------------------------
\ref ARM_ETH_MAC_CONFIGURE | Configure the Ethernet MAC interface; For \em arg values, see table <b>Parameter \em arg for CONFIGURE</b>
\ref ARM_ETH_MAC_CONTROL_TX | Enable or disable the transmitter; \em arg : \token{0=disable; 1=enable}
\ref ARM_ETH_MAC_CONTROL_RX | Enable or disable the receiver; \em arg : \token{0=disable; 1=enable}
\ref ARM_ETH_MAC_FLUSH | Flush a buffer; \em arg : see table <b>Parameter \em arg for FLUSH</b>
\ref ARM_ETH_MAC_SLEEP | Exit/Enter Sleep mode; \em arg : \token{0=exit; 1=enter and wait for Magic packet}
\ref ARM_ETH_MAC_VLAN_FILTER | Configure VLAN Filter for received frames; \em arg : See table <b>Parameter \em arg for VLAN Filter</b>
The table <b>Parameter \em arg for CONFIGURE</b> lists the \em arg values for the \em control \b ARM_ETH_MAC_CONFIGURE.
The values can be ORed in the following way:
\code
mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_LOOPBACK);
\endcode
<table class="cmtable" summary="">
<tr><th colspan="4">Parameter \em arg CONFIGURE </th></tr>
<tr><th>Parameter \em arg </th><th> Bit </th><th> Category </th><th>Description </th></tr>
<tr><td>\ref ARM_ETH_MAC_SPEED_10M </td><td rowspan="3"> 0..1 </td><td rowspan="3">Link Speed </td><td>Set the link speed to \token{10 [Mbps]} </td></tr>
<tr><td>\ref ARM_ETH_MAC_SPEED_100M </td> <td>Set the link speed to \token{100 [Mbps]}</td></tr>
<tr><td>\ref ARM_ETH_MAC_SPEED_1G </td> <td>Set the link speed to \token{1 [Gbps]} </td></tr>
<tr><td>\ref ARM_ETH_MAC_DUPLEX_HALF </td><td rowspan="2"> 2 </td><td rowspan="2">Link Mode </td><td>Set the link mode to half duplex </td></tr>
<tr><td>\ref ARM_ETH_MAC_DUPLEX_FULL </td> <td>Set the link mode to full duplex </td></tr>
<tr><td>n.a. </td><td> 3 </td><td> n.a. </td><td>\em reserved </td></tr>
<tr><td>\ref ARM_ETH_MAC_LOOPBACK </td><td> 4 </td><td> Loopback Test Mode </td><td>Set the interface into a Loop-back test mode</td></tr>
<tr><td>\ref ARM_ETH_MAC_CHECKSUM_OFFLOAD_RX</td><td> 5 </td><td>Receiver Checksum offload</td><td>Enable Receiver Checksum offload </td></tr>
<tr><td>\ref ARM_ETH_MAC_CHECKSUM_OFFLOAD_TX</td><td> 6 </td><td>Transmitter Checksum offload</td><td>Enable Transmitter Checksum offload </td></tr>
<tr><td>\ref ARM_ETH_MAC_ADDRESS_BROADCAST </td><td> 7 </td><td>Broadcast Frame address </td><td>Accept frames with Broadcast address </td></tr>
<tr><td>\ref ARM_ETH_MAC_ADDRESS_MULTICAST </td><td> 8 </td><td>Multicast Frame address </td><td>Accept frames with any Multicast address</td></tr>
<tr><td>\ref ARM_ETH_MAC_ADDRESS_ALL </td><td> 9 </td><td>Any Frame address </td><td>Accept frames with any address (Promiscuous Mode)</td></tr>
</table>
The table <b>Parameter \em arg for FLUSH</b> lists the \em arg values for the \em control \b ARM_ETH_MAC_FLUSH.
The \em arg values can be ORed.
<table class="cmtable" summary="">
<tr><th colspan="4">Parameter \em arg for FLUSH </th></tr>
<tr><th>Parameter \em arg </th><th> Bit </th><th> Category </th><th> Description </th></tr>
<tr><td>\ref ARM_ETH_MAC_FLUSH_RX </td><td> 1 </td><td> Receive buffer </td><td> Flush the Receive buffer </td></tr>
<tr><td>\ref ARM_ETH_MAC_FLUSH_TX </td><td> 2 </td><td> Transmit buffer </td><td> Flush the Transmit buffer </td></tr>
</table>
The table <b>Parameter \em arg for VLAN Filter</b> lists the \em arg values for the \em control \b ARM_ETH_MAC_VLAN_FILTER.
The \em arg values can be ORed.
<table class="cmtable" summary="">
<tr><th colspan="4">Parameter \em arg for VLAN Filter</th></tr>
<tr><th>Parameter \em arg </th><th> Bit </th><th> Category </th><th> Description </th></tr>
<tr><td>\em value </td><td> 0..15 </td><td> VLAN Tag </td><td> Set VLAN Tag value </td></tr>
<tr><td>\token{0} </td><td rowspan="2"> 16 </td><td rowspan="2"> Use of VLAN </td><td> Compare the complete 16-bit VLAN Tag value </td></tr>
<tr><td>\ref ARM_ETH_MAC_VLAN_FILTER_ID_ONLY </td> <td>Compare only the 12-bit VLAN Identifier </td></tr>
<tr><td>\token{0} </td><td> 0..16 </td><td> Disable </td><td> Disable the VLAN Filter </td></tr>
</table>
\b Example:
\code
...
// start transfer
mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_ADDRESS_BROADCAST);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 1);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 1);
... // stop transfer
mac->Control(ARM_ETH_MAC_FLUSH, ARM_ETH_MAC_FLUSH_TX | ARM_ETH_MAC_FLUSH_RX);
mac->Control(ARM_ETH_MAC_CONTROL_TX, 0);
mac->Control(ARM_ETH_MAC_CONTROL_RX, 0);
}
}
\endcode
For a complete example, refer to \ref eth_interface_gr - Driver Functions.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) {
}
/**
\fn int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time)
\details
The function \b ARM_ETH_MAC_ControlTimer controls the timer required for PTP (Precision Time Protocol).
The parameter \em control receives \b ARM_ETH_MAC_TIMER_xxx codes to manage the timer for a PTP enabled Ethernet MAC interface. \n
The parameter \em time is pointer to a structure that holds time information.
Mode Parameters: Timer Controls | Description
:---------------------------------------|:--------------------------------------------
\ref ARM_ETH_MAC_TIMER_GET_TIME | Retrieve the current time and update the content \ref ARM_ETH_MAC_TIME *time.
\ref ARM_ETH_MAC_TIMER_SET_TIME | Set the new time using the values provided with \ref ARM_ETH_MAC_TIME *time.
\ref ARM_ETH_MAC_TIMER_INC_TIME | Increment the current time by using the values provided with \ref ARM_ETH_MAC_TIME *time.
\ref ARM_ETH_MAC_TIMER_DEC_TIME | Decrement the current time by using the values provided with \ref ARM_ETH_MAC_TIME *time.
\ref ARM_ETH_MAC_TIMER_SET_ALARM | Set the alarm time to the values provided with \ref ARM_ETH_MAC_TIME *time.
\ref ARM_ETH_MAC_TIMER_ADJUST_CLOCK | Set the clock frequency; the value in time->ns is the <b>correction factor</b> in fractional format q31.
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) {
}
/**
\fn int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
\details
Read Ethernet PHY Register through the Management Interface. The function is passed to \ref ARM_ETH_PHY_Initialize.
The Ethernet PHY driver uses this function to read the value of PHY registers.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) {
}
/**
\fn int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
\details
The function \b ARM_ETH_MAC_PHY_Write writes to a Ethernet PHY register through the Management Interface. The function is passed to \ref ARM_ETH_PHY_Initialize.
The Ethernet PHY driver uses this function to write data to PHY registers.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*******************************************************************************************************************/
void ARM_ETH_MAC_SignalEvent (uint32_t event) {
;
}
/**
\fn void ARM_ETH_MAC_SignalEvent (uint32_t event)
\details
The function \b ARM_ETH_MAC_SignalEvent is a callback function registered by the function
\ref ARM_ETH_MAC_Initialize. This function is typically called from interrupt service routines (ISR) to indicate that
a frame is processed or a special event occurred.
The parameter \a event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_ETH_MAC_CAPABILITIES, which can be retrieved with the function \ref ARM_ETH_MAC_GetCapabilities.
The following events can be generated:
Parameter \em event | Bit | Description
:----------------------------------------|:---:|:----------------------------------------
\ref ARM_ETH_MAC_EVENT_RX_FRAME | 0 | Occurs after a frame is received. Frame can be read by calling \ref ARM_ETH_MAC_ReadFrame.
\ref ARM_ETH_MAC_EVENT_TX_FRAME | 1 | Occurs after call to \ref ARM_ETH_MAC_SendFrame to indicate that the frame is transmitted.
\ref ARM_ETH_MAC_EVENT_WAKEUP | 2 | Indicates that a Magic Packet is received while the driver is in Sleep mode (set by \ref ARM_ETH_MAC_SLEEP using \ref ARM_ETH_MAC_Control).
\ref ARM_ETH_MAC_EVENT_TIMER_ALARM | 3 | Indicates that a Timer Alarm occurred that was set with \ref ARM_ETH_MAC_TIMER_SET_ALARM using ARM_ETH_MAC_ControlTimer.
*******************************************************************************************************************/
/**
\defgroup eth_mac_control Ethernet MAC Control Codes
\ingroup eth_mac_interface_gr
\brief Configure and control the Ethernet MAC using the \ref ARM_ETH_MAC_Control.
\details
@{
Many parameters of the Ethernet MAC driver are configured using the \ref ARM_ETH_MAC_Control function.
The various Ethernet MAC control codes define:
- \ref eth_mac_ctrls configures and controls the Ethernet MAC interface
- \ref eth_mac_configuration_ctrls specifies speed mode, link mode, checksum, and frame filtering modes
- \ref eth_mac_flush_flag_ctrls specify controls to flush a buffer
- \ref eth_mac_vlan_filter_ctrls specifies whether to compare only the VLAN Identifier
Refer to the \ref ARM_ETH_MAC_Control function for further details.
*/
/**
\defgroup eth_mac_ctrls Ethernet MAC Controls
\brief Configure and control the Ethernet MAC interface.
\details
@{
\def ARM_ETH_MAC_CONFIGURE
\sa ARM_ETH_MAC_Control
\def ARM_ETH_MAC_CONTROL_TX
\sa ARM_ETH_MAC_Control
\def ARM_ETH_MAC_CONTROL_RX
\sa ARM_ETH_MAC_Control
\def ARM_ETH_MAC_FLUSH
\sa ARM_ETH_MAC_Control
\def ARM_ETH_MAC_SLEEP
\sa ARM_ETH_MAC_Control
\def ARM_ETH_MAC_VLAN_FILTER
\sa ARM_ETH_MAC_Control
@}
*/
/**
\defgroup eth_mac_configuration_ctrls Ethernet MAC Configuration
\brief Specifies speed mode, link mode, checksum, and frame filtering modes.
\details
@{
The function \ref ARM_ETH_MAC_Control with \em control = \ref ARM_ETH_MAC_CONFIGURE configures the Ethernet MAC interface
as specified with \em arg listed bellow.
\def ARM_ETH_MAC_SPEED_10M
\def ARM_ETH_MAC_SPEED_100M
\def ARM_ETH_MAC_SPEED_1G
\def ARM_ETH_MAC_DUPLEX_HALF
\def ARM_ETH_MAC_DUPLEX_FULL
\def ARM_ETH_MAC_LOOPBACK
\def ARM_ETH_MAC_CHECKSUM_OFFLOAD_RX
\def ARM_ETH_MAC_CHECKSUM_OFFLOAD_TX
\def ARM_ETH_MAC_ADDRESS_BROADCAST
\def ARM_ETH_MAC_ADDRESS_MULTICAST
\def ARM_ETH_MAC_ADDRESS_ALL
@}
*/
/**
\defgroup eth_mac_flush_flag_ctrls Ethernet MAC Flush Flags
\brief Specify controls to flush a buffer
\details
@{
The function \ref ARM_ETH_MAC_Control with \em control = \ref ARM_ETH_MAC_FLUSH flushes the buffer
which is specified with \em arg listed bellow.
\def ARM_ETH_MAC_FLUSH_RX
\def ARM_ETH_MAC_FLUSH_TX
@}
*/
/**
\defgroup eth_mac_vlan_filter_ctrls Ethernet MAC VLAN Filter Flag
\brief Specify whether to compare only the VLAN Identifier
\details
@{
The function \ref ARM_ETH_MAC_Control with \em control = \ref ARM_ETH_MAC_VLAN_FILTER configures the VLAN Filter for received frames as specified with \em arg.
By default the complete VLAN Tag (16-bit) is compared. When \ref ARM_ETH_MAC_VLAN_FILTER_ID_ONLY is specified then only the VLAN Identifier (12-bit) is compared.
Specifying \em arg=0 disables the VLAN Filter.
\def ARM_ETH_MAC_VLAN_FILTER_ID_ONLY
@}
*/
/**
@} */ // end group eth_mac_control
/**
\defgroup eth_mac_time_control Ethernet MAC Timer Control Codes
\ingroup eth_mac_interface_gr
\brief Control codes for \ref ARM_ETH_MAC_ControlTimer function.
\details
The following timer controls are used as parameter \em control for the \ref ARM_ETH_MAC_ControlTimer function:
@{
\def ARM_ETH_MAC_TIMER_GET_TIME
\sa ARM_ETH_MAC_ControlTimer
\def ARM_ETH_MAC_TIMER_SET_TIME
\sa ARM_ETH_MAC_ControlTimer
\def ARM_ETH_MAC_TIMER_INC_TIME
\sa ARM_ETH_MAC_ControlTimer
\def ARM_ETH_MAC_TIMER_DEC_TIME
\sa ARM_ETH_MAC_ControlTimer
\def ARM_ETH_MAC_TIMER_SET_ALARM
\sa ARM_ETH_MAC_ControlTimer
\def ARM_ETH_MAC_TIMER_ADJUST_CLOCK
\sa ARM_ETH_MAC_ControlTimer
@}
*/
/**
\defgroup eth_mac_frame_transmit_ctrls Ethernet MAC Frame Transmit Flags
\brief Specify frame transmit flags
\details
@{
\def ARM_ETH_MAC_TX_FRAME_FRAGMENT
\sa ARM_ETH_MAC_SendFrame
\def ARM_ETH_MAC_TX_FRAME_EVENT
\sa ARM_ETH_MAC_SendFrame
\def ARM_ETH_MAC_TX_FRAME_TIMESTAMP
\sa ARM_ETH_MAC_SendFrame
@}
*/
/**
@}
*/
// End ETH MAC Interface

View File

@ -0,0 +1,303 @@
/**
\defgroup eth_phy_interface_gr Ethernet PHY Interface
\ingroup eth_interface_gr
\brief Driver API for Ethernet PHY Peripheral (%Driver_ETH_PHY.h)
\details The following section describes the Ethernet PHY Interface as defined in the %Driver_ETH_PHY.h header file.
The %Driver_ETH_PHY.h contains two \#defines that are used to configure the connection between the PHY and the
microcontroller device:
- \c ETH_PHY_NUM and
- \c ETH_PHY_ADDR
Usually, the Serial Management Interface (\b SMI) (using MDC and MDIO) is used to access the PHYs internal registers to read
the state of the link (up/down), duplex mode, speed, and to restart auto-negotiation etc. SMI is a serial bus, which allows
to connect up to 32 devices. Devices on the bus are accessed using a 5-bit device address. A default device address is
hardware configurable by pin-strapping on the device (some pins are sampled when a reset is asserted or at power-up).
The devices internal weak pull-up or pull-down resistors define a default device address. This address can be changed by
connecting strong pull-up or pull-down resistors externally. In this case, the \c ETH_PHY_ADDR needs to be defined by the
user.
If a microcontroller device offers more than one Ethernet PHY driver, the user needs to set the correct \c ETH_PHY_NUM in his
application.
@{
*/
/**
\struct ARM_DRIVER_ETH_PHY
\details
The functions of the Ethernet PHY are accessed by function pointers exposed by this structure. Refer to \ref DriverFunctions for
overview information.
Each instance of an Ethernet PHY provides such an access struct. The instance is identified by
a postfix number in the symbol name of the access struct, for example:
- \b Driver_ETH_PHY0 is the name of the access struct of the first instance (no. 0).
- \b Driver_ETH_PHY1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_ETH_PHY<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*****************************************************************************************************************/
/**
\typedef ARM_ETH_PHY_Read_t
\details
Provides the typedef for the register read function \ref ARM_ETH_MAC_PHY_Read.
<b>Parameter for:</b>
- \ref ARM_ETH_PHY_Initialize
*******************************************************************************************************************/
/**
\typedef ARM_ETH_PHY_Write_t
\details
Provides the typedef for the register write function \ref ARM_ETH_MAC_PHY_Write.
<b>Parameter for:</b>
- \ref ARM_ETH_PHY_Initialize
*******************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_ETH_PHY_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_ETH_PHY_GetVersion (void)
\details
The function \b ARM_ETH_PHY_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_ETH_PHY Driver_ETH_PHY0;
ARM_DRIVER_ETH_PHY *drv_info;
void setup_ethernet_phy (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_ETH_PHY0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
int32_t ARM_ETH_PHY_Initialize (ARM_ETH_PHY_Read_t fn_read, ARM_ETH_PHY_Write_t fn_write) {
return 0;
}
/**
\fn int32_t ARM_ETH_PHY_Initialize (ARM_ETH_PHY_Read_t fn_read, ARM_ETH_PHY_Write_t fn_write)
\details
The function \b ARM_ETH_PHY_Initialize initializes the Ethernet PHY interface.
It is called when the middleware component starts operation.
The \ref ARM_ETH_PHY_Initialize function performs the following operations:
- Initializes the resources needed for Ethernet PHY peripheral.
- Registers the \ref ARM_ETH_MAC_PHY_Read register read access function.
- Registers the \ref ARM_ETH_MAC_PHY_Write register write access function.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_ETH_PHY_Uninitialize (void) {
return 0;
}
/**
\fn int32_t ARM_ETH_PHY_Uninitialize (void)
\details
The function \b ARM_ETH_PHY_Uninitialize de-initializes the resources of Ethernet PHY interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_ETH_PHY_PowerControl (ARM_POWER_STATE state) {
return 0;
}
/**
\fn int32_t ARM_ETH_PHY_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_ETH_PHY_PowerControl operates the power modes of the Ethernet PHY interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_ETH_PHY_SetInterface (uint32_t interface) {
return 0;
}
/**
\fn int32_t ARM_ETH_PHY_SetInterface (uint32_t interface)
\details
The function \b ARM_ETH_PHY_SetInterface specifies the \ref eth_interface_types1 that links the Ethernet MAC and Ethernet PHY.
After initialization of the PHY interface, you can set the media type.
The function \ref ARM_ETH_MAC_GetCapabilities retrieves the media interface type encoded in the data field \b media_interface of the structure
\ref ARM_ETH_MAC_CAPABILITIES.
The parameter \em interface can have the following values:
Parameter \em interface | Media Type
:-----------------------------|:-------------------------
\ref ARM_ETH_INTERFACE_MII | Media Independent Interface (MII)
\ref ARM_ETH_INTERFACE_RMII | Reduced Media Independent Interface (RMII)
\ref ARM_ETH_INTERFACE_SMII | Serial Media Independent Interface (SMII);
\note
Some \em interface values may be unsupported by a driver implementation. For example \ref ARM_ETH_INTERFACE_SMII may return \b ARM_DRIVER_ERROR_UNSUPPORTED.
\b Example:
\code
static ARM_ETH_MAC_CAPABILITIES capabilities;
static ARM_DRIVER_ETH_MAC *mac;
static ARM_DRIVER_ETH_PHY *phy;
mac = &Driver_ETH_MAC0;
phy = &Driver_ETH_PHY0;
// Initialize Media Access Controller
capabilities = mac->GetCapabilities ();
...
status = phy->SetInterface (capabilities.media_interface);
if (status != ARM_DRIVER_OK) ... // error handling
status = phy->SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE);
if (status != ARM_DRIVER_OK) ... // error handling
...
\endcode
*****************************************************************************************************************/
int32_t ARM_ETH_PHY_SetMode (uint32_t mode) {
return 0;
}
/**
\fn int32_t ARM_ETH_PHY_SetMode (uint32_t mode)
\details
The function \b ARM_ETH_PHY_SetMode sets the operation mode parameters for the Ethernet PHY.
The table below lists the possible values for the parameter \em mode. Values from different categories can be ORed as shown in this example code:
\code
phy->SetMode (ARM_ETH_PHY_SPEED_100M | ARM_ETH_PHY_LOOPBACK | ARM_ETH_PHY_DUPLEX_HALF );
\endcode
\n
<table class="cmtable" summary="">
<tr><th>Parameter \em mode </th><th> bit </th><th> Category </th> <th>Description</th></tr>
<tr><td>\ref ARM_ETH_PHY_SPEED_10M </td><td rowspan="3"> 0..1 </td><td rowspan="3">Link Speed </td> <td>Set the link speed to \token{10 [Mbps]} </td></tr>
<tr><td>\ref ARM_ETH_PHY_SPEED_100M </td> <td>Set the link speed to \token{100 [Mbps]} </td></tr>
<tr><td>\ref ARM_ETH_PHY_SPEED_1G </td> <td>Set the link speed to \token{1 [Gbps]} </td></tr>
<tr><td>\ref ARM_ETH_PHY_DUPLEX_HALF </td><td rowspan="2"> 2 </td><td rowspan="2">Link Mode </td> <td>Set the link mode to half duplex </td></tr>
<tr><td>\ref ARM_ETH_PHY_DUPLEX_FULL </td> <td>Set the link mode to full duplex </td></tr>
<tr><td>\ref ARM_ETH_PHY_AUTO_NEGOTIATE </td><td> 3 </td><td>Autonegotiation </td> <td>Set the interface to Auto Negotiation mode of transmission parameters</td></tr>
<tr><td>\ref ARM_ETH_PHY_LOOPBACK </td><td> 4 </td><td>Loopback </td> <td>Set the interface into a Loop-back test mode </td></tr>
<tr><td>\ref ARM_ETH_PHY_ISOLATE </td><td> 5 </td><td>Isolation </td> <td>Set to indicate electrical isolation of PHY interface from MII/RMII interface</td></tr>
</table>
\note
Some settings may be also taken from configuration pins (example \ref ARM_ETH_PHY_ISOLATE). Check the effect of mode settings in the actual driver implementation.
\note
Some \em mode values may be unsupported by a driver implementation. For example \ref ARM_ETH_PHY_SPEED_1G may return \b ARM_DRIVER_ERROR_UNSUPPORTED.
\b Example:
\code
static ARM_ETH_MAC_CAPABILITIES capabilities;
static ARM_DRIVER_ETH_MAC *mac;
static ARM_DRIVER_ETH_PHY *phy;
mac = &Driver_ETH_MAC0;
phy = &Driver_ETH_PHY0;
// Initialize Media Access Controller
capabilities = mac->GetCapabilities ();
...
status = phy->SetInterface (capabilities.media_interface);
if (status != ARM_DRIVER_OK) ... // error handling
status = phy->SetMode (ARM_ETH_PHY_SPEED_100M | ARM_ETH_PHY_DUPLEX_FULL | ARM_ETH_PHY_ISOLATE);
if (status != ARM_DRIVER_OK) ... // error handling
...
\endcode
*****************************************************************************************************************/
ARM_ETH_LINK_STATE ARM_ETH_PHY_GetLinkState (void) {
return 0;
}
/**
\fn ARM_ETH_LINK_STATE ARM_ETH_PHY_GetLinkState (void)
\details
The function \b ARM_ETH_PHY_GetLinkState retrieves the connection status of the physical Ethernet link.
\b Example:
- see \ref eth_interface_gr - Driver Functions
*****************************************************************************************************************/
ARM_ETH_LINK_INFO ARM_ETH_PHY_GetLinkInfo (void) {
return 0;
}
/**
\fn ARM_ETH_LINK_INFO ARM_ETH_PHY_GetLinkInfo (void)
\details
The function \b ARM_ETH_PHY_GetLinkInfo retrieves information about the current established communication
mode (half/full duplex) and communication speed. Information is only valid when link is up (see \ref ARM_ETH_PHY_GetLinkState).
\b Example:
- see \ref eth_interface_gr - Driver Functions
*****************************************************************************************************************/
/**
@}
*/
// End ETH PHY Interface group; below the groups are included with \ingroup
/**
\defgroup eth_phy_mode_ctrls Ethernet PHY Mode
\ingroup eth_phy_interface_gr
\brief Specify operation modes of the Ethernet PHY interface
\details
@{
\def ARM_ETH_PHY_SPEED_10M
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_SPEED_100M
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_SPEED_1G
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_DUPLEX_HALF
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_DUPLEX_FULL
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_AUTO_NEGOTIATE
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_LOOPBACK
\sa ARM_ETH_PHY_SetMode
\def ARM_ETH_PHY_ISOLATE
\sa ARM_ETH_PHY_SetMode
@}
*/

View File

@ -0,0 +1,365 @@
/**
\defgroup flash_interface_gr Flash Interface
\brief Driver API for Flash Device Interface (%Driver_Flash.h)
\details
<a href="http://en.wikipedia.org/wiki/Flash_memory" target="_blank">Flash devices</a> based on NOR memory cells are the
preferred technology for embedded applications requiring a discrete non-volatile memory device. The low read latency
characteristic of these Flash devices allow a direct code execution
(<a href="http://en.wikipedia.org/wiki/Execute_in_place" target="_blank">XIP</a>) and data storage in a single memory
product.
<b>Flash API</b>
The Flash API provides a generic API suitable for Flashes with NOR memory cells independent from the actual interface
to the MCU (memory bus, SPI, ...). <a href="http://en.wikipedia.org/wiki/Flash_memory#Serial_flash" target="_blank">SPI</a>
flashes are typically not named NOR flashes but have usually same flash cell properties.
The following header files define the Application Programming Interface (API) for the Flash interface:
- \b %Driver_Flash.h : Driver API for Flash Device Interface
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_FLASH : access struct for Flash driver functions
@{
A typical setup sequence for the driver is shown below:
<b>Example Code:</b>
\include Flash_Demo.c
*/
*******************************************************************************************************************/
/**
\defgroup Flash_events Flash Events
\ingroup flash_interface_gr
\brief The Flash driver generates call back events that are notified via the function \ref ARM_Flash_SignalEvent.
\details
This section provides the event values for the \ref ARM_Flash_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_FLASH_EVENT_READY
\def ARM_FLASH_EVENT_ERROR
@}
*/
/**
\struct ARM_FLASH_SECTOR
\details
Specifies sector start and end address.
<b>Element of</b>:
- \ref ARM_FLASH_INFO structure
*******************************************************************************************************************/
/**
\struct ARM_FLASH_INFO
\details
Stores the characteristics of a Flash device. This includes sector layout, programming size and a default value for erased memory.
This information can be obtained from the Flash device datasheet and is used by the middleware in order to properly interact with the Flash device.
Sector layout is described by specifying the \em sector_info which points to an array of sector information (start and end address) and by specifying the \em sector_count which defines the number of sectors.
The element \em sector_size is not used in this case and needs to be \em 0.
Flash sectors need not to be aligned continuously. Gaps are allowed in the device memory space in order to reserve sectors for other usage (for example application code).
When the device has uniform sector size than the sector layout can be described by specifying the \em sector_size which defines the size of a single sector and by specifying the \em sector_count which defines the number of sectors.
The element \em sector_info is not used in this case and needs to be \em NULL.
The smallest programmable unit within a sector is specified by the \em program_unit. It defines the granularity for programming data.
Optimal programming page size is specified by the \em page_size and defines the amount of data that should be programmed in one step to achieve maximum programming speed.
Contents of erased memory is specified by the \em erased_value and is typically \em 0xFF. This value can be used before erasing a sector to check if the sector is blank and erase can be skipped.
*******************************************************************************************************************/
/**
\struct ARM_DRIVER_FLASH
\details
The functions of the Flash driver are accessed by function pointers exposed by this structure. Refer to \ref DriverFunctions for overview information.
Each instance of a Flash interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_Flash0 is the name of the access struct of the first instance (no. 0).
- \b Driver_Flash1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_Flash<i>n</i>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*******************************************************************************************************************/
/**
\struct ARM_FLASH_CAPABILITIES
\details
A Flash driver can be implemented with different capabilities. The data fields of this struct encode
the capabilities implemented by this driver.
The element \em event_ready indicates that the driver is able to generate the \ref ARM_FLASH_EVENT_READY event. In case that this event is not available it is possible to poll the driver status by calling the \ref ARM_Flash_GetStatus and check the \em busy flag.
The element \em data_width specifies the data access size and also defines the data type (uint8_t, uint16_t or uint32_t) for the \em data parameter in \ref ARM_Flash_ReadData and \ref ARM_Flash_ProgramData functions.
The element \em erase_chip specifies that the \ref ARM_Flash_EraseChip function is supported. Typically full chip erase is much faster than erasing the whole device sector per sector.
<b>Returned by:</b>
- \ref ARM_Flash_GetCapabilities
*******************************************************************************************************************/
/**
\struct ARM_FLASH_STATUS
\details
Structure with information about the status of the Flash.
The flag \em busy indicates that the driver is busy executing read/program/erase operation.
The flag \em error flag is cleared on start of read/program/erase operation and is set at the end of the current operation in case of error.
<b>Returned by:</b>
- \ref ARM_Flash_GetStatus
*****************************************************************************************************************/
/**
\typedef ARM_Flash_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_Flash_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_Flash_Initialize
*******************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_Flash_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_Flash_GetVersion (void)
\details
The function \b ARM_Flash_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_FLASH Driver_Flash0;
ARM_DRIVER_FLASH *drv_info;
void read_version (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_Flash0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*******************************************************************************************************************/
ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities (void)
\details
The function \b ARM_Flash_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the struct \ref ARM_FLASH_CAPABILITIES encode various capabilities, for example
if a hardware is able to create signal events using the \ref ARM_Flash_SignalEvent callback function.
Example:
\code
extern ARM_DRIVER_FLASH Driver_Flash0;
ARM_DRIVER_FLASH *drv_info;
void read_capabilities (void) {
ARM_FLASH_CAPABILITIES drv_capabilities;
drv_info = &Driver_Flash0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*******************************************************************************************************************/
int32_t ARM_Flash_Initialize (ARM_Flash_SignalEvent_t cb_event) {
return 0;
}
/**
\fn int32_t ARM_Flash_Initialize (ARM_Flash_SignalEvent_t cb_event)
\details
The function \b ARM_Flash_Initialize initializes the Flash interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the Flash interface.
- Registers the \ref ARM_Flash_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_Flash_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
\b Example:
- see \ref flash_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_Flash_Uninitialize (void) {
return 0;
}
/**
\fn int32_t ARM_Flash_Uninitialize (void)
\details
The function \b ARM_Flash_Uninitialize de-initializes the resources of Flash interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*******************************************************************************************************************/
int32_t ARM_Flash_PowerControl (ARM_POWER_STATE state) {
return 0;
}
/**
\fn int32_t ARM_Flash_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_Flash_PowerControl operates the power modes of the Flash interface.
The parameter \em state can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA. Can be called multiple times.
If the peripheral is already in this mode, then the function performs no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*******************************************************************************************************************/
int32_t ARM_Flash_ReadData (uint32_t addr, void *data, uint32_t cnt) {
return 0;
}
/**
\fn int32_t ARM_Flash_ReadData (uint32_t addr, void *data, uint32_t cnt)
\details
This function \b ARM_Flash_ReadData reads data from the Flash device.
The parameter \em addr specifies the address from where to read data (needs to be aligned to data type size). \n
The parameter \em data specifies the pointer to a buffer storing the data read.
The data type is \em uint8_t, \em uint16_t or \em uint32_t and is specified by the \em data_width in \ref ARM_FLASH_CAPABILITIES. \n
The parameter \em cnt specifies the number of data items to read.
The function executes in the following ways:
- When the operation is non-blocking (typical for SPI Flash) then the function only starts the operation and returns with zero number of data items read.
When the operation is completed the \ref ARM_FLASH_EVENT_READY event is generated (if supported and reported by \ref ARM_Flash_GetCapabilities).
In case of errors the \ref ARM_FLASH_EVENT_ERROR event is generated at the same time.
Progress of the operation can also be monitored by calling the \ref ARM_Flash_GetStatus function and checking the \em busy flag.
- When the operation is blocking (typical for memory mapped Flash) then the function returns after the data is read and returns the number of data items read.
*******************************************************************************************************************/
int32_t ARM_Flash_ProgramData (uint32_t addr, const void *data, uint32_t cnt) {
return 0;
}
/**
\fn int32_t ARM_Flash_ProgramData (uint32_t addr, const void *data, uint32_t cnt)
\details
This function \b ARM_Flash_ProgramData programs data to the Flash device.
The parameter \em addr specifies the address to where to program data (needs to be aligned to \em program_unit specified in \ref ARM_FLASH_INFO). \n
The parameter \em data specifies the pointer to a buffer containing data to be programmed.
The data type is \em uint8_t, \em uint16_t or \em uint32_t and is specified by the \em data_width in \ref ARM_FLASH_CAPABILITIES. \n
The parameter \em cnt specifies the number of data items to program (data size needs to be a multiple of \em program_unit).
The function executes in the following ways:
- When the operation is non-blocking (typically) then the function only starts the operation and returns with zero number of data items programmed.
When the operation is completed the \ref ARM_FLASH_EVENT_READY event is generated (if supported and reported by \ref ARM_Flash_GetCapabilities).
In case of errors the \ref ARM_FLASH_EVENT_ERROR event is generated at the same time.
Progress of the operation can also be monitored by calling the \ref ARM_Flash_GetStatus function and checking the \em busy flag.
- When the operation is blocking then the function returns after the data is programmed and returns the number of data items programmed.
*******************************************************************************************************************/
int32_t ARM_Flash_EraseSector (uint32_t addr) {
return 0;
}
/**
\fn int32_t ARM_Flash_EraseSector (uint32_t addr)
\details
This function \b ARM_Flash_EraseSector erases a flash sector specified by the parameter <i>adr</i> (points to start of the sector).
The function is non-blocking and returns as soon as the driver has started the operation.
When the operation is completed the \ref ARM_FLASH_EVENT_READY event is generated (if supported and reported by \ref ARM_Flash_GetCapabilities).
In case of errors the \ref ARM_FLASH_EVENT_ERROR event is generated at the same time.
Progress of the operation can also be monitored by calling the \ref ARM_Flash_GetStatus function and checking the \em busy flag.
*******************************************************************************************************************/
int32_t ARM_Flash_EraseChip (void) {
return 0;
}
/**
\fn int32_t ARM_Flash_EraseChip (void)
\details
The optional function \b ARM_Flash_EraseChip erases the complete device.
If the device does not support global erase or only a portion of the Flash memory space is used for storing files,
then the functions returns the error value \ref ARM_DRIVER_ERROR_UNSUPPORTED.
The data field \em eras_chip = \token{1} of the structure \ref ARM_FLASH_CAPABILITIES encodes that \b ARM_Flash_EraseChip is supported.
The field can be verified with the function \ref ARM_Flash_GetCapabilities.
The function is non-blocking and returns as soon as the driver has started the operation.
When the operation is completed, the \ref ARM_FLASH_EVENT_READY event is generated (if supported and reported by \ref ARM_Flash_GetCapabilities).
In case of errors, the \ref ARM_FLASH_EVENT_ERROR event is generated at the same time.
Progress of the operation can also be monitored by calling the \ref ARM_Flash_GetStatus function and checking the \em busy flag.
<b>See also:</b>
- ARM_Flash_SignalEvent
*******************************************************************************************************************/
ARM_FLASH_STATUS ARM_Flash_GetStatus (void) {
return 0;
}
/**
\fn ARM_FLASH_STATUS ARM_Flash_GetStatus (void)
\details
The function \b ARM_Flash_GetStatus returns the current Flash interface status stored in the structure \ref ARM_FLASH_STATUS.
*******************************************************************************************************************/
ARM_FLASH_INFO * ARM_Flash_GetInfo (void) {
return NULL;
}
/**
\fn ARM_FLASH_INFO * ARM_Flash_GetInfo (void)
\details
The function \b ARM_Flash_GetInfo returns information about the Flash device.
*******************************************************************************************************************/
void ARM_Flash_SignalEvent (uint32_t event) {
return 0;
}
/**
\fn void ARM_Flash_SignalEvent (uint32_t event)
\details
The function \b ARM_Flash_SignalEvent is a callback function registered by the function \ref ARM_Flash_Initialize.
The function is called automatically after read/program/erase operation completes.
The parameter \em event indicates one or more events that occurred during driver operation. Each event is coded in a separate bit and
therefore it is possible to signal multiple events in the event call back function.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_FLASH_CAPABILITIES, which can be retrieved with the function \ref ARM_Flash_GetCapabilities.
The following events can be generated:
Parameter \em event | Bit | Description
:-----------------------------------|:---:|:-----------
\ref ARM_FLASH_EVENT_READY | 0 | Occurs after read/program/erase operation completes.
\ref ARM_FLASH_EVENT_ERROR | 1 | Occurs together with \ref ARM_FLASH_EVENT_READY when operation completes with errors.
<b>See also:</b>
- \ref ARM_Flash_EraseChip
*******************************************************************************************************************/
/**
@}
*/
// End Flash Interface

View File

@ -0,0 +1,605 @@
/**
\defgroup i2c_interface_gr I2C Interface
\brief Driver API for I2C Bus Peripheral (%Driver_I2C.h)
\details
I<sup>2</sup>C (Inter-Integrated Circuit, referred to as I-squared-C, I-two-C, or IIC) is a multi-master serial single-ended bus and is mostly used
on single boards, but can also connect to components which are linked via cable.
Most significant features of the I<sup>2</sup>C bus include:
- Only two bus lines are required
- I<sup>2</sup>C is a true multi-master bus. Simple master/slave relationships exist between all components
- A baud rate is not required; the master device determines a bus clock
- Each connected device is addressable by a unique address
- Providing arbitration and collision detection
For more information about I<sup>2</sup>C refer to the following web pages:
- Wikipedia: <a href="http://en.wikipedia.org/wiki/I%C2%B2C" target="_blank">I<sup>2</sup>C</a>
- <a href="http://www.i2c-bus.org" target="_blank">www.i2c-bus.org</a>.
Devices can operation in Master or Slave mode:
- To operate in Master mode call the functions \ref ARM_I2C_MasterTransmit or \ref ARM_I2C_MasterReceive. These functions get as argument a <em>slave address</em>.
- To operate in Slave mode set the <em>slave address</em> using the function \ref ARM_I2C_Control. The functions \ref ARM_I2C_SlaveTransmit or \ref ARM_I2C_SlaveReceive are used to transfer data in Slave mode.
<b>I<sup>2</sup>C Slave Address</b>
Depending on the device, I<sup>2</sup>C supports 7-bit and 10-bit Slaves addresses.
The element <em>address_10_bit</em> in \ref ARM_I2C_CAPABILITIES indicates that the driver is able to handle 10-bit addresses.
A 10-bit Slave address is ORed with \ref ARM_I2C_ADDRESS_10BIT.
I<sup>2</sup>C also supports a General Call to all Slaves by using the slave address value \token{0}.
A General Call is recognized by Slaves have a slave address value \ref ARM_I2C_ADDRESS_GC registered with the
function \ref ARM_I2C_Control.
<b>Block Diagram</b>
The I2C driver allows you to connect low-speed peripherals to a motherboard, embedded system, cellphone, or other electronic device.
\image html I2C_BlockDiagram.png "Master/Slave connected via I2C interface"
<b>I<sup>2</sup>C API</b>
The following header files define the Application Programming Interface (API) for the I<sup>2</sup>C interface:
- \b %Driver_I2C.h : Driver API for I2C Bus Peripheral
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_I2C : access struct for I2C driver functions
\anchor example <b>Example Code</b>
The following example code shows the usage of the I<sup>2</sup>C interface in Master mode.
\include I2C_Demo.c
The following example code shows the usage of the I<sup>2</sup>C interface in Slave mode.
\include I2C_SlaveDemo.c
@{
*/
/**
\struct ARM_DRIVER_I2C
\details
The functions of the I2C interface are accessed by function pointers exposed by this structure. Refer to \ref DriverFunctions for
overview information.
Each instance of an I2C provides such an access structure. The instance is indicated by
a postfix in the symbol name of the access structure, for example:
- \b Driver_I2C0 is the name of the access struct of the first instance (no. 0).
- \b Driver_I2C1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>%Driver_I2C<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*******************************************************************************************************************/
/**
\struct ARM_I2C_CAPABILITIES
\details
An I2C driver can be implemented with different capabilities.
The data fields of this struct encode the capabilities implemented by this driver.
The element \em address_10_bit indicates that the driver is able to handle 10-bit addressing natively.
User can still emulate the 10-bit addressing in software if the driver does not support it.
<b>Returned by:</b>
- \ref ARM_I2C_GetCapabilities
*******************************************************************************************************************/
/**
\struct ARM_I2C_STATUS
\details
Structure with information about the status of the I2C.
The flag \em busy indicates that the driver is busy executing Master/Slave Transmit/Receive operation.
It is set:
- when Master operation starts: after calling \ref ARM_I2C_MasterTransmit or \ref ARM_I2C_MasterReceive
- when Slave operation starts: after calling \ref ARM_I2C_SlaveTransmit or \ref ARM_I2C_SlaveReceive and after being addressed by a Master as the Slave
It is cleared when Master/Slave operation has finished.
The flag \em mode indicates the current mode which is Master when Master Transmit/Receive is active or Slave otherwise.
The flag \em direction indicates either Transmitter or Receiver mode. It is updated during Master/Slave operation when the Slave is addressed by a Master.
The flag \em general_call indicates a General call (address \token{0}) when in Slave mode.
The flag \em arbitration_lost indicates that the Master has lost arbitration. The current Master operation is aborted.
The flag \em bus_error indicates that a bus error has been detected. The current Master/Slave operation is aborted.
<b>Returned by:</b>
- \ref ARM_I2C_GetStatus
*******************************************************************************************************************/
/**
\typedef ARM_I2C_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_I2C_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_I2C_Initialize
*******************************************************************************************************************/
/**
\defgroup I2C_events I2C Events
\ingroup i2c_interface_gr
\brief The I2C driver generates call back events that are notified via the function \ref ARM_I2C_SignalEvent.
\details
This section provides the event values for the \ref ARM_I2C_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_I2C_EVENT_TRANSFER_DONE
\def ARM_I2C_EVENT_TRANSFER_INCOMPLETE
\def ARM_I2C_EVENT_SLAVE_TRANSMIT
\def ARM_I2C_EVENT_SLAVE_RECEIVE
\def ARM_I2C_EVENT_ADDRESS_NACK
\def ARM_I2C_EVENT_GENERAL_CALL
\def ARM_I2C_EVENT_ARBITRATION_LOST
\def ARM_I2C_EVENT_BUS_ERROR
\def ARM_I2C_EVENT_BUS_CLEAR
@}
*/
//
// Functions
//
ARM_DRIVER_VERSION ARM_I2C_GetVersion (void) {
return { 0, 0 };
};
/**
\fn ARM_DRIVER_VERSION ARM_I2C_GetVersion (void)
\details
The function \b ARM_I2C_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_I2C Driver_I2C0;
ARM_DRIVER_I2C *drv_info;
void setup_i2c (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_I2C0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*******************************************************************************************************************/
ARM_I2C_CAPABILITIES ARM_I2C_GetCapabilities (void) {
return { 0 };
};
/**
\fn ARM_I2C_CAPABILITIES ARM_I2C_GetCapabilities (void)
\details
The function \b ARM_I2C_GetCapabilities returns information about capabilities of this driver implementation.
The data fields of the struct \ref ARM_I2C_CAPABILITIES encodes the driver capabilities.
Example:
\code
extern ARM_DRIVER_I2C Driver_I2C0;
ARM_DRIVER_I2C *drv_info;
void read_capabilities (void) {
ARM_I2C_CAPABILITIES drv_capabilities;
drv_info = &Driver_I2C0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*******************************************************************************************************************/
int32_t ARM_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event)
\details
The function \b ARM_I2C_Initialize initializes the I2C interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes and the I/O resources for the I2C interface.
- Registers the \ref ARM_I2C_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_I2C_SignalEvent callback function.
Use a NULL pointer when no callback events are required.
Can be called multiple times. If the peripheral is already initialized the function performs no operation and
returns with \ref ARM_DRIVER_OK. Refer to \ref CallSequence for more information.
\sa ARM_I2C_PowerControl
\sa ARM_I2C_Uninitialize
\b Example:
- refer to \ref example "Example Code"
*******************************************************************************************************************/
int32_t ARM_I2C_Uninitialize (void) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_Uninitialize (void)
\details
The function \b ARM_I2C_Uninitialize releases the I/O resources of I2C interface.
It is called when the middleware component stops operation and releases the I/O resources used by the I2C interface.
Refer to \ref CallSequence for more information.
\sa ARM_I2C_Initialize
\sa ARM_I2C_PowerControl
*******************************************************************************************************************/
int32_t ARM_I2C_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_I2C_PowerControl operates the power modes of the I2C interface.
The parameter \em state can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode,
then the function performs no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
\sa ARM_I2C_Initialize
\sa ARM_I2C_Uninitialize
*******************************************************************************************************************/
int32_t ARM_I2C_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending)
\details
This function \b ARM_I2C_MasterTransmit transmits data as Master to the selected Slave.
The operation consists of:
- Master generates START condition
- Master addresses the Slave as Master Transmitter
- Master transmits data to the addressed Slave
- Master generates STOP condition (if \em xfer_pending is "false")
The parameter \em addr is the address of the slave to transmit the data to. The value can be ORed with \ref ARM_I2C_ADDRESS_10BIT to
identify a 10-bit address value. \n
The parameter \em data and \em num specify the address of a data buffer and the number of bytes to transmit. \n
Set the parameter \em xfer_pending to 'true' if another transfer operation follows. With \em xfer_pending set to 'false' a STOP condition is generated.
The function is non-blocking and returns as soon as the driver has started the operation.
During the operation it is not allowed to call any Master function again. Also the data buffer must stay allocated and the contents of data must not be modified.
When transmit operation has finished the \ref ARM_I2C_EVENT_TRANSFER_DONE event is generated.
When not all the data is transferred then the \ref ARM_I2C_EVENT_TRANSFER_INCOMPLETE flag is set at the same time.
Number of data bytes transmitted and acknowledged is returned by the function \ref ARM_I2C_GetDataCount during and after the operation has finished.
The operation is aborted in the following cases (\ref ARM_I2C_EVENT_TRANSFER_DONE event is generated together with):
- selected slave has not acknowledged the address: \ref ARM_I2C_EVENT_ADDRESS_NACK event
- arbitration has been lost: \ref ARM_I2C_EVENT_ARBITRATION_LOST event
- bus error has been detected: \ref ARM_I2C_EVENT_BUS_ERROR event
Status can be monitored by calling the \ref ARM_I2C_GetStatus and checking the flags.
Transmit operation can be aborted also by calling \ref ARM_I2C_Control with the parameter \em control \ref ARM_I2C_ABORT_TRANSFER.
*******************************************************************************************************************/
int32_t ARM_I2C_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending)
\details
This function \b ARM_I2C_MasterReceive is used to receive data as Master from the selected Slave.
The operation consists of:
- Master generates START condition
- Master addresses the Slave as Master Receiver
- Master receives data from the addressed Slave
- Master generates STOP condition (if \em xfer_pending is "false")
The parameter \em addr is the address of the slave to receive the data from. The value can be ORed with \ref ARM_I2C_ADDRESS_10BIT to
identify a 10-bit address value. \n
The parameter \em data and \em num specify the address of a data buffer and the number of bytes to receive. \n
Set the parameter \em xfer_pending to 'true' if another transfer operation follows. With \em xfer_pending set to 'false' a STOP condition is generated.
The function is non-blocking and returns as soon as the driver has started the operation.
During the operation it is not allowed to call any Master function again. Also the data buffer must stay allocated.
When receive operation has finished the \ref ARM_I2C_EVENT_TRANSFER_DONE event is generated.
When not all the data is transferred then the \ref ARM_I2C_EVENT_TRANSFER_INCOMPLETE flag is set at the same time.
Number of data bytes received is returned by the function \ref ARM_I2C_GetDataCount during and after the operation has finished.
The operation is aborted in the following cases (\ref ARM_I2C_EVENT_TRANSFER_DONE event is generated together with):
- selected slave has not acknowledged the address: \ref ARM_I2C_EVENT_ADDRESS_NACK event
- arbitration has been lost: \ref ARM_I2C_EVENT_ARBITRATION_LOST event
- bus error has been detected: \ref ARM_I2C_EVENT_BUS_ERROR event
Status can be monitored by calling the \ref ARM_I2C_GetStatus and checking the flags.
Receive operation can be aborted also by calling \ref ARM_I2C_Control with the parameter \em control = \ref ARM_I2C_ABORT_TRANSFER.
*******************************************************************************************************************/
int32_t ARM_I2C_SlaveTransmit (const uint8_t *data, uint32_t num) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_SlaveTransmit (const uint8_t *data, uint32_t num)
\details
This function \b ARM_I2C_SlaveTransmit is used to transmit data as Slave to the Master.
The parameter \em data is a pointer to the data to transmit. \n
The parameter \em num specifies the number of bytes to transmit.
The function is non-blocking and returns as soon as the driver has registered the operation.
The actual operation will start after being addressed by the master as a Slave Transmitter. If the operation has not been registered at that point the \ref ARM_I2C_EVENT_SLAVE_TRANSMIT event is generated.
The same event is also generated if the operation has finished (specified number of bytes transmitted) but more data is requested by the master.
It is not allowed to call this function again if the operation has started until it finishes. Also the data buffer must stay allocated and the contents of data must not be modified.
When transmit operation has finished the \ref ARM_I2C_EVENT_TRANSFER_DONE event is generated.
When not all the data is transferred then the \ref ARM_I2C_EVENT_TRANSFER_INCOMPLETE flag is set at the same time.
Number of data bytes transmitted is returned by the function \ref ARM_I2C_GetDataCount during and after the operation has finished.
In case that a General call has been detected the \ref ARM_I2C_EVENT_GENERAL_CALL flag is indicated together with the \ref ARM_I2C_EVENT_TRANSFER_DONE event (also with \ref ARM_I2C_EVENT_SLAVE_TRANSMIT event).
In case that bus error has been detected then the operation is aborted and the \ref ARM_I2C_EVENT_BUS_ERROR event is generated together with \ref ARM_I2C_EVENT_TRANSFER_DONE.
Slave will only respond to its own address (or General call if enabled) that is specified by calling \ref ARM_I2C_Control with \ref ARM_I2C_OWN_ADDRESS as control parameter.
Using address \token{0} disables the slave.
Status can be monitored by calling the \ref ARM_I2C_GetStatus and checking the flags.
Transmit operation can be canceled or aborted by calling \ref ARM_I2C_Control with the parameter \em control = \ref ARM_I2C_ABORT_TRANSFER.
*******************************************************************************************************************/
int32_t ARM_I2C_SlaveReceive (uint8_t *data, uint32_t num) {
return ARM_DRIVER_OK;
};
/**
\fn int32_t ARM_I2C_SlaveReceive (uint8_t *data, uint32_t num)
\details
This function \b ARM_I2C_SlaveReceive receives data as Slave from the Master.
The parameter \em data is a pointer to the data to receive. \n
The parameter \em num specifies the number of bytes to receive.
The function is non-blocking and returns as soon as the driver has registered the operation.
The actual operation will start after being addressed by the master as a Slave Receiver. If the operation has not been registered at that point the \ref ARM_I2C_EVENT_SLAVE_RECEIVE event is generated.
It is not allowed to call this function again if the operation has started until it finishes. Also the data buffer must stay allocated.
When receive operation has finished the \ref ARM_I2C_EVENT_TRANSFER_DONE event is generated.
When not all the data is transferred then the \ref ARM_I2C_EVENT_TRANSFER_INCOMPLETE flag is set at the same time.
Number of data bytes received and acknowledged is returned by the function \ref ARM_I2C_GetDataCount during and after the operation has finished.
In case that a General call has been detected the \ref ARM_I2C_EVENT_GENERAL_CALL flag is indicated together with the \ref ARM_I2C_EVENT_TRANSFER_DONE event (also with \ref ARM_I2C_EVENT_SLAVE_RECEIVE event).
In case that bus error has been detected then the operation is aborted and the \ref ARM_I2C_EVENT_BUS_ERROR event is generated together with \ref ARM_I2C_EVENT_TRANSFER_DONE.
Slave will only respond to its own address (or General call if enabled) that is specified by calling \ref ARM_I2C_Control with \ref ARM_I2C_OWN_ADDRESS as control parameter.
Using address \token{0} disables the slave.
Status can be monitored by calling the \ref ARM_I2C_GetStatus and checking the flags.
Receive operation can be canceled or aborted by calling \ref ARM_I2C_Control with the parameter \em control = \ref ARM_I2C_ABORT_TRANSFER.
*******************************************************************************************************************/
int32_t ARM_I2C_GetDataCount (void) {
return 0;
}
/**
\fn int32_t ARM_I2C_GetDataCount (void)
\details
The function \b ARM_I2C_GetDataCount returns the number of currently transferred data bytes during and after:
- \ref ARM_I2C_MasterTransmit : number of data bytes transmitted and acknowledged
- \ref ARM_I2C_MasterReceive : number of data bytes received
- \ref ARM_I2C_SlaveTransmit : number of data bytes transmitted
- \ref ARM_I2C_SlaveReceive : number of data bytes received and acknowledged
When the Slave is not yet addressed by the Master then \token{-1} is returned.
*****************************************************************************************************************/
int32_t ARM_I2C_Control (uint32_t control, uint32_t arg) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_I2C_Control (uint32_t control, uint32_t arg)
\details
The function \b ARM_I2C_Control operates the I2C interface and executes various operations.
The parameter \em control specifies various operations as listed in the table below. \n
The parameter \em arg provides, depending on the operation, additional information. \n
Parameter \em control | Operation
:--------------------------------|:--------------------------------------------
\ref ARM_I2C_OWN_ADDRESS | Set Own Slave Address; \em arg = slave address
\ref ARM_I2C_BUS_SPEED | Set Bus Speed; \em arg = bus speed
\ref ARM_I2C_BUS_CLEAR | Clear the bus by sending nine clock pulses
\ref ARM_I2C_ABORT_TRANSFER | Aborts the data transfer between Master and Slave for Transmit or Receive
<b>Set Own Slave Address</b>
After initialization, the I2C Device has no slave address assigned and does not accept any requests from
an I2C Master.
The \em control operation \ref ARM_I2C_OWN_ADDRESS sets the slave address with the parameter \em arg.
The slave address can be ORed with \ref ARM_I2C_ADDRESS_10BIT to indicate a 10-bit address.
The slave address can be ORed with \ref ARM_I2C_ADDRESS_GC to indicate that the slave accepts a General Call.
If the slave address value is only \ref ARM_I2C_ADDRESS_GC, then the slave only accepts a General Call.
The slave address value \token{0} disables Slave mode and clears any assigned slave address.
**Examples:**
Set the Slave address value \token{0x45} as 7-bit address.
\code
I2Cdrv->Control (ARM_I2C_OWN_ADDRESS, 0x45);
\endcode
Set the Slave address value \token{0x135} as 10-bit address and accept a General Call.
\code
I2Cdrv->Control (ARM_I2C_OWN_ADDRESS, 0x135 | ARM_I2C_ADDRESS_10BIT | ARM_I2C_ADDRESS_GC);
\endcode
<b>Bus Speed</b>
The \em control operation \ref ARM_I2C_BUS_SPEED sets the bus speed using the parameter \em arg.
Parameter \em arg | Bus Speed
:--------------------------------|:--------------------------------------------
\ref ARM_I2C_BUS_SPEED_STANDARD | Standard Speed to (\token{100 kHz})
\ref ARM_I2C_BUS_SPEED_FAST | Fast Speed (\token{400kHz})
\ref ARM_I2C_BUS_SPEED_FAST_PLUS | Fast + Speed (\token{1MHz})
\ref ARM_I2C_BUS_SPEED_HIGH | High Speed (\token{3.4MHz})
**Example:**
\code
I2Cdrv->Control (ARM_I2C_BUS_SPEED, I2C_BUS_SPEED_FAST);
\endcode
*****************************************************************************************************************/
ARM_I2C_STATUS ARM_I2C_GetStatus (void) {
return { 0 };
}
/**
\fn ARM_I2C_STATUS ARM_I2C_GetStatus (void)
\details
The function \b ARM_I2C_GetStatus returns the current I2C interface status.
Refer to \ref ARM_I2C_STATUS for details.
*****************************************************************************************************************/
void ARM_I2C_SignalEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_I2C_SignalEvent (uint32_t event)
\details
The function \b ARM_I2C_SignalEvent is a callback function registered by the function \ref ARM_I2C_Initialize..
It is called by the I2C driver to notify the application about \ref I2C_events occured during operation.
The parameter \a event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
The following events can be generated:
Parameter \em event | Bit | Description
:---------------------------------------- |:---------:|:----------------------------------------------------------
\ref ARM_I2C_EVENT_TRANSFER_DONE | 1UL&nbsp;<<&nbsp;0 | Occurs after Master/Slave Transmit/Receive operation has finished.
\ref ARM_I2C_EVENT_TRANSFER_INCOMPLETE | 1UL << 1 | Occurs together with \ref ARM_I2C_EVENT_TRANSFER_DONE when less data is transferred then requested.
\ref ARM_I2C_EVENT_SLAVE_TRANSMIT | 1UL << 2 | Occurs when addressed as Slave Transmitter and \ref ARM_I2C_SlaveTransmit has not been started.
\ref ARM_I2C_EVENT_SLAVE_RECEIVE | 1UL << 3 | Occurs when addressed as Slave Receiver and \ref ARM_I2C_SlaveReceive has not been started.
\ref ARM_I2C_EVENT_ADDRESS_NACK | 1UL << 4 | Occurs in master mode when address is not acknowledged from slave.
\ref ARM_I2C_EVENT_GENERAL_CALL | 1UL << 5 | Indicates General Call in slave mode together with \ref ARM_I2C_EVENT_TRANSFER_DONE, \ref ARM_I2C_EVENT_SLAVE_TRANSMIT and \ref ARM_I2C_EVENT_SLAVE_RECEIVE.
\ref ARM_I2C_EVENT_ARBITRATION_LOST | 1UL << 6 | Occurs in master mode when arbitration is lost.
\ref ARM_I2C_EVENT_BUS_ERROR | 1UL << 7 | Occurs when bus error is detected.
\ref ARM_I2C_EVENT_BUS_CLEAR | 1UL << 8 | Occurs after \ref ARM_I2C_BUS_CLEAR Control operation has finished.
**************************************************************************************************************************/
/**
\defgroup i2c_control_gr I2C Control Codes
\ingroup i2c_interface_gr
\brief Many parameters of the I2C driver are configured using the \ref ARM_I2C_Control function.
@{
\details
The various I2C control codes define:
- \ref i2c_control_codes specify operation parameters and various controls
- \ref i2c_bus_speed_ctrls specify the I2C bus speed
Refer to the \ref ARM_I2C_Control function for further details.
*/
/**
\defgroup i2c_control_codes I2C Control Codes
\ingroup i2c_control_gr
\brief Specify operation parameters and various controls.
\details
@{
\def ARM_I2C_OWN_ADDRESS
\sa ARM_I2C_Control
\def ARM_I2C_BUS_SPEED
Speed is specified using the following values: \ref i2c_bus_speed_ctrls
\sa ARM_I2C_Control
\def ARM_I2C_BUS_CLEAR
\sa ARM_I2C_Control
\def ARM_I2C_ABORT_TRANSFER
\sa ARM_I2C_Control
@}
*/
/**
\defgroup i2c_bus_speed_ctrls I2C Bus Speed
\ingroup i2c_control_gr
\brief Specify the I2C bus speed.
\details
@{
\def ARM_I2C_BUS_SPEED_STANDARD
\sa ARM_I2C_Control
\def ARM_I2C_BUS_SPEED_FAST
\sa ARM_I2C_Control
\def ARM_I2C_BUS_SPEED_FAST_PLUS
\sa ARM_I2C_Control
\def ARM_I2C_BUS_SPEED_HIGH
\sa ARM_I2C_Control
@}
*/
/**
@}
*/
/**
\defgroup i2c_address_flags I2C Address Flags
\ingroup i2c_interface_gr
\brief Specify address flags
\details
Specifies the address type for the functions \ref ARM_I2C_MasterReceive, \ref ARM_I2C_MasterTransmit and \ref ARM_I2C_OWN_ADDRESS.
@{
\def ARM_I2C_ADDRESS_10BIT
\sa ARM_I2C_OWN_ADDRESS
\sa ARM_I2C_MasterTransmit
\sa ARM_I2C_MasterReceive
\def ARM_I2C_ADDRESS_GC
\sa ARM_I2C_OWN_ADDRESS
@}
*/
/**
@}
*/
// End I2C Interface

View File

@ -0,0 +1,799 @@
/**
\defgroup mci_interface_gr MCI Interface
\brief Driver API for Memory Card Interface using SD/MMC interface (%Driver_MCI.h)
\details
The <b>Memory Card Interface</b> (MCI) implements the hardware abstraction layer for Secure Digital (SD) and Multi Media Card (MMC)
memory that is typically used as file storage. For embedded systems, SD/MMC devices are available as memory cards in several
forms (SD, miniSD, microSD, MMC, MMCmicro) or as non-removable device
es that are directly soldered to the PCB (eMMC).
\b References:
- Wikipedia offers more information about the <a href="http://en.wikipedia.org/wiki/SD_card" target="_blank"><b>Secure Digital</b> memory</a>.
- Wikipedia offers more information about the <a href="http://en.wikipedia.org/wiki/MultiMediaCard" target="_blank"><b>MultiMediaCard</b></a>.
- The SD Association provides detailed documentation under <a href="http://www.sdcard.org">www.sdcard.org</a>.
- The MultiMediaCard Association (merged with JEDEC) provides detailed documentation under <a href="http://www.jedec.org">www.jedec.org</a>.
<b>Block Diagram</b>
The MCI driver allows you to exchange data of the SD/MMC memory via SD/MMC interface.
The following modes are supported by SD/MMC memory cards:
- SPI bus mode: Serial Peripheral Interface Bus supported by most microcontrollers.
- 1-bit SD/MMC Bus mode: proprietary data transfer protocol supported by SD/MMC interfaces.
- 4-bit SD/MMC Bus mode: high-speed version of the SD/MMC interface using 4 data I/O pins.
- 8-bit SD/MMC Bus mode: high-speed version of the SD/MMC interface using 8 data I/O pins.
\image html SPI_BusMode.png "SD memory connected via SPI interface"
<p>&nbsp;</p>
\image html SD_1BitBusMode.png "SD memory connected via 1-bit SD Bus Mode"
<p>&nbsp;</p>
\image html SD_4BitBusMode.png "SD memory connected via 4-bit SD Bus Mode"
<b>MCI API</b>
The following header files define the Application Programming Interface (API) for the MCI interface:
- \b %Driver_MCI.h : Driver API for Memory Card Interface using SD/MMC interface
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
\note
For parameters, the value marked with (default) is the setting after the driver initialization.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_MCI : access struct for MCI driver functions
<b>Example Code</b>
The following example code shows the usage of the MCI interface.
\include MCI_Demo.c
@{
*/
/************* Structures ******************************************************************************************************/
/**
\struct ARM_DRIVER_MCI
\details
The functions of the MCI are accessed by function pointers exposed by this structure. Refer to \ref DriverFunctions for overview information.
Each instance of an MCI provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_MCI0 is the name of the access struct of the first instance (no. 0).
- \b Driver_MCI1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_MCI<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*******************************************************************************************************************/
/**
\struct ARM_MCI_CAPABILITIES
\details
A MCI driver can be implemented with different capabilities.
The data fields of this struct encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_MCI_GetCapabilities
*******************************************************************************************************************/
/**
\defgroup mci_event_gr MCI Events
\brief The MCI driver generates call back events that are notified via the function \ref ARM_MCI_SignalEvent.
\details
This section provides the event values for the \ref ARM_MCI_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_MCI_EVENT_CARD_INSERTED
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_CARD_REMOVED
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_COMMAND_COMPLETE
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_COMMAND_TIMEOUT
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_COMMAND_ERROR
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_TRANSFER_COMPLETE
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_TRANSFER_TIMEOUT
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_TRANSFER_ERROR
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_SDIO_INTERRUPT
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_CCS
\sa \ref ARM_MCI_SignalEvent
\def ARM_MCI_EVENT_CCS_TIMEOUT
\sa \ref ARM_MCI_SignalEvent
@}
*******************************************************************************************************************/
//open mci_contorl_gr
/**
@{
*/
/**
\defgroup mci_control_gr MCI Control Codes
\ingroup mci_interface_gr
\brief Configure and control the MCI using the \ref ARM_MCI_Control.
\details
@{
Many parameters of the MCI driver are configured using the \ref ARM_MCI_Control function.
The various MCI control codes define:
- \ref mci_mode_ctrls configures and controls the MCI interface
- \ref mci_bus_speed_ctrls specifies the bus speed mode
- \ref mci_bus_data_width_ctrls specifies the data bus width
- \ref mci_cmd_line_ctrls specifies the CMD line mode
- \ref mci_driver_strength_ctrls specifies the driver strength
Refer to the function \ref ARM_MCI_Control for further details.
@}
*******************************************************************************************************************/
/**
\defgroup mci_mode_ctrls MCI Controls
\ingroup mci_control_gr
\brief Configure and control the MCI interface.
\details
The following codes are used as values for the parameter \em control of the function \ref ARM_MCI_Control to setup the MCI interface.
@{
\def ARM_MCI_BUS_SPEED
\def ARM_MCI_BUS_SPEED_MODE
\def ARM_MCI_BUS_CMD_MODE
\def ARM_MCI_BUS_DATA_WIDTH
\def ARM_MCI_DRIVER_STRENGTH
\def ARM_MCI_CONTROL_RESET
\def ARM_MCI_CONTROL_CLOCK_IDLE
\def ARM_MCI_UHS_TUNING_OPERATION
\def ARM_MCI_UHS_TUNING_RESULT
\def ARM_MCI_DATA_TIMEOUT
\def ARM_MCI_CSS_TIMEOUT
\def ARM_MCI_MONITOR_SDIO_INTERRUPT
\def ARM_MCI_CONTROL_READ_WAIT
\def ARM_MCI_SUSPEND_TRANSFER
\def ARM_MCI_RESUME_TRANSFER
@}
*******************************************************************************************************************/
/**
\defgroup mci_bus_speed_ctrls MCI Bus Speed Mode
\ingroup mci_control_gr
\brief Specify the bus speed mode.
\details
@{
The function \ref ARM_MCI_Control with \em control = \ref ARM_MCI_BUS_SPEED configures the bus speed of the MCI to the
requested bits/s specified with \em arg.
The function \ref ARM_MCI_Control with \em control = \ref ARM_MCI_BUS_SPEED_MODE configures the bus speed mode of the MCI
as specified with \em arg listed bellow.
The function \ref ARM_MCI_GetCapabilities lists the supported bus speed modes. Initially, all SD cards use a 3.3 volt electrical interface.
Some SD cards can switch to 1.8 volt operation. For example, the use of ultra-high-speed (UHS)
SD cards requires 1.8 volt operation and a 4-bit bus data width. The data field \em uhs_signaling of the structure ARM_MCI_CAPABILITIES encodes
whether the driver supports 1.8 volt UHS signaling.
\sa
- \ref mci_driver_strength_ctrls
The following codes are defined:
\def ARM_MCI_BUS_DEFAULT_SPEED
\def ARM_MCI_BUS_HIGH_SPEED
\def ARM_MCI_BUS_UHS_SDR12
\def ARM_MCI_BUS_UHS_SDR25
\def ARM_MCI_BUS_UHS_SDR50
\def ARM_MCI_BUS_UHS_SDR104
\def ARM_MCI_BUS_UHS_DDR50
@}
*******************************************************************************************************************/
/**
\defgroup mci_bus_data_width_ctrls MCI Bus Data Width
\ingroup mci_control_gr
\brief Specify the data bus width.
\details
@{
The function \ref ARM_MCI_Control with \em control = \ref ARM_MCI_BUS_DATA_WIDTH specifies with \em arg the number of data I/O pins on the SD/MMC interface.
For high-speed memory cards, a 4-bit bus data width should be used (or 8-bit for eMMC). The data fields \em data_width_4 and \em data_width_8
of the structure ARM_MCI_CAPABILITIES encode whether the driver supports a specific bus data with.
The following codes are defined:
\def ARM_MCI_BUS_DATA_WIDTH_1
\def ARM_MCI_BUS_DATA_WIDTH_4
\def ARM_MCI_BUS_DATA_WIDTH_8
\def ARM_MCI_BUS_DATA_WIDTH_4_DDR
\def ARM_MCI_BUS_DATA_WIDTH_8_DDR
@}
*******************************************************************************************************************/
/**
\defgroup mci_cmd_line_ctrls MCI CMD Line Mode
\ingroup mci_control_gr
\brief Specify the CMD line mode (Push-Pull or Open Drain).
\details
@{
Set the CMD line type with the function \ref ARM_MCI_Control.
The CMD line mode is push-pull (default) or open drain (needed for older MMC).
\def ARM_MCI_BUS_CMD_PUSH_PULL
\def ARM_MCI_BUS_CMD_OPEN_DRAIN
@}
*******************************************************************************************************************/
/**
\defgroup mci_driver_strength_ctrls MCI Driver Strength
\ingroup mci_control_gr
\brief Specify the driver strength.
\details
@{
The function \ref ARM_MCI_Control with \em control = \ref ARM_MCI_DRIVER_STRENGTH specifies with \em arg the driver type of the SD interface.
\sa
- \ref mci_bus_speed_ctrls
The following codes are defined:
\def ARM_MCI_DRIVER_TYPE_A
\def ARM_MCI_DRIVER_TYPE_B
\def ARM_MCI_DRIVER_TYPE_C
\def ARM_MCI_DRIVER_TYPE_D
@}
*******************************************************************************************************************/
/**
@}
*/ // close group mci_control_gr
/**
\defgroup mci_send_command_flags_ctrls MCI Send Command Flags
\ingroup mci_interface_gr
\brief Specify various options for sending commands to the card and the expected response.
\details
\b ARM_MCI_xxx flags are sent with the function \ref ARM_MCI_SendCommand as the parameter \em flag.
It controls the behavior of the command sent to the card and provides information about the expected response from the card.
The following codes are defined:
@{
\def ARM_MCI_RESPONSE_NONE
\def ARM_MCI_RESPONSE_SHORT
\def ARM_MCI_RESPONSE_SHORT_BUSY
\def ARM_MCI_RESPONSE_LONG
\def ARM_MCI_RESPONSE_INDEX
\def ARM_MCI_RESPONSE_CRC
\def ARM_MCI_WAIT_BUSY
\def ARM_MCI_TRANSFER_DATA
\def ARM_MCI_CARD_INITIALIZE
\def ARM_MCI_INTERRUPT_COMMAND
\def ARM_MCI_INTERRUPT_RESPONSE
\def ARM_MCI_BOOT_OPERATION
\def ARM_MCI_BOOT_ALTERNATIVE
\def ARM_MCI_BOOT_ACK
\def ARM_MCI_CCSD
\def ARM_MCI_CCS
@}
*******************************************************************************************************************/
/**
\defgroup mci_transfer_ctrls MCI Transfer Controls
\ingroup mci_interface_gr
\brief Specify data transfer mode.
\details
Data transfer codes specifies the transfer direction and type and are used with the function \ref ARM_MCI_SetupTransfer as the parameter \em mode.
The following codes are defined:
@{
\def ARM_MCI_TRANSFER_READ
\def ARM_MCI_TRANSFER_WRITE
\def ARM_MCI_TRANSFER_BLOCK
\def ARM_MCI_TRANSFER_STREAM
@}
*******************************************************************************************************************/
/**
\defgroup mci_card_power_ctrls MCI Card Power Controls
\ingroup mci_interface_gr
\brief Specify Memory Card Power supply voltage
\details
Specifies the power supply volatge for a memory card. Used with the function \ref ARM_MCI_CardPower as the parameter \em voltage.
The following codes are defined:
@{
\def ARM_MCI_POWER_VDD_OFF
\def ARM_MCI_POWER_VDD_3V3
\def ARM_MCI_POWER_VDD_1V8
\def ARM_MCI_POWER_VCCQ_OFF
\def ARM_MCI_POWER_VCCQ_3V3
\def ARM_MCI_POWER_VCCQ_1V8
\def ARM_MCI_POWER_VCCQ_1V2
@}
*******************************************************************************************************************/
/**
\struct ARM_MCI_STATUS
\details
Structure with information about the status of the MCI.
<b>Returned by:</b>
- \ref ARM_MCI_GetStatus
*******************************************************************************************************************/
/**
\typedef ARM_MCI_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_MCI_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_MCI_Initialize
*******************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_MCI_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_MCI_GetVersion (void)
\details
The function \b ARM_MCI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_MCI Driver_MCI0;
ARM_DRIVER_MCI *drv_info;
void setup_mci (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_MCI0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*******************************************************************************************************************/
ARM_MCI_CAPABILITIES ARM_MCI_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_MCI_CAPABILITIES ARM_MCI_GetCapabilities (void)
\details
The function \b ARM_MCI_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_MCI_CAPABILITIES encode various capabilities, for example
supported bus modes ...
Example:
\code
extern ARM_DRIVER_MCI Driver_MCI0;
ARM_DRIVER_MCI *drv_info;
void read_capabilities (void) {
ARM_MCI_CAPABILITIES drv_capabilities;
drv_info = &Driver_MCI0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*******************************************************************************************************************/
int32_t ARM_MCI_Initialize (ARM_MCI_SignalEvent_t cb_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_Initialize (ARM_MCI_SignalEvent_t cb_event)
\details
The function \b ARM_MCI_Initialize initializes the MCI interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the MCI interface.
- Registers the \ref ARM_MCI_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_MCI_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
\b Example:
- see \ref mci_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_MCI_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_Uninitialize (void)
\details
The function \b ARM_MCI_Uninitialize de-initializes the resources of I2C interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*******************************************************************************************************************/
int32_t ARM_MCI_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_MCI_PowerControl operates the power modes of the MCI interface.
The parameter \em state can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA. Can be called multiple times.
If the peripheral is already in this mode, then the function performs no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*******************************************************************************************************************/
int32_t ARM_MCI_CardPower (uint32_t voltage) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_CardPower (uint32_t voltage)
\details
The function \b ARM_MCI_CardPower operates the memory card power supply voltage.
The parameter \em voltage sets the voltage. Not every voltage might be supported by the driver implementation.
The structure \ref ARM_MCI_CAPABILITIES encodes the supported voltage. Retrieve the information with the function \ref ARM_MCI_GetCapabilities and
verify the data fields.
The following values:
Parameter \em voltage | Description | supported when ARM_MCI_CAPABILITIES
:-------------------------------------|:------------------------------|-----------------------------------------
\ref ARM_MCI_POWER_VDD_OFF | VDD (VCC) turned off | <i>always supported</i>
\ref ARM_MCI_POWER_VDD_3V3 | VDD (VCC) = \token{3.3V} | data field \em vdd = \token{1}
\ref ARM_MCI_POWER_VDD_1V8 | VDD (VCC) = \token{1.8V} | data field \em vdd_1v8 = \token{1}
\ref ARM_MCI_POWER_VCCQ_OFF | eMMC VCCQ turned off | <i>always supported</i>
\ref ARM_MCI_POWER_VCCQ_3V3 | eMMC VCCQ = \token{3.3V} | data field \em vccq = \token{1}
\ref ARM_MCI_POWER_VCCQ_1V8 | eMMC VCCQ = \token{1.8V} | data field \em vccq_1v8 = \token{1}
\ref ARM_MCI_POWER_VCCQ_1V2 | eMMC VCCQ = \token{1.2V} | data field \em vccq_1v2 = \token{1}
*******************************************************************************************************************/
int32_t ARM_MCI_ReadCD (void) {
return 0;
}
/**
\fn int32_t ARM_MCI_ReadCD (void)
\details
The function \b ARM_MCI_ReadCD reads the status of the Card Detect (CD) pin.
*******************************************************************************************************************/
int32_t ARM_MCI_ReadWP (void) {
return 0;
}
/**
\fn int32_t ARM_MCI_ReadWP (void)
\details
The function \b ARM_MCI_ReadWP reads the status of the Write Protect (WP) pin.
*******************************************************************************************************************/
int32_t ARM_MCI_SendCommand (uint32_t cmd, uint32_t arg, uint32_t flags, uint32_t *response) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_SendCommand (uint32_t cmd, uint32_t arg, uint32_t flags, uint32_t *response)
\details
The function \b ARM_MCI_SendCommand
- sends commands to the memory card
- retrieve the response from the card
- optionally, start the data transfer.
The parameter \em cmd is the command sent to the card. \n
The parameter \em arg contains arguments for the command \em cmd. \n
The parameter \em flags controls the behavior of the operation and takes predefined values listed in the table below. \n
The parameter \em response is a pointer to receive data.
The parameter \em flags can have the following values:
Parameter \em flags | Description
:-------------------------------------|:------------
\ref ARM_MCI_RESPONSE_NONE | No response expected (default)
\ref ARM_MCI_RESPONSE_SHORT | Short response (\token{48}-bit) expected
\ref ARM_MCI_RESPONSE_SHORT_BUSY | Short response with busy signal (\token{48}-bit) expected
\ref ARM_MCI_RESPONSE_LONG | Long response (\token{136}-bit) expected
\ref ARM_MCI_RESPONSE_INDEX | Check command index in response
\ref ARM_MCI_RESPONSE_CRC | Check CRC in response
\ref ARM_MCI_WAIT_BUSY | Wait until busy before sending the command
\ref ARM_MCI_TRANSFER_DATA | Activate Data transfer
\ref ARM_MCI_CARD_INITIALIZE | Execute Memory Card initialization sequence
\ref ARM_MCI_INTERRUPT_COMMAND | Send Interrupt command (CMD40 - MMC only)
\ref ARM_MCI_INTERRUPT_RESPONSE | Send Interrupt response (CMD40 - MMC only)
\ref ARM_MCI_BOOT_OPERATION | Execute Boot operation (MMC only)
\ref ARM_MCI_BOOT_ALTERNATIVE | Execute Alternative Boot operation (MMC only)
\ref ARM_MCI_BOOT_ACK | Expect Boot Acknowledge (MMC only)
\ref ARM_MCI_CCSD | Send Command Completion Signal Disable (CCSD) for CE-ATA device
\ref ARM_MCI_CCS | Expect Command Completion Signal (CCS) for CE-ATA device
Calling the function <b>ARM_MCI_SendCommand</b> only starts the operation.
The function is non-blocking and returns as soon as the driver has started the operation.
It is not allowed to call this function again until the operation is in progress.
After the command is sent the response is retrieved if specified with <b>ARM_MCI_RESPONSE_xxx</b> flags.
When the command completes successfully (requested response is received without errors) the \ref ARM_MCI_EVENT_COMMAND_COMPLETE event is generated.
In case that response is requested but not received the \ref ARM_MCI_EVENT_COMMAND_TIMEOUT event is generated instead.
In case of invalid response (or CRC error) the \ref ARM_MCI_EVENT_COMMAND_ERROR event is generated instead.
Progress of command operation can be monitored by calling the \ref ARM_MCI_GetStatus and checking the \em command_active flag.
After the command operation the data transfer operation is started if specified with <b>ARM_MCI_TRANSFER_DATA</b> flag.
The data transfer needs to be configured before that by calling the \ref ARM_MCI_SetupTransfer.
When the data transfer completes successfully the \ref ARM_MCI_EVENT_TRANSFER_COMPLETE event is generated.
In case that data transfer is not completed in-time (specified by \ref ARM_MCI_DATA_TIMEOUT) the \ref ARM_MCI_EVENT_TRANSFER_TIMEOUT event is generated instead.
In case of CRC errors the \ref ARM_MCI_EVENT_TRANSFER_ERROR event is generated instead.
Progress of data transfer operation can be monitored by calling the \ref ARM_MCI_GetStatus and checking the \em transfer_active flag.
<b>See also:</b>
- \ref ARM_MCI_SignalEvent
*******************************************************************************************************************/
int32_t ARM_MCI_SetupTransfer (uint8_t *data, uint32_t block_count, uint32_t block_size, uint32_t mode) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_SetupTransfer (uint8_t *data, uint32_t block_count, uint32_t block_size, uint32_t mode)
\details
The function \b ARM_MCI_SetupTransfer prepares the data transfer operation that is initiated
by calling the function \ref ARM_MCI_SendCommand with the parameter \em flags = \ref ARM_MCI_TRANSFER_DATA.
The parameter \em data is a pointer to the data to transfer. \n
The parameter \em block_count is the number of blocks to transfer. \n
The parameter \em block_size is the size of a block. \n
The parameter \em mode sets the transfer mode and can have the values liste in the table below:
Transfer Directions | Description
:-------------------------------------|:------------
\ref ARM_MCI_TRANSFER_READ | Read data from MCI
\ref ARM_MCI_TRANSFER_WRITE | Write data to MCI
\ref ARM_MCI_TRANSFER_BLOCK (default) | Block Data transfer
\ref ARM_MCI_TRANSFER_STREAM | Stream Data transfer (MMC only)
*******************************************************************************************************************/
int32_t ARM_MCI_AbortTransfer (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_AbortTransfer (void)
\details
The function \b ARM_MCI_AbortTransfer aborts the active data transfer operation initiated with \ref ARM_MCI_SendCommand.
*******************************************************************************************************************/
int32_t ARM_MCI_Control (uint32_t control, uint32_t arg) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_MCI_Control (uint32_t control, uint32_t arg)
\details
Th function \b ARM_MCI_Control controls the MCI interface and executes various operations.
The parameter \em control specifies the operation.
Values for \em control cannot be ORed, but must be called separately in the code. \n
The parameter \em arg provides, depending on the operation, additional information or sets values.
\note
For parameters, the values marked with (default) are the setting after the driver initialization.
The table lists values for the parameter \em control.
Parameter \em control | Operation
:-------------------------------------|:------------
\ref ARM_MCI_BUS_SPEED | Set the Bus Speed. The parameter \em arg specifies the speed in bits/s; The function returns the bus speed configured in bits/s.
\ref ARM_MCI_BUS_SPEED_MODE | Set the Bus Speed Mode. Predefined values for \em arg are listed in the table <b>Bus Speed Mode</b>.
\ref ARM_MCI_BUS_CMD_MODE | Set the CMD Line Mode. Predefined values for \em arg are listed in the table <b>Bus CMD Line Mode</b>.
\ref ARM_MCI_BUS_DATA_WIDTH | Set data bus width. Predefined values for \em arg are encoded in <b>Bus Data Width</b>.
\ref ARM_MCI_DRIVER_STRENGTH | Set driver strength. Predefined values for \em arg are listed in the table <b>Driver Type</b>
\ref ARM_MCI_CONTROL_RESET | Control optional RST_n Pin (eMMC). The parameter \em arg can have the values \token{[0:inactive(default); 1:active]}
\ref ARM_MCI_CONTROL_CLOCK_IDLE | Control clock generation on CLK Pin when idle. The parameter \em arg can have the values \token{[0:disabled; 1:enabled]}
\ref ARM_MCI_UHS_TUNING_OPERATION | Sampling clock Tuning operation (SD UHS-I). The parameter \em arg can have the values \token{[0:reset; 1:execute]}
\ref ARM_MCI_UHS_TUNING_RESULT | Sampling clock Tuning result (SD UHS-I). Returns \token{[0:done; 1:in progress; -1:error]}
\ref ARM_MCI_DATA_TIMEOUT | Set Data timeout; The parameter \em arg sets the timeout in bus cycles.
\ref ARM_MCI_CSS_TIMEOUT | Set Command Completion Signal (CCS) timeout. The parameter \em arg sets timeout in bus cycles.
\ref ARM_MCI_MONITOR_SDIO_INTERRUPT | Monitor SD I/O interrupt. The parameter \em arg can have the values \token{[0:disabled(default); 1:enabled]}. Monitoring is automatically disabled when an interrupt is recognized.
\ref ARM_MCI_CONTROL_READ_WAIT | Control Read/Wait states for SD I/O. The parameter \em arg can have the values \token{[0:disabled(default); 1:enabled]}.
\ref ARM_MCI_SUSPEND_TRANSFER | Suspend Data transfer (SD I/O). Returns the number of remaining bytes to transfer.
\ref ARM_MCI_RESUME_TRANSFER | Resume Data transfer (SD I/O).
<b>Bus Speed Mode</b>
The function \ref ARM_MCI_GetCapabilities lists the supported bus speed modes. Initially, all SD cards use a 3.3 volt electrical interface.
Some SD cards can switch to 1.8 volt operation. For example, the use of ultra-high-speed (UHS)
SD cards requires 1.8 volt operation and a 4-bit bus data width. The bit field ARM_MCI_CAPABILITIES.uhs_signaling encodes
whether the driver supports 1.8 volt UHS signaling.
The \em control operation \b ARM_MCI_BUS_SPEED_MODE sets the bus speed mode using the parameter \em arg.
Parameter \em arg | Bus Speed Mode
:-------------------------------------------------------------|:------------------------------------------
\ref ARM_MCI_BUS_DEFAULT_SPEED (default) | Set the bus speed for SD/MMC cards: Default Speed mode up to \token{[25;26]MHz}
\ref ARM_MCI_BUS_HIGH_SPEED | Set the bus speed for SD/MMC: High Speed mode up to \token{[50;52]MHz}
\ref ARM_MCI_BUS_UHS_SDR12 | Set the bus speed for SD: SDR12 (Single Data Rate) up to \token{25MHz, 12.5MB/s: UHS-I (Ultra High Speed) 1.8V signalling}
\ref ARM_MCI_BUS_UHS_SDR25 | Set the bus speed for SD: SDR25 (Single Data Rate) up to \token{50MHz, 25 MB/s: UHS-I (Ultra High Speed) 1.8V signalling}
\ref ARM_MCI_BUS_UHS_SDR50 | Set the bus speed for SD: SDR50 (Single Data Rate) up to \token{100MHz, 50 MB/s: UHS-I (Ultra High Speed) 1.8V signalling}
\ref ARM_MCI_BUS_UHS_SDR104 | Set the bus speed for SD: SDR104 (Single Data Rate) up to \token{208MHz, 104 MB/s: UHS-I (Ultra High Speed) 1.8V signalling}
\ref ARM_MCI_BUS_UHS_DDR50 | Set the bus speed for SD: DDR50 (Dual Data Rate) up to \token{50MHz, 50 MB/s: UHS-I (Ultra High Speed) 1.8V signalling}
<b>Bus CMD Line Mode</b>
The \em control operation \b ARM_MCI_BUS_CMD_MODE sets the bus command line mode using the parameter \em arg.
Parameter \em arg | Bus CMD Line Mode
:-------------------------------------------------------------|:------------------------------------------
\ref ARM_MCI_BUS_CMD_PUSH_PULL (default) | Set the Push-Pull CMD line
\ref ARM_MCI_BUS_CMD_OPEN_DRAIN | Set the Open Drain CMD line (MMC only)
<b>Bus Data Width</b>
Specifies the bus data width (the number of data I/O pins on the SD/MMC interface).
For high speed memory cards, a 4-bit bus data width should be used (or 8-bit for eMMC). The bit fields ARM_MCI_CAPABILITIES.data_width_4 and
ARM_MCI_CAPABILITIES.data_width_8 encode whether the driver supports a specific bus data with.
The \em control operation \b ARM_MCI_BUS_DATA_WIDTH sets the bus data width using the parameter \em arg.
Parameter \em arg | Bus Data Width
:-------------------------------------------------------------|:------------------------------------------
\ref ARM_MCI_BUS_DATA_WIDTH_1 (default) | Set the Bus data width to \token{1 bit}
\ref ARM_MCI_BUS_DATA_WIDTH_4 | Set the Bus data width to \token{4 bits}
\ref ARM_MCI_BUS_DATA_WIDTH_8 | Set the Bus data width to \token{8 bits}
\ref ARM_MCI_BUS_DATA_WIDTH_4_DDR | Set the Bus data width to \token{4 bits}, DDR (Dual Data Rate) - MMC only
\ref ARM_MCI_BUS_DATA_WIDTH_8_DDR | Set the Bus data width to \token{8 bits}, DDR (Dual Data Rate) - MMC only
<b>Driver Type</b>
Specifies the interface driver type.
The \em control operation \b ARM_MCI_DRIVER_STRENGTH sets the interface driver type using the parameter \em arg.
Parameter \em arg | Driver Type
:-------------------------------------------------------------|:------------------------------------------
\ref ARM_MCI_DRIVER_TYPE_A | Set the interface to SD UHS-I Driver Type A
\ref ARM_MCI_DRIVER_TYPE_B (default) | Set the interface to SD UHS-I Driver Type B
\ref ARM_MCI_DRIVER_TYPE_C | Set the interface to SD UHS-I Driver Type C
\ref ARM_MCI_DRIVER_TYPE_D | Set the interface to SD UHS-I Driver Type D
\b Examples:
\code
// Set Bus Speed to 25MHz
MCIdrv->Control(ARM_MCI_BUS_SPEED, 25000000);
// Set High Speed mode
MCIdrv->Control(ARM_MCI_BUS_SPEED_MODE, ARM_MCI_BUS_HIGH_SPEED);
// Configure CMD line as Open Drain (MMC only)
MCIdrv->Control(ARM_MCI_BUS_CMD_MODE, ARM_MCI_BUS_CMD_OPEN_DRAIN);
// Set Bus Data Width = 4bits
MCIdrv->Control(ARM_MCI_BUS_DATA_WIDTH, ARM_MCI_BUS_DATA_WIDTH_4);
// Set SD UHS-I Driver Type B
MCIdrv->Control(ARM_MCI_DRIVER_STRENGTH, ARM_MCI_DRIVER_TYPE_B);
// RTS_n Pin is not active by default
// Assert RTS_n Pin (eMMC)
MCIdrv->Control(ARM_MCI_CONTROL_RESET, 1);
// De-assert RTS_n Pin (eMMC)
MCIdrv->Control(ARM_MCI_CONTROL_RESET, 0);
// Clock generation on CLK when Idle: hardware specific default behavior
// Enable Clock generation on CLK when Idle
MCIdrv->Control(ARM_MCI_CONTROL_CLOCK_IDLE, 1);
// Disable Clock generation on CLK when Idle
MCIdrv->Control(ARM_MCI_CONTROL_CLOCK_IDLE, 0);
// UHS Tuning
MCIdrv->Control(ARM_MCI_UHS_TUNING_OPERATION, 1); // start tuning
do {
status = MCIdrv->Control(ARM_MCI_UHS_TUNING_RESULT, 0/*argument not used*/);
if (status == -1) { break; /* tuning failed */ }
} while (status == 1);
// Set Data Timeout to 12500000 bus cycles (0.5s @25MHz Bus Speed)
// Default value is hardware specific (typically 2^32-1)
MCIdrv->Control(ARM_MCI_DATA_TIMEOUT, 12500000);
// Set CSS Timeout to 1000000 bus cycles
// Default value is hardware specific
MCIdrv->Control(ARM_MCI_CSS_TIMEOUT, 1000000);
// SD I/O Interrupt Monitoring is disabled by default
// Enable SD I/O Interrupt Monitoring
MCIdrv->Control(ARM_MCI_MONITOR_SDIO_INTERRUPT, 1);
// Disable SD I/O Interrupt Monitoring
MCIdrv->Control(ARM_MCI_MONITOR_SDIO_INTERRUPT, 0);
// Read/Wait for SD I/O is disabled by default
// Enable Read/Wait for SD I/O
MCIdrv->Control(ARM_MCI_CONTROL_READ_WAIT, 1);
// Disable Read/Wait for SD I/O
MCIdrv->Control(ARM_MCI_CONTROL_READ_WAIT, 0);
// Suspend Data transfer (SD I/O)
MCIdrv->Control(ARM_MCI_SUSPEND_TRANSFER, 0/*argument not used*/);
// Resume Data transfer (SD I/O)
MCIdrv->Control(ARM_MCI_RESUME_TRANSFER, 0/*argument not used*/);
\endcode
*******************************************************************************************************************/
ARM_MCI_STATUS ARM_MCI_GetStatus (void) {
return ARM_DRIVER_OK;
}
/**
\fn ARM_MCI_STATUS ARM_MCI_GetStatus (void)
\details
The function \b ARM_MCI_GetStatus returns the current MCI interface status.
*******************************************************************************************************************/
void ARM_MCI_SignalEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_MCI_SignalEvent (uint32_t event)
\details
The function \b ARM_MCI_SignalEvent is a callback function registered by the function \ref ARM_MCI_Initialize.
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_NAND_CAPABILITIES, which can be retrieved with the function \ref ARM_NAND_GetCapabilities.
The following events can be generated:
Parameter \em event |Bit | Description | supported when \ref ARM_NAND_CAPABILITIES
:------------------------------------------|---:|:----------------------------------------------------------------------|:---------------------------------------------
\ref ARM_MCI_EVENT_CARD_INSERTED | 0 | Occurs after Memory Card inserted | <i>always supported</i>
\ref ARM_MCI_EVENT_CARD_REMOVED | 1 | Occurs after Memory Card removal | <i>always supported</i>
\ref ARM_MCI_EVENT_COMMAND_COMPLETE | 2 | Occurs after command completed successfully | <i>always supported</i>
\ref ARM_MCI_EVENT_COMMAND_TIMEOUT | 3 | Occurs after command timeout | <i>always supported</i>
\ref ARM_MCI_EVENT_COMMAND_ERROR | 4 | Occurs after command response error (CRC error or invalid response) | <i>always supported</i>
\ref ARM_MCI_EVENT_TRANSFER_COMPLETE | 5 | Occurs after data transfer completed successfully | <i>always supported</i>
\ref ARM_MCI_EVENT_TRANSFER_TIMEOUT | 6 | Occurs after data transfer timeout | <i>always supported</i>
\ref ARM_MCI_EVENT_TRANSFER_ERROR | 7 | Occurs after data transfer error (CRC failed) | <i>always supported</i>
\ref ARM_MCI_EVENT_SDIO_INTERRUPT | 8 | Indicates SD I/O Interrupt | data field \em sdio_interrupt = \token{1}
\ref ARM_MCI_EVENT_CCS | 9 | Indicates a Command Completion Signal (CCS) | data field \em ccs = \token{1}
\ref ARM_MCI_EVENT_CCS_TIMEOUT |10 | Indicates a Command Completion Signal (CCS) Timeout | data field \em css_timeout = \token{1}
<b>See also:</b>
- \ref ARM_MCI_SendCommand
*******************************************************************************************************************/
/**
@}
*/
// End MCI Interface

View File

@ -0,0 +1,897 @@
/**
\defgroup nand_interface_gr NAND Interface
\brief Driver API for NAND Flash Device Interface (%Driver_NAND.h).
\details
<b>NAND</b> devices are a type of non-volatile storage and do not require power to hold data.
Wikipedia offers more information about
the <a href="http://en.wikipedia.org/wiki/Flash_memory#ARM_NAND_memories" target="_blank"><b>Flash Memories</b></a>, including NAND.
<b>Block Diagram</b>
<p>&nbsp;</p>
\image html NAND_Schematics.png "Simplified NAND Flash Schematic"
<p>&nbsp;</p>
<b>NAND API</b>
The following header files define the Application Programming Interface (API) for the NAND interface:
- \b %Driver_NAND.h : Driver API for NAND Flash Device Interface
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
NAND Flash is organized in pages, grouped into blocks as the smallest erasable unit. The addressing
of data is achieved by `byte_address = block * block_size + page_in_block * page_size + offset_in_page`.
In terms of this NAND API blocks and pages are referred to as `row` and the byte offset within the page as `col`.
Thus one can calculate the `byte_address = row * page_size + col`. The parameters `page_size` and `block_size`
are device specific and must be handled by the driver user appropriately.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_NAND : access struct for NAND driver functions
@{
\anchor example <b>Example Code:</b>
\include NAND_Demo.c
*/
/*******************************************************************************************************************/
/**
\defgroup nand_execution_status Status Error Codes
\ingroup common_drv_gr
\brief Negative values indicate errors (NAND has specific codes in addition to common \ref execution_status).
\details
The NAND driver has additional status error codes that are listed below.
Note that the NAND driver also returns the common \ref execution_status.
@{
\def ARM_NAND_ERROR_ECC
ECC generation or correction failed during \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData or \ref ARM_NAND_ExecuteSequence.
@}
*/
/**
\defgroup NAND_events NAND Events
\ingroup nand_interface_gr
\brief The NAND driver generates call back events that are notified via the function \ref ARM_NAND_SignalEvent.
\details
This section provides the event values for the \ref ARM_NAND_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_NAND_EVENT_DEVICE_READY
\def ARM_NAND_EVENT_DRIVER_READY
\def ARM_NAND_EVENT_DRIVER_DONE
\def ARM_NAND_EVENT_ECC_ERROR
@}
*/
/**
\defgroup nand_driver_flag_codes NAND Flags
\ingroup nand_interface_gr
\brief Specify Flag codes.
\details
The defines can be used in the function \ref ARM_NAND_ReadData and \ref ARM_NAND_WriteData for the parameter \em mode
and in the function \ref ARM_NAND_ExecuteSequence for the parameter \em code.
@{
\def ARM_NAND_DRIVER_DONE_EVENT
@}
*/
/**
\defgroup nand_control_gr NAND Control Codes
\ingroup nand_interface_gr
\brief Many parameters of the NAND driver are configured using the \ref ARM_NAND_Control function.
@{
\details
Refer to the function \ref ARM_NAND_Control for further details.
*/
/**
\defgroup nand_control_codes NAND Mode Controls
\ingroup nand_control_gr
\brief Specify operation modes of the NAND interface.
\details
These controls can be used in the function \ref ARM_NAND_Control for the parameter \em control.
@{
\def ARM_NAND_BUS_MODE
\def ARM_NAND_BUS_DATA_WIDTH
\def ARM_NAND_DRIVER_STRENGTH
\def ARM_NAND_DEVICE_READY_EVENT
\def ARM_NAND_DRIVER_READY_EVENT
@}
*/
/**
\defgroup nand_bus_mode_codes NAND Bus Modes
\ingroup nand_control_gr
\brief Specify bus mode of the NAND interface.
\details
The defines can be used in the function \ref ARM_NAND_Control for the parameter \em arg and with the \ref ARM_NAND_BUS_MODE as the \em control code.
@{
\def ARM_NAND_BUS_SDR
\def ARM_NAND_BUS_DDR
\def ARM_NAND_BUS_DDR2
\def ARM_NAND_BUS_TIMING_MODE_0
\def ARM_NAND_BUS_TIMING_MODE_1
\def ARM_NAND_BUS_TIMING_MODE_2
\def ARM_NAND_BUS_TIMING_MODE_3
\def ARM_NAND_BUS_TIMING_MODE_4
\def ARM_NAND_BUS_TIMING_MODE_5
\def ARM_NAND_BUS_TIMING_MODE_6
\def ARM_NAND_BUS_TIMING_MODE_7
\def ARM_NAND_BUS_DDR2_DO_WCYC_0
\def ARM_NAND_BUS_DDR2_DO_WCYC_1
\def ARM_NAND_BUS_DDR2_DO_WCYC_2
\def ARM_NAND_BUS_DDR2_DO_WCYC_4
\def ARM_NAND_BUS_DDR2_DI_WCYC_0
\def ARM_NAND_BUS_DDR2_DI_WCYC_1
\def ARM_NAND_BUS_DDR2_DI_WCYC_2
\def ARM_NAND_BUS_DDR2_DI_WCYC_4
\def ARM_NAND_BUS_DDR2_VEN
\def ARM_NAND_BUS_DDR2_CMPD
\def ARM_NAND_BUS_DDR2_CMPR
@}
*/
/**
\defgroup nand_data_bus_width_codes NAND Data Bus Width
\ingroup nand_control_gr
\brief Specify data bus width of the NAND interface.
\details
The defines can be used in the function \ref ARM_NAND_Control for the parameter \em arg and with the \ref ARM_NAND_BUS_DATA_WIDTH as the \em control code.
@{
\def ARM_NAND_BUS_DATA_WIDTH_8
\def ARM_NAND_BUS_DATA_WIDTH_16
@}
*/
/**
\defgroup nand_driver_strength_codes NAND Driver Strength
\ingroup nand_control_gr
\brief Specify driver strength of the NAND interface.
\details
The defines can be used in the function \ref ARM_NAND_Control for the parameter \em arg and with the \ref ARM_NAND_DRIVER_STRENGTH as the \em control code.
@{
\def ARM_NAND_DRIVER_STRENGTH_18
\def ARM_NAND_DRIVER_STRENGTH_25
\def ARM_NAND_DRIVER_STRENGTH_35
\def ARM_NAND_DRIVER_STRENGTH_50
@}
*/
/**
@}
*/
/**
\defgroup nand_driver_ecc_codes NAND ECC Codes
\ingroup nand_interface_gr
\brief Specify ECC codes.
\details
The defines can be used in the function \ref ARM_NAND_ReadData and \ref ARM_NAND_WriteData for the parameter \em mode
and in the function \ref ARM_NAND_ExecuteSequence for the parameter \em code.
@{
\def ARM_NAND_ECC(n)
\def ARM_NAND_ECC0
\def ARM_NAND_ECC1
@}
*/
/**
\defgroup nand_driver_seq_exec_codes NAND Sequence Execution Codes
\ingroup nand_interface_gr
\brief Specify execution codes
\details
The defines can be used in the function \ref ARM_NAND_ExecuteSequence for the parameter \em code.
@{
\def ARM_NAND_CODE_SEND_CMD1
\def ARM_NAND_CODE_SEND_ADDR_COL1
\def ARM_NAND_CODE_SEND_ADDR_COL2
\def ARM_NAND_CODE_SEND_ADDR_ROW1
\def ARM_NAND_CODE_SEND_ADDR_ROW2
\def ARM_NAND_CODE_SEND_ADDR_ROW3
\def ARM_NAND_CODE_INC_ADDR_ROW
\def ARM_NAND_CODE_WRITE_DATA
\def ARM_NAND_CODE_SEND_CMD2
\def ARM_NAND_CODE_WAIT_BUSY
\def ARM_NAND_CODE_READ_DATA
\def ARM_NAND_CODE_SEND_CMD3
\def ARM_NAND_CODE_READ_STATUS
@}
*/
/*------------ Structures --------------------------------------------------------------------------------------*/
/**
\struct ARM_NAND_STATUS
\details
Structure with information about the status of a NAND. The data fields encode flags for the driver.
<b>Returned by:</b>
- \ref ARM_NAND_GetStatus
*****************************************************************************************************************/
/**
\struct ARM_DRIVER_NAND
\details
The functions of the NAND driver are accessed by function pointers exposed by this structure. Refer to \ref DriverFunctions for overview information.
Each instance of a NAND interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_NAND0 is the name of the access struct of the first instance (no. 0).
- \b Driver_NAND1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance <b>Driver_NAND<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*******************************************************************************************************************/
/**
\struct ARM_NAND_CAPABILITIES
\details
A NAND driver can be implemented with different capabilities. The data fields of this struct encode
the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_NAND_GetCapabilities
*******************************************************************************************************************/
/**
\typedef ARM_NAND_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_NAND_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_NAND_Initialize
*******************************************************************************************************************/
/**
\struct ARM_NAND_ECC_INFO
\details
Stores the characteristics of a ECC (Error Correction Code) algorithm and provides the information about necessary
application data handling in order to protect stored data from NAND bit errors.
ECC algorithms applied on NAND memory typically operate on NAND device page level which is virtually divided to multiple
main and spare areas. Data from main and spare area is taken into account when generating ECC data which is also stored
into spare area. ECC codeword defines how much data will be protected and how much ECC data will be generated.
To describe how application data must be organized, ECC information structure specifies protection \em type which
defines the protected part of data. As main and spare are of different size, two different algorithms could be
provided, we can describe them as ECC0 and ECC1. Type can then have the following values:
Type| Description
:---|:-----------
0 | ECC algorithm not used
1 | ECC0 algorithm protects main data
2 | ECC0 algorithm protects main and spare data
3 | ECC0 algorithm protects main and ECC1 algorithm protects spare data
Virtual page division is described with page layout (\em page_layout), number of pages (\em page_count) and
virtual page size (\em page_size or \em virtual_page_size). Virtual page size used by ECC algorithm can be defined
by either \em page_size or \em virtual_page_size, depending on the \em page_size values:
Value| Main + Spare size
:----|:-----------
0 | 512 + 16
1 | 1024 + 32
2 | 2048 + 64
3 | 4096 + 128
4 | 8192 + 256
8 | 512 + 28
9 | 1024 + 56
10 | 2048 + 112
11 | 4096 + 224
12 | 8192 + 448
15 | Not used, use virtual_page_size
Structure member \em virtual_page_size is an array of two 16-bit values. First field of array (i.e. \em virtual_page_size[0])
contains main area size while second (i.e. \em virtual_page_size[1]) contains spare area size. Number of virtual pages N
is defined with \em page_count and must be calculated as N = 2 ^ page_count.
Page layout defines main and spare ordering and two different page layouts are possible. First ordering assumes that
spare area follows after every main area, while in second case all main areas build one contiguous region followed by
contiguous region of spare areas. This is defined by member \em page_layout:
Layout| Description
:-----|:-----------
0 | Single spare follows after single main: Main0,Spare0 ... MainN-1,SpareN-1
1 | Contiguous spare follows after contiguous main: Main0 ... MainN-1,Spare0 ... SpareN-1
ECC codeword size defines the size of data that is protected by ECC algorithm and is different for main and spare
area. All structure members that define the codeword are therefore arrays of two 16-bit values. Codeword offset defines
where ECC protected data starts in main (\em codeword_offset[0]) or spare (\em codeword_offset[1]) area, codeword
size (\em codeword_size) defines the number of data that is protected i.e. data over which ECC is calculated and
codeword gap (\em codeword_gap) defines the space between two consecutive codeword regions.
Generated ECC data is stored into spare area and is described similar as codeword, with offset from start of spare area
(\em ecc_offset), size of generated data (\em ecc_size) and gap (\em ecc_gap) between two consecutive ECC data regions.
Number of bits that ECC algorithm can correct per codeword is defined with \em correctable_bits.
<b>Parameter for:</b>
- \ref ARM_NAND_InquireECC
*****************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_NAND_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_NAND_GetVersion (void)
\details
The function \b ARM_NAND_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_NAND Driver_NAND0;
ARM_DRIVER_NAND *drv_info;
void setup_nand (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_NAND0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*******************************************************************************************************************/
ARM_NAND_CAPABILITIES ARM_NAND_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_NAND_CAPABILITIES ARM_NAND_GetCapabilities (void)
\details
The function \b ARM_NAND_GetCapabilities retrieves information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_NAND_CAPABILITIES encode various capabilities, for example
if a hardware is able to create signal events using the \ref ARM_NAND_SignalEvent
callback function.
Example:
\code
extern ARM_DRIVER_NAND Driver_NAND0;
ARM_DRIVER_NAND *drv_info;
void read_capabilities (void) {
ARM_NAND_CAPABILITIES drv_capabilities;
drv_info = &Driver_NAND0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*******************************************************************************************************************/
int32_t ARM_NAND_Initialize (ARM_NAND_SignalEvent_t cb_event) {
return 0;
}
/**
\fn int32_t ARM_NAND_Initialize (ARM_NAND_SignalEvent_t cb_event)
\details
The function \b ARM_NAND_Initialize initializes the NAND interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the NAND interface.
- Registers the \ref ARM_NAND_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_NAND_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
\b Example:
- see \ref nand_interface_gr - Driver Functions
*******************************************************************************************************************/
int32_t ARM_NAND_Uninitialize (void) {
return 0;
}
/**
\fn int32_t ARM_NAND_Uninitialize (void)
\details
The function \b ARM_NAND_Uninitialize de-initializes the resources of NAND interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*******************************************************************************************************************/
int32_t ARM_NAND_PowerControl (ARM_POWER_STATE state) {
return 0;
}
/**
\fn int32_t ARM_NAND_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_NAND_PowerControl controls the power modes of the NAND interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*******************************************************************************************************************/
int32_t ARM_NAND_DevicePower (uint32_t voltage) {
return 0;
}
/**
\fn int32_t ARM_NAND_DevicePower (uint32_t voltage)
\details
The function \b ARM_NAND_DevicePower controls the power supply of the NAND device.
The parameter \em voltage sets the device supply voltage as defined in the table.
\b AMR_NAND_POWER_xxx_xxx specifies power settings.
Device Power Bits | Description
:--------------------------------|:--------------------------------------------
\ref ARM_NAND_POWER_VCC_OFF | Set VCC Power off
\ref ARM_NAND_POWER_VCC_3V3 | Set VCC = 3.3V
\ref ARM_NAND_POWER_VCC_1V8 | Set VCC = 1.8V
\ref ARM_NAND_POWER_VCCQ_OFF | Set VCCQ I/O Power off
\ref ARM_NAND_POWER_VCCQ_3V3 | Set VCCQ = 3.3V
\ref ARM_NAND_POWER_VCCQ_1V8 | Set VCCQ = 1.8V
\ref ARM_NAND_POWER_VPP_OFF | Set VPP off
\ref ARM_NAND_POWER_VPP_ON | Set VPP on
*******************************************************************************************************************/
int32_t ARM_NAND_WriteProtect (uint32_t dev_num, bool enable) {
return 0;
}
/**
\fn int32_t ARM_NAND_WriteProtect (uint32_t dev_num, bool enable)
\details
The function \b ARM_NAND_WriteProtect controls the Write Protect (WPn) pin of a NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em enable specifies whether to enable or disable write protection.
*******************************************************************************************************************/
int32_t ARM_NAND_ChipEnable (uint32_t dev_num, bool enable) {
return 0;
}
/**
\fn int32_t ARM_NAND_ChipEnable (uint32_t dev_num, bool enable)
\details
The function \b ARM_NAND_ChipEnable control the Chip Enable (CEn) pin of a NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em enable specifies whether to enable or disable the device.
This function is optional and supported only when the data field \em ce_manual = \token{1} in the structure \ref ARM_NAND_CAPABILITIES.
Otherwise, the Chip Enable (CEn) signal is controlled automatically by SendCommand/Address, Read/WriteData and ExecuteSequence
(for example when the NAND device is connected to a memory bus).
*******************************************************************************************************************/
int32_t ARM_NAND_GetDeviceBusy (uint32_t dev_num) {
return 0;
}
/**
\fn int32_t ARM_NAND_GetDeviceBusy (uint32_t dev_num)
\details
The function \b ARM_NAND_GetDeviceBusy returns the status of the Device Busy pin: [\token{1=busy; 0=not busy or error}].
The parameter \em dev_num is the device number.
*******************************************************************************************************************/
int32_t ARM_NAND_SendCommand (uint32_t dev_num, uint8_t cmd) {
return 0;
}
/**
\fn int32_t ARM_NAND_SendCommand (uint32_t dev_num, uint8_t cmd)
\details
The function \b ARM_NAND_SendCommand sends a command to the NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em cmd is the command sent to the NAND device.
*******************************************************************************************************************/
int32_t ARM_NAND_SendAddress (uint32_t dev_num, uint8_t addr) {
return 0;
}
/**
\fn int32_t ARM_NAND_SendAddress (uint32_t dev_num, uint8_t addr)
\details
Send an address to the NAND device.
The parameter \em dev_num is the device number.
The parameter \em addr is the address.
*******************************************************************************************************************/
int32_t ARM_NAND_ReadData (uint32_t dev_num, void *data, uint32_t cnt, uint32_t mode) {
return 0;
}
/**
\fn int32_t ARM_NAND_ReadData (uint32_t dev_num, void *data, uint32_t cnt, uint32_t mode)
\details
The function \b ARM_NAND_ReadData reads data from a NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em data is a pointer to the buffer that stores the data read from a NAND device. \n
The parameter \em cnt is the number of data items to read. \n
The parameter \em mode defines the operation mode as listed in the table below.
Read Data Mode | Description
:----------------------------------|:--------------------------------------------
\ref ARM_NAND_ECC(n) | Select ECC
\ref ARM_NAND_ECC0 | Use ECC0 of selected ECC
\ref ARM_NAND_ECC1 | Use ECC1 of selected ECC
\ref ARM_NAND_DRIVER_DONE_EVENT | Generate \ref ARM_NAND_EVENT_DRIVER_DONE
The data item size is defined by the data type, which depends on the configured data bus width.
Data type is:
- \em uint8_t for 8-bit data bus
- \em uint16_t for 16-bit data bus
The function executes in the following ways:
- When the operation is blocking (typical for devices connected to memory bus when not using DMA),
then the function returns after all data is read and returns the number of data items read.
- When the operation is non-blocking (typical for NAND controllers), then the function only starts the operation and returns with zero number of data items read.
After the operation is completed, the \ref ARM_NAND_EVENT_DRIVER_DONE event is generated (if enabled by \b ARM_NAND_DRIVER_DONE_EVENT).
Progress of the operation can also be monitored by calling the \ref ARM_NAND_GetStatus function and checking the \em busy data field.
Operation is automatically aborted if ECC is used and ECC correction fails, which generates the \ref ARM_NAND_EVENT_ECC_ERROR event
(together with \ref ARM_NAND_DRIVER_DONE_EVENT if enabled).
*******************************************************************************************************************/
int32_t ARM_NAND_WriteData (uint32_t dev_num, const void *data, uint32_t cnt, uint32_t mode) {
return 0;
}
/**
\fn int32_t ARM_NAND_WriteData (uint32_t dev_num, const void *data, uint32_t cnt, uint32_t mode)
\details
The function \b ARM_NAND_WriteData writes data to a NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em data is a pointer to the buffer with data to write. \n
The parameter \em cnt is the number of data items to write. \n
The parameter \em mode defines the operation mode as listed in the table below.
Write Data Mode | Description
:----------------------------------|:--------------------------------------------
\ref ARM_NAND_ECC(n) | Select ECC
\ref ARM_NAND_ECC0 | Use ECC0 of selected ECC
\ref ARM_NAND_ECC1 | Use ECC1 of selected ECC
\ref ARM_NAND_DRIVER_DONE_EVENT | Generate \ref ARM_NAND_EVENT_DRIVER_DONE
The data item size is defined by the data type, which depends on the configured data bus width.
Data type is:
- \em uint8_t for 8-bit data bus
- \em uint16_t for 16-bit data bus
The function executes in the following ways:
- When the operation is blocking (typical for devices connected to memory bus when not using DMA),
then the function returns after all data is written and returns the number of data items written.
- When the operation is non-blocking (typical for NAND controllers), then the function only starts the operation
and returns with zero number of data items written. After the operation is completed,
the \ref ARM_NAND_EVENT_DRIVER_DONE event is generated (if enabled by \b ARM_NAND_DRIVER_DONE_EVENT).
Progress of the operation can also be monitored by calling the \ref ARM_NAND_GetStatus function and checking the \em busy data field.
Operation is automatically aborted if ECC is used and ECC generation fails,
which generates the \ref ARM_NAND_EVENT_ECC_ERROR event (together with \ref ARM_NAND_DRIVER_DONE_EVENT if enabled).
*******************************************************************************************************************/
int32_t ARM_NAND_ExecuteSequence (uint32_t dev_num, uint32_t code, uint32_t cmd,
uint32_t addr_col, uint32_t addr_row,
void *data, uint32_t data_cnt,
uint8_t *status, uint32_t *count) {
return 0;
}
/**
\fn int32_t ARM_NAND_ExecuteSequence (uint32_t dev_num, uint32_t code, uint32_t cmd, uint32_t addr_col, uint32_t addr_row, void *data, uint32_t data_cnt, uint8_t *status, uint32_t *count)
\details
The function \b ARM_NAND_ExecuteSequence executes a sequence of operations for a NAND device.
The parameter \em dev_num is the device number. \n
The parameter \em code is the sequence encoding as defined in the table <b>Sequence execution Code</b>. \n
The parameter \em cmd is the command or a series of commands. \n
The parameter \em addr_col is the column address. \n
The parameter \em addr_row is the row address. \n
The parameter \em data is a pointer to the buffer that stores the data to or loads the data from. \n
The parameter \em data_cnt is the number of data items to read or write in one iteration. \n
The parameter \em status is a pointer to the buffer that stores the status read. \n
The parameter \em count is a pointer to the number of iterations. \n
\b ARM_NAND_CODE_xxx specifies sequence execution codes.
Sequence Execution Code | Description
:----------------------------------|:--------------------------------------------
\ref ARM_NAND_CODE_SEND_CMD1 | Send Command 1 (cmd[7..0])
\ref ARM_NAND_CODE_SEND_ADDR_COL1 | Send Column Address 1 (addr_col[7..0])
\ref ARM_NAND_CODE_SEND_ADDR_COL2 | Send Column Address 2 (addr_col[15..8])
\ref ARM_NAND_CODE_SEND_ADDR_ROW1 | Send Row Address 1 (addr_row[7..0])
\ref ARM_NAND_CODE_SEND_ADDR_ROW2 | Send Row Address 2 (addr_row[15..8])
\ref ARM_NAND_CODE_SEND_ADDR_ROW3 | Send Row Address 3 (addr_row[23..16])
\ref ARM_NAND_CODE_INC_ADDR_ROW | Auto-increment Row Address
\ref ARM_NAND_CODE_WRITE_DATA | Write Data
\ref ARM_NAND_CODE_SEND_CMD2 | Send Command 2 (cmd[15..8])
\ref ARM_NAND_CODE_WAIT_BUSY | Wait while R/Bn busy
\ref ARM_NAND_CODE_READ_DATA | Read Data
\ref ARM_NAND_CODE_SEND_CMD3 | Send Command 3 (cmd[23..16])
\ref ARM_NAND_CODE_READ_STATUS | Read Status byte and check FAIL bit (bit 0)
\ref ARM_NAND_ECC(n) | Select ECC
\ref ARM_NAND_ECC0 | Use ECC0 of selected ECC
\ref ARM_NAND_ECC1 | Use ECC1 of selected ECC
\ref ARM_NAND_DRIVER_DONE_EVENT | Generate \ref ARM_NAND_EVENT_DRIVER_DONE
The data item size is defined by the data type, which depends on the configured data bus width.
Data type is:
- \em uint8_t for 8-bit data bus
- \em uint16_t for 16-bit data bus
The function is non-blocking and returns as soon as the driver has started executing the specified sequence.
When the operation is completed, the \ref ARM_NAND_EVENT_DRIVER_DONE event is generated (if enabled by \b ARM_NAND_DRIVER_DONE_EVENT).
Progress of the operation can also be monitored by calling the \ref ARM_NAND_GetStatus function and checking the \em busy data field.
Driver executes the number of specified iterations where in each iteration
items specified by \b ARM_NAND_CODE_xxx are executed in the order as listed in the table <b>Sequence execution Code</b>.
The parameter \em count is holding the current number of iterations left.
Execution is automatically aborted and \ref ARM_NAND_EVENT_DRIVER_DONE event is generated (if enabled by \b ARM_NAND_DRIVER_DONE_EVENT):
- if Read Status is enabled and the FAIL bit (bit 0) is set
- if ECC is used and ECC fails (also sets \ref ARM_NAND_EVENT_ECC_ERROR event)
\note
\ref ARM_NAND_CODE_WAIT_BUSY can only be specified if the Device Ready event can be generated (reported by \em event_device_ready in \ref ARM_NAND_CAPABILITIES).
The event \ref ARM_NAND_EVENT_DEVICE_READY is not generated during sequence execution but rather used internally by the driver.
*******************************************************************************************************************/
int32_t ARM_NAND_AbortSequence (uint32_t dev_num) {
return 0;
}
/**
\fn int32_t ARM_NAND_AbortSequence (uint32_t dev_num)
\details
The function \b ARM_NAND_AbortSequence aborts execution of the current sequence for a NAND device.
The parameter \em dev_num is the device number.
*******************************************************************************************************************/
int32_t ARM_NAND_Control (uint32_t dev_num, uint32_t control, uint32_t arg) {
return 0;
}
/**
\fn int32_t ARM_NAND_Control (uint32_t dev_num, uint32_t control, uint32_t arg)
\details
The function \b ARM_NAND_Control controls the NAND interface and executes operations.
The parameter \em dev_num is the device number. \n
The parameter \em control specifies the operation. \n
The parameter \em arg provides (depending on the \em control) additional information or sets values.
The table lists the operations for the parameter \em control.
Parameter \em control | Operation
:--------------------------------|:--------------------------------------------
\ref ARM_NAND_BUS_MODE | Set the bus mode. The parameter \em arg sets the \ref bus_mode_tab "\b Bus Mode".
\ref ARM_NAND_BUS_DATA_WIDTH | Set the data bus width. The parameter \em arg sets the \ref bus_data_width_tab "\b Bus Data Width".
\ref ARM_NAND_DRIVER_STRENGTH | Set the driver strength. The parameter \em arg sets the \ref driver_strength_tab "\b Driver Strength".
\ref ARM_NAND_DRIVER_READY_EVENT | Control generation of callback event \ref ARM_NAND_EVENT_DRIVER_READY. Enable: \em arg = \token{1}. Disable: \em arg = \token{0}.
\ref ARM_NAND_DEVICE_READY_EVENT | Control generation of callback event \ref ARM_NAND_EVENT_DEVICE_READY; Enable: \em arg = \token{1}. Disable: \em arg = \token{0}.
<b>See Also</b>
- \ref ARM_NAND_GetCapabilities returns information about supported operations, which are stored in the structure \ref ARM_NAND_CAPABILITIES.
- \ref ARM_NAND_SignalEvent provides information about the callback events \ref ARM_NAND_EVENT_DRIVER_READY and \ref ARM_NAND_EVENT_DEVICE_READY
The table lists values for the parameter \em arg used with the \em control operation \ref ARM_NAND_BUS_MODE, \ref ARM_NAND_BUS_DATA_WIDTH, and
\ref ARM_NAND_DRIVER_STRENGTH. Values from different categories can be ORed.
\anchor bus_mode_tab
<table class="cmtable" summary="">
<tr><th> Parameter \em arg <br> for <i>control</i> = \ref ARM_NAND_BUS_MODE </th>
<th> Bit </th>
<th> Category </th>
<th> Description </th>
<th width="30%"> Supported when \ref ARM_NAND_CAPABILITIES </th></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_0 (default) </td>
<td rowspan="8" style="text-align:right"> 0..3 </td>
<td rowspan="8"> \anchor bus_timing_tab Bus Timing Mode </td>
<td> \token{0} </td>
<td rowspan="8"> The maximum timing mode that can be applied to a specific \ref bus_data_interface_tab "\b Bus Data Interface"
is stored in the data fields: <br><br>
<i>sdr_timing_mode</i> - for SDR <br>
<i>ddr_timing_mode</i> - for NV-DDR <br>
<i>ddr2_timing_mode</i> - for NV_DDR2 </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_1 </td><td> \token{1} </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_2 </td><td> \token{2} </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_3 </td><td> \token{3} </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_4 </td><td> \token{4} (SDR EDO capable) </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_5 </td><td> \token{5} (SDR EDO capable) </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_6 </td><td> \token{6} (NV-DDR2 only) </td></tr>
<tr><td> \ref ARM_NAND_BUS_TIMING_MODE_7 </td><td> \token{7} (NV-DDR2 only) </td></tr>
<tr><td> \ref ARM_NAND_BUS_SDR (default) \anchor bus_data_interface_tab </td>
<td rowspan="3" style="text-align:right"> 4..7 </td>
<td rowspan="3"> Bus Data Interface </td>
<td> SDR (Single Data Rate) - Traditional interface </td>
<td> <i>always supported</i> </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR </td><td> NV-DDR (Double Data Rate) </td><td> data field <i>ddr</i> = \token{1} </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2 </td><td> NV-DDR2 (Double Data Rate) </td><td> data field <i>ddr2</i> = \token{1} </td></tr>
<tr><td style="white-space: nowrap"> \ref ARM_NAND_BUS_DDR2_DO_WCYC_0 (default) </td>
<td rowspan="4" style="text-align:right"> 8..11 </td>
<td rowspan="4" style="white-space: nowrap"> Data Output Warm-up \anchor bus_output_tab </td>
<td> Set the DDR2 Data Output Warm-up to \token{0} cycles </td>
<td rowspan="4"> <b>Data Output Warm-up</b> cycles are dummy cycles for interface calibration with no incremental data transfer
and apply to NV-DDR2 of the \ref bus_data_interface_tab "\b Bus Data Interface".
</td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DO_WCYC_1 </td><td> Set the DDR2 Data Output Warm-up to \token{1} cycles </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DO_WCYC_2 </td><td> Set the DDR2 Data Output Warm-up to \token{2} cycles </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DO_WCYC_4 </td><td> Set the DDR2 Data Output Warm-up to \token{4} cycles </td></tr>
<tr><td style="white-space: nowrap"> \ref ARM_NAND_BUS_DDR2_DI_WCYC_0 (default) \anchor bus_input_tab</td>
<td rowspan="4" style="text-align:right"> 12..15 </td>
<td rowspan="4" style="white-space: nowrap"> Data Input Warm-up </td>
<td> Set the DDR2 Data Input Warm-up to \token{0} cycles </td>
<td rowspan="4"> <b>Data Input Warm-up</b> cycles are dummy cycles for interface calibration with no incremental data transfer
and apply to NV-DDR2 of the \ref bus_data_interface_tab "\b Bus Data Interface".
</td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DI_WCYC_1 </td><td> Set the DDR2 Data Input Warm-up to \token{1} cycles </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DI_WCYC_2 </td><td> Set the DDR2 Data Input Warm-up to \token{2} cycles </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_DI_WCYC_4 </td><td> Set the DDR2 Data Input Warm-up to \token{4} cycles </td></tr>
<tr><td style="white-space: nowrap"> \ref ARM_NAND_BUS_DDR2_VEN \anchor bus_misc_tab </td>
<td style="text-align:right"> 16 </td>
<td rowspan="3" style="white-space: nowrap"> Miscellaneous </td>
<td> Set the DDR2 Enable external VREFQ as reference </td>
<td rowspan="3"> &nbsp;
</td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_CMPD </td><td style="text-align:right"> 17 </td><td> Set the DDR2 Enable complementary DQS (DQS_c) signal </td></tr>
<tr><td> \ref ARM_NAND_BUS_DDR2_CMPR </td><td style="text-align:right"> 18 </td><td> Set the DDR2 Enable complementary RE_n (RE_c) signal </td></tr>
<tr><th> Parameter \em arg <br> for <i>control</i> = \ref ARM_NAND_BUS_DATA_WIDTH </th>
<th> Bit </th>
<th> Category \anchor bus_data_width_tab </th>
<th> Description </th>
<th width="30%"> Supported when \ref ARM_NAND_CAPABILITIES </th></tr>
<tr><td style="white-space: nowrap"> \ref ARM_NAND_BUS_DATA_WIDTH_8 (default) </td>
<td rowspan="2" style="text-align:right"> 0..1 </td>
<td rowspan="2" style="white-space: nowrap"> Bus Data Width </td>
<td> Set to \token{8 bit} </td>
<td> <i>always supported</i>
</td></tr>
<tr><td> \ref ARM_NAND_BUS_DATA_WIDTH_16 </td><td> Set to \token{16 bit} </td><td> data field <i>data_width_16</i> = \token{1} </td></tr>
<tr><th style="white-space: nowrap"> Parameter \em arg <br> for <i>control</i> = \ref ARM_NAND_DRIVER_STRENGTH </th>
<th> Bit </th>
<th> Category \anchor driver_strength_tab </th>
<th> Description </th>
<th width="30%"> Supported when \ref ARM_NAND_CAPABILITIES </th></tr>
<tr><td style="white-space: nowrap"> \ref ARM_NAND_DRIVER_STRENGTH_18 </td>
<td rowspan="4" style="text-align:right"> 0..3 </td>
<td rowspan="4" style="white-space: nowrap"> Driver Strength </td>
<td> Set the Driver Strength 2.0x = 18 Ohms </td>
<td> data field <i>driver_strength_18</i> = \token{1}
</td></tr>
<tr><td> \ref ARM_NAND_DRIVER_STRENGTH_25 </td><td> Set the Driver Strength 1.4x = 25 Ohms </td><td> data field <i>driver_strength_25</i> = \token{1} </td></tr>
<tr><td> \ref ARM_NAND_DRIVER_STRENGTH_35 (default) </td><td> Set the Driver Strength 1.0x = 35 Ohms </td><td> <i>always supported</i> </td></tr>
<tr><td> \ref ARM_NAND_DRIVER_STRENGTH_50 </td><td> Set the Driver Strength 0.7x = 50 Ohms </td><td> data field <i>driver_strength_50</i> = \token{1} </td></tr>
</table>
<b>Example</b>
\code
extern ARM_DRIVER_NAND Driver_NAND0;
status = Driver_NAND0.Control (0, ARM_NAND_BUS_MODE, ARM_NAND_BUS_TIMING_MODE_5 |
ARM_NAND_BUS_DDR2 |
ARM_NAND_BUS_DDR2_VEN);
status = Driver_NAND0.Control (0, ARM_NAND_BUS_DATA_WIDTH, ARM_NAND_BUS_DATA_WIDTH_16);
status = Driver_NAND0.Control (0, ARM_NAND_DRIVER_STRENGTH, ARM_NAND_DRIVER_STRENGTH_50);
\endcode
*******************************************************************************************************************/
ARM_NAND_STATUS ARM_NAND_GetStatus (uint32_t dev_num) {
return 0;
}
/**
\fn ARM_NAND_STATUS ARM_NAND_GetStatus (uint32_t dev_num)
\details
The function \b ARM_NAND_GetStatus returns the current NAND device status.
The parameter \em dev_num is the device number.
*******************************************************************************************************************/
int32_t ARM_NAND_InquireECC (int32_t index, ARM_NAND_ECC_INFO *info) {
return 0;
}
/**
\fn int32_t ARM_NAND_InquireECC (int32_t index, ARM_NAND_ECC_INFO *info)
\details
The function \b ARM_NAND_InquireECC reads error correction code information.
The parameter \em index is the ECC index and is used to retrieve different ECC configurations. \n
The parameter \em info is a pointer of type \ref ARM_NAND_ECC_INFO. The data fields store the information.
When multiple different ECC configurations exist, ARM_NAND_ECC_INFO structure exists for each configuration. Parameter
\em index denotes which configuration will be retrieved. Value of index should start with zero to retrieve first ECC
configuration and should be incremented in order to retrieve next ECC configuration. When index is out of range function
ARM_NAND_InquireECC returns with error.
Parameter \em index is used by \ref ARM_NAND_ECC(n) in \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData and
\ref ARM_NAND_ExecuteSequence to select suitable ECC configuration.
<b>Example</b>
\code
extern ARM_DRIVER_NAND Driver_NAND0;
ARM_NAND_ECC_INFO ecc;
int32_t idx;
idx = 0;
while (Driver_NAND0.InquireECC (idx, &ecc) == ARM_DRIVER_OK) {
// Examine retrieved ECC configuration
if (ecc.type == 2) {
// Algorithm ECC0 protects Main+Spare
}
// ..
idx++;
}
\endcode
*******************************************************************************************************************/
void ARM_NAND_SignalEvent (uint32_t dev_num, uint32_t event) {
return 0;
}
/**
\fn void ARM_NAND_SignalEvent (uint32_t dev_num, uint32_t event)
\details
The function \b ARM_NAND_SignalEvent is a callback function registered by the function \ref ARM_NAND_Initialize.
The parameter \em dev_num is the device number. \n
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_NAND_CAPABILITIES, which can be retrieved with the function \ref ARM_NAND_GetCapabilities.
The following events can be generated:
Parameter \em event | Bit | Description
:---------------------------------|-----|:---------------------------
\ref ARM_NAND_EVENT_DEVICE_READY | 0 | Occurs when rising edge is detected on R/Bn (Ready/Busy) pin indicating that the device is ready.
\ref ARM_NAND_EVENT_DRIVER_READY | 1 | Occurs to indicate that commands can be executed (after previously being busy and not able to start the requested operation).
\ref ARM_NAND_EVENT_DRIVER_DONE | 2 | Occurs after an operation completes. An operation was successfully started before with \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData, \ref ARM_NAND_ExecuteSequence.
\ref ARM_NAND_EVENT_ECC_ERROR | 3 | Occurs when ECC generation failed or ECC correction failed. An operation was successfully started before with \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData, \ref ARM_NAND_ExecuteSequence.
The event \ref ARM_NAND_EVENT_DEVICE_READY occurs after complete execution of commands
(initiated with the functions \ref ARM_NAND_SendCommand, \ref ARM_NAND_SendAddress, \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData, \ref ARM_NAND_ExecuteSequence).
It is useful to indicate completion of complex operations (such as erase).
The event is only generated when \ref ARM_NAND_GetCapabilities returns data field \em event_device_ready = \token{1}
and was enabled by calling \ref ARM_NAND_Control (\ref ARM_NAND_DEVICE_READY_EVENT, 1).
If the event is not available, poll the \em busy data field using the function \ref ARM_NAND_GetStatus.
The event \ref ARM_NAND_EVENT_DRIVER_READY occurs when previously a function
(\ref ARM_NAND_SendCommand, \ref ARM_NAND_SendAddress, \ref ARM_NAND_ReadData, \ref ARM_NAND_WriteData, \ref ARM_NAND_ExecuteSequence)
returned with \ref ARM_DRIVER_ERROR_BUSY. It is useful when functions are called simultaneously from independent threads
(for example to control multiple devices) and the threads have no knowledge about each other (driver rejects reentrant calls with return of \ref ARM_DRIVER_ERROR_BUSY).
\em dev_num indicates the device that returned previously busy.
*******************************************************************************************************************/
/**
@}
*/
// End NAND Interface

View File

@ -0,0 +1,73 @@
/*
Purpose: The text might be of interest in another place.
We have to decide whether we want to use it.
Until a decision is made, do not delete the file.
Usage: Storage of text. Not used in doxygen.
Created: March 21, 2014
Author : Bruno
Changed:
*/
/**
\struct ARM_NAND_DEVICE
\details
Stores the characteristics of a NAND Flash device. This includes the page layout configuration, NAND type,
device number (chip select), number of blocks, pages, sectors, and error correction code.
<b>Parameter for:</b>
- \ref ARM_NAND_Initialize
*******************************************************************************************************************/
/**
\struct ARM_NAND_ECC_INFO_x
\details
Stores the default NAND page layout definition (with \ref spare_size and \ref spare_offset),
which contains a \b Spare area after each sector. The struct \b ARM_NAND_ECC_INFO defines the \b Spare area.
The page size is defined as the sum of \b User area plus \b Spare area.
Each page has a small number of associated "spare" bytes (typically 1/32 of the data size) to store the Error Correction Algorithms (ECC).
The following standard page sizes are available:
Page Size| User + Spare Area
---------|-------------------
528 | 512 + 16 bytes
2112 | 2048 + 64 bytes
4224 | 4096 + 128 bytes
8448 | 8192 + 256 bytes
\image html NAND_PageLayout.png "Default Page Layout"
<p>&nbsp;</p>
\image html NAND_SpareArea.png "Organization of the default 16-byte Spare area"
NAND devices require bad block management by the driver software or by a separate controller chip.
For example, SD cards have mechanisms that execute wear leveling and bad block management.
The memory capacity shrinks as more blocks are marked bad.
The block size is a value specified as amount of flash pages.
The following block sizes are available:
Block Size| Pages
----------|-------------------
8 | 8
16 | 16
32 | 32
64 | 64
128 | 128
256 | 256
\note
NAND chip manufacturers document the order in which pages can be written.
Typically, single pages of an erase block must be written in sequential order starting from the first. Random-order writes are prohibited or unspecified.
<b>Parameter for:</b>
- \ref ARM_NAND_DEVICE structure
*******************************************************************************************************************/

View File

@ -0,0 +1,936 @@
/* -----------------------------------------------------------------------------
* Copyright (c) 2013-2014 ARM Ltd.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software. Permission is granted to anyone to use this
* software for any purpose, including commercial applications, and to alter
* it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* $Date: 9. Dec 2014
* $Revision: V1.00
*
* Project: SAI (Serial Audio Interface) Driver definitions
* -------------------------------------------------------------------------- */
/**
\defgroup sai_interface_gr SAI Interface
\brief Driver API for Serial Audio Interface (%Driver_SAI.h)
\details
The <b>Serial Audio Interface</b> (SAI) implements a synchronous serial bus interface for connecting digital audio devices.
It is by far the most common mechanism used to transfer two channels of audio data between devices within a system. \b SAI
can transfer digital audio using various protocols:
- \ref Driver_SAI_I2S
- \ref Driver_SAI_MSB
- \ref Driver_SAI_LSB
- \ref Driver_SAI_PCM
- \ref Driver_SAI_AC97
- \ref Driver_SAI_User
<b>Block Diagram</b>
<p>&nbsp;</p>
\image html SAI_Schematics.png "Simplified SAI Schematic"
<p>&nbsp;</p>
<b>SAI API</b>
The following header files define the Application Programming Interface (API) for the SAI interface:
- \b %Driver_SAI.h : Driver API for Serial Audio Interface
The driver implementation is a typical part of the
<a class="el" href="../../Pack/html/index.html" target="_blank">Device Family Pack (DFP)</a> that supports the peripherals of
the microcontroller family.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_SAI : access struct for SAI driver functions
\section Driver_SAI_I2S I2S
<a href="https://en.wikipedia.org/wiki/I%C2%B2S" target="_blank">Integrated Interchip Sound</a> (\b I2S) is a serial bus
interface that connects digital audio devices together. It was introduced by Philips (now
<a href="http://www.nxp.com" target="_blank">NXP</a>) in the late 80's and last revised 1996. It uses pulse code modulation
to exchange the audio data between the devices. The following timing diagram explains the operation:
\image html driver_sai_i2s.png
I2S separates the clock (\b SCK) from the serial data (\b SD), resulting in a lower jitter. A complete audio data frame
consists of two slots, one for the left channel and one for the right. The slot size equals the data size.
The word select (\b WS) line lets the device know whether the left channel (WS is low) or the right channel (WS is high) is
currently being transmitted. WS has a 50% duty-cycle signal that has the same frequency as the sample frequency. It is an
early signal, meaning that the WS line changes one clock cycle before the actual data (SD) is transmitted (left or right).
The data on SD is always transmitted MSB first and can have a data size of 8 up to 32 bits.
In terms of the CMSIS-Driver for SAI, the I2S protocol can be described as follows:
- Data Size: 8..32 (MSB first)
- Clock Polarity: Drive on falling edge, Capture on rising edge
- Frame Length: 2 * Data Size = 2 * Slot Size
- Frame Sync Width: Frame Length / 2
- Frame Sync Polarity: Active Low
- Frame Sync Early
- Slot Count: 2 (L R)
- Slot Size: Data Size
- Slot Offset: 0
\section Driver_SAI_MSB MSB Justified
\b MSB \b Justified is much like \ref Driver_SAI_I2S, with a few differences:
\image html driver_sai_msb.png
Unlike I2S, in MSB Justified the word select (\b WS) signals the left channel when it is active high and the right channel,
when it is active low. The signal changes when the first actual \b SD data is available. It might happen that a frame (left
or right) is not fully filled with data. In this case, all data after the LSB is forced to zero.
In terms of the CMSIS-Driver for SAI, the MSB Justified protocol can be described as follows:
- Data Size: 8..32 (MSB first)
- Clock Polarity: Drive on falling edge, Capture on rising edge
- Frame Length: 2 * Slot Size
- Frame Sync Width: Frame Length / 2
- Frame Sync Polarity: Active High
- Slot Count: 2 (L R)
- Slot Size: Data Size or higher (16/32)
- Slot Offset: 0 (Zero padding after Data: Slot Size - Data Size)
\section Driver_SAI_LSB LSB Justified
\b LSB \b Justified is much like \ref Driver_SAI_MSB, with the single difference that the padding 0's are sent before the
first actual data (MSB on \b SD):
\image html driver_sai_lsb.png
In terms of the CMSIS-Driver for SAI, the LSB Justified protocol can be described as follows:
- Data Size: 8..32 (MSB first)
- Clock Polarity: Drive on falling edge, Capture on rising edge
- Frame Length: 2*Slot Size
- Frame Sync Width: Frame Length / 2
- Frame Sync Polarity: Active High
- Slot Count: 2
- Slot Size: Data Size or higher (16/32)
- Slot Offset: Slot Size - Data Size (Zero padding before Data: Slot Size - Data Size)
\section Driver_SAI_PCM PCM
<a href="https://en.wikipedia.org/wiki/Pulse-code_modulation" target="_blank">Pulse Code Modulation</a> (\b PCM) differs to
the previous protocols in a few ways:
\image html driver_sai_pcm.png
- Only one channel is transferred.
- There are two types of synchronization modes available:
- In \b short \b frame sync mode, the falling edge of \b Frame \b Sync indicates the start of the serial data \b SD. \b Frame \b Sync is always
one clock cycle long.
- In \b long \b frame sync mode, the rising edge of \b Frame \b Sync indicates the start of the serial data \b SD. \b Frame \b Sync stays active
high for 13 clock cycles.
In terms of the CMSIS-Driver for SAI, the PCM protocol can be described as follows:\n
\b PCM \b Short \b Frame
- Data Size: 8..32 (MSB first)
- Clock Polarity: Drive on falling edge, Capture on rising edge
- Frame Length: Slot Size
- Frame Sync Width: 1
- Frame Sync Polarity: Active High
- Frame Sync Early
- Slot Count: 1
- Slot Size: Data Size or higher (16/32)
- Slot Offset: 0
\b PCM \b Long \b Frame
- Data Size: 16..32 (MSB first)
- Clock Polarity: Drive on falling edge, Capture on rising edge
- Frame Length: Slot Size
- Frame Sync Width: 13
- Frame Sync Polarity: Active High
- Slot Count: 1
- Slot Size: Data Size or higher (32)
- Slot Offset: 0
\section Driver_SAI_AC97 AC'97
<a href="https://en.wikipedia.org/wiki/AC'97" target="_blank">Audio Codec '97</a> was developed by
<a href="http://www.intel.com" target="_blank">Intel</a>. It is composed of five wires: the clock (12.288 MHz), a sync
signal, a reset signal, and two data wires: sdata_out (contains the AC97 output) and sdata_in (contains the CODEC output).
For more information, consult the
<a href="http://inst.eecs.berkeley.edu/~cs150/Documents/ac97_r23.pdf" target="_blank">standard documentation</a>.
\section Driver_SAI_User User Defined Protocol
Using the control structs of the CMSIS-Driver SAI, it is possible to create support for nearly all serial audio protocols
that are available today.
\image html driver_sai_user.png
The following properties can be configured for a user protocol:
- Data Size in bits (8..32)
- Data Bit Order: MSB first (default) or LSB first
- Clock Polarity:
- Driver on falling edge, Capture on rising edge (default)
- Driver on rising edge, Capture on falling edge
- Frame Length in bits
- Frame Sync Width in bits (default=1)
- Frame Sync Polarity: active high (default) or low
- Frame Sync Early: Sync signal one bit before the first bit of frame
- Slot Count: number of slots in frame (default=1)
- Slot Size: equal to data size (default) or 16 or 32-bit
- Slot Offset: offset of first data bit in slot (default=0)
For more information, refer to \ref ARM_SAI_Control that explains the different configuration options in more detail.
@{
*/
/**
\struct ARM_DRIVER_SAI
\details
The functions of the SAI driver are accessed by function pointers exposed by this structure.
Refer to \ref DriverFunctions for overview information.
Each instance of an SAI interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_SAI0 is the name of the access struct of the first instance (no. 0).
- \b Driver_SAI1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_SAI<i>n</i>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*****************************************************************************************************************/
/**
\struct ARM_SAI_CAPABILITIES
\details
An SAI driver can be implemented with different capabilities (for example protocol support). The data fields of this
structure encode the capabilities implemented by this driver. If a certain hardware peripheral is not able to handle one
of the protocols directly (not advertised using ARM_SAI_CAPABILITIES), then it might be possible to implement it using
the \ref Driver_SAI_User (if supported).
<b>Returned by:</b>
- \ref ARM_SAI_GetCapabilities
*****************************************************************************************************************/
/**
\struct ARM_SAI_STATUS
\details
Structure with information about the status of the SAI. The data fields encode busy flags and error flags.
<b>Returned by:</b>
- \ref ARM_SAI_GetStatus
*****************************************************************************************************************/
/**
\typedef ARM_SAI_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_SAI_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_SAI_Initialize
*******************************************************************************************************************/
/****** SAI specific error codes *****/
/**
\defgroup sai_execution_status Status Error Codes
\ingroup common_drv_gr
\brief Negative values indicate errors (SAI has specific codes in addition to common \ref execution_status).
\details
The SAI driver has additional status error codes that are listed below.
\note
- In case multiple errors exist, only the first encountered error will be reported.
- errors ARM_SAI_ERROR_BIT_ORDER, ARM_SAI_ERROR_FRAME_SYNC_xxx, ARM_SAI_ERROR_SLOT_xxx will only be reported in \ref Driver_SAI_User mode.
- The SAI driver also returns the common \ref execution_status.
@{
\def ARM_SAI_ERROR_SYNCHRONIZATION
The \b synchronization requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_PROTOCOL
The \b protocol requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_DATA_SIZE
The <b>data size</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_BIT_ORDER
The <b>bit order</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_MONO_MODE
The <b>mono mode</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_COMPANDING
The <b>companding</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_CLOCK_POLARITY
The <b>clock polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_AUDIO_FREQ
The <b>audio frequency</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_MCLK_PIN
The <b>MCLK pin</b> setting requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_MCLK_PRESCALER
The <b>MCLK prescaler</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_FRAME_LENGTH
The <b>frame length</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_FRAME_SYNC_WIDTH
The <b>frame sync width</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_FRAME_SYNC_POLARITY
The <b>frame sync polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_FRAME_SYNC_EARLY
The <b>frame sync early</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_SLOT_COUNT
The <b>slot count</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_SLOT_SIZE
The <b>slot size</b> requested with the function \ref ARM_SAI_Control is not supported.
\def ARM_SAI_ERROR_SLOT_OFFESET
The <b>slot offset</b> requested with the function \ref ARM_SAI_Control is not supported.
@}
*/
/****** SAI Event *****/
/**
\defgroup SAI_events SAI Events
\ingroup sai_interface_gr
\brief The SAI driver generates call back events that are notified via the function \ref ARM_SAI_SignalEvent.
\details
This section provides the event values for the \ref ARM_SAI_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_SAI_EVENT_SEND_COMPLETE
\def ARM_SAI_EVENT_RECEIVE_COMPLETE
\def ARM_SAI_EVENT_TX_UNDERFLOW
\def ARM_SAI_EVENT_RX_OVERFLOW
\def ARM_SAI_EVENT_FRAME_ERROR
@}
*/
/**
\defgroup sai_control SAI Control Codes
\ingroup sai_interface_gr
\brief Many parameters of the SAI driver are configured using the \ref ARM_SAI_Control function.
\details
@{
The various SAI control codes define:
- \ref sai_configure_control specifies SAI configuration
- \ref sai_controls specifies SAI controls
Refer to the \ref ARM_SAI_Control function for further details.
*/
/**
\defgroup sai_configure_control SAI Configuration
\ingroup sai_control
\brief Specify Transmitter/Receiver configuration.
\details
@{
Configuration is specified by ORing \b ARM_SAI_CONFIGURE_<i>x</i> with the following parameters:
- \ref sai_mode_control
- \ref sai_sync_control
- \ref sai_protocol_control
- \ref sai_data_bits_control
- \ref sai_bit_order_control
- \ref sai_mono_control
- \ref sai_clock_pol_control
- \ref sai_companding_control
- \ref sai_mclk_pin_control
Additional configuration specified by \em arg1:
- \ref sai_frame_control
- \ref sai_slot_control
Additional configuration specified by \em arg2:
- <b>Audio Frequency</b> (Master only)
- \ref sai_mclk_pres_control
\defgroup sai_mode_control SAI Mode
\ingroup sai_configure_control
\brief Defines Transmitter/Receiver mode.
\details
@{
\def ARM_SAI_MODE_MASTER
\def ARM_SAI_MODE_SLAVE
@}
\defgroup sai_sync_control SAI Synchronization
\ingroup sai_configure_control
\brief Defines Transmitter/Receiver synchronization.
\details
@{
\def ARM_SAI_ASYNCHRONOUS
\def ARM_SAI_SYNCHRONOUS
@}
\defgroup sai_protocol_control SAI Protocol
\ingroup sai_configure_control
\brief Defines Transmitter/Receiver protocol.
\details
@{
\def ARM_SAI_PROTOCOL_USER
\def ARM_SAI_PROTOCOL_I2S
\def ARM_SAI_PROTOCOL_MSB_JUSTIFIED
\def ARM_SAI_PROTOCOL_LSB_JUSTIFIED
\def ARM_SAI_PROTOCOL_PCM_SHORT
\def ARM_SAI_PROTOCOL_PCM_LONG
\def ARM_SAI_PROTOCOL_AC97
@}
\defgroup sai_data_bits_control SAI Data Size
\ingroup sai_configure_control
\brief Defines data size in bits (per channel/slot).
\details
@{
\def ARM_SAI_DATA_SIZE(n)
@}
\defgroup sai_bit_order_control SAI Bit Order
\ingroup sai_configure_control
\brief Defines the bit order.
\details
@{
\def ARM_SAI_MSB_FIRST
\def ARM_SAI_LSB_FIRST
@}
\defgroup sai_mono_control SAI Mono Mode
\ingroup sai_configure_control
\brief Defines mono mode.
\details
@{
\def ARM_SAI_MONO_MODE
@}
\defgroup sai_companding_control SAI Companding
\ingroup sai_configure_control
\brief Defines companding.
\details
@{
\def ARM_SAI_COMPANDING_NONE
\def ARM_SAI_COMPANDING_A_LAW
\def ARM_SAI_COMPANDING_U_LAW
@}
\defgroup sai_clock_pol_control SAI Clock Polarity
\ingroup sai_configure_control
\brief Defines clock polarity.
\details
@{
\def ARM_SAI_CLOCK_POLARITY_0
\def ARM_SAI_CLOCK_POLARITY_1
@}
\defgroup sai_frame_control SAI Frame
\ingroup sai_configure_control
\brief Defines frame.
\details
@{
\def ARM_SAI_FRAME_LENGTH(n)
\def ARM_SAI_FRAME_SYNC_WIDTH(n)
\def ARM_SAI_FRAME_SYNC_POLARITY_HIGH
\def ARM_SAI_FRAME_SYNC_POLARITY_LOW
\def ARM_SAI_FRAME_SYNC_EARLY
@}
\defgroup sai_slot_control SAI Slot
\ingroup sai_configure_control
\brief Defines data slots.
\details
@{
\def ARM_SAI_SLOT_COUNT(n)
\def ARM_SAI_SLOT_SIZE_DEFAULT
\def ARM_SAI_SLOT_SIZE_16
\def ARM_SAI_SLOT_SIZE_32
\def ARM_SAI_SLOT_OFFSET(n)
@}
\defgroup sai_mclk_pin_control SAI Master Clock Pin
\ingroup sai_configure_control
\brief Defines MCLK pin.
\details
@{
\def ARM_SAI_MCLK_PIN_INACTIVE
\def ARM_SAI_MCLK_PIN_OUTPUT
\def ARM_SAI_MCLK_PIN_INPUT
@}
\defgroup sai_mclk_pres_control SAI Master Clock Prescaler
\ingroup sai_configure_control
\brief Defines MCLK prescaler.
\details
@{
\def ARM_SAI_MCLK_PRESCALER(n)
@}
@}
*/
/**
\defgroup sai_controls SAI Controls
\ingroup sai_control
\brief Specifies controls.
\details
@{
\def ARM_SAI_CONFIGURE_TX
\sa ARM_SAI_Control
\def ARM_SAI_CONFIGURE_RX
\sa ARM_SAI_Control
\def ARM_SAI_CONTROL_TX
\sa ARM_SAI_Control; ARM_SAI_Send
\def ARM_SAI_CONTROL_RX
\sa ARM_SAI_Control; ARM_SAI_Receive
\def ARM_SAI_MASK_SLOTS_TX
\sa ARM_SAI_Control; ARM_SAI_Send
\def ARM_SAI_MASK_SLOTS_RX
\sa ARM_SAI_Control; ARM_SAI_Receive
\def ARM_SAI_ABORT_SEND
\sa ARM_SAI_Control; ARM_SAI_Send
\def ARM_SAI_ABORT_RECEIVE
\sa ARM_SAI_Control; ARM_SAI_Receive
@}
*/
/**
@}
*/
// end group SAI_control
//
// Function documentation
//
ARM_DRIVER_VERSION ARM_SAI_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)
\details
The function \b ARM_SAI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
\b Example:
\code
extern ARM_DRIVER_SAI Driver_SAI0;
ARM_DRIVER_SAI *drv_info;
void setup_sai (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_SAI0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void) {
return {0};
}
/**
\details
\fn ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)
The function \b ARM_SAI_GetCapabilities retrieves information about the capabilities in this driver implementation.
The data fields of the struct \ref ARM_SAI_CAPABILITIES encode various capabilities, for example
supported protocols, or if a hardware is capable to create signal events using the \ref ARM_SAI_SignalEvent
callback function.
\b Example:
\code
extern ARM_DRIVER_SAI Driver_SAI0;
ARM_DRIVER_SAI *drv_info;
void read_capabilities (void) {
ARM_SAI_CAPABILITIES drv_capabilities;
drv_info = &Driver_SAI0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*****************************************************************************************************************/
int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)
\details
The function \b ARM_SAI_Initialize initializes the SAI interface. It is called when the middleware component starts
operation.
The function performs the following operations:
- Initializes the required resources of the SAI interface.
- Registers the \ref ARM_SAI_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_SAI_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
*****************************************************************************************************************/
int32_t ARM_SAI_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_Uninitialize (void)
\details
The function \b ARM_SAI_Uninitialize de-initializes the resources of SAI interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_SAI_PowerControl allows you to control the power modes of the SAI interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*****************************************************************************************************************/
int32_t ARM_SAI_Send (const void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_Send (const void *data, uint32_t num)
\details
The function \b ARM_SAI_Send sends data to the SAI transmitter.
The function parameters specify the buffer with \a data and the number \a num of items to send.
The item size is defined by the data type which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for \token{8} data bits
- \em uint16_t when configured for \token{9..16} data bits
- \em uint32_t when configured for \token{17..32} data bits
Transmitter is enabled by calling \ref ARM_SAI_Control with \ref ARM_SAI_CONTROL_TX as the control parameter and \token{1} as
an argument. This starts the transmit engine which, generates a clock and frame sync signal in master mode and transmits the
data. In slave mode, clock and frame sync are generated by the external master. When mute is active, data is discarded and
zero values are transmitted.
Calling the function <b>ARM_SAI_Send</b> only starts the send operation. The function is non-blocking and returns as soon as
the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous transfer).
During the operation it is not allowed to call this function again. Also, the data buffer must stay allocated and the
contents of unsent data must not be modified. When the send operation is completed (requested number of items have been
sent), the event \ref ARM_SAI_EVENT_SEND_COMPLETE is generated. Progress of the send operation can be monitored by reading
the number of already sent items by calling the function \ref ARM_SAI_GetTxCount.
The status of the transmitter can also be monitored by calling the function \ref ARM_SAI_GetStatus and checking the \em tx_busy flag,
which indicates if a transmission is still in progress.
If the transmitter is enabled and data is to be sent but the send operation has not been started yet, then the event
\ref ARM_SAI_EVENT_TX_UNDERFLOW is generated.
If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
The send operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_SEND.
*****************************************************************************************************************/
int32_t ARM_SAI_Receive (void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_Receive (void *data, uint32_t num)
\details
The function \b ARM_SAI_Receive is used to receive data from the SAI receiver. The function parameters specify the buffer for
\a data and the number \a num of items to receive. The item size is defined by the data type, which depends on the configured
number of data bits.
Data type is:
- \em uint8_t when configured for \token{8} data bits
- \em uint16_t when configured for \token{9..16} data bits
- \em uint32_t when configured for \token{17..32} data bits
The receiver is enabled by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_CONTROL_RX and the value \token{1}
for the parameter \em arg1. This starts the receive engine, which generates a clock and frame sync signal in master mode and receives
data. In slave mode, clock and frame sync are generated by the external master.
Calling the function <b>ARM_SAI_Receive</b> only starts the receive operation. The function is non-blocking and returns as
soon as the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous
transfer). During the operation, it is not allowed to call this function again. The data buffer must also stay allocated.
When receive operation is completed (the requested number of items have been received), the
\ref ARM_SAI_EVENT_RECEIVE_COMPLETE event is generated. Progress of the receive operation can also be monitored by reading
the number of items already received by calling the function \ref ARM_SAI_GetRxCount.
The status of the receiver can also be monitored by calling the function \ref ARM_SAI_GetStatus and checking the \em rx_busy flag, which
indicates whether a reception is still in progress.
When the receiver is enabled and data is received but the receive operation has not been started yet, then the event
\ref ARM_SAI_EVENT_RX_OVERFLOW is generated.
If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
The receive operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_RECEIVE.
*****************************************************************************************************************/
uint32_t ARM_SAI_GetTxCount (void) {
return 0;
}
/**
\fn uint32_t ARM_SAI_GetTxCount (void)
\details
The function \b ARM_SAI_GetTxCount returns the number of the currently transmitted data items during an \ref ARM_SAI_Send
operation.
*****************************************************************************************************************/
uint32_t ARM_SAI_GetRxCount (void) {
return 0;
}
/**
\fn uint32_t ARM_SAI_GetRxCount (void)
\details
The function \b ARM_SAI_GetRxCount returns the number of the currently received data items during an \ref ARM_SAI_Receive
operation.
*****************************************************************************************************************/
int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)
\details
The function \b ARM_SAI_Control controls the SAI interface and executes various operations.
The parameter \em control specifies the operation. Values are listed in the table <a href="#sai_contrl_tab"><b>Parameter <i>control</i></b></a>.\n
The parameter \em arg1 provides, depending on the operation, additional information or sets values.
Refer to table <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>. \n
The parameter \em arg2 provides, depending on the operation and/or \em arg1, additional information or sets values.
The driver provides a receiver/transmitter pair of signals.
In asynchronous operation mode, they operate completely independent from each other.
In synchronous operation mode, the synchronous channel uses the Clock (SCK) and Frame Sync (WS) signal from the asynchronous one
(control category <a href="#sai_sync"><b>Synchronization</b></a>).
The clock polarity can be set for every protocol, regardless whether it is already predefined for I2S, MSB/LSB Jusitified
(control category <a href="#sai_clk_polarity"><b>Clock Polarity</b></a>).
A master clock provides a faster clock from which the frame can be derived (usually 256 x faster than the normal frame clock).
You can use a master clock only in master mode. A slave will always have only one clock
(control category <a href="#master_clock"><b>Master Clock pin (MCLK)</b></a>).
\anchor sai_contrl_tab
The table lists the operation values for \em control. Values from different categories can be ORed.
<table class="cmtable" summary="">
<tr><th> Parameter \em control </th><th> Bit </th><th> Category </th>
<th> Description </th></tr>
<tr><td> \ref ARM_SAI_CONFIGURE_TX </td><td rowspan="8" style="text-align:right"> 0..7 </td><td rowspan="8"> Operation </td>
<td> Configure transmitter. \em arg1 (see <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>) and \em arg2 provide additional configuration. </td></tr>
<tr><td> \ref ARM_SAI_CONFIGURE_RX </td>
<td> Configure receiver. \em arg1 (see <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>) and \em arg2 provide additional configuration. </td></tr>
<tr><td> \ref ARM_SAI_CONTROL_TX </td>
<td> Enable or disable transmitter and control mute;
\em arg1.0 : \token{0=disable (default); 1=enable;} \em arg1.1 : \token{mute} (see \ref ARM_SAI_Send) </td></tr>
<tr><td> \ref ARM_SAI_CONTROL_RX </td>
<td> Enable or disable receiver; \em arg1.0 : \token{0=disable (default); 1=enable} (see \ref ARM_SAI_Receive) </td></tr>
<tr><td> \ref ARM_SAI_MASK_SLOTS_TX </td>
<td> Mask transmitter slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default. </td></tr>
<tr><td> \ref ARM_SAI_MASK_SLOTS_RX </td>
<td> Mask receiver slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default. </td></tr>
<tr><td> \ref ARM_SAI_ABORT_SEND </td>
<td> Abort send operation (see \ref ARM_SAI_Send). </td></tr>
<tr><td> \ref ARM_SAI_ABORT_RECEIVE </td>
<td> Abort receive operation (see \ref ARM_SAI_Receive). </td></tr>
<tr><td> \ref ARM_SAI_MODE_MASTER </td><td rowspan="2" style="text-align:right"> 8 </td><td rowspan="2"> Mode </td>
<td> Master mode. \em arg2 specifies the audio frequency in [Hz]. You can also set the <a href="#master_clock"><b>Master Clock pin</b></a>.</td></tr>
<tr><td> \ref ARM_SAI_MODE_SLAVE (default) </td>
<td> Slave mode. </td></tr>
<tr><td> \ref ARM_SAI_ASYNCHRONOUS (default) \anchor sai_sync </td><td rowspan="2" style="text-align:right"> 9 </td><td rowspan="2"> Synchronization </td>
<td> Asynchronous operation using own clock and sync signal. </td></tr>
<tr><td> \ref ARM_SAI_SYNCHRONOUS </td>
<td> Synchronous operation using clock and sync signal from other transmitter/receiver. </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_USER (default) </td><td rowspan="7" style="text-align:right"> 10..12 </td><td rowspan="7"> Protocol </td>
<td> User defined </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_I2S </td>
<td> I2C </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_MSB_JUSTIFIED </td>
<td> MSB (left) justified </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_LSB_JUSTIFIED </td>
<td> LSB (right) justified </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_PCM_SHORT </td>
<td> PCM with short frame </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_PCM_LONG </td>
<td> PCM with long frame </td></tr>
<tr><td> \ref ARM_SAI_PROTOCOL_AC97 </td>
<td> AC'97 </td></tr>
<tr><td> \ref ARM_SAI_DATA_SIZE(n) </td><td style="text-align:right"> 13..17 </td><td> Data Size </td>
<td> Data size in bits; the range for \em n is \token{8..32}. See also: <a href="#frame_slot_size"><b>Frame Slot Size</b></a>. </td></tr>
<tr><td> \ref ARM_SAI_MSB_FIRST </td><td rowspan="2" style="text-align:right"> 18 </td><td rowspan="2"> Bit Order </td>
<td> Data is transferred with MSB first. </td></tr>
<tr><td> \ref ARM_SAI_LSB_FIRST </td>
<td> Data is transferred with LSB first (User protocol only, ignored otherwise). </td></tr>
<tr><td> \ref ARM_SAI_MONO_MODE </td><td style="text-align:right"> 19 </td><td> Mono Mode</td>
<td> Only for I2S, MSB/LSB justified.
When using \ref Driver_SAI_I2S in mono mode, only data for a single channel is sent to and received from the driver.
Hardware will duplicate the data for the second channel on transmit and ignore the second channel on receive. </td></tr>
<tr><td> \ref ARM_SAI_COMPANDING_NONE (default) </td><td rowspan="3" style="text-align:right"> 20..22 </td><td rowspan="3"> Companding </td>
<td> No companding </td></tr>
<tr><td> \ref ARM_SAI_COMPANDING_A_LAW </td>
<td> A-Law companding (8-bit data) </td></tr>
<tr><td> \ref ARM_SAI_COMPANDING_U_LAW </td>
<td> u-Law companding (8-bit data) </td></tr>
<tr><td> \ref ARM_SAI_CLOCK_POLARITY_0&nbsp;(default) \anchor sai_clk_polarity > </td><td rowspan="2" style="text-align:right"> 23 </td><td rowspan="2"> Clock Polarity </td>
<td> Drive on falling edge, capture on rising edge. </td></tr>
<tr><td> \ref ARM_SAI_CLOCK_POLARITY_1 \anchor master_clock </td>
<td> Drive on rising edge, capture on falling edge. </td></tr>
<tr><td> \ref ARM_SAI_MCLK_PIN_INACTIVE&nbsp;(default) </td><td rowspan="3" style="text-align:right"> 24..26 </td><td rowspan="3"> Master Clock pin (MCLK) </td>
<td> MCLK not used. </td></tr>
<tr><td> \ref ARM_SAI_MCLK_PIN_OUTPUT </td>
<td> MCLK is output (Master mode only). </td></tr>
<tr><td> \ref ARM_SAI_MCLK_PIN_INPUT </td>
<td> MCLK is input (Master mode only). </td></tr>
</table>
\anchor sai_arg1_tab
The parameter \em arg1 provides frame-specific values depending on the \em control operation. Values from different categories can be ORed.
<table class="cmtable" summary="">
<tr><th nowrap> Parameter \em arg1 </th>
<th style="text-align:right"> Bit </th>
<th> Category </th>
<th> Description </th></tr>
<tr><td> \ref ARM_SAI_FRAME_LENGTH(n) </td>
<td style="text-align:right"> 0..9 </td>
<td> Frame Length </td>
<td> Frame length in bits; the possible range for \em n is \token{8..1024}; default depends on protocol and data. </td></tr>
<tr><td> \ref ARM_SAI_FRAME_SYNC_WIDTH(n)</td>
<td style="text-align:right"> 10..17 </td>
<td> Frame Sync Width </td>
<td> Frame Sync width in bits; the possible range for \em n is \token{1..256}; \token{default=1}; User protocol only, ignored otherwise. </td></tr>
<tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_HIGH </td>
<td rowspan="2" style="text-align:right"> 18 </td>
<td rowspan="2" style="white-spaces:nowrap"> Frame Sync Polarity </td>
<td> Frame Sync is active high (default). </td></tr>
<tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_LOW </td>
<td> Frame Sync is active low (User protocol only, ignored otherwise). </td></tr>
<tr><td> \ref ARM_SAI_FRAME_SYNC_EARLY </td>
<td style="text-align:right"> 19 </td>
<td> Frame Sync Early </td>
<td> Frame Sync one bit before the first bit of the frame (User protocol only, ignored otherwise). </td></tr>
<tr><td> \ref ARM_SAI_SLOT_COUNT(n) </td>
<td style="text-align:right"> 20..24 </td>
<td> Frame Sync Count </td>
<td> Number of slots in frame; the possible range for \em n is \token{1..32}; default=\token{1}; User protocol only, ignored otherwise. </td></tr>
<tr><td> \ref ARM_SAI_SLOT_SIZE_DEFAULT \anchor frame_slot_size </td>
<td rowspan="3" style="text-align:right"> 25..26 </td>
<td rowspan="3"> Frame Slot Size </td>
<td> Slot size is equal to data size (default). </td></tr>
<tr><td> \ref ARM_SAI_SLOT_SIZE_16 </td>
<td> Slot size is \token{16 bits} (User protocol only, ignored otherwise). </td></tr>
<tr><td> \ref ARM_SAI_SLOT_SIZE_32 </td>
<td> Slot size is \token{32 bits} (User protocol only, ignored otherwise). </td></tr>
<tr><td> \ref ARM_SAI_SLOT_OFFSET(n) </td>
<td style="text-align:right"> 27..31 </td>
<td> Frame Slot Offset </td>
<td> Offset of first data bit in slot; The range for \em n is \token{0..31}; default=\token{0}; User protocol only, ignored otherwise. </td></tr>
</table>
\anchor mckl_prescaler
Depending on the \em control operation, the parameter \em arg2 specifies the Master Clock (MCLK) prescaler and calculates the audio frequency automatically.
Parameter \em arg2 | MCLK Prescaler
:----------------------------------------|:--------------------------------------------
\ref ARM_SAI_MCLK_PRESCALER(n) | MCLK prescaler; Audio frequency = MCLK/n; the range for \em n is \token{1..4096}; default=\token{1}.
\b Example
\code
extern ARM_DRIVER_SAI Driver_SAI0;
// configure Transmitter to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_TX |
ARM_SAI_MODE_MASTER |
ARM_SAI_ASYNCHRONOUS |
ARM_SAI_PROTOCOL_I2S |
ARM_SAI_DATA_SIZE(16), 0, 16000);
// configure Receiver to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_RX |
ARM_SAI_MODE_MASTER |
ARM_SAI_ASYNCHRONOUS |
ARM_SAI_PROTOCOL_I2S |
ARM_SAI_DATA_SIZE(16), 0, 16000);
// enable Transmitter
status = Driver_SAI0.Control(ARM_SAI_CONTROL_TX, 1, 0);
// enable Receiver
status = Driver_SAI0.Control(ARM_SAI_CONTROL_RX, 1, 0);
\endcode
*****************************************************************************************************************/
ARM_SAI_STATUS ARM_SAI_GetStatus (void) {
return { 0 };
}
/**
\fn ARM_SAI_STATUS ARM_SAI_GetStatus (void)
\details
The function \b ARM_SAI_GetStatus retrieves the current SAI interface status.
*****************************************************************************************************************/
void ARM_SAI_SignalEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_SAI_SignalEvent (uint32_t event)
\details
The function \b ARM_SAI_SignalEvent is a callback function registered by the function \ref ARM_SAI_Initialize.
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
The following events can be generated:
Parameter \em event | Bit | Description
------------------------------------------ |:---:|:-----------
\ref ARM_SAI_EVENT_SEND_COMPLETE | 0 | Occurs after call to \ref ARM_SAI_Send to indicate that all the data has been sent (or queued in transmit buffers). The driver is ready for the next call to \ref ARM_SAI_Send.
\ref ARM_SAI_EVENT_RECEIVE_COMPLETE | 1 | Occurs after call to \ref ARM_SAI_Receive to indicate that all the data has been received. The driver is ready for the next call to \ref ARM_SAI_Receive.
\ref ARM_SAI_EVENT_TX_UNDERFLOW | 2 | Occurs when data is to be sent but send operation has not been started. Data field \em tx_underflow = \token{1} of \ref ARM_SAI_STATUS.
\ref ARM_SAI_EVENT_RX_OVERFLOW | 3 | Occurs when data is received but receive operation has not been started. Data field \em rx_underflow = \token{1} of \ref ARM_SAI_STATUS.
\ref ARM_SAI_EVENT_FRAME_ERROR | 4 | Occurs in slave mode when invalid synchronization frame is detected. Data field \em event_frame_error = \token{1} of \ref ARM_SAI_STATUS.
*****************************************************************************************************************/
/**
@}
*/
// End SAI Interface

View File

@ -0,0 +1,723 @@
/**
\defgroup spi_interface_gr SPI Interface
\brief Driver API for SPI Bus Peripheral (%Driver_SPI.h)
\details
The <b>Serial Peripheral Interface Bus</b> (SPI) implements a synchronous serial bus for data exchange. In microcontroller (MCU) applications,
the interface is often used to connect peripheral components at board (PCB) level. SPI devices can operate as Master (SCLK and SS are outputs) or
Slave (SCLK and SS are inputs). Wikipedia offers more information about
the <a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus" target="_blank"><b>Serial Peripheral Interface Bus</b></a>.
<b>Block Diagram</b>
The SPI Driver API defines a <b>SPI</b> interface for middleware components. The SPI Driver supports multiple
slaves, but if only one slave is connected, then the Slave Select signal can be omitted.
\image html SPI_Master1Slaves.png "SPI Master connected to a single slave"
<p>&nbsp;</p>
\image html SPI_Master3Slaves.png "SPI Master connected to 3 slaves"
The SPI Driver functions control the following SPI signal lines.
Signal | Name | Description
-------|-------------------------------------|------------------------------------------------------------------------------
SS | Slave Select (active low) | Selects the slave. This signal can be part of the SPI peripheral or implemented using a GPIO pin.
MOSI | Master&nbsp;Out,&nbsp;Slave&nbsp;In | MOSI output of the Master connects to MOSI input of the Slave.
SCLK | Serial Clock | Serial clock output from Master. Controls the transfer speed and when data are sent and read.
MISO | Master&nbsp;In,&nbsp;Slave&nbsp;Out | MISO input of the Master connects to MISO output of the Slave.
<b>SPI API</b>
The following header files define the Application Programming Interface (API) for the SPI interface:
- \b %Driver_SPI.h : Driver API for SPI Bus Peripheral
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_SPI : access struct for SPI driver functions
<b>Example Code</b>
The following example code shows the usage of the SPI interface.
\include SPI_Demo.c
@{
*/
/**
\struct ARM_DRIVER_SPI
\details
The functions of the SPI driver are accessed by function pointers exposed by this structure.
Refer to \ref DriverFunctions for overview information.
Each instance of a SPI interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_SPI0 is the name of the access struct of the first instance (no. 0).
- \b Driver_SPI1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_SPI<i>n</i>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
**************************************************************************************************************************/
/**
\struct ARM_SPI_CAPABILITIES
\details
A SPI driver can be implemented with different capabilities.
The data fields of this structure encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_SPI_GetCapabilities
**************************************************************************************************************************/
/**
\struct ARM_SPI_STATUS
\details
Structure with information about the status of the SPI. The data fields encode busy flag and error flags.
<b>Returned by:</b>
- \ref ARM_SPI_GetStatus
*****************************************************************************************************************/
/**
\typedef ARM_SPI_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_SPI_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_SPI_Initialize
*******************************************************************************************************************/
/**
\defgroup spi_execution_status Status Error Codes
\ingroup common_drv_gr
\brief Negative values indicate errors (SPI has specific codes in addition to common \ref execution_status).
\details
The SPI driver has additional status error codes that are listed below.
Note that the SPI driver also returns the common \ref execution_status.
@{
\def ARM_SPI_ERROR_MODE
The \b mode requested with the function \ref ARM_SPI_Control is not supported by this driver.
\def ARM_SPI_ERROR_FRAME_FORMAT
The <b>frame format</b> requested with the function \ref ARM_SPI_Control is not supported by this driver.
\def ARM_SPI_ERROR_DATA_BITS
The number of <b>data bits</b> requested with the function \ref ARM_SPI_Control is not supported by this driver.
\def ARM_SPI_ERROR_BIT_ORDER
The <b>bit order</b> requested with the function \ref ARM_SPI_Control is not supported by this driver.
\def ARM_SPI_ERROR_SS_MODE
The <b>slave select mode</b> requested with the function \ref ARM_SPI_Control is not supported by this driver.
@}
*/
/**
\defgroup SPI_events SPI Events
\ingroup spi_interface_gr
\brief The SPI driver generates call back events that are notified via the function \ref ARM_SPI_SignalEvent.
\details
This section provides the event values for the \ref ARM_SPI_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_SPI_EVENT_TRANSFER_COMPLETE
\def ARM_SPI_EVENT_DATA_LOST
\def ARM_SPI_EVENT_MODE_FAULT
@}
*/
//
// Functions
//
ARM_DRIVER_VERSION ARM_SPI_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_SPI_GetVersion (void)
\details
The function \b ARM_SPI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_SPI Driver_SPI0;
ARM_DRIVER_SPI *drv_info;
void setup_spi (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_SPI0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
**************************************************************************************************************************/
ARM_SPI_CAPABILITIES ARM_SPI_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_SPI_CAPABILITIES ARM_SPI_GetCapabilities (void)
\details
The function \b ARM_SPI_GetCapabilities returns information about the capabilities in this driver implementation.
The data fields of the structure \ref ARM_SPI_CAPABILITIES encode various capabilities, for example
supported modes.
Example:
\code
extern ARM_DRIVER_SPI Driver_SPI0;
ARM_DRIVER_SPI *drv_info;
void read_capabilities (void) {
ARM_SPI_CAPABILITIES drv_capabilities;
drv_info = &Driver_SPI0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
**************************************************************************************************************************/
int32_t ARM_SPI_Initialize (ARM_SPI_SignalEvent_t cb_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Initialize (ARM_SPI_SignalEvent_t cb_event)
\details
The function \b ARM_SPI_Initialize initializes the SPI interface.
The parameter \em cb_event is a pointer to the \ref ARM_SPI_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
The function is called when the middleware component starts operation and performs the following:
- Initializes the resources needed for the SPI interface.
- Registers the \ref ARM_SPI_SignalEvent callback function.
\b Example:
- see \ref spi_interface_gr - Driver Functions
**************************************************************************************************************************/
int32_t ARM_SPI_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Uninitialize (void)
\details
The function \b ARM_SPI_Uninitialize de-initializes the resources of SPI interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
**************************************************************************************************************************/
int32_t ARM_SPI_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_SPI_PowerControl controls the power modes of the SPI interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
**************************************************************************************************************************/
int32_t ARM_SPI_Send (const void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Send (const void *data, uint32_t num)
\details
This function \b ARM_SPI_Send is used to send data to the SPI transmitter (received data is ignored).
The parameter \em data specifies the data buffer. \n
The parameter \em num specifies the number of items to send. \n
The item size is defined by the data type, which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 1..8 data bits
- \em uint16_t when configured for 9..16 data bits
- \em uint32_t when configured for 17..32 data bits
Calling the function \b ARM_SPI_Send only starts the send operation.
When in slave mode, the operation is only registered and started when the master starts the transfer.
The function is non-blocking and returns as soon as the driver has started the operation
(driver typically configures DMA or the interrupt system for continuous transfer).
During the operation it is not allowed to call this function or any other data transfer function again.
Also the data buffer must stay allocated and the contents of unsent data must not be modified.
When send operation is completed (requested number of items sent), the \ref ARM_SPI_EVENT_TRANSFER_COMPLETE event is generated.
Progress of send operation can also be monitored by reading the number of items already sent by calling \ref ARM_SPI_GetDataCount.
Status of the transmitter can also be monitored by calling the \ref ARM_SPI_GetStatus and checking the \em busy data field,
which indicates if transmission is still in progress or pending.
When in master mode and configured to monitor slave select and the slave select gets deactivated during transfer,
then the SPI mode changes to inactive and the \ref ARM_SPI_EVENT_MODE_FAULT event is generated (instead of \ref ARM_SPI_EVENT_TRANSFER_COMPLETE).
When in slave mode but send/receive/transfer operation is not started and data is sent/requested by the master,
then the \ref ARM_SPI_EVENT_DATA_LOST event is generated.
Send operation can be aborted by calling \ref ARM_SPI_Control with \ref ARM_SPI_ABORT_TRANSFER as the control parameter.
**************************************************************************************************************************/
int32_t ARM_SPI_Receive (void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Receive (void *data, uint32_t num)
\details
The function \b ARM_SPI_Receive is used to receive data
(transmits the default value as specified by \ref ARM_SPI_Control with \ref ARM_SPI_SET_DEFAULT_TX_VALUE as control parameter).
The parameter \em data specifies the data buffer. \n
The parameter \em num specifies the number of items to receive. \n
The item size is defined by the data type, which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 1..8 data bits
- \em uint16_t when configured for 9..16 data bits
- \em uint32_t when configured for 17..32 data bits
Calling the function \b ARM_SPI_Receive only starts the receive operation.
The function is non-blocking and returns as soon as the driver has started the operation
(driver typically configures DMA or the interrupt system for continuous transfer).
When in slave mode, the operation is only registered and started when the master starts the transfer.
During the operation it is not allowed to call this function or any other data transfer function again. Also the data buffer must stay allocated.
When receive operation is completed (requested number of items received), the \ref ARM_SPI_EVENT_TRANSFER_COMPLETE event is generated.
Progress of receive operation can also be monitored by reading the number of items already received by calling \ref ARM_SPI_GetDataCount.
Status of the receiver can also be monitored by calling the \ref ARM_SPI_GetStatus and checking the \em busy data field,
which indicates if reception is still in progress or pending.
When in master mode and configured to monitor slave select and the slave select gets deactivated during transfer,
then the SPI mode changes to inactive and the \ref ARM_SPI_EVENT_MODE_FAULT event is generated (instead of \ref ARM_SPI_EVENT_TRANSFER_COMPLETE).
When in slave mode but send/receive/transfer operation is not started and data is sent/requested by the master,
then the \ref ARM_SPI_EVENT_DATA_LOST event is generated.
Receive operation can be aborted by calling \ref ARM_SPI_Control with \ref ARM_SPI_ABORT_TRANSFER as the control parameter.
**************************************************************************************************************************/
int32_t ARM_SPI_Transfer (const void *data_out, void *data_in, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Transfer (const void *data_out, void *data_in, uint32_t num)
\details
The function \b ARM_SPI_Transfer transfers data via SPI. It synchronously sends data to the SPI transmitter and receives data from the SPI receiver.
The parameter \em data_out is a pointer to the buffer with data to send. \n
The parameter \em data_in is a pointer to the buffer which receives data. \n
The parameter \em num specifies the number of items to transfer. \n
The item size is defined by the data type which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 1..8 data bits
- \em uint16_t when configured for 9..16 data bits
- \em uint32_t when configured for 17..32 data bits
Calling the function \b ARM_SPI_Transfer only starts the transfer operation.
The function is non-blocking and returns as soon as the driver has started the operation
(driver typically configures DMA or the interrupt system for continuous transfer).
When in slave mode, the operation is only registered and started when the master starts the transfer.
During the operation it is not allowed to call this function or any other data transfer function again.
Also the data buffers must stay allocated and the contents of unsent data must not be modified.
When transfer operation is completed (requested number of items transferred), the \ref ARM_SPI_EVENT_TRANSFER_COMPLETE event is generated.
Progress of transfer operation can also be monitored by reading the number of items already transferred by calling \ref ARM_SPI_GetDataCount.
Status of the transmitter and receiver can also be monitored by calling the \ref ARM_SPI_GetStatus and checking the \em busy flag.
When in master mode and configured to monitor slave select and the slave select gets deactivated during transfer,
then the SPI mode changes to inactive and the \ref ARM_SPI_EVENT_MODE_FAULT event is generated (instead of \ref ARM_SPI_EVENT_TRANSFER_COMPLETE).
When in slave mode but send/receive/transfer operation is not started and data is sent/requested by the master,
then the \ref ARM_SPI_EVENT_DATA_LOST event is generated.
Transfer operation can also be aborted by calling \ref ARM_SPI_Control with \ref ARM_SPI_ABORT_TRANSFER as the control parameter.
**************************************************************************************************************************/
uint32_t ARM_SPI_GetDataCount (void) {
return 0;
}
/**
\fn uint32_t ARM_SPI_GetDataCount (void)
\details
The function \b ARM_SPI_GetDataCount returns the number of currently transferred data items
during \ref ARM_SPI_Send, \ref ARM_SPI_Receive and \ref ARM_SPI_Transfer operation.
*****************************************************************************************************************/
int32_t ARM_SPI_Control (uint32_t control, uint32_t arg) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_SPI_Control (uint32_t control, uint32_t arg)
\details
The function \b ARM_SPI_Control controls the SPI interface settings and executes various operations.
The parameter \em control is a bit mask that specifies various operations.
- Controls form different categories can be ORed.
- If one control is omitted, then the default value of that category is used.
- Miscellaneous controls cannot be combined.
The parameter \em arg provides (depending on the parameter \em control) additional information, for example the Bus Speed.
<table class="cmtable" summary="">
<tr><th> Parameter \em control </th>
<th style="text-align:right"> Bit </th>
<th> Category </th>
<th> Description
</th></tr>
<tr><td> \ref ARM_SPI_MODE_INACTIVE </td>
<td rowspan="3" style="text-align:right"> 0..7 </td>
<td rowspan="3"> \anchor spi_mode_tab Mode Controls </td>
<td> Set SPI to inactive.
</td></tr>
<tr><td> \ref ARM_SPI_MODE_MASTER </td>
<td> Set the SPI Master (Output on MOSI, and the Input on MISO); \em arg = Bus Speed in \token{bps}
</td></tr>
<tr><td> \ref ARM_SPI_MODE_SLAVE </td>
<td> Set the SPI Slave (Output on MISO, and the Input on MOSI)
</td></tr>
<tr><td> \ref ARM_SPI_CPOL0_CPHA0 (default) </td>
<td rowspan="6" style="text-align:right"> 8..11 </td>
<td rowspan="6"> Clock Polarity <br> (Frame Format) </td><td> CPOL=\token{0} and CPHA=\token{0}: Clock Polarity 0, Clock Phase 0 </td>
</tr>
<tr><td> \ref ARM_SPI_CPOL0_CPHA1 </td>
<td> CPOL=\token{0} and CPHA=\token{1}: Clock Polarity 0, Clock Phase 1
</td></tr>
<tr><td> \ref ARM_SPI_CPOL1_CPHA0 </td>
<td> CPOL=\token{1} and CPHA=\token{0}: Clock Polarity 1, Clock Phase 0
</td></tr>
<tr><td> \ref ARM_SPI_CPOL1_CPHA1 </td>
<td> CPOL=\token{1} and CPHA=\token{1}: Clock Polarity 1, Clock Phase 1
</td></tr>
<tr><td> \ref ARM_SPI_TI_SSI </td>
<td> Specifies that the frame format corresponds to the Texas Instruments Frame Format
</td></tr>
<tr><td> \ref ARM_SPI_MICROWIRE </td>
<td> Specifies that the frame format corresponds to the National Semiconductor Microwire Frame Format
</td></tr>
<tr><td> \ref ARM_SPI_DATA_BITS(n) </td>
<td style="text-align:right"> 12..17 </td>
<td> Data Bits </td>
<td> Set the number of bits per SPI frame; range for \em n = \token{1..32}.
This is the minimum required parameter.
</td></tr>
<tr><td> \ref ARM_SPI_MSB_LSB (default) </td>
<td rowspan="2" style="text-align:right"> 18 </td>
<td rowspan="2"> Bit Order </td>
<td> Set the bit order from MSB to LSB
</td></tr>
<tr><td> \ref ARM_SPI_LSB_MSB </td>
<td> Set the bit order from LSB to MSB
</td></tr>
<tr><td nowrap>\ref ARM_SPI_SS_MASTER_UNUSED (default) </td>
<td rowspan="6" style="text-align:right"> 19..21 </td>
<td rowspan="6"> Slave Select
<br>when Master
<div style="min-height:200px">&nbsp;</div>
Must be used with the corresponding master or slave controls from category <a href="#spi_mode_tab"><b>Mode Controls</b></a>.
<div style="min-height:200px">&nbsp;</div>
Slave Select
<br>when Slave
</td>
<td>Set the Slave Select mode for the master to <b>Not used</b>. Used with Mode Control ARM_SPI_MODE_MASTER.
Master does not drive or monitor the SS line. For example, when connecting to a single slave,
which has the SS line connected to a fixed low level.
</td></tr>
<tr><td>\ref ARM_SPI_SS_MASTER_SW</td>
<td>Set the Slave Select mode for the master to <b>Software controlled</b>. Used with Mode Control ARM_SPI_MODE_MASTER.
The Slave Select line is configured as output and controlled via the Miscellaneous Control \ref ARM_SPI_CONTROL_SS.
By default, the line it is not active (high), and is not affected by transfer-, send-, or receive functions.
</td></tr>
<tr><td>\ref ARM_SPI_SS_MASTER_HW_OUTPUT</td>
<td>Set the Slave Select mode for the master to <b>Hardware controlled Output</b>. Used with Mode Control ARM_SPI_MODE_MASTER.
The Slave Select line is configured as output and controlled by hardware.
The line gets activated or deactivated automatically by the hardware for transfers and is not controlled by the Miscellaneous Control \ref ARM_SPI_CONTROL_SS.
When exactly the line is activated or deactivated is hardware dependent. Typically, the hardware will activate the line before starting the transfer
and deactivate it after the transfer completes. Some hardware will keep the line active as long as the SPI stays master.
\note Some devices require that the SS signal is strictly defined regarding transfers. Refer to the documentation of your device.
</td></tr>
<tr>
<td>\ref ARM_SPI_SS_MASTER_HW_INPUT</td>
<td>Set the Slave Select mode for the master to <b>Hardware monitored Input</b>. Used with Mode Control ARM_SPI_MODE_MASTER.
Used in multi-master configuration where a master does not drive the Slave Select when driving the bus, but rather monitors it.
When another master activates this line, the active master backs off. This is called Mode Fault. Slave Select is configured as input
and hardware only monitors the line. When the line is activated externally while we are master,
it presents a Mode Fault (\ref ARM_SPI_EVENT_MODE_FAULT) and the SPI switches to inactive mode.
</td></tr>
<tr><td>\ref ARM_SPI_SS_SLAVE_HW (default)</td>
<td>Set the Slave Select mode for the slave to <b>Hardware monitored</b>. Used with Mode Control ARM_SPI_MODE_SLAVE.
Hardware monitors the Slave Select line and accepts transfers only when the line is active. Transfers are ignored while the Slave Select line is inactive.
</td></tr>
<tr><td>\ref ARM_SPI_SS_SLAVE_SW</td>
<td>Set the Slave Select mode for the slave to <b>Software controlled</b>. Used with Mode Control ARM_SPI_MODE_SLAVE.
Used only when the Slave Select line is not used. For example, when a single master and slave are connected in the system
then the Slave Select line is not needed. Software controls if the slave is responding or not (by default it is not responding).
Software enables or disables transfers by using the Miscellaneous Control \ref ARM_SPI_CONTROL_SS.
</td></tr>
<tr><td> \ref ARM_SPI_SET_BUS_SPEED </td>
<td rowspan="5" style="text-align:right"> 0..21 </td>
<td rowspan="5"> Miscellaneous Controls <br>(cannot be ORed)</td>
<td>Set the bus speed; \em arg= Bus Speed in \token{bps}
</td></tr>
<tr><td> \ref ARM_SPI_GET_BUS_SPEED </td>
<td> Get the bus speed; Return values >= \token{0} represent the bus speed in \token{bps}. Negative values are \ref spi_execution_status.
</td></tr>
<tr><td> \ref ARM_SPI_SET_DEFAULT_TX_VALUE </td>
<td> Set the default transmission value; the parameter \em arg sets the value
</td></tr>
<tr><td> \ref ARM_SPI_CONTROL_SS </td>
<td> Control the Slave Select signal (SS); the values for the parameter \em arg are: \token{ARM_SPI_SS_INACTIVE; ARM_SPI_SS_ACTIVE}
</td></tr>
<tr><td> \ref ARM_SPI_ABORT_TRANSFER </td>
<td> Abort the current data transfer
</td></tr>
</table>
\b Example
\code
extern ARM_DRIVER_SPI Driver_SPI0;
// configure: SPI master | clock polarity=1, clock phase=1 | bits per frame=16 | bus speed : 1000000
status = Driver_SPI0.Control(ARM_SPI_MODE_MASTER |
ARM_SPI_CPOL1_CPHA1 |
ARM_SPI_DATA_BITS(16), 1000000);
\endcode
*****************************************************************************************************************/
ARM_SPI_STATUS ARM_SPI_GetStatus (void) {
return { 0 };
}
/**
\fn ARM_SPI_STATUS ARM_SPI_GetStatus (void)
\details
The function \b ARM_SPI_GetStatus returns the current SPI interface status.
*****************************************************************************************************************/
void ARM_SPI_SignalEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_SPI_SignalEvent (uint32_t event)
\details
The function \b ARM_SPI_SignalEvent is a callback function registered by the function \ref ARM_SPI_Initialize.
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_SPI_CAPABILITIES, which can be retrieved with the function \ref ARM_SPI_GetCapabilities.
The following events can be generated:
<table class="cmtable" summary="">
<tr>
<th> Parameter \em event </th><th> Bit </th><th> Description </th>
<th> supported when ARM_SPI_CAPABILITIES </th>
</tr>
<tr>
<td> \ref ARM_SPI_EVENT_TRANSFER_COMPLETE </td><td> 0 </td><td> Occurs after call to \ref ARM_SPI_Send, \ref ARM_SPI_Receive,
or \ref ARM_SPI_Transfer
to indicate that all the data has been transferred.
The driver is ready for the next transfer operation. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_SPI_EVENT_DATA_LOST </td><td> 1 </td><td> Occurs in slave mode when data is requested/sent by master
but send/receive/transfer operation has not been started and
indicates that data is lost. Occurs also in master mode when
driver cannot transfer data fast enough. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_SPI_EVENT_MODE_FAULT </td><td> 2 </td><td> Occurs in master mode when Slave Select is deactivated and
indicates Master Mode Fault.
The driver is ready for the next transfer operation. </td>
<td> data field \em event_mode_fault = \token{1} </td>
</tr>
</table>
**************************************************************************************************************************/
/**
\defgroup SPI_control SPI Control Codes
\ingroup spi_interface_gr
\brief Many parameters of the SPI driver are configured using the \ref ARM_SPI_Control function.
\details
@{
The various SPI control codes define:
- \ref spi_mode_ctrls specifies SPI mode
- \ref spi_frame_format_ctrls defines the frame format
- \ref spi_data_bits_ctrls defines the number of data bits
- \ref spi_bit_order_ctrls defines the bit order
- \ref spi_slave_select_mode_ctrls specifies slave select mode
- \ref spi_misc_ctrls specifies additional miscellaneous controls
Refer to the \ref ARM_SPI_Control function for further details.
*/
/**
\defgroup spi_mode_ctrls SPI Mode Controls
\ingroup SPI_control
\brief Specifies SPI mode.
\details
@{
\def ARM_SPI_MODE_INACTIVE
\sa ARM_SPI_Control
\def ARM_SPI_MODE_MASTER
\sa ARM_SPI_Control
\def ARM_SPI_MODE_SLAVE
\sa ARM_SPI_Control
@}
*/
/**
\defgroup spi_frame_format_ctrls SPI Frame Format
\ingroup SPI_control
\brief Defines the frame format.
\details
@{
\def ARM_SPI_CPOL0_CPHA0
\sa ARM_SPI_Control
\def ARM_SPI_CPOL0_CPHA1
\sa ARM_SPI_Control
\def ARM_SPI_CPOL1_CPHA0
\sa ARM_SPI_Control
\def ARM_SPI_CPOL1_CPHA1
\sa ARM_SPI_Control
\def ARM_SPI_TI_SSI
\sa ARM_SPI_Control
\def ARM_SPI_MICROWIRE
\sa ARM_SPI_Control
@}
*/
/**
\defgroup spi_data_bits_ctrls SPI Data Bits
\ingroup SPI_control
\brief Defines the number of data bits.
\details
@{
\def ARM_SPI_DATA_BITS(n)
\sa ARM_SPI_Control
@}
*/
/**
\defgroup spi_bit_order_ctrls SPI Bit Order
\ingroup SPI_control
\brief Defines the bit order.
\details
@{
\def ARM_SPI_MSB_LSB
\sa ARM_SPI_Control
\def ARM_SPI_LSB_MSB
\sa ARM_SPI_Control
@}
*/
/**
\defgroup spi_slave_select_mode_ctrls SPI Slave Select Mode
\ingroup SPI_control
\brief Specifies SPI slave select mode.
\details
\b SPI \b Slave \b Select \b Mode configures the behavior of the \b Slave \b Select \b (SS) signal. The configuration is
separate for \b Master (ARM_SPI_SS_MASTER_*) and for \b Slave (\ref ARM_SPI_SS_SLAVE_HW, \ref ARM_SPI_SS_SLAVE_SW). The
active configuration depends on the current state (Master/Slave).
@{
\def ARM_SPI_SS_MASTER_UNUSED
An SPI master does not drive or monitor the SS line. For example, when connecting to a single slave, the SS line can be connected
to a fixed low level.
\sa ARM_SPI_Control
\def ARM_SPI_SS_MASTER_SW
SS is configured as an output and controlled via \ref ARM_SPI_Control (\ref ARM_SPI_CONTROL_SS). By default, it is not active
(high). It is activated (low) by \ref ARM_SPI_Control (\ref ARM_SPI_CONTROL_SS, \ref ARM_SPI_SS_ACTIVE) and deactivated by
\ref ARM_SPI_Control (\ref ARM_SPI_CONTROL_SS, \ref ARM_SPI_SS_INACTIVE). It is not affected by transfer/send/receive
functions.
\sa ARM_SPI_Control
\def ARM_SPI_SS_MASTER_HW_OUTPUT
Here, SS is configured as an output. It will be automatically activated/deactivated for the transfers by hardware (not
controlled by \ref ARM_SPI_Control (\ref ARM_SPI_CONTROL_SS)). The activation/deactivation of the line is completely hardware
dependent. Typically, the hardware will activate it before starting a transfer and deactivate it after a transfer completes.
Some hardware will keep the line active as long as the SPI stays master. Due to different hardware behavior, this mode is
typically not useful because certain devices require that the SS signal is strictly defined with regards to transfers.
\sa ARM_SPI_Control
\def ARM_SPI_SS_MASTER_HW_INPUT
This is normally used in a multi-master configuration, where a master does not drive the SS line when driving the bus but only
monitors it. When another master activates this line, the active master backs off. This is called \b mode \b fault. SS is
configured as input and the hardware only monitors it. When it is externally deactivated while being the master, it presents
a mode fault and the SPI switches to \b inactive mode.
\sa ARM_SPI_Control
\def ARM_SPI_SS_SLAVE_HW
Hardware monitors the SS line and accepts transfers only when SS line is activate. Transfers while SS is not active are
ignored.
\sa ARM_SPI_Control
\def ARM_SPI_SS_SLAVE_SW
Used only when SS line is not used. For example, when a single master and slave are connected in a system, the SS line is not
needed (reduces the number of lines and pins used). Slave responses are controlled by software (by default, it is not
responding). Software enables/disables transfers by calling \ref ARM_SPI_Control (\ref ARM_SPI_CONTROL_SS, \ref ARM_SPI_SS_ACTIVE / \ref ARM_SPI_SS_INACTIVE).
\sa ARM_SPI_Control
@}
*/
/**
\defgroup spi_misc_ctrls SPI Miscellaneous Controls
\ingroup SPI_control
\brief Specifies additional miscellaneous controls.
\details
@{
\def ARM_SPI_SET_BUS_SPEED
\sa ARM_SPI_Control
\def ARM_SPI_GET_BUS_SPEED
\sa ARM_SPI_Control
\def ARM_SPI_SET_DEFAULT_TX_VALUE
\sa ARM_SPI_Control
\def ARM_SPI_CONTROL_SS
\sa ARM_SPI_Control
\def ARM_SPI_ABORT_TRANSFER
\sa ARM_SPI_Control
@}
*/
/**
@}
*/
// end group SPI_control
/**
@}
*/
// End SPI Interface

View File

@ -0,0 +1,770 @@
/**
\defgroup storage_interface_gr Storage Interface
\brief Driver API for Storage Device Interface (%Driver_Storage.h)
\details
This is an abstraction for a storage controller. It offers an interface to
access an address space of storage locations, comprising APIs for
initialization, erase, access, program, and status-fetch operations. It also
offers APIs to iterate over the available Storage Blocks (\ref
ARM_STORAGE_BLOCK), allowing the discovery of block attributes such as
write/erase granularities. Using the Storage abstraction, it becomes possible to
write generic algorithms, such as block copy, to operate on any conforming
storage device.
\note The storage abstraction layer is not responsible for storage management.
Algorithms such as block-allocation, wear-leveling, erase-before-write and other
storage-management policies are the responsibility of modules external to the
storage abstraction layer. In essence, the storage interface is the lowest
abstraction upon which block management policies can be implemented.
Here's a picture to help locate the storage abstraction in the software stack.
The part below the box labeled 'Storage abstraction layer' is implemented by a
storage driver.
\image html storage_sw_stack.png
<b>Storage API</b>
The following header files define the Application Programming Interface (API) for the Flash interface:
- \b %Driver_Storage.h : Driver API for Storage Device Interface
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref StorageDriverFunctions
- \ref ARM_DRIVER_STORAGE : access struct for Storage driver functions
A sample use for the driver can be found at: \ref SampleUseOfStorageDriver
*******************************************************************************************************************/
/**
\addtogroup storage_interface_gr
@{
*******************************************************************************************************************/
/**
\struct ARM_STORAGE_BLOCK_ATTRIBUTES
<b>Contained in:</b>
- \ref ARM_STORAGE_BLOCK
*******************************************************************************************************************/
/**
\struct ARM_STORAGE_BLOCK
\details Storage blocks combine to make up the address map of a storage controller.
*******************************************************************************************************************/
/**
\struct ARM_STORAGE_INFO
\details
It describes the characteristics of a Storage device. This includes total
storage, programming size, a default value for erased memory etc. This
information can be obtained from the Storage device datasheet and is used by the
middleware in order to properly interact with the Storage device.
Total available storage (in bytes) is contained in \em total_storage. Minimum
programming size (in bytes) is described by \em program_unit (applicable only if
the \em programmable attribute is set for a block). It defines the granularity
for programming data. The offset of the start of a program-range and the size
should also be aligned with \em program_unit.
\note: setting \em program_unit to 0 has the effect of disabling the size and
alignment restrictions (setting it to 1 also has the same effect).
Optimal programming page-size (in bytes) is specified by \em
optimal_program_unit. Some storage controllers have internal buffers into which
to receive data. Writing in chunks of \em optimal_program_unit would achieve
maximum programming speed. Like with \em program_unit, this is applicable only
if the \em programmable attribute is set for the underlying storage block(s).
\em program_cycles is a measure of endurance for reprogramming.
A value of \em ARM_STORAGE_PROGRAM_CYCLES_INFINITE may be used to signify
infinite or unknown endurance.
Contents of erased memory is specified by the \em erased_value. It is usually
\token{1} to indicate erased bytes with state 0xFF.
\em memory_mapped can be set to \token{1} to indicate that the storage device
has a mapping onto the processor's memory address space.
\note: For a memory-mapped block which isn't erasable but is programmable,
writes should be possible directly to the memory-mapped storage without going
through the \ref ARM_Storage_ProgramData operation.
The field \em programmability holds a value to indicate storage programmability.
Similarly, \em retention_level holds a for encoding data-retention levels for
all storage blocks.
\note
These fields serve a different purpose than the ones contained in
\ref ARM_STORAGE_CAPABILITIES, which is another structure containing device-level
metadata. ARM_STORAGE_CAPABILITIES describes the API capabilities, whereas
ARM_STORAGE_INFO describes the device. Furthermore ARM_STORAGE_CAPABILITIES fits
within a single word, and is designed to be passed around by value;
ARM_STORAGE_INFO, on the other hand, contains metadata which doesn't fit into a
single word and requires the use of pointers to be moved around.
<b>Returned by:</b>
- \ref ARM_Storage_GetInfo
*******************************************************************************************************************/
/**
\struct ARM_DRIVER_STORAGE
\details
This is the set of operations constituting the Storage driver. Their
implementation is platform-specific, and needs to be supplied by the porting
effort. The functions of the Storage driver are accessed by function pointers
exposed by this structure. Refer to \ref StorageDriverFunctions for overview
information.
Each instance of a Storage interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_Storage0 is the name of the access struct of the first instance (no. 0).
- \b Driver_Storage1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_Flash<i>n</i>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*******************************************************************************************************************/
/**
\defgroup StorageDriverFunctions Use of Storage APIs
Function pointers within \ref ARM_DRIVER_STORAGE form the set of operations
constituting the Storage driver. Their implementation is platform-specific, and
needs to be supplied by the porting effort.
Some of these APIs will always operate synchronously:
- \ref ARM_Storage_GetVersion
- \ref ARM_Storage_GetCapabilities
- \ref ARM_Storage_GetStatus
- \ref ARM_Storage_GetInfo
- \ref ARM_Storage_ResolveAddress
- \ref ARM_Storage_GetNextBlock and
- \ref ARM_Storage_GetBlock.
This means that control returns to the caller with a relevant status code only after the completion of the operation (or
the discovery of a failure condition).
The remainder of the APIs:
- \ref ARM_Storage_Initialize
- \ref ARM_Storage_Uninitialize
- \ref ARM_Storage_PowerControl
- \ref ARM_Storage_ReadData
- \ref ARM_Storage_ProgramData
- \ref ARM_Storage_Erase and
- \ref ARM_Storage_EraseAll
can function asynchronously if the underlying controller supports it; that is if ARM_STORAGE_CAPABILITIES::asynchronous_ops
is set. In the case of asynchronous operation, the invocation returns early (with ARM_DRIVER_OK) and results in a completion
callback later. If ARM_STORAGE_CAPABILITIES::asynchronous_ops is not set, then all such APIs execute synchronously, and
control returns to the caller with a status code only after the completion of the operation (or the discovery of a failure
condition).
If ARM_STORAGE_CAPABILITIES::asynchronous_ops is set, a storage driver may
still choose to execute asynchronous operations in a synchronous manner. If
so, the driver returns a positive value to indicate successful synchronous
completion (or an error code in case of failure) and no further invocation of
completion callback should be expected. The expected return value for
synchronous completion of such asynchronous operations varies depending on
the operation. For operations involving data access, it often equals the
amount of data transferred or affected. For non data-transfer operations,
such as EraseAll or Initialize, it is usually 1.
Here's a code snippet to suggest how asynchronous APIs might be used by
callers to handle both synchronous and asynchronous execution by the
underlying storage driver:
\code
ASSERT(ARM_DRIVER_OK == 0); // this is a precondition; it doesn't need to be put in code
int32_t returnValue = drv->asynchronousAPI(...);
if (returnValue < ARM_DRIVER_OK) {
// handle error.
} else if (returnValue == ARM_DRIVER_OK) {
ASSERT(drv->GetCapabilities().asynchronous_ops == 1);
// handle early return from asynchronous execution; remainder of the work is done in the callback handler.
} else {
ASSERT(returnValue == EXPECTED_RETURN_VALUE_FOR_SYNCHRONOUS_COMPLETION);
// handle synchronous completion.
}
\endcode
THis example is mixing synchronous and asynchronous APIs: \ref SampleUseOfStorageDriver
*******************************************************************************************************************/
/**
\struct ARM_STORAGE_CAPABILITIES
\details
A Storage driver can be implemented with different capabilities. The data fields
of this struct encode the API capabilities implemented by this driver.
The element \em asynchronous_ops indicates if APIs like initialize, read, erase,
program, etc. can operate in asynchronous mode. Having this bit set to 1 means
that the driver is capable of launching asynchronous operations; command
completion for asynchronous operations is signaled by the invocation of a
completion callback. If set to 1, drivers may still complete asynchronous
operations synchronously as necessary--in which case they return a positive
error code to indicate synchronous completion. If \em asynchronous_ops is not
set, then all such APIs execute synchronously, and control returns to the caller
with a status code only after the completion of the operation (or the discovery
of a failure condition).
The element \em erase_all specifies that the \ref ARM_Storage_EraseAll function
is supported. Typically full chip erase is much faster than erasing the whole
device using \em ARM_Storage_Erase.
<b>Returned by:</b>
- \ref ARM_Storage_GetCapabilities
\note
This data structure is designed to fit within a single word so that it can be
fetched cheaply using a call to driver->GetCapabilities().
*******************************************************************************************************************/
/**
\struct ARM_STORAGE_STATUS
\details
Structure with information about the status of the Storage device.
The flag \em busy indicates that the driver is busy executing read/program/erase operation.
The flag \em error flag is cleared on start of read/program/erase operation and is set at the end of the current operation in case of error.
<b>Returned by:</b>
- \ref ARM_Storage_GetStatus
*****************************************************************************************************************/
/**
\enum ARM_STORAGE_OPERATION
\details
Command opcodes for the Storage interface. Completion callbacks use these codes
to refer to completing commands. Refer to \ref ARM_Storage_Callback_t.
*****************************************************************************************************************/
/**
\typedef ARM_Storage_Callback_t
\details
Provides the typedef for the callback function \ref ARM_Storage_Callback_t.
\param [in] status
A code to indicate the status of the completed operation. For data
transfer operations, the status field is overloaded in case of
success to return the count of bytes successfully transferred; this
can be done safely because error codes are negative values.
\param [in] operation
The command op-code. This value isn't essential, but it is expected that
this information could be a quick and useful filter for the handler.
<b>Parameter for:</b>
- \ref ARM_Storage_Initialize
*******************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_Storage_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_Storage_GetVersion (void)
\details
The function \b ARM_Storage_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION.
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_STORAGE *drv_info;
void read_version (void) {
ARM_DRIVER_VERSION version;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
\note The function GetVersion() can be called any time to obtain the
required information from the driver (even before initialization). It
always returns the same information.
*******************************************************************************************************************/
ARM_STOR_CAPABILITIES ARM_Storage_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_STORAGE_CAPABILITIES ARM_Storage_GetCapabilities (void)
\details
The function \b ARM_Storage_GetCapabilities returns information about
capabilities in this driver implementation. The data fields of the struct
ARM_STORAGE_CAPABILITIES encode various capabilities, for example if the device
is able to execute operations asynchronously.
Example:
\code
extern ARM_DRIVER_STORAGE *drv_info;
void read_capabilities (void) {
ARM_STORAGE_CAPABILITIES drv_capabilities;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
\note The function GetCapabilities() can be called any time to obtain the
required information from the driver (even before initialization). It
always returns the same information.
*******************************************************************************************************************/
int32_t ARM_Storage_Initialize (ARM_Storage_Callback_t callback) {
return 0;
}
/**
\fn int32_t ARM_Storage_Initialize (ARM_Storage_Callback_t callback)
\details
The function \b ARM_Storage_Initialize is called when the middleware component starts
operation. In addition to bringing the controller to a ready state,
Initialize() receives a callback handler to be invoked upon completion of
asynchronous operations.
ARM_Storage_Initialize() needs to be called explicitly before
powering the peripheral using ARM_Storage_PowerControl(), and before initiating other
accesses to the storage controller.
The function performs the following operations:
- Initializes the resources needed for the Storage interface.
- Registers the \ref ARM_Storage_Callback_t callback function.
To start working with a peripheral the functions ARM_Storage_Initialize and ARM_Storage_PowerControl() need to be called in this order:
\code
drv->Initialize (...); // Allocate I/O pins
drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA
\endcode
- ARM_Storage_Initialize() typically allocates the I/O resources (pins) for the
peripheral. The function can be called multiple times; if the I/O resources
are already initialized it performs no operation and just returns with
ARM_DRIVER_OK.
- ARM_Storage_PowerControl (ARM_POWER_FULL) sets the peripheral registers including
interrupt (NVIC) and optionally DMA. The function can be called multiple
times; if the registers are already set it performs no operation and just
returns with ARM_DRIVER_OK.
To stop working with a peripheral the functions ARM_Storage_PowerControl() and ARM_Storage_Uninitialize() need to be called in this order:
\code
drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral
drv->Uninitialize (...); // Release I/O pins
\endcode
The functions ARM_Storage_PowerControl() and ARM_Storage_Uninitialize() always execute and can be used
to put the peripheral into a Safe State, for example after any data
transmission errors. To restart the peripheral in an error condition,
you should first execute the Stop Sequence and then the Start Sequence.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
int32_t ARM_Storage_Uninitialize (void) {
return 0;
}
/**
\fn int32_t ARM_Storage_Uninitialize (void)
\details
It is called when the middleware component stops operation, and wishes to
release the software resources used by the interface.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
int32_t ARM_Storage_PowerControl (ARM_POWER_STATE state) {
return 0;
}
/**
\fn int32_t ARM_Storage_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_Storage_PowerControl operates the power modes of the Storage interface.
To start working with a peripheral the functions Initialize and PowerControl need to be called in this order:
\code
drv->Initialize (...); // Allocate I/O pins
drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA
\endcode
- ARM_Storage_Initialize() typically allocates the I/O resources (pins) for the
peripheral. The function can be called multiple times; if the I/O resources
are already initialized it performs no operation and just returns with
ARM_DRIVER_OK.
- PowerControl (ARM_POWER_FULL) sets the peripheral registers including
interrupt (NVIC) and optionally DMA. The function can be called multiple
times; if the registers are already set it performs no operation and just
returns with ARM_DRIVER_OK.
To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order:
\code
drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral
drv->Uninitialize (...); // Release I/O pins
\endcode
The functions ARM_Storage_PowerControl and ARM_Storage_Uninitialize always execute and can be used
to put the peripheral into a Safe State, for example after any data
transmission errors. To restart the peripheral in an error condition,
you should first execute the Stop Sequence and then the Start Sequence.
The parameter \em state can have the following values:
- \ref ARM_POWER_FULL : set-up the Storage device for data transfers, enable interrupts (NVIC) and optionally DMA. Can be called multiple times.
If the device is already in this mode, then the function performs no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
int32_t ARM_Storage_ReadData (uint64_t addr, void *data, uint32_t size) {
return 0;
}
/**
\fn int32_t ARM_Storage_ReadData (uint64_t addr, void *data, uint32_t size)
\details
Read the contents of a range of storage memory into a buffer
supplied by the caller. The buffer is owned by the caller and should
remain accessible for the lifetime of this command.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
int32_t ARM_Storage_ProgramData (uint64_t addr, const void *data, uint32_t size) {
return 0;
}
/**
\fn int32_t ARM_Storage_ProgramData (uint64_t addr, const void *data, uint32_t size)
\details
Write the contents of a given memory buffer into a range of
storage memory. In the case of flash memory, the destination range in
storage memory typically has its contents in an erased state from a
preceding erase operation. The source memory buffer is owned by the
caller and should remain accessible for the lifetime of this command.
\note It is best for the middleware to write in units of
'optimal_program_unit' (\ref ARM_STORAGE_INFO) of the device.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
int32_t ARM_Storage_Erase (uint64_t addr, uint32_t size) {
return 0;
}
/**
\fn int32_t ARM_Storage_Erase (uint64_t addr, uint32_t size)
\details
This function erases a range of storage specified by [addr, addr +
size). Both 'addr' and 'addr + size' should align with the
'erase_unit'(s) of the respective owning storage block(s) (see \ref
ARM_STORAGE_BLOCK and \ref ARM_STORAGE_BLOCK_ATTRIBUTES). The range to
be erased will have its contents returned to the un-programmed state--
i.e. to \ref ARM_STORAGE_INFO::erased_value, which
is usually 1 to indicate the pattern of all ones: 0xFF.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
\note Erase() may return a smaller (positive) value than the size of the
requested range. The returned value indicates the actual number of bytes
erased. It is the caller's responsibility to follow up with an appropriate
request to complete the operation.
\note in the case of a failed erase (except when
ARM_DRIVER_ERROR_PARAMETER, ARM_STORAGE_ERROR_PROTECTED, or
ARM_STORAGE_ERROR_NOT_ERASABLE is returned synchronously), the
requested range should be assumed to be in an unknown state. The
previous contents may not be retained.
*******************************************************************************************************************/
int32_t ARM_Storage_EraseAll (void) {
return 0;
}
/**
\fn int32_t ARM_Storage_EraseAll (void)
\details
This optional function erases the complete device. If the device does not
support global erase then the function returns the error value \ref
ARM_DRIVER_ERROR_UNSUPPORTED. The data field \em 'erase_all' =
\token{1} of the structure \ref ARM_STORAGE_CAPABILITIES encodes that
\ref ARM_Storage_EraseAll is supported.
\note This API may execute asynchronously if
ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous
execution is optional even if 'asynchronous_ops' is set.
*******************************************************************************************************************/
ARM_Storage_STATUS ARM_Storage_GetStatus (void) {
return 0;
}
/**
\fn ARM_STORAGE_STATUS ARM_Storage_GetStatus (void)
\details
Get the status of the current (or previous) command executed by the
storage controller; stored in the structure \ref ARM_STORAGE_STATUS.
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
*******************************************************************************************************************/
int32_t ARM_Storage_GetInfo (ARM_STORAGE_INFO *info) {
return 0;
}
/**
\fn int32_t ARM_Storage_GetInfo (ARM_STORAGE_INFO *info)
\details
Get information about the Storage device; stored in the structure \ref ARM_STORAGE_INFO.
\note It is the caller's responsibility to ensure that the buffer passed in
is able to be initialized with a \ref ARM_STORAGE_INFO.
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
*******************************************************************************************************************/
uint32_t ARM_Storage_ResolveAddress(uint64_t addr) {
return 0;
}
/**
\fn uint32_t ARM_Storage_ResolveAddress(uint64_t addr)
\details
Only applicable to devices with memory-mapped storage.
\note This API returns synchronously. The invocation should return quickly,
and result in a resolved address.
*******************************************************************************************************************/
int32_t ARM_Storage_GetNextBlock(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block) {
return 0;
}
/**
\fn int32_t ARM_Storage_GetNextBlock(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block);
\details
This helper function fetches (an iterator to) the next block (or
the first block if 'prev_block' is passed in as NULL). In the failure
case, a terminating, invalid block iterator is filled into the out
parameter: 'next_block'. In combination with \ref
ARM_STORAGE_VALID_BLOCK, it can be used to iterate over the sequence
of blocks within the storage map:
\code
ARM_STORAGE_BLOCK block;
for (drv->GetNextBlock(NULL, &block); ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) {
// make use of block
}
\endcode
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
*******************************************************************************************************************/
int32_t ARM_Storage_GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *block) {
return 0;
}
/**
\fn int32_t ARM_Storage_GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *block);
\note This API returns synchronously--it does not result in an invocation
of a completion callback.
*******************************************************************************************************************/
/**
@}
*/
/**
\defgroup SampleUseOfStorageDriver Sample Use of Storage Driver
\ingroup storage_interface_gr
@{
<b>Example Code:</b>
The following is a generic algorithm to erase
and program one \ref ARM_STORAGE_BLOCK_ATTRIBUTES::erase_unit worth of storage
and then read it back to be verified. It handles both synchronous and
asynchronous driver implementations.
\code
// Copyright (c) 2006-2016, Arm Limited, All Rights Reserved
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:// www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Driver_Storage.h"
#include <stdio.h>
#include <string.h>
#define TEST_ASSERT(Expr) if (!(Expr)) { printf("%s:%u: assertion failure\n", __FUNCTION__, __LINE__); while (1) ;}
#define TEST_ASSERT_EQUAL(expected, actual) if ((expected) != (actual)) {printf("%s:%u: assertion failure\n", __FUNCTION__, __LINE__); while (1) ;}
#define TEST_ASSERT_NOT_EQUAL(expected, actual) if ((expected) == (actual)) {printf("%s:%u: assertion failure\n", __FUNCTION__, __LINE__); while (1) ;}
// forward declarations
void callbackHandler(int32_t status, ARM_STORAGE_OPERATION operation);
void progressStateMachine(void);
static enum {
NEEDS_INITIALIZATION,
NEEDS_ERASE,
NEEDS_PROGRAMMING,
NEEDS_READ,
NEEDS_VERIFICATION_FOLLOWING_READ,
FINISHED
} state;
extern ARM_DRIVER_STORAGE ARM_Driver_Storage_(0);
ARM_DRIVER_STORAGE *drv = &ARM_Driver_Storage_(0);
static const unsigned BUFFER_SIZE = 16384;
static uint8_t buffer[BUFFER_SIZE];
void main(int argc __unused, char** argv __unused)
{
state = NEEDS_INITIALIZATION;
progressStateMachine();
while (true) {
// WFE(); // optional low-power sleep
}
}
void progressStateMachine(void)
{
int32_t rc;
static ARM_STORAGE_BLOCK firstBlock;
if (!ARM_STORAGE_VALID_BLOCK(&firstBlock)) {
// Get the first block. This block is entered only once.
rc = drv->GetNextBlock(NULL, &firstBlock); // get first block
TEST_ASSERT_EQUAL(ARM_DRIVER_OK, rc);
}
TEST_ASSERT(ARM_STORAGE_VALID_BLOCK(&firstBlock));
TEST_ASSERT(firstBlock.size > 0);
switch (state) {
case NEEDS_INITIALIZATION:
rc = drv->Initialize(callbackHandler);
TEST_ASSERT(rc >= ARM_DRIVER_OK);
if (rc == ARM_DRIVER_OK) {
TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops);
state = NEEDS_ERASE;
return; // there is pending asynchronous activity which will lead to a completion callback later.
}
TEST_ASSERT_EQUAL(1, rc); // synchronous completion
// intentional fall-through
case NEEDS_ERASE:
TEST_ASSERT(firstBlock.attributes.erase_unit > 0);
rc = drv->Erase(firstBlock.addr, firstBlock.attributes.erase_unit);
TEST_ASSERT(rc >= ARM_DRIVER_OK);
if (rc == ARM_DRIVER_OK) {
TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops);
state = NEEDS_PROGRAMMING;
return; // there is pending asynchronous activity which will lead to a completion callback later.
}
TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, (uint32_t)rc); // synchronous completion
// intentional fall-through
case NEEDS_PROGRAMMING:
TEST_ASSERT(BUFFER_SIZE >= firstBlock.attributes.erase_unit);
#define PATTERN 0xAA
memset(buffer, PATTERN, firstBlock.attributes.erase_unit);
rc = drv->ProgramData(firstBlock.addr, buffer, firstBlock.attributes.erase_unit);
TEST_ASSERT(rc >= ARM_DRIVER_OK);
if (rc == ARM_DRIVER_OK) {
TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops);
state = NEEDS_READ;
return; // there is pending asynchronous activity which will lead to a completion callback later.
}
TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, (uint32_t)rc); // synchronous completion
// intentional fall-through
case NEEDS_READ:
rc = drv->ReadData(firstBlock.addr, buffer, firstBlock.attributes.erase_unit);
TEST_ASSERT(rc >= ARM_DRIVER_OK);
if (rc == ARM_DRIVER_OK) {
TEST_ASSERT_EQUAL(1, drv->GetCapabilities().asynchronous_ops);
state = NEEDS_VERIFICATION_FOLLOWING_READ;
return; // there is pending asynchronous activity which will lead to a completion callback later.
}
TEST_ASSERT_EQUAL(firstBlock.attributes.erase_unit, (uint32_t)rc);
// intentional fall-through
case NEEDS_VERIFICATION_FOLLOWING_READ:
printf("verifying data\r\n");
for (unsigned i = 0; i < firstBlock.attributes.erase_unit; i++) {
TEST_ASSERT_EQUAL(PATTERN, buffer[i]);
}
state = FINISHED;
printf("done\r\n");
break;
case FINISHED:
break;
} // switch (state)
}
void callbackHandler(int32_t status, ARM_STORAGE_OPERATION operation)
{
(void)status;
(void)operation;
switch (operation) {
case ARM_STORAGE_OPERATION_INITIALIZE:
case ARM_STORAGE_OPERATION_READ_DATA:
case ARM_STORAGE_OPERATION_PROGRAM_DATA:
case ARM_STORAGE_OPERATION_ERASE:
progressStateMachine();
break;
default:
printf("callbackHandler: unexpected callback for opcode %u with status %ld\r\n", operation, status);
break;
}
}
\endcode
@}
*******************************************************************************************************************/
// End Storage Interface

View File

@ -0,0 +1,801 @@
/**
\defgroup usart_interface_gr USART Interface
\brief Driver API for Universal Synchronous Asynchronous Receiver/Transmitter (%Driver_USART.h)
\details
The <b>Universal Synchronous Asynchronous Receiver/Transmitter</b> (USART) implements a synchronous and asynchronous serial bus for exchanging data.
When only asynchronous mode is supported it is called Universal Asynchronous Receiver/Transmitter (UART).
Almost all microcontrollers have a serial interface (UART/USART peripheral). A UART is a simple device to send data to a PC
via a terminal emulation program (Hyperterm, TeraTerm) or to another microcontroller.
A UART takes bytes of data and transmits the individual bits in a sequential mode. At the destination,
a second UART reassembles the bits into complete bytes. Each UART contains a shift register for converting between serial and parallel transmission forms.
Wikipedia offers more information about
the <a href="http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter" target="_blank"><b>Universal asynchronous receiver/transmitter</b></a>.
<b>USART API</b>
The following header files define the Application Programming Interface (API) for the USART interface:
- \b %Driver_USART.h : Driver API for Universal Synchronous Asynchronous Receiver/Transmitter
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_USART : access struct for USART driver functions
<b>Example Code</b>
The following example code shows the usage of the USART interface for asynchronous communication.
\include USART_Demo.c
@{
*/
/**
\struct ARM_DRIVER_USART
\details
The functions of the USART driver are accessed by function pointers exposed by this structure.
Refer to \ref DriverFunctions for overview information.
Each instance of an USART interface provides such an access structure.
The instance is identified by a postfix number in the symbol name of the access structure, for example:
- \b Driver_USART0 is the name of the access struct of the first instance (no. 0).
- \b Driver_USART1 is the name of the access struct of the second instance (no. 1).
A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_USART<i>n</i>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
*****************************************************************************************************************/
/**
\struct ARM_USART_CAPABILITIES
\details
An USART driver can be implemented with different capabilities.
The data fields of this structure encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_USART_GetCapabilities
*****************************************************************************************************************/
/**
\struct ARM_USART_STATUS
\details
Structure with information about the status of the USART. The data fields encode busy flags and error flags.
<b>Returned by:</b>
- \ref ARM_USART_GetStatus
*****************************************************************************************************************/
/**
\enum ARM_USART_MODEM_CONTROL
\details
Specifies values for controlling the modem control lines.
<b>Parameter for:</b>
- \ref ARM_USART_SetModemControl
*****************************************************************************************************************/
/**
\struct ARM_USART_MODEM_STATUS
\details
Structure with information about the status of modem lines. The data fields encode states of modem status lines.
<b>Returned by:</b>
- \ref ARM_USART_GetModemStatus
*****************************************************************************************************************/
/**
\typedef ARM_USART_SignalEvent_t
\details
Provides the typedef for the callback function \ref ARM_USART_SignalEvent.
<b>Parameter for:</b>
- \ref ARM_USART_Initialize
*******************************************************************************************************************/
/**
\defgroup usart_execution_status Status Error Codes
\ingroup common_drv_gr
\brief Negative values indicate errors (USART has specific codes in addition to common \ref execution_status).
\details
The USART driver has additional status error codes that are listed below.
Note that the USART driver also returns the common \ref execution_status.
@{
\def ARM_USART_ERROR_MODE
The \b mode requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_BAUDRATE
The <b>baud rate</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_DATA_BITS
The number of <b>data bits</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_PARITY
The <b>parity bit</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_STOP_BITS
The <b>stop bit</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_FLOW_CONTROL
The <b>flow control</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_CPOL
The <b>clock polarity</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
\def ARM_USART_ERROR_CPHA
The <b>clock phase</b> requested with the function \ref ARM_USART_Control is not supported by this driver.
@}
*/
/**
\defgroup USART_events USART Events
\ingroup usart_interface_gr
\brief The USART driver generates call back events that are notified via the function \ref ARM_USART_SignalEvent.
\details
This section provides the event values for the \ref ARM_USART_SignalEvent callback function.
The following call back notification events are generated:
@{
\def ARM_USART_EVENT_SEND_COMPLETE
\def ARM_USART_EVENT_RECEIVE_COMPLETE
\def ARM_USART_EVENT_TRANSFER_COMPLETE
\def ARM_USART_EVENT_TX_COMPLETE
\def ARM_USART_EVENT_TX_UNDERFLOW
\def ARM_USART_EVENT_RX_OVERFLOW
\def ARM_USART_EVENT_RX_TIMEOUT
\def ARM_USART_EVENT_RX_BREAK
\def ARM_USART_EVENT_RX_FRAMING_ERROR
\def ARM_USART_EVENT_RX_PARITY_ERROR
\def ARM_USART_EVENT_CTS
\def ARM_USART_EVENT_DSR
\def ARM_USART_EVENT_DCD
\def ARM_USART_EVENT_RI
@}
*/
/**
\defgroup USART_control USART Control Codes
\ingroup usart_interface_gr
\brief Many parameters of the USART driver are configured using the \ref ARM_USART_Control function.
\details
@{
The various USART control codes define:
- \ref usart_mode_control specifies USART mode
- \ref usart_data_bits defines the number of data bits
- \ref usart_parity_bit defines the parity bit
- \ref usart_stop_bits defines the number of stop bits
- \ref usart_flow_control specifies RTS/CTS flow control
- \ref usart_clock_polarity defines the clock polarity for the synchronous mode
- \ref usart_clock_phase defines the clock phase for the synchronous mode
- \ref usart_misc_control specifies additional miscellaneous controls
Refer to the \ref ARM_USART_Control function for further details.
*/
/**
\defgroup usart_mode_control USART Mode Control
\ingroup USART_control
\brief Specify USART mode.
\details
@{
\def ARM_USART_MODE_ASYNCHRONOUS
\sa ARM_USART_Control
\def ARM_USART_MODE_SYNCHRONOUS_MASTER
\sa ARM_USART_Control
\def ARM_USART_MODE_SYNCHRONOUS_SLAVE
\sa ARM_USART_Control
\def ARM_USART_MODE_SINGLE_WIRE
\sa ARM_USART_Control
\def ARM_USART_MODE_IRDA
\sa ARM_USART_Control
\def ARM_USART_MODE_SMART_CARD
\sa ARM_USART_Control
@}
*/
/**
\defgroup usart_misc_control USART Miscellaneous Control
\ingroup USART_control
\brief Specifies additional miscellaneous controls.
\details
@{
\def ARM_USART_SET_DEFAULT_TX_VALUE
\sa ARM_USART_Control; ARM_USART_Receive;
\def ARM_USART_SET_IRDA_PULSE
\sa ARM_USART_Control
\def ARM_USART_SET_SMART_CARD_GUARD_TIME
\sa ARM_USART_Control
\def ARM_USART_SET_SMART_CARD_CLOCK
\sa ARM_USART_Control
\def ARM_USART_CONTROL_SMART_CARD_NACK
\sa ARM_USART_Control
\def ARM_USART_CONTROL_TX
\sa ARM_USART_Control; ARM_USART_Send; ARM_USART_Transfer
\def ARM_USART_CONTROL_RX
\sa ARM_USART_Control; ARM_USART_Receive; ARM_USART_Transfer;
\def ARM_USART_CONTROL_BREAK
\sa ARM_USART_Control
\def ARM_USART_ABORT_SEND
\sa ARM_USART_Control;
\def ARM_USART_ABORT_RECEIVE
\sa ARM_USART_Control;
\def ARM_USART_ABORT_TRANSFER
\sa ARM_USART_Control;
@}
*/
/**
\defgroup usart_data_bits USART Data Bits
\ingroup USART_control
\brief Defines the number of data bits.
\details
@{
\def ARM_USART_DATA_BITS_5
\sa ARM_USART_Control
\def ARM_USART_DATA_BITS_6
\sa ARM_USART_Control
\def ARM_USART_DATA_BITS_7
\sa ARM_USART_Control
\def ARM_USART_DATA_BITS_8
\sa ARM_USART_Control
\def ARM_USART_DATA_BITS_9
\sa ARM_USART_Control
@}
*/
/**
\defgroup usart_parity_bit USART Parity Bit
\ingroup USART_control
\brief Defines the parity bit.
\details
@{
\def ARM_USART_PARITY_NONE
\sa ARM_USART_Control
\def ARM_USART_PARITY_EVEN
\sa ARM_USART_Control
\def ARM_USART_PARITY_ODD
\sa ARM_USART_Control
@}
*/
/**
\defgroup usart_stop_bits USART Stop Bits
\ingroup USART_control
\brief Defines the number of stop bits.
\details
@{
\sa ARM_USART_Control
\def ARM_USART_STOP_BITS_1
\sa ARM_USART_Control
\def ARM_USART_STOP_BITS_2
\sa ARM_USART_Control
\def ARM_USART_STOP_BITS_1_5
\sa ARM_USART_Control
\def ARM_USART_STOP_BITS_0_5
\sa ARM_USART_Control
@}
*/
/**
\defgroup usart_flow_control USART Flow Control
\ingroup USART_control
\brief Specifies RTS/CTS flow control.
\details
@{
\def ARM_USART_FLOW_CONTROL_NONE
\sa ARM_USART_Control
\def ARM_USART_FLOW_CONTROL_RTS
\sa ARM_USART_Control
\def ARM_USART_FLOW_CONTROL_CTS
\sa ARM_USART_Control
\def ARM_USART_FLOW_CONTROL_RTS_CTS
\sa ARM_USART_Control
@}
*/
/**
\defgroup usart_clock_polarity USART Clock Polarity
\ingroup USART_control
\brief Defines the clock polarity for the synchronous mode.
\details
@{
\def ARM_USART_CPOL0
\sa ARM_USART_Control; ARM_USART_Receive; ARM_USART_Send; ARM_USART_Transfer
\def ARM_USART_CPOL1
\sa ARM_USART_Control; ARM_USART_Receive; ARM_USART_Send; ARM_USART_Transfer
@}
*/
/**
\defgroup usart_clock_phase USART Clock Phase
\ingroup USART_control
\brief Defines the clock phase for the synchronous mode.
\details
@{
\def ARM_USART_CPHA0
\sa ARM_USART_Control; ARM_USART_Receive; ARM_USART_Send; ARM_USART_Transfer
\def ARM_USART_CPHA1
\sa ARM_USART_Control; ARM_USART_Receive; ARM_USART_Send; ARM_USART_Transfer
@}
*/
/**
@}
*/
// end group USART_control
//
// Functions
//
ARM_DRIVER_VERSION ARM_USART_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_USART_GetVersion (void)
\details
The function \b ARM_USART_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_USART Driver_USART0;
ARM_DRIVER_USART *drv_info;
void setup_usart (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_USART0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
ARM_USART_CAPABILITIES ARM_USART_GetCapabilities (void) {
return { 0 } ;
}
/**
\fn ARM_USART_CAPABILITIES ARM_USART_GetCapabilities (void)
\details
The function \b ARM_USART_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_USART_CAPABILITIES encode various capabilities, for example:
supported modes, if hardware and driver are capable of signaling events using the \ref ARM_USART_SignalEvent
callback function ...
Example:
\code
extern ARM_DRIVER_USART Driver_USART0;
ARM_DRIVER_USART *drv_info;
void read_capabilities (void) {
ARM_USART_CAPABILITIES drv_capabilities;
drv_info = &Driver_USART0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*****************************************************************************************************************/
int32_t ARM_USART_Initialize (ARM_USART_SignalEvent_t cb_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Initialize (ARM_USART_SignalEvent_t cb_event)
\details
The function \b ARM_USART_Initialize initializes the USART interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the USART interface.
- Registers the \ref ARM_USART_SignalEvent callback function.
The parameter \em cb_event is a pointer to the \ref ARM_USART_SignalEvent callback function; use a NULL pointer
when no callback signals are required.
\b Example:
- see \ref usart_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_USART_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Uninitialize (void)
\details
The function \b ARM_USART_Uninitialize de-initializes the resources of USART interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_USART_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_USART_PowerControl operates the power modes of the USART interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*****************************************************************************************************************/
int32_t ARM_USART_Send (const void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Send (const void *data, uint32_t num)
\details
This functions \b ARM_USART_Send is used in asynchronous mode to send data to the USART transmitter.
It can also be used in synchronous mode when sending data only (received data is ignored).
Transmitter needs to be enabled by calling \ref ARM_USART_Control with \ref ARM_USART_CONTROL_TX as the control parameter and \token{1} as argument.
The function parameters specify the buffer with data and the number of items to send.
The item size is defined by the data type which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 5..8 data bits
- \em uint16_t when configured for 9 data bits
Calling the function <b>ARM_USART_Send</b> only starts the send operation.
The function is non-blocking and returns as soon as the driver has started the operation (driver typically configures DMA or the interrupt system for continuous transfer).
When in synchronous slave mode the operation is only registered and started when the master starts the transfer.
During the operation it is not allowed to call this function again or any other data transfer function when in synchronous mode. Also the data buffer must stay allocated and the contents of unsent data must not be modified.
When send operation is completed (requested number of items sent) the \ref ARM_USART_EVENT_SEND_COMPLETE event is generated.
Progress of send operation can also be monitored by reading the number of items already sent by calling \ref ARM_USART_GetTxCount.
After send operation has completed there might still be some data left in the driver's hardware buffer which is still being transmitted.
When all data has been physically transmitted the \ref ARM_USART_EVENT_TX_COMPLETE event is generated (if supported and reported by \em event_tx_complete in \ref ARM_USART_CAPABILITIES).
At that point also the \em tx_busy data field in \ref ARM_USART_STATUS is cleared.
Status of the transmitter can be monitored by calling the \ref ARM_USART_GetStatus and checking the \em tx_busy flag
which indicates if transmission is still in progress.
When in synchronous slave mode and transmitter is enabled but send/receive/transfer operation is not started and data is requested by the master then the \ref ARM_USART_EVENT_TX_UNDERFLOW event is generated.
Send operation can be aborted by calling \ref ARM_USART_Control with \ref ARM_USART_ABORT_SEND as the control parameter.
*****************************************************************************************************************/
int32_t ARM_USART_Receive (void *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Receive (void *data, uint32_t num)
\details
This functions \b ARM_USART_Receive is used in asynchronous mode to receive data from the USART receiver.
It can also be used in synchronous mode when receiving data only (transmits the default value as specified by \ref ARM_USART_Control with \ref ARM_USART_SET_DEFAULT_TX_VALUE as control parameter).
Receiver needs to be enabled by calling \ref ARM_USART_Control with \ref ARM_USART_CONTROL_RX as the control parameter and \token{1} as argument.
The function parameters specify the buffer for data and the number of items to receive.
The item size is defined by the data type which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 5..8 data bits
- \em uint16_t when configured for 9 data bits
Calling the function <b>ARM_USART_Receive</b> only starts the receive operation.
The function is non-blocking and returns as soon as the driver has started the operation (driver typically configures DMA or the interrupt system for continuous transfer).
When in synchronous slave mode the operation is only registered and started when the master starts the transfer.
During the operation it is not allowed to call this function again or any other data transfer function when in synchronous mode. Also the data buffer must stay allocated.
When receive operation is completed (requested number of items received) the \ref ARM_USART_EVENT_RECEIVE_COMPLETE event is generated.
Progress of receive operation can also be monitored by reading the number of items already received by calling \ref ARM_USART_GetRxCount.
Status of the receiver can be monitored by calling the \ref ARM_USART_GetStatus and checking the \em rx_busy flag
which indicates if reception is still in progress.
During reception the following events can be generated (in asynchronous mode):
- \ref ARM_USART_EVENT_RX_TIMEOUT : Receive timeout between consecutive characters detected (optional)
- \ref ARM_USART_EVENT_RX_BREAK : Break detected (Framing error is not generated for Break condition)
- \ref ARM_USART_EVENT_RX_FRAMING_ERROR : Framing error detected
- \ref ARM_USART_EVENT_RX_PARITY_ERROR : Parity error detected
- \ref ARM_USART_EVENT_RX_OVERFLOW : Data overflow detected (also in synchronous slave mode)
\ref ARM_USART_EVENT_RX_OVERFLOW event is also generated when receiver is enabled but data is lost because
receive operation in asynchronous mode or receive/send/transfer operation in synchronous slave mode has not been started.
Receive operation can be aborted by calling \ref ARM_USART_Control with \ref ARM_USART_ABORT_RECEIVE as the control parameter.
*****************************************************************************************************************/
int32_t ARM_USART_Transfer (const void *data_out, void *data_in, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Transfer (const void *data_out, void *data_in, uint32_t num)
\details
This functions \b ARM_USART_Transfer is used in synchronous mode to transfer data via USART. It synchronously sends data to the USART transmitter and receives data from the USART receiver.
Transmitter needs to be enabled by calling \ref ARM_USART_Control with \ref ARM_USART_CONTROL_TX as the control parameter and \token{1} as argument.
Receiver needs to be enabled by calling \ref ARM_USART_Control with \ref ARM_USART_CONTROL_RX as the control parameter and \token{1} as argument.
The function parameters specify the buffer with data to send, the buffer for data to receive and the number of items to transfer.
The item size is defined by the data type which depends on the configured number of data bits.
Data type is:
- \em uint8_t when configured for 5..8 data bits
- \em uint16_t when configured for 9 data bits
Calling the function <b>ARM_USART_Transfer</b> only starts the transfer operation.
The function is non-blocking and returns as soon as the driver has started the operation (driver typically configures DMA or the interrupt system for continuous transfer).
When in synchronous slave mode the operation is only registered and started when the master starts the transfer.
During the operation it is not allowed to call this function or any other data transfer function again. Also the data buffers must stay allocated and the contents of unsent data must not be modified.
When transfer operation is completed (requested number of items transferred) the \ref ARM_USART_EVENT_TRANSFER_COMPLETE event is generated.
Progress of transfer operation can also be monitored by reading the number of items already transferred by calling \ref ARM_USART_GetTxCount or \ref ARM_USART_GetRxCount.
Status of the transmitter or receiver can be monitored by calling the \ref ARM_USART_GetStatus and checking the \em tx_busy or \em rx_busy flag.
When in synchronous slave mode also the following events can be generated:
- \ref ARM_USART_EVENT_TX_UNDERFLOW : transmitter is enabled but transfer operation is not started and data is requested by the master
- \ref ARM_USART_EVENT_RX_OVERFLOW : data lost during transfer or because receiver is enabled but transfer operation has not been started
Transfer operation can also be aborted by calling \ref ARM_USART_Control with \ref ARM_USART_ABORT_TRANSFER as the control parameter.
*****************************************************************************************************************/
uint32_t ARM_USART_GetTxCount (void) {
return 0;
}
/**
\fn uint32_t ARM_USART_GetTxCount (void)
\details
The function \b ARM_USART_GetTxCount returns the number of the currently transmitted data items during \ref ARM_USART_Send and \ref ARM_USART_Transfer operation.
*****************************************************************************************************************/
uint32_t ARM_USART_GetRxCount (void) {
return 0;
}
/**
\fn uint32_t ARM_USART_GetRxCount (void)
\details
The function \b ARM_USART_GetRxCount returns the number of the currently received data items during \ref ARM_USART_Receive and \ref ARM_USART_Transfer operation.
*****************************************************************************************************************/
int32_t ARM_USART_Control (uint32_t control, uint32_t arg) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_Control (uint32_t control, uint32_t arg)
\details
The function \b ARM_USART_Control control the USART interface settings and execute various operations.
The parameter \em control sets the operation and is explained in the table below.
Values from different categories can be ORed with the exception of \ref usart_misc_tab "Miscellaneous Operations".
The parameter \em arg provides, depending on the operation, additional information, for example the baudrate.
The table lists the available \em control operations.
<TABLE class="cmtable" summary="">
<TR><TH>Parameter \em control </TH> <TH style="text-align:right"> Bit </TH> <TH> Category </TH> <TH>Description </TH></TR>
<TR><TD>\ref ARM_USART_MODE_ASYNCHRONOUS</TD> <td rowspan="6" style="text-align:right"> 0..7 </td> <td rowspan="6"> Operation Mode </td><TD>Set to asynchronous UART mode. \em arg specifies baudrate.</TD></TR>
<TR><TD>\ref ARM_USART_MODE_SYNCHRONOUS_MASTER</TD> <TD>Set to synchronous master mode with clock signal generation. \em arg specifies baudrate.</TD></TR>
<TR><TD>\ref ARM_USART_MODE_SYNCHRONOUS_SLAVE</TD> <TD>Set to synchronous slave mode with external clock signal.</TD></TR>
<TR><TD>\ref ARM_USART_MODE_SINGLE_WIRE</TD> <TD>Set to single-wire (half-duplex) mode. \em arg specifies baudrate.</TD></TR>
<TR><TD>\ref ARM_USART_MODE_IRDA</TD> <TD>Set to Infra-red data mode. \em arg specifies baudrate.</TD></TR>
<TR><TD>\ref ARM_USART_MODE_SMART_CARD</TD> <TD>Set to Smart Card mode. \em arg specifies baudrate.</TD></TR>
<TR><TD>\ref ARM_USART_DATA_BITS_5</TD> <td rowspan="5" style="text-align:right"> 8..11 </td> <td rowspan="5"> Data Bits </td><TD>Set to \token{5} data bits</TD></TR>
<TR><TD>\ref ARM_USART_DATA_BITS_6</TD> <TD>Set to \token{6} data bits</TD></TR>
<TR><TD>\ref ARM_USART_DATA_BITS_7</TD> <TD>Set to \token{7} data bits</TD></TR>
<TR><TD>\ref ARM_USART_DATA_BITS_8</TD> <TD>Set to \token{8} data bits (default)</TD></TR>
<TR><TD>\ref ARM_USART_DATA_BITS_9</TD> <TD>Set to \token{9} data bits</TD></TR>
<TR><TD>\ref ARM_USART_PARITY_EVEN</TD> <td rowspan="3" style="text-align:right"> 12..13 </td> <td rowspan="3"> Parity Bit </td><TD>Set to Even Parity</TD></TR>
<TR><TD>\ref ARM_USART_PARITY_NONE</TD> <TD>Set to No Parity (default)</TD></TR>
<TR><TD>\ref ARM_USART_PARITY_ODD</TD> <TD>Set to Odd Parity</TD></TR>
<TR><TD>\ref ARM_USART_STOP_BITS_1</TD> <td rowspan="4" style="text-align:right"> 14..15 </td> <td rowspan="4"> Stop Bit </td><TD>Set to \token{1} Stop bit (default)</TD></TR>
<TR><TD>\ref ARM_USART_STOP_BITS_2</TD> <TD>Set to \token{2} Stop bits</TD></TR>
<TR><TD>\ref ARM_USART_STOP_BITS_1_5</TD> <TD>Set to \token{1.5} Stop bits</TD></TR>
<TR><TD>\ref ARM_USART_STOP_BITS_0_5</TD> <TD>Set to \token{0.5} Stop bits</TD></TR>
<TR><TD>\ref ARM_USART_FLOW_CONTROL_NONE</TD> <td rowspan="4" style="text-align:right"> 16..17 </td> <td rowspan="4"> Flow Control </td><TD>No flow control signal (default)</TD></TR>
<TR><TD>\ref ARM_USART_FLOW_CONTROL_CTS</TD> <TD>Set to use the CTS flow control signal</TD></TR>
<TR><TD>\ref ARM_USART_FLOW_CONTROL_RTS</TD> <TD>Set to use the RTS flow control signal</TD></TR>
<TR><TD>\ref ARM_USART_FLOW_CONTROL_RTS_CTS</TD> <TD>Set to use the RTS and CTS flow control signal</TD></TR>
<TR><TD>\ref ARM_USART_CPOL0</TD> <td rowspan="2" style="text-align:right"> 18 </td> <td rowspan="2"> Clock Polarity </td><TD>CPOL=\token{0} (default) : data are captured on rising edge (low->high transition)</TD></TR>
<TR><TD>\ref ARM_USART_CPOL1</TD> <TD>CPOL=\token{1} : data are captured on falling edge (high->low transition)</TD></TR>
<TR><TD>\ref ARM_USART_CPHA0</TD> <td rowspan="2" style="text-align:right"> 19 </td> <td rowspan="2"> Clock Phase </td><TD>CPHA=\token{0} (default) : sample on first (leading) edge</TD></TR>
<TR><TD>\ref ARM_USART_CPHA1</TD> <TD>CPHA=\token{1} : sample on second (trailing) edge</TD></TR>
<TR><TD>\ref ARM_USART_ABORT_RECEIVE</TD> <td rowspan="11" style="text-align:right"> 0..19 </td> <td rowspan="11"> \anchor usart_misc_tab Miscellaneous Operations <br>(cannot be ORed) </td><TD>Abort receive operation (see also: \ref ARM_USART_Receive)</TD></TR>
<TR> <TD>\ref ARM_USART_ABORT_SEND</TD> <TD>Abort send operation (see also: \ref ARM_USART_Send)</TD></TR>
<TR> <TD>\ref ARM_USART_ABORT_TRANSFER</TD> <TD>Abort transfer operation (see also: \ref ARM_USART_Transfer)</TD></TR>
<TR> <TD>\ref ARM_USART_CONTROL_BREAK</TD> <TD>Enable or disable continuous Break transmission; \em arg : \token{0=disabled; 1=enabled}</TD></TR>
<TR> <TD>\ref ARM_USART_CONTROL_RX</TD> <TD>Enable or disable receiver; \em arg : \token{0=disabled; 1=enabled} (see also: \ref ARM_USART_Receive; \ref ARM_USART_Transfer)</TD></TR>
<TR> <TD>\ref ARM_USART_CONTROL_SMART_CARD_NACK</TD> <TD>Enable or disable Smart Card NACK generation; \em arg : \token{0=disabled; 1=enabled}</TD></TR>
<TR> <TD>\ref ARM_USART_CONTROL_TX</TD> <TD>Enable or disable transmitter; \em arg : \token{0=disabled; 1=enabled} (see also: \ref ARM_USART_Send; \ref ARM_USART_Transfer)</TD></TR>
<TR> <TD>\ref ARM_USART_SET_DEFAULT_TX_VALUE</TD> <TD>Set the default transmit value (synchronous receive only); \em arg specifies the value. (see also: \ref ARM_USART_Receive)</TD></TR>
<TR> <TD>\ref ARM_USART_SET_IRDA_PULSE</TD> <TD>Set the IrDA pulse value in \token{ns}; \em arg : \token{0=3/16 of bit period}</TD></TR>
<TR> <TD>\ref ARM_USART_SET_SMART_CARD_CLOCK</TD> <TD>Set the Smart Card Clock in \token{Hz}; \em arg : \token{0=Clock not set}</TD></TR>
<TR> <TD>\ref ARM_USART_SET_SMART_CARD_GUARD_TIME</TD> <TD>Set the Smart Card guard time; \em arg = number of bit periods</TD></TR>
</TABLE>
\b Example
\code
extern ARM_DRIVER_USART Driver_USART0;
// configure to UART mode: 8 bits, no parity, 1 stop bit, no flow control, 9600 bps
status = Driver_USART0.Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, 9600);
// identical with above settings (default settings removed)
// configure to UART mode: 8 bits, no parity, 1 stop bit, flow control, 9600 bps
status = Driver_USART0.Control(ARM_USART_MODE_ASYNCHRONOUS, 9600);
// enable TX output
status = Driver_USART0.Control(ARM_USART_CONTROL_TX, 1);
// disable RX output
status = Driver_USART0.Control(ARM_USART_CONTROL_RX, 0);
\endcode
*****************************************************************************************************************/
ARM_USART_STATUS ARM_USART_GetStatus (void) {
return { 0 };
}
/**
\fn ARM_USART_STATUS ARM_USART_GetStatus (void)
\details
The function \b ARM_USART_GetStatus retrieves the current USART interface status.
*****************************************************************************************************************/
int32_t ARM_USART_SetModemControl (ARM_USART_MODEM_CONTROL control) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USART_SetModemControl (ARM_USART_MODEM_CONTROL control)
\details
The function \b ARM_USART_SetModemControl activates or deactivates the selected USART modem control line.
The function \ref ARM_USART_GetModemStatus returns information about status of the modem lines.
*****************************************************************************************************************/
ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus (void) {
return { 0 };
}
/**
\fn ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus (void)
\details
The function \b ARM_USART_GetModemStatus returns the current USART Modem Status lines state.
The function \ref ARM_USART_SetModemControl sets the modem control lines of the USART.
*****************************************************************************************************************/
void ARM_USART_SignalEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_USART_SignalEvent (uint32_t event)
\details
The function \b ARM_USART_SignalEvent is a callback function registered by the function \ref ARM_USART_Initialize.
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_USART_CAPABILITIES, which can be retrieved with the function \ref ARM_USART_GetCapabilities.
The following events can be generated:
<table class="cmtable" summary="">
<tr>
<th> Parameter \em event </th><th> Bit </th><th> Description </th>
<th> supported when ARM_USART_CAPABILITIES </th>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_SEND_COMPLETE </td><td> 0 </td><td> Occurs after call to \ref ARM_USART_Send to indicate that all the data to be sent
was processed by the driver. All the data might have been already transmitted
or parts of it are still queued in transmit buffers. The driver is ready for the next
call to \ref ARM_USART_Send; however USART may still transmit data. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_RECEIVE_COMPLETE </td><td> 1 </td><td> Occurs after call to \ref ARM_USART_Receive to indicate that all the data has been
received. The driver is ready for the next call to \ref ARM_USART_Receive. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_TRANSFER_COMPLETE </td><td> 2 </td><td> Occurs after call to \ref ARM_USART_Transfer to indicate that all the data has been
transferred. The driver is ready for the next call to \ref ARM_USART_Transfer. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_TX_COMPLETE </td><td> 3 </td><td> Occurs after call to \ref ARM_USART_Send to indicate that all the data has been
physically transmitted on the wires. </td>
<td> data field \em event_tx_complete = \token{1} </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_TX_UNDERFLOW </td><td> 4 </td><td> Occurs in synchronous slave mode when data is requested by the master but
send/receive/transfer operation has not been started.
Data field \em rx_underflow = \token{1} of \ref ARM_USART_STATUS. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_RX_OVERFLOW </td><td> 5 </td><td> Occurs when data is lost during receive/transfer operation or when data is lost
because receive operation in asynchronous mode or receive/send/transfer operation in
synchronous slave mode has not been started.
Data field \em rx_overflow = \token{1} of \ref ARM_USART_STATUS. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> ARM_USART_EVENT_RX_TIMEOUT </td><td> 6 </td><td> Occurs during receive when idle time is detected between consecutive characters
(idle time is hardware dependent).</td>
<td> data field \em event_rx_timeout = \token{1} </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_RX_BREAK </td><td> 7 </td><td> Occurs when break is detected during receive.
Data field \em rx_break = \token{1} of \ref ARM_USART_STATUS. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_RX_FRAMING_ERROR </td><td> 8 </td><td> Occurs when framing error is detected during receive.
Data field \em rx_framing_error = \token{1} of \ref ARM_USART_STATUS. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> \ref ARM_USART_EVENT_RX_PARITY_ERROR </td><td> 9 </td><td> Occurs when parity error is detected during receive.
Data field \em rx_parity_error = \token{1} of \ref ARM_USART_STATUS. </td>
<td> <i>always supported</i> </td>
</tr>
<tr>
<td> ARM_USART_EVENT_CTS </td><td> 10 </td><td> Indicates that CTS modem line state has changed.
Data field \em cts of \ref ARM_USART_MODEM_STATUS has changed. </td>
<td> data field \em event_cts = \token{1} and <br>
data field \em cts = \token{1} </td>
</tr>
<tr>
<td> ARM_USART_EVENT_DSR </td><td> 11 </td><td> Indicates that DSR modem line state has changed.
Data field \em dsr of \ref ARM_USART_MODEM_STATUS has changed. </td>
<td> data field \em event_dsr = \token{1} and <br>
data field \em dsr = \token{1} </td>
</tr>
<tr>
<td> ARM_USART_EVENT_DCD </td><td> 12 </td><td> Indicates that DCD modem line state has changed.
Data field \em dcd of \ref ARM_USART_MODEM_STATUS has changed. </td>
<td> data field \em event_dcd = \token{1} and <br>
data field \em dcd = \token{1} </td>
</tr>
<tr>
<td> ARM_USART_EVENT_RI </td><td> 13 </td><td> Indicates that RI modem line state has changed from active to inactive
(trailing edge on RI).
Data field \em ri of \ref ARM_USART_MODEM_STATUS has changed from \token{1} to \token{0}. </td>
<td> data field \em event_ri = \token{1} and <br>
data field \em ri = \token{1} </td>
</tr>
</table>
*****************************************************************************************************************/
/**
@}
*/
// End USART Interface

View File

@ -0,0 +1,153 @@
/**
\defgroup usb_interface_gr USB Interface
\brief USB common definitions (%Driver_USB.h)
\details
The <b>Universal Serial Bus</b> (USB) implements a serial bus for data exchange. It is a host controlled, plug-and-play interface
between a USB host and USB devices using a tiered star topology.
In microcontroller (MCU) applications, the interface is often used to connect a device to a host for data exchange or control purposes.
- Wikipedia offers more information about the <a href="http://en.wikipedia.org/wiki/Universal_Serial_Bus" target="_blank"><b>Universal Serial Bus</b></a>.
- The USB Implementers Forum provides detailed documentation under <a href="http://www.usb.org"><b>www.usb.org</b></a>.
<b>Block Diagram</b>
Typically only one USB Device is connected to a USB Host. If several USB devices must be connected to the same USB host, then
the connection must be done via a USB hub.
<p>
\image html USB_Schematics.png "Simplified USB Schema"
</p>
<b>USB API</b>
The following header files define the Application Programming Interface (API) for the USB interface:
- \b %Driver_USB.h : Common definitions of the USBD and USBH interface
- \b %Driver_USBD.h : Driver API for USB Device Peripheral
- \b %Driver_USBH.h : Driver API for USB Host Peripheral
The driver implementation is a typical part of the Device Family Pack (DFP) that supports the
peripherals of the microcontroller family.
<b>Driver Functions</b>
The driver functions are published in the access struct as explained in \ref DriverFunctions
- \ref ARM_DRIVER_USBD : access struct for USBD driver functions
- \ref ARM_DRIVER_USBH : access struct for USBH driver functions
<hr>
*/
/**
\addtogroup usbd_interface_gr
\ingroup usb_interface_gr
\details
<b>USB Device API</b>
The header file \b Driver_USBD.h defines the API for the <b>USB Device Driver</b> interface used by middleware components.
The driver implementation itself is a typical part of the Device Family Pack, which provides entry points to the interface
as function pointers in the struct \ref ARM_DRIVER_USBD. This structure can be available several times in each interface to control multiple USBD interfaces.
Header file \b Driver_USBD.h also defines callback routines that can be categorized as
<b>device event callbacks</b> and <b>endpoint event callbacks</b>.
Callbacks are called by the driver, in interrupt context when an appropriate event occurs, to signal device related events (\ref USBD_dev_events)
and endpoint related events (\ref USBD_ep_events).
<b>USB Device Function Call Sequence</b>
To use the USBD driver invoke the API functions in the following order:
\msc
a [label="", textcolor="indigo", linecolor="indigo", arclinecolor="red"],
b [label="", textcolor="blue", linecolor="blue", arclinecolor="blue"];
a rbox a [label="Middleware", linecolor="indigo"],
b rbox b [label="USBD Driver", linecolor="blue"];
a=>b [label="ARM_USBD_Initialize", URL="\ref ARM_USBD_Initialize"];
a=>b [label="ARM_USBD_PowerControl (ARM_POWER_FULL)", URL="\ref ARM_USBD_Initialize"];
a=>b [label="ARM_USBD_DeviceConnect", URL="\ref ARM_USBD_DeviceConnect"];
a<=b [label="ARM_USBD_SignalDeviceEvent (ARM_USBD_EVENT_RESET)", URL="\ref ARM_USBD_SignalDeviceEvent", linecolor="orange"];
a=>b [label="ARM_USBD_DeviceGetState", URL="\ref ARM_USBD_DeviceGetState"];
a=>b [label="ARM_USBD_EndpointConfigure", URL="\ref ARM_USBD_EndpointConfigure", linecolor="green"];
--- [label="Repeat and use as needed"];
a=>b [label="ARM_USBD_EndpointTransfer", URL="\ref ARM_USBD_EndpointTransfer", linecolor="green"];
a<=b [label="ARM_USBD_SignalEndpointEvent", URL="\ref ARM_USBD_SignalEndpointEvent", linecolor="orange"];
a=>b [label="ARM_USBD_EndpointTransferGetResult", URL="\ref ARM_USBD_EndpointTransferGetResult", linecolor="green"];
--- [label="Repeat End"];
a=>b [label="ARM_USBD_DeviceDisconnect", URL="\ref ARM_USBD_DeviceDisconnect"];
a=>b [label="ARM_USBD_PowerControl (ARM_POWER_OFF)", URL="\ref ARM_USBD_Initialize"];
a=>b [label="ARM_USBD_Uninitialize", URL="\ref ARM_USBD_Uninitialize"];
\endmsc
*/
/**
\addtogroup usbh_interface_gr
\ingroup usb_interface_gr
\details
<b>USB Host API</b>
The header file \b Driver_USBH.h defines the API for the <b>USB Host Driver</b> interface used by middleware components.
The driver implementation itself is a typical part of the Device Family Pack, which provides entry points to the interface
as function pointers in the struct \ref ARM_DRIVER_USBH. This structure can be available several times in each interface to control multiple USBH interfaces.
\b Driver_USBH.h also defines callback routines, which are categorized in
<b>port event callbacks</b> and <b>pipe event callbacks</b>.
Callbacks are called by the driver, in interrupt context when an appropriate event occurs, to signal port related events (\ref ARM_USBH_SignalPortEvent)
and pipe related events (\ref ARM_USBH_SignalPipeEvent).
\cond
<b>USB Host Function Call Sequence</b>
To use the USBH driver invoke the API functions in the following order:
\msc
a [label="", textcolor="indigo", linecolor="indigo", arclinecolor="red"],
b [label="", textcolor="blue", linecolor="blue", arclinecolor="blue"];
a rbox a [label="Middleware", linecolor="indigo"],
b rbox b [label="USBH Driver", linecolor="blue"];
a=>b [label="ARM_USBH_Initialize", URL="\ref ARM_USBD_Initialize"];
--- [label="Repeat and use as needed"];
--- [label="Repeat End"];
a=>b [label="ARM_USBH_Uninitialize", URL="\ref ARM_USBH_Uninitialize"];
\endmsc
<hr>
\endcond
*/
/**
\defgroup USB_speed USB Speed
\ingroup usb_interface_gr
\brief USB Speed definitions
\details
The following USB speed values are defined:
@{
\def ARM_USB_SPEED_LOW
\def ARM_USB_SPEED_FULL
\def ARM_USB_SPEED_HIGH
@}
*/
/**
\defgroup USB_endpoint_type USB Endpoint Type
\ingroup usb_interface_gr
\brief USB Endpoint Type definitions
\details
The following USB Endpoint Type values are defined:
@{
\def ARM_USB_ENDPOINT_CONTROL
\def ARM_USB_ENDPOINT_ISOCHRONOUS
\def ARM_USB_ENDPOINT_BULK
\def ARM_USB_ENDPOINT_INTERRUPT
@}
*/

View File

@ -0,0 +1,420 @@
/**
\defgroup usbd_interface_gr USB Device Interface
\ingroup usb_interface_gr
\brief Driver API for USB Device Peripheral (%Driver_USBD.h)
@{
*/
/**
\struct ARM_DRIVER_USBD
\details
The functions of the USB Device driver are accessed by function pointers. Refer to \ref DriverFunctions for
overview information.
Each instance of an USBD provides such an access struct. The instance is indicated by
a postfix in the symbol name of the access struct, for example:
- \b Driver_USBD0 is the name of the access struct of the first instance (no. 0).
- \b Driver_USBD1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_USBD<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
\note The struct must remain unchanged.
*****************************************************************************************************************/
/**
\struct ARM_USBD_CAPABILITIES
\details
A USB Device driver can be implemented with different capabilities.
The data fields of this structure encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_USBD_GetCapabilities
\note The struct must remain unchanged.
*****************************************************************************************************************/
/**
\struct ARM_USBD_STATE
\details
This structure stores information about the state of the USB Device. The data fields encode the established speed,
whether the device is powered and active.
<b>Returned by:</b>
- \ref ARM_USBD_DeviceGetState
*****************************************************************************************************************/
/**
\typedef ARM_USBD_SignalDeviceEvent_t
\details
Provides the typedef for the callback function \ref ARM_USBD_SignalDeviceEvent.
<b>Parameter for:</b>
- \ref ARM_USBD_Initialize
*******************************************************************************************************************/
/**
\typedef ARM_USBD_SignalEndpointEvent_t
\details
Provides the typedef for the callback function \ref ARM_USBD_SignalEndpointEvent.
<b>Parameter for:</b>
- \ref ARM_USBD_Initialize
*******************************************************************************************************************/
/**
\defgroup USBD_dev_events USBD Device Events
\ingroup usbd_interface_gr
\brief The USB Device driver generates Device call back events that are notified via the function \ref ARM_USBD_SignalDeviceEvent.
\details
This section provides the event values for the \ref ARM_USBD_SignalDeviceEvent callback function.
The following call back notification events are generated:
@{
\def ARM_USBD_EVENT_VBUS_ON
\def ARM_USBD_EVENT_VBUS_OFF
\def ARM_USBD_EVENT_RESET
\def ARM_USBD_EVENT_HIGH_SPEED
\def ARM_USBD_EVENT_SUSPEND
\def ARM_USBD_EVENT_RESUME
@}
*/
/**
\defgroup USBD_ep_events USBD Endpoint Events
\ingroup usbd_interface_gr
\brief The USB Device driver generates Endpoint call back events that are notified via the function \ref ARM_USBD_SignalEndpointEvent.
\details
This section provides the event values for the \ref ARM_USBD_SignalEndpointEvent callback function.
The following call back notification events are generated:
@{
\def ARM_USBD_EVENT_SETUP
\def ARM_USBD_EVENT_OUT
\def ARM_USBD_EVENT_IN
@}
*/
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBD_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_USBD_GetVersion (void)
\details
The function \b ARM_USBD_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_USBD Driver_USBD0;
ARM_DRIVER_USBD *drv_info;
void setup_usbd (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_USBD0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
ARM_USBD_CAPABILITIES ARM_USBD_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_USBD_CAPABILITIES ARM_USBD_GetCapabilities (void)
\details
The function \b ARM_USBD_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_USBD_CAPABILITIES encode various capabilities, for example
if the hardware can create signal events using the \ref ARM_USBD_SignalDeviceEvent callback function.
Example:
\code
extern ARM_DRIVER_USBD Driver_USBD0;
ARM_DRIVER_USBD *drv_info;
void read_capabilities (void) {
ARM_USBD_CAPABILITIES drv_capabilities;
drv_info = &Driver_USBD0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*****************************************************************************************************************/
int32_t ARM_USBD_Initialize (ARM_USBD_SignalDeviceEvent_t cb_device_event,
ARM_USBD_SignalEndpointEvent_t cb_endpoint_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_Initialize (ARM_USBD_SignalDeviceEvent_t cb_device_event, ARM_USBD_SignalEndpointEvent_t cb_endpoint_event)
\details
The function \b ARM_USBD_Initialize initializes the USB Device interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the USBD interface.
- Registers the \ref ARM_USBD_SignalDeviceEvent callback function.
- Registers the \ref ARM_USBD_SignalEndpointEvent callback function.
The parameter \em cb_device_event is a pointer to the \ref ARM_USBD_SignalDeviceEvent callback function; use a NULL pointer
when no device callback signals are required. \n
The parameter \em cb_endpoint_event is a pointer to the \ref ARM_USBD_SignalEndpointEvent callback function.
\b Example:
- see \ref usbd_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_USBD_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_Uninitialize (void)
\details
The function \b ARM_USBD_Uninitialize de-initializes the resources of USBD interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_USBD_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_USBD_PowerControl operates the power modes of the USB Device interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*****************************************************************************************************************/
int32_t ARM_USBD_DeviceConnect (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_DeviceConnect (void)
\details
The function \b ARM_USBD_DeviceConnect signals to the host that the device is connected.
*****************************************************************************************************************/
int32_t ARM_USBD_DeviceDisconnect (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_DeviceDisconnect (void)
\details
The function \b ARM_USBD_DeviceDisconnect signals to the host that the device is disconnected.
*****************************************************************************************************************/
ARM_USBD_STATE ARM_USBD_DeviceGetState (void) {
return ARM_DRIVER_OK;
}
/**
\fn ARM_USBD_STATE ARM_USBD_DeviceGetState (void)
\details
Retrieves the current USB device state.
*****************************************************************************************************************/
int32_t ARM_USBD_DeviceRemoteWakeup (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_DeviceRemoteWakeup (void)
\details
The function \b ARM_USBD_DeviceRemoteWakeup signals remote wakeup to the host.
*****************************************************************************************************************/
int32_t ARM_USBD_DeviceSetAddress (uint8_t dev_addr) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_DeviceSetAddress (uint8_t dev_addr)
\details
Assigns an address to the device.
\note This function is called after status stage of the Set Address request (after IN packet in status stage was sent with the old address).
*****************************************************************************************************************/
int32_t ARM_USBD_ReadSetupPacket (uint8_t *setup) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_ReadSetupPacket (uint8_t *setup)
\details
The function \b ARM_USBD_ReadSetupPacket reads the last SETUP packet (8 bytes) that was received over Control Endpoint (Endpoint 0)
which is indicated by \ref ARM_USBD_EVENT_SETUP event.
<b>See also:</b>
- \ref ARM_USBD_SignalEndpointEvent
*****************************************************************************************************************/
int32_t ARM_USBD_EndpointConfigure (uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_EndpointConfigure (uint8_t ep_addr, uint8_t ep_type, uint16_t ep_max_packet_size)
\details
The function \b ARM_USBD_EndpointConfigure configures an endpoint for transfers.
*****************************************************************************************************************/
int32_t ARM_USBD_EndpointUnconfigure (uint8_t ep_addr) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_EndpointUnconfigure (uint8_t ep_addr)
\details
The function \b ARM_USBD_EndpointUnconfigure de-configures the specified endpoint.
The parameter \em ep_addr specifies the endpoint address.
*****************************************************************************************************************/
int32_t ARM_USBD_EndpointStall (uint8_t ep_addr, bool stall) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_EndpointStall (uint8_t ep_addr, bool stall)
\details
The function \b ARM_USBD_EndpointStall sets or clears stall condition for the specified endpoint.
The parameter \em ep_addr specifies the endpoint address. \n
The parameter \em stall is a boolean parameter.
*****************************************************************************************************************/
int32_t ARM_USBD_EndpointTransfer (uint8_t ep_addr, uint8_t *data, uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_EndpointTransfer (uint8_t ep_addr, uint8_t *data, uint32_t num)
\details
The function \b ARM_USBD_EndpointTransfer reads from or writes data to an USB Endpoint.
The parameter \em ep_addr specifies the endpoint address. \n
The parameter \em data is a buffer for data to read or data to write. \n
The parameter \em num is the number of bytes to transfer (must be multiple of endpoint maximum packet size for Read transfers).
The function is non-blocking and returns as soon as the driver starts the operation on the specified endpoint.
During the operation it is not allowed to call this function again on the same endpoint.
Also the data buffer must stay allocated and the contents of data must not be modified.
Direction in the endpoint address specifies the type of transfer:
- Endpoint Read for OUT endpoint (direction = 0)
- Endpoint Write for IN endpoint (direction = 1)
Endpoint Read is finished when the requested number of data bytes have been received or when a short packet or ZLP (Zero-Length Packet) has been received.
Completion of operation is indicated by \ref ARM_USBD_EVENT_OUT event. Number of successfully received data bytes can be retrieved
by calling \ref ARM_USBD_EndpointTransferGetResult.
Endpoint Write is finished when the requested number of data bytes have been sent.
Completion of operation is indicated by \ref ARM_USBD_EVENT_IN event. Number of successfully sent data bytes can be retrieved
by calling \ref ARM_USBD_EndpointTransferGetResult.
Transfer operation can be aborted by calling \ref ARM_USBD_EndpointTransferAbort.
*****************************************************************************************************************/
uint32_t ARM_USBD_EndpointTransferGetResult (uint8_t ep_addr) {
return 0;
}
/**
\fn uint32_t ARM_USBD_EndpointTransferGetResult (uint8_t ep_addr)
\details
The function \b ARM_USBD_EndpointTransferGetResult returns the number of successfully transferred data bytes started by \ref ARM_USBD_EndpointTransfer.
The parameter \em ep_addr specifies the endpoint address.
*****************************************************************************************************************/
int32_t ARM_USBD_EndpointTransferAbort (uint8_t ep_addr) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBD_EndpointTransferAbort (uint8_t ep_addr)
\details
The function \b ARM_USBD_EndpointTransferAbort aborts the transfer to an endpoint started by \ref ARM_USBD_EndpointTransfer.
The parameter \em ep_addr specifies the endpoint address.
*****************************************************************************************************************/
uint16_t ARM_USBD_GetFrameNumber (void) {
return 0;
}
/**
\fn uint16_t ARM_USBD_GetFrameNumber (void)
\details
Retrieves the sequential 11-bit frame number of the last Start of Frame (SOF) packet.
*****************************************************************************************************************/
void ARM_USBD_SignalDeviceEvent (uint32_t event) {
// function body
}
/**
\fn void ARM_USBD_SignalDeviceEvent (uint32_t event)
\details
The function \b ARM_USBD_SignalDeviceEvent is a callback function registered by the function \ref ARM_USBD_Initialize.
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_USBD_CAPABILITIES, which can be retrieved with the function \ref ARM_USBD_GetCapabilities.
The following events can be generated:
Event | Bit| Description | supported when \ref ARM_USBD_CAPABILITIES
:-------------------------------|---:|:---------------------------------------------------|----------------------------------------------
\ref ARM_USBD_EVENT_VBUS_ON | 0 | Occurs when valid VBUS voltage is detected. | data field \em event_vbus_on = \token{1}
\ref ARM_USBD_EVENT_VBUS_OFF | 1 | Occurs when VBUS voltage is turned off. | data field \em event_vbus_off = \token{1}
\ref ARM_USBD_EVENT_RESET | 2 | Occurs when USB Reset is detected. | <i>always supported</i>
\ref ARM_USBD_EVENT_HIGH_SPEED | 3 | Occurs when USB Device is switched to High-speed. | <i>always supported</i>
\ref ARM_USBD_EVENT_SUSPEND | 4 | Occurs when USB Suspend is detected. | <i>always supported</i>
\ref ARM_USBD_EVENT_RESUME | 5 | Occurs when USB Resume is detected. | <i>always supported</i>
*****************************************************************************************************************/
void ARM_USBD_SignalEndpointEvent (uint8_t ep_addr, uint32_t ep_event) {
// function body
}
/**
\fn void ARM_USBD_SignalEndpointEvent (uint8_t ep_addr, uint32_t event)
\details
The function \b ARM_USBD_SignalEndpointEvent is a callback function registered by the function \ref ARM_USBD_Initialize.
The argument \a ep_addr specifies the endpoint. \n
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
The following events can be generated:
Event | Bit | Description
:----------------------------------------|----:|:-----------
\ref ARM_USBD_EVENT_SETUP | 0 | Occurs when SETUP packet is received over Control Endpoint.
\ref ARM_USBD_EVENT_OUT | 1 | Occurs when data is received over OUT Endpoint.
\ref ARM_USBD_EVENT_IN | 2 | Occurs when data is sent over IN Endpoint.
*****************************************************************************************************************/
/**
@}
*/
// End USBD Interface

View File

@ -0,0 +1,681 @@
/**
\defgroup usbh_interface_gr USB Host Interface
\ingroup usb_interface_gr
\brief Driver API for USB Host Peripheral (%Driver_USBH.h)
*/
/**
\defgroup usbh_host_gr USB Host
\ingroup usbh_interface_gr
\brief Driver API for USB Host
@{
*/
/**
\struct ARM_DRIVER_USBH
\details
The functions of the USB Host driver are accessed by function pointers. Refer to \ref DriverFunctions for
overview information.
Each instance of an USBH provides such an access struct. The instance is indicated by
a postfix in the symbol name of the access struct, for example:
- \b Driver_USBH0 is the name of the access struct of the first instance (no. 0).
- \b Driver_USBH1 is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_USBH<i>n</i></b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
\note The struct must remain unchanged.
*****************************************************************************************************************/
/**
\struct ARM_USBH_CAPABILITIES
\details
A USB Host driver can be implemented with different capabilities.
The data fields of this structure encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_USBH_GetCapabilities
\note The struct must remain unchanged.
*****************************************************************************************************************/
/**
\struct ARM_USBH_PORT_STATE
\details
This structure stores information about the state of the USB Host Port. The data fields encode whether a device
is connected to the port, if port overcurrent is detected, and the port speed.
<b>Returned by:</b>
- \ref ARM_USBH_PortGetState
*****************************************************************************************************************/
/**
\typedef uint32_t ARM_USBH_PIPE_HANDLE
\details
Each pipe is identified through a unique number, which is created by the function \ref ARM_USBH_PipeCreate.
<b>Parameter for:</b>
- \ref ARM_USBH_PipeModify,
\ref ARM_USBH_PipeDelete,
\ref ARM_USBH_PipeReset,
\ref ARM_USBH_PipeTransfer,
\ref ARM_USBH_PipeTransferGetResult,
\ref ARM_USBH_PipeTransferAbort,
\ref ARM_USBH_SignalPipeEvent
<b>Retruned by:</b>
- \ref ARM_USBH_PipeCreate
*****************************************************************************************************************/
/**
\typedef ARM_USBH_SignalPortEvent_t
\details
Provides the typedef for the callback function \ref ARM_USBH_SignalPortEvent.
<b>Parameter for:</b>
- \ref ARM_USBH_Initialize
*******************************************************************************************************************/
/**
\typedef ARM_USBH_SignalPipeEvent_t
\details
Provides the typedef for the callback function \ref ARM_USBH_SignalPipeEvent.
<b>Parameter for:</b>
- \ref ARM_USBH_Initialize
*******************************************************************************************************************/
/**
\defgroup USBH_port_events USBH Port Events
\ingroup usbh_host_gr
\brief The USB Host driver generates Port call back events that are notified via the function \ref ARM_USBH_SignalPortEvent.
\details
This section provides the event values for the \ref ARM_USBH_SignalPortEvent callback function.
The following call back notification events are generated:
@{
\def ARM_USBH_EVENT_CONNECT
\def ARM_USBH_EVENT_DISCONNECT
\def ARM_USBH_EVENT_OVERCURRENT
\def ARM_USBH_EVENT_RESET
\def ARM_USBH_EVENT_SUSPEND
\def ARM_USBH_EVENT_RESUME
\def ARM_USBH_EVENT_REMOTE_WAKEUP
@}
*/
/**
\defgroup USBH_pipe_events USBH Pipe Events
\ingroup usbh_host_gr
\brief The USB Host driver generates Pipe call back events that are notified via the function \ref ARM_USBH_SignalPipeEvent.
\details
This section provides the event values for the \ref ARM_USBH_SignalPipeEvent callback function.
The following call back notification events are generated:
@{
\def ARM_USBH_EVENT_TRANSFER_COMPLETE
\def ARM_USBH_EVENT_HANDSHAKE_NAK
\def ARM_USBH_EVENT_HANDSHAKE_NYET
\def ARM_USBH_EVENT_HANDSHAKE_MDATA
\def ARM_USBH_EVENT_HANDSHAKE_STALL
\def ARM_USBH_EVENT_HANDSHAKE_ERR
\def ARM_USBH_EVENT_BUS_ERROR
@}
*/
/**
\defgroup USBH_packets USBH Packet Information
\ingroup usbh_host_gr
\brief Specify USB packet information used by the function \ref ARM_USBH_PipeTransfer
\details
This section provides the packet information values (parameter \em packet) for the \ref ARM_USBH_PipeTransfer function.
The following values are defined:
@{
\def ARM_USBH_PACKET_SETUP
Generate SETUP transaction.
\def ARM_USBH_PACKET_OUT
Generate OUT transaction.
\def ARM_USBH_PACKET_IN
Generate IN transaction.
\def ARM_USBH_PACKET_PING
Generate PING transaction (no data packet).
\def ARM_USBH_PACKET_DATA0
Force DATA0 PID (Packet Identifier) for the initial data packet. When not specified than the driver provides the initial value according to the current state.
\def ARM_USBH_PACKET_DATA1
Force DATA1 PID (Packet Identifier) for the initial data packet. When not specified than the driver provides the initial value according to the current state.
\def ARM_USBH_PACKET_SSPLIT
Used when driver does not support automatic handling of SPLIT packets and indicates Start-Split packet.
For isochronous OUT it indicates that the High-speed data is in the middle of the Full-speed data payload.
\def ARM_USBH_PACKET_SSPLIT_S
Used when driver does not support automatic handling of SPLIT packets and indicates Start-Split packet.
Valid only for isochronous OUT and indicates that the High-speed data is the start of the Full-speed data payload.
\def ARM_USBH_PACKET_SSPLIT_E
Used when driver does not support automatic handling of SPLIT packets and indicates Start-Split packet.
Valid only for isochronous OUT and indicates that the High-speed data is the end of the Full-speed data payload.
\def ARM_USBH_PACKET_SSPLIT_S_E
Used when driver does not support automatic handling of SPLIT packets and indicates Start-Split packet.
Valid only for isochronous OUT and indicates that the High-speed data is all of the Full-speed data payload.
\def ARM_USBH_PACKET_CSPLIT
Used when driver does not support automatic handling of SPLIT packets and indicates Complete-Split packet.
\def ARM_USBH_PACKET_PRE
Generate PRE (Preamble) for low-speed devices within a full/low-speed signaling environment.
@}
*/
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBH_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_USBH_GetVersion (void)
\details
The function \b ARM_USBH_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_USBH Driver_USBH0;
ARM_DRIVER_USBH *drv_info;
void setup_usbh (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_USBH0;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
ARM_USBH_CAPABILITIES ARM_USBH_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_USBH_CAPABILITIES ARM_USBH_GetCapabilities (void)
\details
The function \b ARM_USBH_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_USBH_CAPABILITIES encode various capabilities, for example
available HUB ports or if the hardware can generate signal events using the \ref ARM_USBH_SignalPortEvent
callback function.
Example:
\code
extern ARM_DRIVER_USBH Driver_USBH0;
ARM_DRIVER_USBH *drv_info;
void read_capabilities (void) {
ARM_USBH_CAPABILITIES drv_capabilities;
drv_info = &Driver_USBH0;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*****************************************************************************************************************/
int32_t ARM_USBH_Initialize (ARM_USBH_SignalPortEvent_t cb_port_event,
ARM_USBH_SignalPipeEvent_t cb_pipe_event) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_Initialize (ARM_USBH_SignalPortEvent_t cb_port_event, ARM_USBH_SignalPipeEvent_t cb_pipe_event)
\details
The function \b ARM_USBH_Initialize initializes the USB Host interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the USBH interface.
- Registers the \ref ARM_USBH_SignalPortEvent callback function.
- Registers the \ref ARM_USBH_SignalPipeEvent callback function.
The parameter \em cb_port_event is a pointer to the \ref ARM_USBH_SignalPortEvent callback function; use a NULL pointer
when no port callback signals are required.
The parameter \em cb_pipe_event is a pointer to the \ref ARM_USBH_SignalPipeEvent callback function.
\b Example:
- see \ref usbh_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_USBH_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_Uninitialize (void)
\details
The function \b ARM_USBH_Uninitialize de-initializes the resources of USB Host interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_USBH_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_USBH_PowerControl operates the power modes of the USB Host interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*****************************************************************************************************************/
int32_t ARM_USBH_PortVbusOnOff (uint8_t port, bool vbus) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PortVbusOnOff (uint8_t port, bool vbus)
\details
The function \b ARM_USBH_PortVbusOnOff controls the VBUS signal of the specified port.
*****************************************************************************************************************/
int32_t ARM_USBH_PortReset (uint8_t port) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PortReset (uint8_t port)
\details
Executes reset signalling on the specified port.
*****************************************************************************************************************/
int32_t ARM_USBH_PortSuspend (uint8_t port) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PortSuspend (uint8_t port)
\details
The function \b ARM_USBH_PortSuspend auspends USB signaling on the specified port.
*****************************************************************************************************************/
int32_t ARM_USBH_PortResume (uint8_t port) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PortResume (uint8_t port)
\details
The function \b ARM_USBH_PortResume resumes USB signaling on the specified port.
*****************************************************************************************************************/
ARM_USBH_PORT_STATE ARM_USBH_PortGetState (uint8_t port) {
return 0;
}
/**
\fn ARM_USBH_PORT_STATE ARM_USBH_PortGetState (uint8_t port)
\details
The function \b ARM_USBH_PortGetState returns the current state of the specified port.
*****************************************************************************************************************/
ARM_USBH_PIPE_HANDLE ARM_USBH_PipeCreate (uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size,
uint8_t ep_interval) {
return 0;
}
/**
\fn ARM_USBH_PIPE_HANDLE ARM_USBH_PipeCreate (uint8_t dev_addr, uint8_t dev_speed, uint8_t hub_addr, uint8_t hub_port, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_max_packet_size, uint8_t ep_interval)
\details
The function \b ARM_USBH_PipeCreate creates a pipe for transfers (allocates required resources and configures the pipe).
The parameters specify pipe information (connection between host and device endpoint):
- device: address and speed
- hub (optional): hub address and number of the hub port to which the device is connected
- endpoint: address, type, maximum packet size and polling interval
The function returns an pipe handle that is used for all subsequent operations on that pipe.
In case of errors an invalid handle (\em NULL) is returned.
*****************************************************************************************************************/
int32_t ARM_USBH_PipeModify (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint16_t ep_max_packet_size) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PipeModify (ARM_USBH_PIPE_HANDLE pipe_hndl, uint8_t dev_addr, uint8_t dev_speed, uint8_t hub_addr, uint8_t hub_port, uint16_t ep_max_packet_size)
\details
The function \b ARM_USBH_PipeModify modifies a pipe configuration that was created with \ref ARM_USBH_PipeCreate.
*****************************************************************************************************************/
int32_t ARM_USBH_PipeDelete (ARM_USBH_PIPE_HANDLE pipe_hndl) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PipeDelete (ARM_USBH_PIPE_HANDLE pipe_hndl)
\details
The function \b ARM_USBH_PipeDelete deletes a pipe that was created with \ref ARM_USBH_PipeCreate (deactivates the pipe and releases used resources).
*****************************************************************************************************************/
int32_t ARM_USBH_PipeReset (ARM_USBH_PIPE_HANDLE pipe_hndl) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PipeReset (ARM_USBH_PIPE_HANDLE pipe_hndl)
\details
The function \b ARM_USBH_PipeReset clears Halt condition and resets data toggle on the specified pipe.
*****************************************************************************************************************/
int32_t ARM_USBH_PipeTransfer (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint32_t packet,
uint8_t *data,
uint32_t num) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PipeTransfer (ARM_USBH_PIPE_HANDLE pipe_hndl, uint32_t packet, uint8_t *data, uint32_t num)
\details
The function \b ARM_USBH_PipeTransfer generates packets for sending or receiving data from an USB Endpoint.
The function specifies the buffer with data to send or for data to receive and the number of bytes to transfer (must be multiple of device endpoint maximum packet size for receive).
It also specifies \ref USBH_packets with parameter \em packet.
The function is non-blocking and returns as soon as the driver starts the operation on the specified pipe. During the operation it is not allowed to call this function again on the same pipe. Also the data buffer must stay allocated and the contents of data must not be modified.
Operation is completed when the the requested number of data bytes have been transferred and is indicated with \ref ARM_USBH_EVENT_TRANSFER_COMPLETE event.
It can also finish earlier on reception of different handshake tokens which are also indicated through \ref USBH_pipe_events.
Transfer operation can be aborted by calling \ref ARM_USBH_PipeTransferAbort.
*****************************************************************************************************************/
uint32_t ARM_USBH_PipeTransferGetResult (ARM_USBH_PIPE_HANDLE pipe_hndl) {
return 0;
}
/**
\fn uint32_t ARM_USBH_PipeTransferGetResult (ARM_USBH_PIPE_HANDLE pipe_hndl)
\details
The function \b ARM_USBH_PipeTransferGetResult returns the number of successfully transferred data bytes started by \ref ARM_USBH_PipeTransfer operation.
*****************************************************************************************************************/
int32_t ARM_USBH_PipeTransferAbort (ARM_USBH_PIPE_HANDLE pipe_hndl) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_PipeTransferAbort (ARM_USBH_PIPE_HANDLE pipe_hndl)
\details
The function \b ARM_USBH_PipeTransferAbort aborts an active pipe transfer started by \ref ARM_USBH_PipeTransfer.
*****************************************************************************************************************/
uint16_t ARM_USBH_GetFrameNumber (void) {
return 0;
}
/**
\fn uint16_t ARM_USBH_GetFrameNumber (void)
\details
The function \b ARM_USBH_GetFrameNumber returns the sequential 11-bit frame number of the last Start of Frame (SOF) packet.
*****************************************************************************************************************/
void ARM_USBH_SignalPortEvent (uint8_t port, uint32_t event) {
// function body
}
/**
\fn void ARM_USBH_SignalPortEvent (uint8_t port, uint32_t event)
\details
The function \b ARM_USBH_SignalPortEvent is a callback function registered by the function \ref ARM_USBH_Initialize.
The parameter \em port specifies the root hub port number. \n
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
Not every event is necessarily generated by the driver. This depends on the implemented capabilities stored in the
data fields of the structure \ref ARM_USBH_CAPABILITIES, which can be retrieved with the function \ref ARM_USBH_GetCapabilities.
The following events can be generated:
Parameter \em event | Bit | Description | supported when ARM_USBH_CAPABILITIES
:---------------------------------|:---:|:---------------------------------------------------------------------------|---------------------------------------
\ref ARM_USBH_EVENT_CONNECT | 0 | Occurs when USB Device connects to the Host. | data field \em event_connect=\token{1}
\ref ARM_USBH_EVENT_DISCONNECT | 1 | Occurs when USB Device disconnects from the Host. | data field \em event_disconnect=\token{1}
\ref ARM_USBH_EVENT_OVERCURRENT | 2 | Occurs when USB Overcurrent it detected. | data field \em event_overcurrent=\token{1}
\ref ARM_USBH_EVENT_RESET | 3 | Occurs when USB Reset is completed after calling \ref ARM_USBH_PortReset. | <i>always supported</i>
\ref ARM_USBH_EVENT_SUSPEND | 4 | Occurs when USB Suspend is detected. | <i>always supported</i>
\ref ARM_USBH_EVENT_RESUME | 5 | Occurs when USB Resume is detected. | <i>always supported</i>
\ref ARM_USBH_EVENT_REMOTE_WAKEUP | 6 | Occurs when USB Remote wakeup is detected. | <i>always supported</i>
*****************************************************************************************************************/
void ARM_USBH_SignalPipeEvent (ARM_USBH_PIPE_HANDLE pipe_hndl, uint32_t event) {
// function body
}
/**
\fn void ARM_USBH_SignalPipeEvent (ARM_USBH_PIPE_HANDLE pipe_hndl, uint32_t event)
\details
The function \b ARM_USBH_SignalPipeEvent is a callback function registered by the function \ref ARM_USBH_Initialize.
The parameter \em pipe_hndl specifies the pipe handle. \n
The parameter \em event indicates one or more events that occurred during driver operation.
Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
The following events can be generated:
Parameter \em event | Bit| Description
:-----------------------------------------|---:|:-----------
\ref ARM_USBH_EVENT_TRANSFER_COMPLETE | 0 | Occurs after all the data has been transferred without errors.
\ref ARM_USBH_EVENT_HANDSHAKE_NAK | 1 | Occurs when NAK Handshake is received before all the data is transferred.
\ref ARM_USBH_EVENT_HANDSHAKE_NYET | 2 | Occurs when NYET Handshake is received before all the data is transferred.
\ref ARM_USBH_EVENT_HANDSHAKE_MDATA | 3 | Occurs when MDATA Handshake is received before all the data is transferred.
\ref ARM_USBH_EVENT_HANDSHAKE_STALL | 4 | Occurs when STALL Handshake is received before all the data is transferred.
\ref ARM_USBH_EVENT_HANDSHAKE_ERR | 5 | Occurs when ERR Handshake is received before all the data is transferred.
\ref ARM_USBH_EVENT_BUS_ERROR | 6 | Occurs when bus error is detected before all the data is transferred.
<b>See also:</b>
- ARM_USBH_PipeCreate
*****************************************************************************************************************/
/**
@}
*/
/**
\defgroup usbh_hci_gr USB OHCI/EHCI
\ingroup usbh_interface_gr
\brief Driver API for USB OHCI/EHCI
\details
OHCI and EHCI compliant interfaces have memory mapped registers that are used to control the USB host.
Only certain functionalities (interrupts, VBUS control, power control) require device specific interface which is provided through functions
of the struct \ref ARM_DRIVER_USBH_HCI (functionality accessed with the struct \ref ARM_DRIVER_USBH is not needed).
@{
*/
/**
\struct ARM_DRIVER_USBH_HCI
\details
The functions of the USB Host HCI (OHCI/EHCI) driver are accessed by function pointers. Refer to \ref DriverFunctions for
overview information.
Each instance of an USBH provides such an access struct. The instance is indicated by
a postfix in the symbol name of the access struct, for example:
- \b Driver_USBH0_HCI is the name of the access struct of the first instance (no. 0).
- \b Driver_USBH1_HCI is the name of the access struct of the second instance (no. 1).
A configuration setting in the middleware allows connecting the middleware to a specific driver instance <b>Driver_USBH<i>n</i>_HCI</b>.
The default is \token{0}, which connects a middleware to the first instance of a driver.
\note The struct must remain unchanged.
*/
/**
\struct ARM_USBH_HCI_CAPABILITIES
\details
A USB Host HCI (OHCI/EHCI) driver can be implemented with different capabilities.
The data fields of this structure encode the capabilities implemented by this driver.
<b>Returned by:</b>
- \ref ARM_USBH_HCI_GetCapabilities
\note The struct must remain unchanged.
*****************************************************************************************************************/
/**
\typedef ARM_USBH_HCI_Interrupt_t
\details
Provides the typedef for the interrupt handler \ref ARM_USBH_HCI_Interrupt.
<b>Parameter for:</b>
- \ref ARM_USBH_HCI_Initialize
*******************************************************************************************************************/
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBH_HCI_GetVersion (void) {
return { 0, 0 };
}
/**
\fn ARM_DRIVER_VERSION ARM_USBH_HCI_GetVersion (void)
\details
The function \b ARM_USBH_HCI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
- API version is the version of the CMSIS-Driver specification used to implement this driver.
- Driver version is source code version of the actual driver implementation.
Example:
\code
extern ARM_DRIVER_USBH Driver_USBH0_HCI;
ARM_DRIVER_USBH *drv_info;
void setup_usbh (void) {
ARM_DRIVER_VERSION version;
drv_info = &Driver_USBH0_HCI;
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
\endcode
*****************************************************************************************************************/
ARM_USBH_HCI_CAPABILITIES ARM_USBH_HCI_GetCapabilities (void) {
return { 0 };
}
/**
\fn ARM_USBH_HCI_CAPABILITIES ARM_USBH_HCI_GetCapabilities (void)
\details
The function \b ARM_USBH_HCI_GetCapabilities returns information about capabilities in this driver implementation.
The data fields of the structure \ref ARM_USBH_HCI_CAPABILITIES encode various capabilities, for example
available HUB ports.
Example:
\code
extern ARM_DRIVER_USBH_HCI Driver_USBH0_HCI;
ARM_DRIVER_USBH_HCI *drv_info;
void read_capabilities (void) {
ARM_USBH_HCI_CAPABILITIES drv_capabilities;
drv_info = &Driver_USBH0_HCI;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
\endcode
*****************************************************************************************************************/
int32_t ARM_USBH_HCI_Initialize (ARM_USBH_HCI_Interrupt_t *cb_interrupt) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_HCI_Initialize (ARM_USBH_HCI_Interrupt_t *cb_interrupt)
\details
The function \b ARM_USBH_HCI_Initialize initializes the USB Host HCI (OHCI/EHCI) interface.
It is called when the middleware component starts operation.
The function performs the following operations:
- Initializes the resources needed for the USBH interface.
- Registers the \ref ARM_USBH_HCI_Interrupt interrupt handler.
The parameter \em cb_interrupt is a pointer to the interrupt routine of the OHCI/EHCI peripheral
that needs to be registered. This function is called as ECHI Interrupt Service Handler.
\b Example:
- see \ref usbh_interface_gr - Driver Functions
*****************************************************************************************************************/
int32_t ARM_USBH_HCI_Uninitialize (void) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_HCI_Uninitialize (void)
\details
The function \ref ARM_USBH_HCI_Uninitialize de-initializes the resources of USB Host HCI (OHCI/EHCI) interface.
It is called when the middleware component stops operation and releases the software resources used by the interface.
*****************************************************************************************************************/
int32_t ARM_USBH_HCI_PowerControl (ARM_POWER_STATE state) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_HCI_PowerControl (ARM_POWER_STATE state)
\details
The function \b ARM_USBH_HCI_PowerControl operates the power modes of the USB Host HCI (OHCI/EHCI) interface.
The parameter \em state sets the operation and can have the following values:
- \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
Can be called multiple times. If the peripheral is already in this mode the function performs
no operation and returns with \ref ARM_DRIVER_OK.
- \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
- \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Refer to \ref CallSequence for more information.
*****************************************************************************************************************/
int32_t ARM_USBH_HCI_PortVbusOnOff (uint8_t port, bool vbus) {
return ARM_DRIVER_OK;
}
/**
\fn int32_t ARM_USBH_HCI_PortVbusOnOff (uint8_t port, bool vbus)
\details
The function \b ARM_USBH_HCI_PortVbusOnOff controls the VBUS signal of the specified port.
Most HCI complained USB Host controllers do not require this optional function.
It is only required when a external VBUS interface (for example via I/O pin) is required.
*****************************************************************************************************************/
void ARM_USBH_HCI_Interrupt (void) {
// function body
}
/**
\fn void ARM_USBH_HCI_Interrupt (void)
\details
The function \b ARM_USBH_HCI_Interrupt is called from the USBH HCI Interrupt Handler.
*****************************************************************************************************************/
/**
@}
*/
// End USBH Interface

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
#include "Driver_Flash.h"
#include "cmsis_os2.h" // ARM::CMSIS:RTOS2:Keil RTX5
/* Flash driver instance */
extern ARM_DRIVER_FLASH Driver_Flash0;
static ARM_DRIVER_FLASH * flashDev = &Driver_Flash0;
/* CMSIS-RTOS2 Thread Id */
osThreadId_t Flash_Thread_Id;
/* Flash signal event */
void Flash_Callback(uint32_t event)
{
if (event & ARM_FLASH_EVENT_READY) {
/* The read/program/erase operation is completed */
osThreadFlagsSet(Flash_Thread_Id, 1U);
}
if (event & ARM_FLASH_EVENT_ERROR) {
/* The read/program/erase operation is completed with errors */
/* Call debugger or replace with custom error handling */
__breakpoint(0);
}
}
/* CMSIS-RTOS2 Thread */
void Flash_Thread (void *argument)
{
/* Query drivers capabilities */
const ARM_FLASH_CAPABILITIES capabilities = flashDev->GetCapabilities();
/* Initialize Flash device */
if (capabilities.event_ready) {
flashDev->Initialize (&Flash_Callback);
} else {
flashDev->Initialize (NULL);
}
/* Power-on Flash device */
flashDev->PowerControl (ARM_POWER_FULL);
/* Read data taking data_width into account */
uint8_t buf[256U];
flashDev->ReadData (0x1000U, buf, sizeof(buf)>>capabilities.data_width);
/* Wait operation to be completed */
if (capabilities.event_ready) {
osThreadFlagsWait (1U, osFlagsWaitAny, 100U);
} else {
osDelay(100U);
}
/* Switch off gracefully */
flashDev->PowerControl (ARM_POWER_OFF);
flashDev->Uninitialize ();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
#include "Driver_I2C.h"
#define EEPROM_I2C_ADDR 0x51 /* EEPROM I2C address */
/* I2C driver instance */
extern ARM_DRIVER_I2C Driver_I2C0;
static ARM_DRIVER_I2C *I2Cdrv = &Driver_I2C0;
static volatile uint32_t I2C_Event;
/* I2C Signal Event function callback */
void I2C_SignalEvent (uint32_t event) {
/* Save received events */
I2C_Event |= event;
/* Optionally, user can define specific actions for an event */
if (event & ARM_I2C_EVENT_TRANSFER_INCOMPLETE) {
/* Less data was transferred than requested */
}
if (event & ARM_I2C_EVENT_TRANSFER_DONE) {
/* Transfer or receive is finished */
}
if (event & ARM_I2C_EVENT_ADDRESS_NACK) {
/* Slave address was not acknowledged */
}
if (event & ARM_I2C_EVENT_ARBITRATION_LOST) {
/* Master lost bus arbitration */
}
if (event & ARM_I2C_EVENT_BUS_ERROR) {
/* Invalid start/stop position detected */
}
if (event & ARM_I2C_EVENT_BUS_CLEAR) {
/* Bus clear operation completed */
}
if (event & ARM_I2C_EVENT_GENERAL_CALL) {
/* Slave was addressed with a general call address */
}
if (event & ARM_I2C_EVENT_SLAVE_RECEIVE) {
/* Slave addressed as receiver but SlaveReceive operation is not started */
}
if (event & ARM_I2C_EVENT_SLAVE_TRANSMIT) {
/* Slave addressed as transmitter but SlaveTransmit operation is not started */
}
}
/* Read I2C connected EEPROM (event driven example) */
int32_t EEPROM_Read_Event (uint16_t addr, uint8_t *buf, uint32_t len) {
uint8_t a[2];
a[0] = (uint8_t)(addr >> 8);
a[1] = (uint8_t)(addr & 0xFF);
/* Clear event flags before new transfer */
I2C_Event = 0U;
I2Cdrv->MasterTransmit (EEPROM_I2C_ADDR, a, 2, true);
/* Wait until transfer completed */
while ((I2C_Event & ARM_I2C_EVENT_TRANSFER_DONE) == 0U);
/* Check if all data transferred */
if ((I2C_Event & ARM_I2C_EVENT_TRANSFER_INCOMPLETE) != 0U) return -1;
/* Clear event flags before new transfer */
I2C_Event = 0U;
I2Cdrv->MasterReceive (EEPROM_I2C_ADDR, buf, len, false);
/* Wait until transfer completed */
while ((I2C_Event & ARM_I2C_EVENT_TRANSFER_DONE) == 0U);
/* Check if all data transferred */
if ((I2C_Event & ARM_I2C_EVENT_TRANSFER_INCOMPLETE) != 0U) return -1;
return 0;
}
/* Read I2C connected EEPROM (pooling example) */
int32_t EEPROM_Read_Pool (uint16_t addr, uint8_t *buf, uint32_t len) {
uint8_t a[2];
a[0] = (uint8_t)(addr >> 8);
a[1] = (uint8_t)(addr & 0xFF);
I2Cdrv->MasterTransmit (EEPROM_I2C_ADDR, a, 2, true);
/* Wait until transfer completed */
while (I2Cdrv->GetStatus().busy);
/* Check if all data transferred */
if (I2Cdrv->GetDataCount () != len) return -1;
I2Cdrv->MasterReceive (EEPROM_I2C_ADDR, buf, len, false);
/* Wait until transfer completed */
while (I2Cdrv->GetStatus().busy);
/* Check if all data transferred */
if (I2Cdrv->GetDataCount () != len) return -1;
return 0;
}
/* Initialize I2C connected EEPROM */
int32_t EEPROM_Initialize (bool pooling) {
int32_t status;
uint8_t val;
if (pooling == true) {
I2Cdrv->Initialize (NULL);
} else {
I2Cdrv->Initialize (I2C_SignalEvent);
}
I2Cdrv->PowerControl (ARM_POWER_FULL);
I2Cdrv->Control (ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
I2Cdrv->Control (ARM_I2C_BUS_CLEAR, 0);
/* Check if EEPROM can be accessed */
if (pooling == true) {
status = EEPROM_Read_Pool (0x00, &val, 1);
} else {
status = EEPROM_Read_Event (0x00, &val, 1);
}
return (status);
}

View File

@ -0,0 +1,41 @@
#include "Driver_I2C.h"
/* I2C driver instance */
extern ARM_DRIVER_I2C Driver_I2C0;
static ARM_DRIVER_I2C *I2Cdrv = &Driver_I2C0;
static volatile uint32_t I2C_Event;
/* I2C Signal Event function callback */
static void I2C_SignalEvent (uint32_t event) {
I2C_Event |= event;
}
int main (void) {
uint8_t cnt = 0;
/* Initialize I2C peripheral */
I2Cdrv->Initialize(I2C_SignalEvent);
/* Power-on I2C peripheral */
I2Cdrv->PowerControl(ARM_POWER_FULL);
/* Configure I2C bus */
I2Cdrv->Control(ARM_I2C_OWN_ADDRESS, 0x78);
I2C_Event = 0;
while (1) {
/* Receive chunk */
I2Cdrv->SlaveReceive(&cnt, 1);
while ((I2C_Event & ARM_I2C_EVENT_TRANSFER_DONE) == 0);
/* Clear transfer done flag */
I2C_Event &= ~ARM_I2C_EVENT_TRANSFER_DONE;
/* Transmit chunk back */
I2Cdrv->SlaveTransmit(&cnt, 1);
while ((I2C_Event & ARM_I2C_EVENT_TRANSFER_DONE) == 0);
/* Clear transfer done flag */
I2C_Event &= ~ARM_I2C_EVENT_TRANSFER_DONE;
}
}

View File

@ -0,0 +1,253 @@
#include "Driver_MCI.h"
/* Usage example: ARM_MCI_Initialize ----------------------------------------*/
// ARM_MCI_SignalEvent callback function prototype
void MCI_SignalEvent_Callback (uint32_t event);
void init_driver (ARM_DRIVER_MCI *drv) {
int32_t status;
status = drv->Initialize (&MCI_SignalEvent_Callback);
if (status != ARM_DRIVER_OK) {
// Initialization and event callback registration failed
}
}
/* Usage example: ARM_MCI_Uninitialize --------------------------------------*/
void uninit_driver (ARM_DRIVER_MCI *drv) {
int32_t status;
status = drv->Uninitialize ();
if (status == ARM_DRIVER_OK) {
// Driver successfully uninitialized
}
}
/* Usage example: ARM_MCI_PowerControl --------------------------------------*/
void control_driver_power (ARM_DRIVER_MCI *drv, bool enable) {
int32_t status;
if (enable == true) {
status = drv->PowerControl (ARM_POWER_FULL);
}
else {
status = drv->PowerControl (ARM_POWER_OFF);
}
if (status == ARM_DRIVER_OK) {
// Driver power enabled/disabled
}
}
/* Usage example: ARM_MCI_CardPower -----------------------------------------*/
ARM_MCI_CAPABILITIES drv_capabilities;
void set_card_vdd_3v3 (ARM_DRIVER_MCI *drv) {
int32_t status;
if (drv_capabilities.vdd == 1U) {
// Power switching to 3.3V supported
status = drv->CardPower (ARM_MCI_POWER_VDD_3V3);
if (status == ARM_DRIVER_OK) {
// Card power set to 3.3V
}
}
}
/* Usage example: ARM_MCI_ReadCD --------------------------------------------*/
void read_card_detect_state (ARM_DRIVER_MCI *drv) {
int32_t status;
status = drv->ReadCD();
if (status == 1) {
// Memory card is detected
}
else {
if (status == 0) {
// Memory card is not detected
}
else {
// Error reading card detect pin state
}
}
}
/* Usage example: ARM_MCI_ReadWP --------------------------------------------*/
void read_write_protect_state (ARM_DRIVER_MCI *drv) {
int32_t status;
status = drv->ReadWP();
if (status == 1) {
// Memory card write protection is enabled
}
else {
if (status == 0) {
// Memory card write protection is disabled
}
else {
// Error reading write protect pin state
}
}
}
/* Usage example: ARM_MCI_SendCommand ---------------------------------------*/
volatile uint32_t MCI_Events;
void MCI_SignalEvent_Callback (uint32_t event) {
// Save current event
MCI_Events |= event;
}
void send_CMD0 (ARM_DRIVER_MCI *drv) {
int32_t status;
uint32_t cmd;
MCI_Events = 0U; //Clear MCI driver event flags
cmd = 0U; // Set GO_IDLE_STATE command code
status = drv->SendCommand (cmd, 0U, ARM_MCI_CARD_INITIALIZE | ARM_MCI_RESPONSE_NONE, NULL);
if (status == ARM_DRIVER_OK) {
/* Wait for event */
while ((MCI_Events & ARM_MCI_EVENT_COMMAND_COMPLETE) == 0U);
// Command was successfully sent to memory card
// ..
}
else {
// Error
}
}
/* Usage example: ARM_MCI_SetupTransfer -------------------------------------*/
volatile uint32_t MCI_Events;
void MCI_SignalEvent_Callback (uint32_t event) {
MCI_Events |= event; // Save current event
}
void read_sector (ARM_DRIVER_MCI *drv, uint8_t *buf, uint32_t sz) {
int32_t status;
uint32_t cmd, arg;
uint32_t resp;
if (sz < 512U) {
// Invalid buffer size, sector consists of 512 bytes
//...
}
status = drv->SetupTransfer (buf, 1U, 512U, ARM_MCI_TRANSFER_READ | ARM_MCI_TRANSFER_BLOCK);
if (status == ARM_DRIVER_OK) {
MCI_Events = 0U; //Clear MCI driver event flags
cmd = 17U; // Set READ_SINGLE_BLOCK command
arg = 0U; // Set sector number
status = drv->SendCommand (cmd, arg, ARM_MCI_RESPONSE_SHORT | ARM_MCI_RESPONSE_CRC | ARM_MCI_TRANSFER_DATA, &resp);
if (status == ARM_DRIVER_OK) {
/* Wait for event */
while ((MCI_Events & ARM_MCI_EVENT_COMMAND_COMPLETE) == 0U);
// Command was successfully sent to memory card
if ((resp & 0x03U) == 0U) {
// Sector number is valid, wait until data transfer completes
while ((MCI_Events & ARM_MCI_EVENT_TRANSFER_COMPLETE) == 0U);
// Data was successfully read from memory card
// ...
}
}
}
}
/* Usage example: ARM_MCI_AbortTransfer -------------------------------------*/
void abort_data_transfer (ARM_DRIVER_MCI *drv) {
ARM_MCI_STATUS drv_status;
drv_status = drv->GetStatus();
if (drv_status.transfer_active == 1U) {
// Data transfer is active, abort the transfer
if (drv->AbortTransfer() == ARM_DRIVER_OK) {
// Transfer aborted
// ...
}
}
}
/* Usage example: ARM_MCI_GetStatus -----------------------------------------*/
void check_transfer_status (ARM_DRIVER_MCI *drv) {
ARM_MCI_STATUS drv_status;
drv_status = drv->GetStatus();
if (drv_status.transfer_active == 1U) {
// Data transfer is active
}
if (drv_status.transfer_timeout == 1U) {
// Data not received, timeout expired
}
if (drv_status.transfer_error == 1U) {
// Data transfer ended with error
}
}
/* Usage example: ARM_MCI_SignalEvent ---------------------------------------*/
void MCI_SignalEvent_Callback (uint32_t event) {
if ((event & ARM_MCI_EVENT_CARD_INSERTED) != 0U) {
// Memory card was inserted into socket
}
if ((event & ARM_MCI_EVENT_CARD_REMOVED) != 0U) {
// Memory card was removed from socket
}
if ((event & ARM_MCI_EVENT_COMMAND_COMPLETE) != 0U) {
// Command was successfully sent to memory card
}
if ((event & ARM_MCI_EVENT_COMMAND_TIMEOUT) != 0U) {
// Command response was not received in time
}
if ((event & ARM_MCI_EVENT_COMMAND_ERROR) != 0U) {
// Command response was invalid
}
if ((event & ARM_MCI_EVENT_TRANSFER_COMPLETE) != 0U) {
// Data successfully transferred from/to memory card
}
if ((event & ARM_MCI_EVENT_TRANSFER_TIMEOUT) != 0U) {
// Data not transferred from/to memory card, timeout expired
}
if ((event & ARM_MCI_EVENT_TRANSFER_ERROR) != 0U) {
// Data transfer ended with errors
}
if ((event & ARM_MCI_EVENT_SDIO_INTERRUPT) != 0U) {
// SD I/O card sent interrupt request
}
if ((event & ARM_MCI_EVENT_CCS) != 0U) {
// CE-ATA command completion signal received
}
if ((event & ARM_MCI_EVENT_CCS_TIMEOUT) != 0U) {
// CE-ATA command completion signal wait timeout expired
}
}

View File

@ -0,0 +1,165 @@
#include "Driver_NAND.h"
/* ONFI commands */
#define ONFI_CMD_READ_1ST 0x00 ///< Read 1st Cycle
#define ONFI_CMD_PROGRAM_2ND 0x10 ///< Page Program 2nd Cycle
#define ONFI_CMD_READ_2ND 0x30 ///< Read 2nd Cycle
#define ONFI_CMD_PROGRAM_1ST 0x80 ///< Page Program 1st Cycle
#define ONFI_CMD_RESET 0xFF ///< Reset Command
/* NAND Signal Event callback function */
volatile uint32_t NAND_Events;
void NAND_SignalEventCallback (uint32_t dev_num, uint32_t event) {
if (dev_num == 0) {
NAND_Events |= event;
}
else {
// ..
}
}
/* NAND device Power ON */
void PowerOn (ARM_DRIVER_NAND *drv, uint32_t dev_num) {
ARM_NAND_CAPABILITIES capabilities;
// Query drivers capabilities
capabilities = drv->GetCapabilities();
// Initialize NAND device
drv->Initialize (NAND_SignalEventCallback);
// Power-on NAND driver
drv->PowerControl (ARM_POWER_FULL);
// Turn ON device power
uint32_t volt = 0U;
if (capabilities.vcc) { volt |= ARM_NAND_POWER_VCC_3V3; }
if (capabilities.vcc_1v8) { volt |= ARM_NAND_POWER_VCC_1V8; }
if (capabilities.vccq) { volt |= ARM_NAND_POWER_VCCQ_3V3; }
if (capabilities.vccq_1v8) { volt |= ARM_NAND_POWER_VCCQ_1V8; }
if (volt != 0U) {
drv->DevicePower (volt);
}
// Setting bus mode
drv->Control (0U, ARM_NAND_BUS_MODE, ARM_NAND_BUS_SDR);
// Setting bus data width
drv->Control (0U, ARM_NAND_BUS_DATA_WIDTH, ARM_NAND_BUS_DATA_WIDTH_8);
// Enable chip manually if needed
if (capabilities.ce_manual) {
drv->ChipEnable (dev_num, true);
}
// Send ONFI Reset command */
drv->SendCommand (dev_num, ONFI_CMD_RESET);
}
/* NAND device Power OFF */
void PowerOff (ARM_DRIVER_NAND *drv, uint32_t dev_num) {
ARM_NAND_CAPABILITIES capabilities;
// Query drivers capabilities
capabilities = drv->GetCapabilities();
// Disable chip manually if needed
if (capabilities.ce_manual) {
drv->ChipEnable (0U, false);
}
// Switch OFF gracefully
uint32_t volt = 0U;
if (capabilities.vcc) { volt |= ARM_NAND_POWER_VCC_OFF; }
if (capabilities.vccq) { volt |= ARM_NAND_POWER_VCCQ_OFF; }
if (volt) {
drv->DevicePower (volt);
}
drv->PowerControl (ARM_POWER_OFF);
drv->Uninitialize ();
}
/* Read NAND page. */
void ReadPage (ARM_DRIVER_NAND *drv, uint32_t row, uint8_t *data, uint32_t cnt) {
uint32_t dev_num = 0; // Device number
uint32_t mode;
// Send Read 1st command
drv->SendCommand (dev_num, ONFI_CMD_READ_1ST);
// Send address (column: 2 cycles, row: 3 cycles)
drv->SendAddress (dev_num, 0x00);
drv->SendAddress (dev_num, 0x00);
drv->SendAddress (dev_num, (uint8_t)(row));
drv->SendAddress (dev_num, (uint8_t)(row >> 8));
drv->SendAddress (dev_num, (uint8_t)(row >> 16));
// Send Read 2nd command
drv->SendCommand (dev_num, ONFI_CMD_READ_2ND);
// Wait until device ready
while (drv->GetDeviceBusy(dev_num) == 1) { ; }
// Use ECC algorithm number 2, ECC0 (ECC over main+spare)
mode = ARM_NAND_ECC(2) | ARM_NAND_ECC0;
// Transfer data from the NAND chip
if (drv->ReadData (dev_num, data, cnt, mode | ARM_NAND_DRIVER_DONE_EVENT) != cnt) {
// Wait until driver done event received
while ((NAND_Events & ARM_NAND_DRIVER_DONE_EVENT) == 0) { ; }
// Read page completed
if ((NAND_Events & ARM_NAND_EVENT_ECC_ERROR) != 0) {
// ECC correction failed
}
}
}
/* Write NAND page (ExecuteSequence interface). */
void WritePage_Seq (ARM_DRIVER_NAND *drv, uint32_t row, const uint8_t *data, uint32_t cnt) {
uint32_t dev_num = 0; // Device number
uint32_t cmd;
uint32_t code;
uint32_t seq;
// Prepare commands to send
cmd = ONFI_CMD_PROGRAM_1ST | (ONFI_CMD_PROGRAM_2ND << 8);
// Construct sequence code:
// - Send command 1
// - Send 2 cycles of column address and 3 cycles of row address
// - Write data from memory to device
// - Send command 2
code = ARM_NAND_CODE_SEND_CMD1 |
ARM_NAND_CODE_SEND_ADDR_COL1 |
ARM_NAND_CODE_SEND_ADDR_COL2 |
ARM_NAND_CODE_SEND_ADDR_ROW1 |
ARM_NAND_CODE_SEND_ADDR_ROW2 |
ARM_NAND_CODE_SEND_ADDR_ROW3 |
ARM_NAND_CODE_WRITE_DATA |
ARM_NAND_CODE_SEND_CMD2 ;
// - Use ECC algorithm number 2, ECC0 (ECC over main+spare)
code |= ARM_NAND_ECC(2) | ARM_NAND_ECC0;
// Number of iterations in a sequence
seq = 1;
drv->ExecuteSequence (dev_num, // Device number
code, // Sequence code
cmd, // Command(s)
0, // Column address
row, // Row address
(void *)data, // Data buffer
cnt, // Number of data items (per iteration)
NULL, // Device status will not be read
&seq); // Number of iterations
// Wait until done
while (drv->GetStatus(dev_num).busy != 0) { ; }
// Page write completed
}

View File

@ -0,0 +1,98 @@
#include "Driver_SPI.h"
#include "cmsis_os.h" // ARM::CMSIS:RTOS:Keil RTX
void mySPI_Thread(void const *argument);
osThreadId tid_mySPI_Thread;
/* SPI Driver */
extern ARM_DRIVER_SPI Driver_SPI0;
void mySPI_callback(uint32_t event)
{
switch (event)
{
case ARM_SPI_EVENT_TRANSFER_COMPLETE:
/* Success: Wakeup Thread */
osSignalSet(tid_mySPI_Thread, 0x01);
break;
case ARM_SPI_EVENT_DATA_LOST:
/* Occurs in slave mode when data is requested/sent by master
but send/receive/transfer operation has not been started
and indicates that data is lost. Occurs also in master mode
when driver cannot transfer data fast enough. */
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
break;
case ARM_SPI_EVENT_MODE_FAULT:
/* Occurs in master mode when Slave Select is deactivated and
indicates Master Mode Fault. */
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
break;
}
}
/* Test data buffers */
const uint8_t testdata_out[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
uint8_t testdata_in [8];
void mySPI_Thread(void const* arg)
{
ARM_DRIVER_SPI* SPIdrv = &Driver_SPI0;
osEvent evt;
#ifdef DEBUG
ARM_DRIVER_VERSION version;
ARM_SPI_CAPABILITIES drv_capabilities;
version = SPIdrv->GetVersion();
if (version.api < 0x200) /* requires at minimum API version 2.00 or higher */
{ /* error handling */
return;
}
drv_capabilities = SPIdrv->GetCapabilities();
if (drv_capabilities.event_mode_fault == 0)
{ /* error handling */
return;
}
#endif
/* Initialize the SPI driver */
SPIdrv->Initialize(mySPI_callback);
/* Power up the SPI peripheral */
SPIdrv->PowerControl(ARM_POWER_FULL);
/* Configure the SPI to Master, 8-bit mode @10000 kBits/sec */
SPIdrv->Control(ARM_SPI_MODE_MASTER | ARM_SPI_CPOL1_CPHA1 | ARM_SPI_MSB_LSB | ARM_SPI_SS_MASTER_SW | ARM_SPI_DATA_BITS(8), 10000000);
/* SS line = INACTIVE = HIGH */
SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);
/* thread loop */
while (1)
{
/* SS line = ACTIVE = LOW */
SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_ACTIVE);
/* Transmit some data */
SPIdrv->Send(testdata_out, sizeof(testdata_out));
/* Wait for completion */
evt = osSignalWait(0x01, 100);
if (evt.status == osEventTimeout) {
__breakpoint(0); /* Timeout error: Call debugger */
}
/* SS line = INACTIVE = HIGH */
SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);
/* SS line = ACTIVE = LOW */
SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_ACTIVE);
/* Receive 8 bytes of reply */
SPIdrv->Receive(testdata_in, 8);
evt = osSignalWait(0x01, 100);
if (evt.status == osEventTimeout) {
__breakpoint(0); /* Timeout error: Call debugger */
}
/* SS line = INACTIVE = HIGH */
SPIdrv->Control(ARM_SPI_CONTROL_SS, ARM_SPI_SS_INACTIVE);
}
}

View File

@ -0,0 +1,87 @@
#include "Driver_USART.h"
#include "cmsis_os.h" /* ARM::CMSIS:RTOS:Keil RTX */
#include <stdio.h>
#include <string.h>
void myUART_Thread(void const *argument);
osThreadId tid_myUART_Thread;
/* USART Driver */
extern ARM_DRIVER_USART Driver_USART3;
void myUSART_callback(uint32_t event)
{
uint32_t mask;
mask = ARM_USART_EVENT_RECEIVE_COMPLETE |
ARM_USART_EVENT_TRANSFER_COMPLETE |
ARM_USART_EVENT_SEND_COMPLETE |
ARM_USART_EVENT_TX_COMPLETE ;
if (event & mask) {
/* Success: Wakeup Thread */
osSignalSet(tid_myUART_Thread, 0x01);
}
if (event & ARM_USART_EVENT_RX_TIMEOUT) {
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
}
if (event & (ARM_USART_EVENT_RX_OVERFLOW | ARM_USART_EVENT_TX_UNDERFLOW)) {
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
}
}
/* CMSIS-RTOS Thread - UART command thread */
void myUART_Thread(const void* args)
{
static ARM_DRIVER_USART * USARTdrv = &Driver_USART3;
ARM_DRIVER_VERSION version;
ARM_USART_CAPABILITIES drv_capabilities;
char cmd;
#ifdef DEBUG
version = USARTdrv->GetVersion();
if (version.api < 0x200) /* requires at minimum API version 2.00 or higher */
{ /* error handling */
return;
}
drv_capabilities = USARTdrv->GetCapabilities();
if (drv_capabilities.event_tx_complete == 0)
{ /* error handling */
return;
}
#endif
/*Initialize the USART driver */
USARTdrv->Initialize(myUSART_callback);
/*Power up the USART peripheral */
USARTdrv->PowerControl(ARM_POWER_FULL);
/*Configure the USART to 4800 Bits/sec */
USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, 4800);
/* Enable Receiver and Transmitter lines */
USARTdrv->Control (ARM_USART_CONTROL_TX, 1);
USARTdrv->Control (ARM_USART_CONTROL_RX, 1);
USARTdrv->Send("\nPress Enter to receive a message", 34);
osSignalWait(0x01, osWaitForever);
while (1)
{
USARTdrv->Receive(&cmd, 1); /* Get byte from UART */
osSignalWait(0x01, osWaitForever);
if (cmd == 13) /* CR, send greeting */
{
USARTdrv->Send("\nHello World!", 12);
osSignalWait(0x01, osWaitForever);
}
}
}

View File

@ -0,0 +1,515 @@
/**
\defgroup vio_interface_gr VIO
\brief API for Virtual I/O (VIO) (%cmsis_vio.h)
\details
The VIO software component is a virtual I/O abstraction for peripherals that are typically used in example projects. It
enables developers to move from an evaluation kit to custom hardware and helps to scale project examples at large to many
development boards:
\image html vioRationale.png "Virtual I/O provides a generic API for examples and testing"
<b>VIO API</b>
The following header file defines the Application Programming Interface (API) for VIO:
- \b %cmsis_vio.h : API for VIO
<b>VIO User Code Templates</b>
The VIO software component contains two user code templates with different purposes:
- VIO:Custom: This file is an empty stub with all functions that are defined in the header file that can be used to
implement the VIO layer for the hardware that is used in the application.
- VIO:Virtual: This file uses a fixed memory location to emulate the VIO functionality and can be used off-the-shelf.
<b>VIO Memory Location Structure</b>
For testing purposes, it is required to have fixed memory locations that are used to read/store values. In the VIO:Virtual
template file (\b %vio.c), an exemplary implementation is shown:
\code
// Input, output variables
__USED uint32_t vioSignalIn; // Memory for incoming signal
__USED uint32_t vioSignalOut; // Memory for outgoing signal
__USED char vioPrintMem[VIO_PRINTMEM_NUM][VIO_PRINT_MAX_SIZE]; // Memory for the last value for each level
__USED int32_t vioValue [VIO_VALUE_NUM]; // Memory for value used in vioGetValue/vioSetValue
__USED vioValueXYZ_t vioValueXYZ[VIO_VALUEXYZ_NUM]; // Memory for XYZ value for 3-D vector
__USED vioAddrIPv4_t vioAddrIPv4[VIO_IPV4_ADDRESS_NUM]; // Memory for IPv4 address value used in vioSetIPv4/vioGetIPv4
__USED vioAddrIPv6_t vioAddrIPv6[VIO_IPV6_ADDRESS_NUM]; // Memory for IPv6 address value used in vioSetIPv6/vioGetIPv6
\endcode
Use these memory locations to monitor or set the variables as required in the application.
Two defines are available that help to disconnect the actual peripherals and enable virtual I/Os: \c CMSIS_VIN and
\c CMSIS_VOUT. They help to write code that can be used in testing environments without real hardware access. The following
implementation example shows such code:
<b>Code Example (VIO Implementation)</b>
\code
// Initialize test input, output.
void vioInit (void) {
uint32_t i;
#if !defined CMSIS_VIN
// Add user variables here:
#endif
#if !defined CMSIS_VOUT
// Add user variables here:
#endif
vioSignalIn = 0U;
vioSignalOut = 0U;
memset (vioPrintMem, 0, sizeof(vioPrintMem));
memset (vioValue, 0, sizeof(vioValue));
memset (vioValueXYZ, 0, sizeof(vioValueXYZ));
memset (vioAddrIPv4, 0, sizeof(vioAddrIPv4));
memset (vioAddrIPv6, 0, sizeof(vioAddrIPv6));
#if !defined CMSIS_VOUT
// Add user code here:
// <code vioInit output>
BSP_LED_Init(LED_BLUE);
BSP_LED_Init(LED_RED);
BSP_LED_Init(LED_GREEN);
// </code>
#endif
#if !defined CMSIS_VIN
// Add user code here:
// <code vioInit input>
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);
// </code>
#endif
return;
}
\endcode
<b>Memory display in IDEs</b>
Arm Keil MDK uses the provided SCVD file to display the VIO signals in Component Viewer:
\image html vioComponentViewer.png
@{
*/
/**
\defgroup vioDefines_gr Defines and Structs
\ingroup vio_interface_gr
\brief Documents the defines and structs of the VIO API.
\details
@{
Test.
*/
/**
\defgroup vioSignals_gr Signals
\ingroup vioDefines_gr
\brief Signal related defines.
\details
@{
\def vioLED0
\def vioLED1
\def vioLED2
\def vioLED3
\def vioLED4
\def vioLED5
\def vioLED6
\def vioLED7
\def vioLEDon
\def vioLEDoff
\def vioBUTTON0
\def vioBUTTON1
\def vioBUTTON2
\def vioBUTTON3
\def vioJOYup
\def vioJOYdown
\def vioJOYleft
\def vioJOYright
\def vioJOYselect
\def vioJOYall
@}
*/
/**
\defgroup vioValues_gr Values
\ingroup vioDefines_gr
\brief Value related defines.
\details
@{
\def vioAIN0
\def vioAIN1
\def vioAIN2
\def vioAIN3
\def vioAOUT0
/**
\struct vioValueXYZ_t
\details
Structure holding three-dimensional values for gyroscopes, accelerometers, etc.
<b>Parameter for:</b>
- \ref vioGetXYZ
- \ref vioSetXYZ
***************************************************************************************************************************/
@}
*/
/**
\defgroup vioIDs_gr IDs
\ingroup vioDefines_gr
\brief ID related defines.
\details
@{
\def vioAIN0
\def vioAIN1
\def vioAIN2
\def vioAIN3
\def vioAOUT0
\def vioMotionGyro
\def vioMotionAccelero
\def vioMotionMagneto
@}
*/
/**
\defgroup vioPrintLevels_gr Print Levels
\ingroup vioDefines_gr
\brief Print level related defines.
\details
@{
\def vioLevelNone
\def vioLevelHeading
\def vioLevelMessage
\def vioLevelError
@}
*/
/**
\defgroup vioIPAddr_gr IP Addresses
\ingroup vioDefines_gr
\brief IP address related structs.
\details
@{
\struct vioAddrIPv4_t
\details
Structure holding IPv4 addresses.
<b>Parameter for:</b>
- \ref vioGetIPv4
- \ref vioSetIPv4
\struct vioAddrIPv6_t
\details
Structure holding IPv6 addresses.
<b>Parameter for:</b>
- \ref vioGetIPv6
- \ref vioSetIPv6
@}
*/
/**
@}
*/
// end group vioDefines_gr
void vioInit (void) {};
/**
\fn void vioInit (void)
\details
The function \b vioInit initializes the VIO interface. Use it to initialize any connected hardware that is used to
map VIO signals.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
// System Initialization
SystemCoreClockUpdate();
vioInit();
// ...
}
\endcode
***************************************************************************************************************************/
int32_t vioPrint (uint32_t level, const char *format, ...) {
return (0);
};
/**
\fn int32_t vioPrint (uint32_t level, const char *format, ...)
\details
The function \b vioPrint prints a formatted string to a test terminal. Formatting of the output follows the rules of
standard C language printf().
Refer to \ref vioPrintLevels_gr for information about the possible \a levels.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
int x = 3;
vioInit();
vioPrint(vioLevelNone, "Test [None]");
vioPrint(vioLevelHeading, "Test [Heading] = Network Connector Message");
vioPrint(vioLevelMessage, "Test [Message] = Connection failed");
vioPrint(vioLevelError, "Test [Error] = %d", x);
}
\endcode
***************************************************************************************************************************/
void vioSetSignal (uint32_t mask, uint32_t signal) {};
/**
\fn void vioSetSignal (uint32_t mask, uint32_t signal)
\details
The function \b vioSetSignal set a \a signal to an output specified by \a mask. Use this function to map VIOs to actual
hardware for displaying signals on a target board.
Refer to \ref vioSignals_gr for information about the possible \a mask and \a signal values.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioInit();
vioSetSignal(vioLED0, vioLEDon);
// ...
vioSetSignal(vioLED0, vioLEDoff);
}
\endcode
***************************************************************************************************************************/
uint32_t vioGetSignal (uint32_t mask) {
return (0);
};
/**
\fn uint32_t vioGetSignal (uint32_t mask)
\details
The function \b vioGetSignal retrieves a signal from an input identified by \a mask. Use this function to read data from any
input that is provided.
Refer to \ref vioSignals_gr for information about the possible \a mask values.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
uint32_t state;
uint32_t last = 0U;
vioInit();
for (;;) {
state = (vioGetSignal (vioBUTTON0)); // Get pressed button state
if (state != last){
if (state == vioBUTTON0){
// do something
}
}
last = state;
}
}
\endcode
***************************************************************************************************************************/
void vioSetValue (uint32_t id, int32_t value) {};
/**
\fn void vioSetValue (uint32_t id, int32_t value)
\details
The function \b vioSetValue set the \a value to the output identified by \a id. Use this function to set states of I/Os for
example.
Refer to \ref vioValues_gr for information about \a value and \ref vioIDs_gr for \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioInit();
vioSetValue(vioAOUT0, 1024);
}
\endcode
***************************************************************************************************************************/
int32_t vioGetValue (uint32_t id) {
return (0);
};
/**
\fn int32_t vioGetValue (uint32_t id)
\details
The function \b vioGetValue retrieves a value from the input identified by \a id. Use this function to read data from inputs.
Refer to \ref vioIDs_gr for information about \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
uint32_t button;
vioInit();
button = vioGetValue(vioBUTTON0);
}
\endcode
***************************************************************************************************************************/
void vioSetXYZ (uint32_t id, vioValueXYZ_t valueXYZ) {
return (0);
};
/**
\fn void vioSetXYZ (uint32_t id, vioValueXYZ_t valueXYZ)
\details
The function \b vioSetXYZ sets a three-dimensional value \a valueXYZ to the output identified by \a id. Use this function to
apply a 3d value to an output.
Refer to \ref vioValues_gr for information about the \a valueXYZ and \ref vioIDs_gr for \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioValueXYZ_t xyz = {123, 456, 789};
vioInit();
vioSetXYZ(0, xyz);
}
\endcode
***************************************************************************************************************************/
vioValueXYZ_t vioGetXYZ (uint32_t id) {
return (0);
};
/**
\fn vioValueXYZ_t vioGetXYZ (uint32_t id)
\details
The function \b vioGetXYZ retrieves a three-dimensional value from the input identified by \a id. Use this function to get a
3d value.
Refer to \ref vioIDs_gr for information about \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
volatile vioValueXYZ_t xyz;
vioInit();
xyz = vioGetXYZ(vioMotionGyro);
}
\endcode
***************************************************************************************************************************/
void vioSetIPv4 (uint32_t id, vioAddrIPv4_t addrIPv4) {};
/**
\fn void vioSetIPv4 (uint32_t id, vioAddrIPv4_t addrIPv4)
\details
The function \b vioSetIPv4 sets an IPv4 address specified by \a addrIPv4 to an interface identified by \a id. Use this
function to assign an IPv4 address to an interface.
Refer to \ref vioIDs_gr for information about \a id and \ref vioIPAddr_gr for \a addrIPv4.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioAddrIPv4_t addrIPv4 = {192U, 168U, 111U, 123U};
vioInit();
vioSetIPv4 (0, addrIPv4);
}
\endcode
***************************************************************************************************************************/
vioAddrIPv4_t vioGetIPv4 (uint32_t id) {
return (0);
};
/**
\fn vioAddrIPv4_t vioGetIPv4 (uint32_t id)
\details
The function \b vioGetIPv4 retrieves the IPv4 addrIPv4 from an interface identified by \a id. Use this function to read an
IPv4 address.
Refer to \ref vioIDs_gr for information about \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioAddrIPv4_t addrIPv4;
vioInit();
addrIPv4 = vioGetIPv4(0);
}
\endcode
***************************************************************************************************************************/
void vioSetIPv6 (uint32_t id, vioAddrIPv6_t addrIPv6) {};
/**
\fn void vioSetIPv6 (uint32_t id, vioAddrIPv6_t addrIPv6)
\details
The function \b vioSetIPv6 sets an IPv6 address specified by \a addrIPv6 to an interface identified by \a id. Use this
function to assign an IPv6 address to an interface.
Refer to \ref vioIDs_gr for information about \a id and \ref vioIPAddr_gr for \a addrIPv6.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioAddrIPv6_t addrIPv6 = {1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U,
9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U};
vioInit();
vioSetIPv6 (0, addrIPv6);
}
\endcode
***************************************************************************************************************************/
vioAddrIPv6_t vioGetIPv6 (uint32_t id) {
return (0);
};
/**
\fn vioAddrIPv6_t vioGetIPv6 (uint32_t id)
\details
The function \b vioGetIPv6 retrieves the IPv6 addrIPv6 from an interface identified by \a id. Use this function to read an
IPv6 address.
Refer to \ref vioIDs_gr for information about \a id.
\b Code \b Example:
\code
#include "cmsis_vio.h" // ::CMSIS Driver:VIO
int main (void) {
vioAddrIPv6_t addrIPv6;
vioInit();
addrIPv6 = vioGetIPv6(0);
}
\endcode
***************************************************************************************************************************/
/**
@}
*/
// End VIO Interface

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB