This KB shows an implementation of a SPI Master application, because most use cases involve connecting a SPI Slave device, e.g. a sensor, to the Z-Wave device.
In order to implement SPI into the Z-Wave framework, we will be using the SPIDRV API from EMDRV. In this KB, we will be implementing the SPI example from the SPIDRV documentation page.
Step 1: Include header files
You need to include the following header files to the search path of the project.
A) Go to project properties => C/C++ General => Paths and Symbols
B) In the 'Includes' tab, add the two include paths listed below to both 'Assembly' and 'GNU C'
C) Apply the settings and click 'Yes' in the dialog to rebuild.
D) Click OK to close the properties window.
The needed include paths are:
spidrv.h
Include path: ${StudioSdkPath}/platform/emdrv/spidrv/inc
Add the following include to the main file of the Z-Wave Sample App you are using.
#include <spidrv.h>
Step 4: Setup for Master
A) In spidrv_config.h (referenced in spidrv.h), locate the define EMDRV_SPIDRV_INCLUDE_SLAVE and place your cursor.
B) Uncomment this line by start typing “/”.
C) This opens a dialog. In this dialog select “Make a Copy”. This will make a copy of the header file and move it to the local project location, because we are now editing a file in the SDK.
D) Finish uncommenting EMDRV_SPIDRV_INCLUDE_SLAVE
// SPIDRV configuration option. Use this define to include the slave part of the SPIDRV API.
//#define EMDRV_SPIDRV_INCLUDE_SLAVE
Step 5: Build solution
Now build the solution. If everything went well when adding include paths and linking to source files, you should not get any build errors.
Step 6: Setup SPI
A) In the PRIVATE DATA section, add the SPI handle
In ApplicationInit(), initialize the SPI driver just before the call to ZW_ApplicationRegisterTask.
Since we will be using the Z-Wave serial debugging interface as well, we will setup SPI to use USART1.
In addition, we will also try to transmit data using a blocking transmit function and using a callback to catch the transfer completion.
// ACTION: Init SPI and send buffer.
uint8_t buffer[10];
SPIDRV_Init_t initData = SPIDRV_MASTER_USART1;
// Initialize a SPI driver instance
SPIDRV_Init( handle, &initData );
// Example: Transmit data using a blocking transmit function
if(SPIDRV_MTransmitB( handle, buffer, 10 ) == 0)
DPRINT("SPI Transfer Blocking Success\r\n");
// Example: Transmit data using a callback to catch transfer completion.
SPIDRV_MTransmit( handle, buffer, 10, TransferComplete );
Step 8: Build solution and test
Build the solution and flash the new firmware image to the device.
If you enable serial debug output, you should now see that we are successfully sending data.
Closing comments
This KB is a quick demonstration in how to add support for SPI in the Z-Wave Framework.
This implementation just sends out data in the ApplicationInit() function, but this should be done in an appropriate place depending on what functionality is needed.
A word on SPI Slave
The SPIDRV from EMDRV can also be setup as a slave. However, this implementation relies on the Real-time Clock Driver (RTCDRV). Because Z-Wave is using FreeRTOS as the underlying OS, it is not possible to use SPIDRV in Slave mode as it conflicts with how FreeRTOS uses the RTC.
As such, if you need to implement SPI Slave functionality in the Z-Wave framework, you need to use the lower-level USART driver from EMLIB.
INS14280 - Getting Started for End Device This document also describes how to setup the Z-Wave region and serial debug, which is not covered by this KB.
INS14259 - Z-Wave Plus V2 Application Framework SDK7
UG381: ZGM130S Zen Gecko Wireless Starter Kit User's Guide
Z-Wave 700: How to implement SPI into the Z-Wave Embedded Framework
How to implement SPI into the Z-Wave Embedded Framework
Several peripheral drivers are available (EMDRV and EMLIB) and can be linked to the Z-Wave application. EMDRV exist on top of the lower level EMLIB.
The following resources are great places to look for more information:
Software Documentation (e.g., EMDRV and EMLIB)
32-bit Peripheral Examples (EMLIB)
This KB shows an implementation of a SPI Master application, because most use cases involve connecting a SPI Slave device, e.g. a sensor, to the Z-Wave device.
In order to implement SPI into the Z-Wave framework, we will be using the SPIDRV API from EMDRV. In this KB, we will be implementing the SPI example from the SPIDRV documentation page.
Step 1: Include header files
You need to include the following header files to the search path of the project.
The needed include paths are:
Include path: ${StudioSdkPath}/platform/emdrv/spidrv/inc
File location: C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\spidrv\inc
Include path: ${StudioSdkPath}/platform/emdrv/spidrv/config
File location:
C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\spidrv\config
Include path: ${StudioSdkPath}/platform/emdrv/dmadrv/inc
File location: C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\dmadrv\inc
Include path: ${StudioSdkPath}/platform/emdrv/dmadrv/inc
File location: C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\dmadrv\config
Step 2: Link the needed source files
With the header files added to the project, we need to link the source files.
You need to do the steps above (A-F) for the following source files:
C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\spidrv\src
C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emdrv\dmadrv\src
C:\SiliconLabs\SimplicityStudio\v4_ga\developer\sdks\zwave\v7.11.0\platform\emlib\src
Step 3: Include in Z-Wave framework
Add the following include to the main file of the Z-Wave Sample App you are using.
Step 4: Setup for Master
Step 5: Build solution
Now build the solution. If everything went well when adding include paths and linking to source files, you should not get any build errors.
Step 6: Setup SPI
Step 7: Initialize SPI and transfer data
In ApplicationInit(), initialize the SPI driver just before the call to ZW_ApplicationRegisterTask.
Since we will be using the Z-Wave serial debugging interface as well, we will setup SPI to use USART1.
In addition, we will also try to transmit data using a blocking transmit function and using a callback to catch the transfer completion.
Step 8: Build solution and test
Build the solution and flash the new firmware image to the device.
If you enable serial debug output, you should now see that we are successfully sending data.
Closing comments
This KB is a quick demonstration in how to add support for SPI in the Z-Wave Framework.
This implementation just sends out data in the ApplicationInit() function, but this should be done in an appropriate place depending on what functionality is needed.
A word on SPI Slave
The SPIDRV from EMDRV can also be setup as a slave. However, this implementation relies on the Real-time Clock Driver (RTCDRV). Because Z-Wave is using FreeRTOS as the underlying OS, it is not possible to use SPIDRV in Slave mode as it conflicts with how FreeRTOS uses the RTC.
As such, if you need to implement SPI Slave functionality in the Z-Wave framework, you need to use the lower-level USART driver from EMLIB.
Z-Wave 700 End-device framework KBs
Z-Wave 700: How to implement I2C into the Z-Wave Embedded Framework
Z-Wave 700: How to use Software Timers
Z-Wave 700: How to implement SPI into the Z-Wave Embedded Framework (this guide)
Z-Wave 700: How to implement UART with interrupt into the Z-Wave Embedded Framework
Linked documentation (found in Simplicity Studio)
This document also describes how to setup the Z-Wave region and serial debug, which is not covered by this KB.