ISSDK  1.7
IoT Sensing Software Development Kit
control.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
4  * Copyright 2016-2017 NXP
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted (subject to the limitations in the disclaimer below) provided
9  * that the following conditions are met:
10  *
11  * o Redistributions of source code must retain the above copyright notice, this list
12  * of conditions and the following disclaimer.
13  *
14  * o Redistributions in binary form must reproduce the above copyright notice, this
15  * list of conditions and the following disclaimer in the documentation and/or
16  * other materials provided with the distribution.
17  *
18  * o Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*! \file control.c
36  \brief Defines control sub-system
37 
38  This file contains a UART implementation of the control subsystem. The
39  command interpreter and streaming functions are contained in two separate
40  files. So you can easily swap those out with only minor changes here.
41 */
42 #include "fsl_debug_console.h"
43 #include "board.h"
44 #include "pin_mux.h"
45 #include "fsl_uart.h"
46 #include "fsl_port.h"
47 #include "sensor_fusion.h"
48 #include "control.h"
49 
50 #ifndef F_USE_WIRELESS_UART
51 #define F_USE_WIRELESS_UART 0x0001 ///< 0x0001 to include, 0x0000 otherwise
52 #endif
53 #ifndef F_USE_WIRED_UART
54 #define F_USE_WIRED_UART 0x0002 ///< 0x0002 to include, 0x0000 otherwise
55 #endif
56 
57 #define CONTROL_BAUDRATE 115200 ///< Baudrate to be used for serial communications
58 
59 uart_handle_t wired_uartHandle;
60 uart_handle_t wireless_uartHandle;
61 
62 // global structures
63 uint8_t sUARTOutputBuffer[256]; // larger than the nominal 124 byte size for outgoing packets
64 
65 // direct access to sfg here is the only place in the entire library where we cannot simply
66 // pass a pointer. This is because it is needed by the UART interrupt handlers. Since this
67 // only occurs here, in a subsystem which is defined to be application dependent, that is
68 // considered acceptable.
70 
71 // Blocking function to write a single byte to a specified UART
72 void myUART_WriteByte(UART_Type *base, uint8_t data)
73 {
74  uint8_t flag = 0;
75  while (!flag)
76  {
77  flag = base->S1 & 0x80;
78  }
79  UART_WriteByte(base, data);
80 }
81 
82 // Blocking function pipes specified buffer to both output UARTS
83 int8_t writeControlPort(ControlSubsystem *pComm, uint8_t buffer[], uint16_t nbytes)
84 {
85  uint16_t i;
86  for (i = 0; i < nbytes; i++)
87  {
88 #if F_USE_WIRED_UART
89  myUART_WriteByte(WIRED_UART, buffer[i]);
90 #endif
91 #if F_USE_WIRELESS_UART
92  myUART_WriteByte(WIRELESS_UART, buffer[i]);
93 #endif
94  }
95 
96  return (0);
97 }
98 
99 #if F_USE_WIRELESS_UART
100 // writeWirelessPort() is called from BlueRadios_Init(), which is used to
101 // initialize the Bluetooth module on NXP sensor shields. That function will
102 // obviously need to be replaced for alternate hardware.
103 int8_t writeWirelessPort(uint8_t buffer[], uint16_t nbytes)
104 {
105  uint16_t i;
106  for (i = 0; i < nbytes; i++)
107  {
108  myUART_WriteByte(WIRELESS_UART, buffer[i]);
109  }
110 
111  return (0);
112 }
113 // Wired and Wireless UART interrupt handlers are essentially identical.
115 {
116  uint8_t data;
117  status_t sts;
118  uint32_t nbytes; // number of bytes received
119  uint32_t flags;
120  static char iCommandBuffer_B[5] = "~~~~"; // 5 bytes long to include the unused terminating \0
121  sfg.setStatus(&sfg, RECEIVING_WIRELESS);
122  flags = UART_GetStatusFlags(WIRELESS_UART);
123  /* If new data arrived. */
124  if ((kUART_RxDataRegFullFlag | kUART_RxOverrunFlag) & flags)
125  {
126  sts = UART_TransferGetReceiveCount(WIRELESS_UART, &wireless_uartHandle, &nbytes);
127  if (sts == kStatus_Success)
128  {
129  data = UART_ReadByte(WIRELESS_UART);
130  DecodeCommandBytes(&sfg, iCommandBuffer_B, &data, 1);
131  }
132  }
133 }
134 // initialize BlueRadios BR-LE4.0-D2A Bluetooth module
135 // This is required for NXP FRDM-FXS-MULT2-B boards.
136 void BlueRadios_Init(void)
137 {
138  uint16_t ilen; // command string length
139 
140  // transmit "ATSRM,2,0\r" to minimize traffic from the module
141  // command "ATSRM": sets the module response mode which configures how verbose the module will be
142  // 2: response mode at to minimal
143  // 0: disconnected mode is command mode
144  // \r: carriage return escape sequence
145  strcpy((char *)sUARTOutputBuffer, "ATSRM,2,0\r");
146  ilen = strlen((char *)sUARTOutputBuffer);
147  writeWirelessPort(sUARTOutputBuffer, ilen);
148  return;
149 }
150 #endif
151 
152 #if F_USE_WIRED_UART
153 void echo(uint8_t data) // only used for comms debug
154 {
155  /* Send data only when UART TX register is empty and ring buffer has data to send out. */
156  if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(WIRED_UART))
157  {
158  UART_WriteByte(WIRED_UART, data);
159  }
160 }
161 // Wired and Wireless UART interrupt handlers are essentially identical.
163 {
164  uint8_t data;
165  status_t sts;
166  uint32_t nbytes; // number of bytes received
167  uint32_t flags;
168  static char iCommandBuffer_A[5] = "~~~~"; // 5 bytes long to include the unused terminating \0
169 
170  sfg.setStatus(&sfg, RECEIVING_WIRED);
171  flags = UART_GetStatusFlags(WIRED_UART);
172  /* If new data arrived. */
173  if ((kUART_RxDataRegFullFlag | kUART_RxOverrunFlag) & flags)
174  {
175  sts = UART_TransferGetReceiveCount(WIRED_UART, &wired_uartHandle, &nbytes);
176  if (sts == kStatus_Success)
177  {
178  data = UART_ReadByte(WIRED_UART);
179  DecodeCommandBytes(&sfg, iCommandBuffer_A, &data, 1);
180  }
181  }
182 }
183 #endif
184 
185 /// Initialize the control subsystem and all related hardware
187  ControlSubsystem *pComm ///< pointer to the control subystem structure
188 )
189 {
190  uart_config_t config;
191  if (pComm)
192  {
193  pComm->DefaultQuaternionPacketType = Q3; // default to simplest algorithm
194  pComm->QuaternionPacketType = Q3; // default to simplest algorithm
195  pComm->AngularVelocityPacketOn = true; // transmit angular velocity packet
196  pComm->DebugPacketOn = true; // transmit debug packet
197  pComm->RPCPacketOn = true; // transmit roll, pitch, compass packet
198  pComm->AltPacketOn = true; // Altitude packet
199  pComm->AccelCalPacketOn = 0;
200  pComm->write = writeControlPort;
201  pComm->stream = CreateAndSendPackets;
202 
203 #if F_USE_WIRED_UART
204  /* Initialize WIRED UART pins below - currently duplicates code in pin_mux.c */
205  CLOCK_EnableClock(WIRED_UART_PORT_CLKEN);
208  UART_GetDefaultConfig(&config);
209 
210  config.baudRate_Bps = CONTROL_BAUDRATE;
211  config.enableTx = true;
212  config.enableRx = true;
213  config.rxFifoWatermark = 1;
214  UART_Init(WIRED_UART, &config, CLOCK_GetFreq(WIRED_UART_CLKSRC));
215 
216  /* Enable RX interrupt. */
217  UART_EnableInterrupts(WIRED_UART, kUART_RxDataRegFullInterruptEnable |
218  kUART_RxOverrunInterruptEnable);
219  EnableIRQ(WIRED_UART_IRQn);
220 #endif
221 #if F_USE_WIRELESS_UART
222  /* Initialize WIRELESS UART pins below */
223  CLOCK_EnableClock(WIRELESS_UART_PORT_CLKEN);
228 
229  UART_Init(WIRELESS_UART, &config, CLOCK_GetFreq(WIRELESS_UART_CLKSRC));
230  BlueRadios_Init();
231 
232  /* Enable RX interrupt. */
233  UART_EnableInterrupts(WIRELESS_UART, kUART_RxDataRegFullInterruptEnable |
234  kUART_RxOverrunInterruptEnable);
235  EnableIRQ(WIRELESS_UART_IRQn);
236 #endif
237 
238  return (0);
239  }
240  else
241  {
242  return (1);
243  }
244 }
#define WIRED_UART_TX_PIN
The port number associated with TX.
Definition: frdm_k64f.h:149
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:70
void WIRED_UART_IRQHandler(void)
Definition: control.c:162
int8_t writeWirelessPort(uint8_t buffer[], uint16_t nbytes)
Definition: control.c:103
#define WIRED_UART_PORT
KDSK handle for the pin port associated with this UART.
Definition: frdm_k64f.h:147
Receiving commands over wireless interface (momentary)
#define WIRED_UART
KSDK instance name for the debug UART.
Definition: frdm_k64f.h:145
#define WIRELESS_UART_IRQn
The interrupt number associated with this IRQ.
Definition: frdm_k64f.h:168
uint8_t data[FXLS8962_DATA_SIZE]
#define WIRELESS_UART_RX_PIN
The port number associated with RX.
Definition: frdm_k64f.h:162
writePort_t * write
low level function to write a char buffer to the serial stream
Definition: control.h:76
volatile uint8_t AltPacketOn
flag to enable altitude packet
Definition: control.h:74
#define WIRELESS_UART_PORT
KDSK handle for the pin port associated with this UART.
Definition: frdm_k64f.h:161
#define WIRELESS_UART_TX_PIN
The port number associated with TX.
Definition: frdm_k64f.h:163
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:68
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet
Definition: control.h:71
#define WIRELESS_UART_CLKSRC
KSDK instance name for the clock feeding this module.
Definition: frdm_k64f.h:167
uart_handle_t wired_uartHandle
Definition: control.c:59
void myUART_WriteByte(UART_Type *base, uint8_t data)
Definition: control.c:72
The top level fusion structure.
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
Definition: control.h:69
int8_t writeControlPort(ControlSubsystem *pComm, uint8_t buffer[], uint16_t nbytes)
Definition: control.c:83
#define WIRELESS_UART_MUX
KDSK pin mux selector.
Definition: frdm_k64f.h:164
setStatus_t * setStatus
change status indicator immediately
#define WIRED_UART_CLKSRC
KSDK instance name for the clock feeding this module.
Definition: frdm_k64f.h:155
#define WIRELESS_UART
KSDK instance name for the debug UART.
Definition: frdm_k64f.h:159
void CreateAndSendPackets(SensorFusionGlobals *sfg, uint8_t *sUARTOutputBuffer)
The sensor_fusion.h file implements the top level programming interface.
volatile uint8_t RPCPacketOn
flag to enable roll, pitch, compass packet
Definition: control.h:73
Receiving commands over wired interface (momentary)
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
Definition: control.c:63
#define WIRELESS_UART_PORT_CLKEN
KDSK handle for the pin port clock enable.
Definition: frdm_k64f.h:160
int8_t initializeControlPort(ControlSubsystem *pComm)
Initialize the control subsystem and all related hardware.
Definition: control.c:186
streamData_t * stream
function to create packets for serial stream
Definition: control.h:77
void DecodeCommandBytes(SensorFusionGlobals *sfg, char iCommandBuffer[], uint8 sUART_InputBuffer[], uint16 nbytes)
void BlueRadios_Init(void)
Definition: control.c:136
uart_handle_t wireless_uartHandle
Definition: control.c:60
void echo(uint8_t data)
Definition: control.c:153
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:75
Defines control sub-system.
#define WIRED_UART_IRQn
The interrupt number associated with this IRQ.
Definition: frdm_k64f.h:156
#define WIRED_UART_RX_PIN
The port number associated with RX.
Definition: frdm_k64f.h:148
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
#define CONTROL_BAUDRATE
Baudrate to be used for serial communications.
Definition: control.c:57
#define WIRED_UART_PORT_CLKEN
KDSK handle for the pin port clock enable.
Definition: frdm_k64f.h:146
#define WIRED_UART_MUX
If Using Orient App then use Host I/O.
Definition: frdm_k64f.h:150
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
Definition: control.h:75
void WIRELESS_UART_IRQHandler(void)
Definition: control.c:114
volatile uint8_t DebugPacketOn
flag to enable debug packet
Definition: control.h:72