ISF  2.1
Intelligent Sensing Framework for Kinetis with Processor Expert
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
rli_project.c
Go to the documentation of this file.
1 /*!
2  * @file rli_project.c
3  * @brief \b rli_Project.c is an embedded application written using the
4  * ISF to demonstrate the functionality of the rli I2C
5  * magnetometer sensor.
6  *
7  * The rli_project.c is a working example of an ISF embedded application that
8  * enables host configuration of the rli I2C magnetometer sensor. This application
9  * uses the ISF Command Interpreter directly. It can be easily used as a starting
10  * point for modifications to allow anyone to write their own embedded application.
11  * The source code has been commented to explain the various parts of the application.
12  *
13  * @copyright Copyright (c) 2014, Freescale Semiconductor, Inc.
14  *
15  * @addtogroup rli_project_module rli_project module documentation
16  * @{
17 ******************************************************************************/
18 #define MQX_DISABLE_CONFIG_CHECK 1
19 
20 // MQX includes
21 #include <mqxlite.h>
22 #include <lwevent.h> // For LWEVENT_STRUCT, lwevent function prototypes, etc.
23 
24 // ISF includes
25 #include "isf_target.h"
26 #include "isf_types.h" // For uint8, uint16, int32, TRUE, FALSE, etc.
27 #include "isf.h" // For isf_status_t
28 #include "isf_init.h" // For ISF_TASKS_ATTRIBUTES, ISF_APP_CALLBACKS, etc.
29 #include "isf_ci.h" // For ci_response_t, CI function prototypes, etc.
30 #include "isf_pm.h" // For the power management function prototypes
31 #include "isf_devmsg.h"
32 #include "isf_sysconf_comms.h"
33 #include "isf_rli.h"
34 #include "fsl_i2c_master_driver.h"
35 /******************************************************
36  * TYPE DEFINITIONS
37  *****************************************************/
38 
39 /* The event flag used for sensor data notifications.
40  * This is passed to the Sensor Manager during subscription.
41  */
42 #define SENSOR_DATA_READY_EVENT ((uint32)(1 << 10))
43 #define RLI_COMM_BUFFER_SIZE (255)
46 
47 enum {
50 };
51 
52 enum {
56 };
57 
58 /*! @brief Macro that extracts one of the fields below. */
59 #define SET_FIELD(name,val) (((val)<<name##_SHIFT)&(name##_MASK))
60 #define GET_FIELD(name,val) ((val&name##_MASK)>>name##_SHIFT)
61 
62 
63 
64 typedef struct {
65  uint16_t deviceAddress;
68 
69 /*! @brief rli application configuration buffer format. */
70 
71 typedef struct {
76 
77 typedef struct {
78  rliConfigRegister_t CfgBuffer; //!< Application configuration information
80  uint8_t cmdBuffer[RLI_COMM_BUFFER_SIZE];
81  uint8_t rcvBuffer[RLI_COMM_BUFFER_SIZE];
85 /*! @brief rli overall application state buffer format. */
86 
87 /* OVerlays on the standard ci_cmd_packet_t */
88 typedef struct
89 {
90  /*! Application ID */
92 
93  /*! Host command */
95 
96  /*! Register Offset */
98 
99  /*! Number of bytes to read/write */
101 
103 
104 enum {
106 };
107 
108 /******************************************************
109  * FUNCTION PROTOTYPES
110  *****************************************************/
112 void rli_app_task(void);
113 
114 int32 open_channel(rliAppState_t *appState);
118 
119 /******************************************************
120  * GLOBAL VARIABLES
121  *****************************************************/
122 
123 static rliAppState_t rliAppState; //! @brief This data structure/variable holds the complete state of the rli magnetometer sensor embedded application.
124 extern MQX_INITIALIZATION_STRUCT MQX_init_struct;
125 
126 /* Main Task for RLI */
127 void rli_app_task( void )
128 {
129 
130 
131  // Initialize the current application state.
133  rliAppState.CfgBuffer.deviceAddress = 0x0E;
134 
135  // Open the rli channel
136  rliAppState.pChannelDescriptor = isf_rli_init(rliAppState.CfgBuffer.channelID);
137 
138  // Connect to the default device
139  device_connect(&rliAppState);
140 
141  _task_block();
142 
143  for (;;)
144  {
145 
146 
147  } // for (;;)
148 }
149 
150 /* CI Callback for RLI */
152  // New application configuration.
153  ci_response_enum callbackRet = CI_ERROR_NONE;
154 
155  switch(pHostPacket->cmd)
156  {
158  {
159  uint8 *pDataBuffer = (uint8 *)(rliAppState.rcvBuffer);
160 
161  pAppPacket->bytes_xfer = (uint8)isf_ci_app_write(pHostPacket->appId, (uint32)pHostPacket->byte_cnt, (uint8*)(pDataBuffer + pHostPacket->offset));
162  break;
163  }
164 
165  // Read data from the status struct.
167  {
168  uint8 size = sizeof(rliAppState.status);
169  uint8 *pDataBuffer = (uint8 *) &rliAppState.status;
170 
171  // Validate the offset and byte count to ensure the read operation is within the range of the host output buffer.
172  if (pHostPacket->byte_cnt > size) {
173  callbackRet = CI_INVALID_COUNT;
174  break;
175  }
176 
177  if (pHostPacket->offset + pHostPacket->byte_cnt > size ) {
178  callbackRet = CI_ERROR_COMMAND;
179  break;
180  }
181 
182  // Lock the output buffer, update the data to the CI, then unlock the buffer.
183  pAppPacket->bytes_xfer = (uint8)isf_ci_app_write(pHostPacket->appId, (uint32)pHostPacket->byte_cnt, (uint8*)(pDataBuffer + pHostPacket->offset));
184  break;
185  }
186  // Update the Quick-Read data.
188  {
189  uint8 size = sizeof(rliAppState.rcvBuffer);
190  uint8 *pDataBuffer = (uint8 *)(rliAppState.rcvBuffer);
191 
192  isf_ci_qr_update(FSL_RLI_APP_ID, (int8)size, pDataBuffer);
193  break;
194  }
195  // Read or write the application configuration structure.
196  case CI_CMD_READ_CONFIG:
197  // Fall through.
198  case CI_CMD_WRITE_CONFIG:
199  {
200  uint8 size = sizeof(rliAppState.CfgBuffer);
201 
202  // Validate the offset and byte count to ensure the read or write operation is within the range of the host configuration buffer.
203  if (pHostPacket->byte_cnt > size ) {
204  callbackRet = CI_INVALID_COUNT;
205  break;
206  }
207 
208  if (pHostPacket->offset + pHostPacket->byte_cnt > size) {
209  callbackRet = CI_ERROR_COMMAND;
210  break;
211  }
212 
213  // Read or write the data to/from the CI.
214  if (CI_CMD_READ_CONFIG == pHostPacket->cmd)
215  {
216  // The host is reading so we have to write what they've asked for
217  pAppPacket->rw = CI_RW_WRITE; // Write the data to host.
218  pAppPacket->bytes_xfer = (uint8)isf_ci_app_write(pHostPacket->appId, (uint32)pHostPacket->byte_cnt,
219  (uint8*)(&rliAppState.CfgBuffer) + pHostPacket->offset);
220  }
221  else {
222  // The host is writing so we have to read what they've written
223  // Read the new data from the host.
224  pAppPacket->rw = CI_RW_READ;
225  pAppPacket->bytes_xfer =
227  pHostPacket->appId, (uint32)pHostPacket->byte_cnt,
228  (uint8*)(&rliAppState.CfgBuffer) + pHostPacket->offset
229  );
230  /* Brute force transitions - always shutdown and restart on any config change TODO: Make this more elegant */
231  if (rliAppState.status.device == RLI_APP_STATE_OPEN)
232  {
233  device_disconnect(&rliAppState);
234  }
235  if (rliAppState.status.channel == RLI_APP_STATE_OPEN)
236  {
237  close_channel(&rliAppState);
238  }
239  open_channel(&rliAppState);
240  device_connect(&rliAppState);
241  }
242 
243  }
244  break;
245 
246  // Reset the application state.
247  case CI_CMD_RESET_APP:
248 
249  break;
250  // Read or write the application configuration structure.
251 
252  case CI_CMD_DEVICE_READ:
253  // Fall through.
254  case CI_CMD_DEVICE_WRITE:
255  {
256  /* Overlay a device packet structure on the host packet to reinterpret the provided data as a device command
257  * instead of a traditional host packet. This allows the host to skip sending a useless offset and length
258  * and instead immediately place the nWrite and nRead of the comm_Command_t sent to device messaging.
259  */
260  device_cmd_packet_t *pDeviceCmd = (device_cmd_packet_t *)pHostPacket;
261 
262  // Validate the read and write byte counts to ensure they will fit in the configured buffers.
263  if ((pDeviceCmd->nRead > sizeof(rcvBuffer_t)) || (pDeviceCmd->nWrite > sizeof(cmdBuffer_t)) ) {
264  callbackRet = CI_INVALID_COUNT;
265  break;
266  }
267 
268  if (pDeviceCmd->nWrite > 0) {
269  pAppPacket->rw = CI_RW_READ; // Write the data to host.
270  pAppPacket->bytes_xfer = (uint8)isf_ci_app_read (
271  pDeviceCmd->appId,
272  (uint32)pDeviceCmd->nWrite,
273  (uint8*)rliAppState.cmdBuffer
274  );
275  }
276 
277  // Read or write the data to/from the CI.
278  if (CI_CMD_DEVICE_READ == pDeviceCmd->cmd)
279  {
280  // Execute the command
281  callbackRet = isf_rli_read(rliAppState.pHandle, rliAppState.cmdBuffer[0], pDeviceCmd->nRead, rliAppState.rcvBuffer);
282  if ((ci_response_enum)ISF_SUCCESS != callbackRet){
283  rliAppState.status.error= 1;
284  }
285 
286  pAppPacket->rw = CI_RW_WRITE; // Write the data to host.
287  pAppPacket->bytes_xfer = (uint8)isf_ci_app_write(pHostPacket->appId, (uint32)pDeviceCmd->nRead,
288  (uint8*)rliAppState.rcvBuffer);
289  }
290  else {
291  callbackRet = isf_rli_write(rliAppState.pHandle, rliAppState.cmdBuffer[0], pDeviceCmd->nWrite - 1, &rliAppState.cmdBuffer[1] );
292 
293  if ((ci_response_enum)ISF_SUCCESS != callbackRet){
294  rliAppState.status.error= 2;
295  }
296 
297  pAppPacket->rw = CI_RW_WRITE; // Write the data to host.
298  pAppPacket->bytes_xfer = (uint8)isf_ci_app_write(pHostPacket->appId, (uint32)pDeviceCmd->nRead,
299  (uint8*)rliAppState.rcvBuffer);
300 
301  }
302 
303  }
304  break;
305  default:
306  callbackRet = CI_ERROR_COMMAND;
307  break;
308  }
309 
310  return callbackRet;
311 }
312 
314 {
315  i2c_device_t device = {0};
316  device.address = appState->CfgBuffer.deviceAddress;
317  appState->status.device = RLI_APP_STATE_ERROR;
318  appState->pHandle = isf_rli_open(appState->pChannelDescriptor, &device );
319  if (NULL != appState->pHandle){
320  // Open the device and get the device handler
321  appState->status.device = RLI_APP_STATE_OPEN;
322  }
323  return 0;
324 }
325 
327 {
328  appState->status.device = RLI_APP_STATE_ERROR;
329 
330  // Close the device
331  if(isf_rli_close(appState->pHandle)){
332  return 1;
333  }
334  appState->status.device = RLI_APP_STATE_CLOSED;
335  return 0;
336 }
337 
339 {
340  appState->status.channel = RLI_APP_STATE_ERROR;
341 
342  appState->pChannelDescriptor = isf_rli_init(appState->CfgBuffer.channelID);
343  // Initialize the channel
344  if(appState->pChannelDescriptor == NULL){
345  return -1;
346  }
347  appState->status.channel = RLI_APP_STATE_OPEN;
348  return 0;
349 }
350 
351 
353 {
354  appState->status.channel = RLI_APP_STATE_ERROR;
355 
356  // Stop the channel
357  if(!isf_rli_deint(appState->pChannelDescriptor)){
358  return -1;
359  }
360  appState->status.channel = RLI_APP_STATE_CLOSED;
361  return 0;
362 }
363 
364 /*!
365 ** @}
366 */
367 
int32 device_disconnect(rliAppState_t *appState)
Definition: rli_project.c:326
ISF board support header files.
This file defines the system configuration for the communication channel.
unsigned char uint8
This defines uint8 as unsigned char.
Definition: isf_types.h:18
isf_status_t isf_rli_close(RLI_DEV_HANDLE *apRLIDeviceHandle)
This function closes the RLI connection.
Definition: isf_rli.c:93
fsl_i2c_master_driver.h defines structures and types for the i2c master driver.
uint8_t cmdBuffer_t[RLI_COMM_BUFFER_SIZE]
Definition: rli_project.c:45
rli overall application state buffer format.
Definition: rli_project.c:88
void RLI_CHANNEL_HANDLE
Definition: isf_rli.h:13
int32 close_channel(rliAppState_t *appState)
Definition: rli_project.c:352
Information necessary to communicate with an I2C slave device.
MQX_INITIALIZATION_STRUCT MQX_init_struct
This data structure/variable holds the complete state of the rli magnetometer sensor embedded applica...
Definition: MQX1.c:103
RLI_CHANNEL_HANDLE * isf_rli_init(uint32 aChannelId)
This function initializes a register level interface.
Definition: isf_rli.c:20
signed char int8
Definition: basic_types.h:12
unsigned long uint32
This defines uint32 as unsigned long.
Definition: isf_types.h:36
ci_rw_enum rw
Definition: isf_ci.h:217
dm_ChannelId_t channelID
Definition: rli_project.c:66
isf_pm.h describes the API definitions, types, and macros for the Intelligent Sensing Framework (ISF)...
The isf_types.h file contains the ISF data type definitions and some of the globally used macros...
int32 device_connect(rliAppState_t *appState)
Definition: rli_project.c:313
RLI_CHANNEL_HANDLE * pChannelDescriptor
Definition: rli_project.c:82
#define RLI_COMM_BUFFER_SIZE
Definition: rli_project.c:43
uint8_t rcvBuffer_t[RLI_COMM_BUFFER_SIZE]
Definition: rli_project.c:44
uint32 isf_ci_app_read(uint8 aAppId, uint32 anumBytes, uint8 *apDst)
This API reads data from the host via the mailboxes.
uint32 isf_ci_app_write(uint8 aAppId, uint32 anumBytes, uint8 *apSrc)
This API writes data to the host via the mailboxes.
isf_status_t isf_rli_write(RLI_DEV_HANDLE *apRLIDeviceHandle, int32 startAddress, uint32 aNbyteWrite, uint8 *apWriteBuffer)
This function writes to the device registers.
Definition: isf_rli.c:64
ci_response_t rli_ci_app_callback(ci_host_cmd_packet_t *pHostPacket, ci_app_resp_packet_t *pAppPacket)
Definition: rli_project.c:151
int32 open_channel(rliAppState_t *appState)
Definition: rli_project.c:338
void rli_app_task(void)
Definition: rli_project.c:127
isf_status_t isf_rli_deint(RLI_CHANNEL_HANDLE *apRLIChannelHandle)
This function de-initialize the RLI channel.
Definition: isf_rli.c:106
long int32
This defines int32 as long.
Definition: isf_types.h:32
Main ISF header file. Contains code common to all ISF components.
rli application configuration buffer format.
Definition: rli_project.c:71
API definitions, types, and macros for the Intelligent Sensing Framework (ISF) Command Interpreter (C...
rliConfigRegister_t CfgBuffer
Application configuration information.
Definition: rli_project.c:78
ci_status_t isf_ci_qr_update(uint8 aAppId, int8 anumBytes, uint8 *apSrc)
This API updates the Quick-Read mailboxes.
The isf_init.h file contains the task initialization attributes required for initialization of the fo...
uint16_t deviceAddress
Definition: rli_project.c:65
unsigned short uint16
This defines uint16 as unsigned short.
Definition: isf_types.h:27
uint8_t cmdBuffer[RLI_COMM_BUFFER_SIZE]
Definition: rli_project.c:80
This structure enables an application to read from or write to the host.
Definition: isf_ci.h:210
uint8_t rcvBuffer[RLI_COMM_BUFFER_SIZE]
Definition: rli_project.c:81
void RLI_DEV_HANDLE
Definition: isf_rli.h:14
This structure contains host command information.
Definition: isf_ci.h:186
isf_status_t isf_rli_read(RLI_DEV_HANDLE *apRLIDeviceHandle, int32 startAddress, uint32 aNbyteRead, uint8 *apReadBuffer)
This function reads from the device registers.
Definition: isf_rli.c:79
isf_devmsg.h defines the API definitions and types for the Intelligent Sensing (ISF) Device Messaging...
ci_response_enum
These are the CI errors provided to the host.
Definition: isf_ci.h:107
rliAppStatus_t status
Definition: rli_project.c:79
RLI_DEV_HANDLE * isf_rli_open(RLI_CHANNEL_HANDLE *apRLIChannelHandle, void *apSlaveInfo)
This function creates a RLI connection handle at a specified device address.
Definition: isf_rli.c:43
comm_Id_t dm_ChannelId_t
This typedef is a numeric channel identifier index into an array of channels in the system...
Definition: isf_devmsg.h:33
RLI_DEV_HANDLE * pHandle
Definition: rli_project.c:83