Changes

Jump to: navigation, search

SBCX-TN-001: Android Things and SPI bus

7,784 bytes added, 11:35, 5 January 2021
no edit summary
{{InfoBoxTop}}
{{AppliesToSBCX}}
{{AppliesToSBC Axel TN}}
{{AppliesToAxel}}
{{AppliesToAxelLite}}
{{AppliesToAxelEsatta}}
{{AppliesToIoT}}
{{AppliesTo IoT TN}}
{{InfoBoxBottom}}
== History ==
These interfaces don't include the ones that are typically used in products addressing industrial applications: I2C bus, SPI bus, UARTs, etc. However, as Android popularity is growing outside the mobile world too, Google defined a set of additional APIs to standardize the access to these interfaces as well. These new APIs are part of the [https://developer.android.com/things/index.html Android Things project].
This Technical Note describes the implementation of the [https://developer.android.com/things/sdk/pio/spi.html APIs related to the SPI bus] to access the SPI bus TBD SPI4 of the SBCX platformin the form of a native library. The solution was tested with Android 4.4.3.
==Testbed==
TBDAs stated in the introduction, the solution has been tested on a platform running Android 4.4.3. From the software standpoint, this platform is a good example of an implementation where significant changes have been done to the Android Open Source Project (AOSP) in order to use it on an industrial embedded device.
Development Some of these changes modify the Android security model. In many cases, this is acceptable because the overall security of the product is not compromised (for instance, many devices used for industrial applications are not connected to the Internet and/or the physical access is granted to authorized personnel only). In general, system integrators have been performed on to assess the impact of such changes to verify that the resulting configuration meets the following platform:system requirements.
With regard to the platform here considered, the following is a not exhaustive list of the changes with respect to the standard/typical Android configuration used on mobile devices:*As the non-volatile storage device is a NAND flash, [http://www.linux-mtd.infradead.org/doc/ubifs.html UBIFS] file system has been used*There is only one partition*The file system is read/write; as such, the <code>system</code> directory is writeable as well*A serial console is available on a UART port; <code>root</code> login is allowed on this console*U-Boot has been used as bootloader*Some of the device files are directly accessible from the application layer. Development has been performed on the following hardware platform:* Board: [[:Category:SBC-AXEL|SBC-AXEL]] equipped with [[:Category:AxelLite|AxelLite]] SOM* SOC: NXP i.MX6 DualLite* Android Version: 4.4.3 (Jelly Bean). To verify the functionality of the library, a simple device (serial [https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p40.pdf NOR flash memory]) has been connected to the expansion connector (J33). Specifically, the SPI4 bus has been used. To build the example application using the library, the following version [https://developer.android.com/studio/index.html Android Studio] has been used: <pre>Android Studio 3.1Build #AI-173.4670197, built on March 22, 2018JRE: 1.8.0_152-release-1024-b02 amd64JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.oAndroid SDK API 27</pre> === Wiring === [[File:SBCX-Android-4.4.3-SPI-hw.png|thumb|center|600px|Simplyfied diagram of the serial flash memory interfacing]]As depicted in the previous image, the serial flash memory has been connected to the SPI4 bus by using SBCX's expansion connector (J33). The following table details the signals that have been used.{| class="wikitable"!Nor!Name!Signal name!Pin #|-|1|S#|SPI4_SS0_R|10|-|2|DQ1|SPI4_MOSI_R|6|-|3|W#|3v3|48|-|4|Vss|GND|2|-|5|DQ0|SPI4_MOSI_R|8|-|6|C|SPI4_SCLK_R|4|-|7|HOLD#|3v3|48|-|8|Vcc|3v3|48|} ==Software implementation== The following picture shows the organization of the software layers. [[File:SBCX-Android-4.4.3-SPI.png|thumb|center|600px|Software stack]] The solution depicted on the left is fully compliant with the Android/Android Things recommendations. The access to the I/O interface—the SPI bus in this case—is managed by the Peripheral Manager and by a specific service. The solution depicted on the right is the one described in this Technical Note. From the application point of view, it is consistent with the Android Things APIs. However, it is easier to implement thanks to the direct access to the device file associated with the SPI bus. === Requirements ===To implement such solution, the following requirements must be met:*The Linux kernel must support [https://www.kernel.org/doc/Documentation/spi/spidev spidev]*The device file must have the permissions as shown in [[#Managing the device connection|this section]].*The device tree must be modified in order to instantiate the SPI bus to be accessed: it is enough to enable the <code>escpi4</code> peripheral into SBCX device tree<pre>&ecspi4 { status = "okay";};</pre> === Example project===An [[#Downloads|example project]] is provided to illustrate how to use the native library. It includes the library itself and a simple application which reads the device identification data of the flash memory (<code>READ IDENTIFICATION</code> command).[[File:Spi test.png|thumb|center|600px|Test application]]==== Managing the device connection ====In order to open a connection to a particular SPI slave, you need to know the unique name of the bus. The get this name, run the following command from the serial console:<pre>root@sbcx:/ # ls /dev/spi* -alcrw-rw-rw- system root 153, 0 1970-01-01 00:00 spidev32765.0</pre>It is important to note that the above method is the only one available to retrieve the SPI device name because <code>getSpiBusList()</code> function is not implemented within the library. Once this name is known, the APIs defined by Android Things can be used to access the bus because the library—named <code>eu.dave.spi_dev</code>—is consistent with them:<pre>public class HomeActivity extends Activity { // SPI Device Name private static final String SPI_DEVICE_NAME = "/dev/spidev32765.0";  private SpiDevice mDevice;  @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDevice = new SpiDevice(SPI_DEVICE_NAME); // Attempt to access the SPI device try { mDevice.Open(); } catch (IOException e) { Log.w("Error", "Unable to access SPI device" + e.getMessage()); } }  @Override protected void onDestroy() { super.onDestroy();  if (mDevice != null) { try { mDevice.Close(); mDevice = null; } catch (IOException e) { Log.w("Error","Unable to close SPI device" + e.getMessage()); } } }}</pre> ==== Configuring clock and data modes ====Configuration method are identical to the Andriod Things api [https://developer.android.com/things/sdk/pio/spi.html#mode ref]. <pre>public void configureSpiDevice(SpiDevice device) throws IOException { // Low clock, leading edge transfer device.setMode(SpiDevice.MODE0);  device.setFrequency(500000); // 16MHz device.setBitsPerWord(8); // 8 BPW device.setBitJustification(false); // MSB first}</pre> ==== Transferring data ====Is important to note that async I/O are not supported in userspace at this time [https://www.kernel.org/doc/Documentation/spi/spidev ref], furthermore '''LSB''' mode is not supported by the i.MX6 processor [https://community.nxp.com/thread/388187 ref]. To communicate with the device the following methods are available*<code> void WriteByte(byte symbol)</code>: to transfer a byte without reading the response from the device.*<code> void WriteBuffer(byte[] data, int len)</code>: to transfer a buffer to the device without processing the response.*<code> void Transfer(byte[] tx_data, byte[] rx_data, int len)</code>: to transfer a buffer smaller than the length of the receiving one.*<code> void Transfer(byte[] tx_data, byte[] rx_data) </code>: to transfer and read a buffer with the same length.*<code> void Transfer(byte symbol, byte[] rx_data, int len)</code>: to transfer a byte and read a buffer of length ''len''. <pre>public void sendCommand(SpiDevice device, byte[] buffer) throws IOException { byte[] response = new byte[buffer.length]; device.Transfer(buffer, response, buffer.length); ...} </pre> ==ImplementationDownloads==TBDThe example project is available for download at [http://mirror.dave.eu/axel/SBCX-TN-001 this link].
dave_user, Administrators
5,166
edits

Navigation menu