ISSDK  1.8
IoT Sensing Software Development Kit
control.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /*! \file control.c
10  \brief Defines control sub-system
11 
12  This file contains a UART implementation of the control subsystem. The
13  command interpreter and streaming functions are contained in two separate
14  files. So you can easily swap those out with only minor changes here.
15 */
16 #include "fsl_debug_console.h"
17 #include "board.h"
18 #include "pin_mux.h"
19 #include "fsl_uart.h"
20 #include "fsl_port.h"
21 #include "sensor_fusion.h"
22 #include "control.h"
23 
24 #ifndef F_USE_WIRELESS_UART
25 #define F_USE_WIRELESS_UART 0x0001 ///< 0x0001 to include, 0x0000 otherwise
26 #endif
27 #ifndef F_USE_WIRED_UART
28 #define F_USE_WIRED_UART 0x0002 ///< 0x0002 to include, 0x0000 otherwise
29 #endif
30 
31 #define CONTROL_BAUDRATE 115200 ///< Baudrate to be used for serial communications
32 
33 uart_handle_t wired_uartHandle;
34 uart_handle_t wireless_uartHandle;
35 
36 // global structures
37 uint8_t sUARTOutputBuffer[256]; // larger than the nominal 124 byte size for outgoing packets
38 
39 // direct access to sfg here is the only place in the entire library where we cannot simply
40 // pass a pointer. This is because it is needed by the UART interrupt handlers. Since this
41 // only occurs here, in a subsystem which is defined to be application dependent, that is
42 // considered acceptable.
44 
45 // Blocking function to write a single byte to a specified UART
46 void myUART_WriteByte(UART_Type *base, uint8_t data)
47 {
48  uint8_t flag = 0;
49  while (!flag)
50  {
51  flag = base->S1 & 0x80;
52  }
53  UART_WriteByte(base, data);
54 }
55 
56 // Blocking function pipes specified buffer to both output UARTS
57 int8_t writeControlPort(ControlSubsystem *pComm, uint8_t buffer[], uint16_t nbytes)
58 {
59  uint16_t i;
60  for (i = 0; i < nbytes; i++)
61  {
62 #if F_USE_WIRED_UART
63  myUART_WriteByte(WIRED_UART, buffer[i]);
64 #endif
65 #if F_USE_WIRELESS_UART
66  myUART_WriteByte(WIRELESS_UART, buffer[i]);
67 #endif
68  }
69 
70  return (0);
71 }
72 
73 #if F_USE_WIRELESS_UART
74 // writeWirelessPort() is called from BlueRadios_Init(), which is used to
75 // initialize the Bluetooth module on NXP sensor shields. That function will
76 // obviously need to be replaced for alternate hardware.
77 int8_t writeWirelessPort(uint8_t buffer[], uint16_t nbytes)
78 {
79  uint16_t i;
80  for (i = 0; i < nbytes; i++)
81  {
82  myUART_WriteByte(WIRELESS_UART, buffer[i]);
83  }
84 
85  return (0);
86 }
87 // Wired and Wireless UART interrupt handlers are essentially identical.
89 {
90  uint8_t data;
91  status_t sts;
92  uint32_t nbytes; // number of bytes received
93  uint32_t flags;
94  static char iCommandBuffer_B[5] = "~~~~"; // 5 bytes long to include the unused terminating \0
95  sfg.setStatus(&sfg, RECEIVING_WIRELESS);
96  flags = UART_GetStatusFlags(WIRELESS_UART);
97  /* If new data arrived. */
98  if ((kUART_RxDataRegFullFlag | kUART_RxOverrunFlag) & flags)
99  {
100  sts = UART_TransferGetReceiveCount(WIRELESS_UART, &wireless_uartHandle, &nbytes);
101  if (sts == kStatus_Success)
102  {
103  data = UART_ReadByte(WIRELESS_UART);
104  DecodeCommandBytes(&sfg, iCommandBuffer_B, &data, 1);
105  }
106  }
107 }
108 // initialize BlueRadios BR-LE4.0-D2A Bluetooth module
109 // This is required for NXP FRDM-FXS-MULT2-B boards.
110 void BlueRadios_Init(void)
111 {
112  uint16_t ilen; // command string length
113 
114  // transmit "ATSRM,2,0\r" to minimize traffic from the module
115  // command "ATSRM": sets the module response mode which configures how verbose the module will be
116  // 2: response mode at to minimal
117  // 0: disconnected mode is command mode
118  // \r: carriage return escape sequence
119  strcpy((char *)sUARTOutputBuffer, "ATSRM,2,0\r");
120  ilen = strlen((char *)sUARTOutputBuffer);
121  writeWirelessPort(sUARTOutputBuffer, ilen);
122  return;
123 }
124 #endif
125 
126 #if F_USE_WIRED_UART
127 void echo(uint8_t data) // only used for comms debug
128 {
129  /* Send data only when UART TX register is empty and ring buffer has data to send out. */
130  if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(WIRED_UART))
131  {
132  UART_WriteByte(WIRED_UART, data);
133  }
134 }
135 // Wired and Wireless UART interrupt handlers are essentially identical.
137 {
138  uint8_t data;
139  status_t sts;
140  uint32_t nbytes; // number of bytes received
141  uint32_t flags;
142  static char iCommandBuffer_A[5] = "~~~~"; // 5 bytes long to include the unused terminating \0
143 
144  sfg.setStatus(&sfg, RECEIVING_WIRED);
145  flags = UART_GetStatusFlags(WIRED_UART);
146  /* If new data arrived. */
147  if ((kUART_RxDataRegFullFlag | kUART_RxOverrunFlag) & flags)
148  {
149  sts = UART_TransferGetReceiveCount(WIRED_UART, &wired_uartHandle, &nbytes);
150  if (sts == kStatus_Success)
151  {
152  data = UART_ReadByte(WIRED_UART);
153  DecodeCommandBytes(&sfg, iCommandBuffer_A, &data, 1);
154  }
155  }
156 }
157 #endif
158 
159 /// Initialize the control subsystem and all related hardware
161  ControlSubsystem *pComm ///< pointer to the control subystem structure
162 )
163 {
164  uart_config_t config;
165  if (pComm)
166  {
167  pComm->DefaultQuaternionPacketType = Q3; // default to simplest algorithm
168  pComm->QuaternionPacketType = Q3; // default to simplest algorithm
169  pComm->AngularVelocityPacketOn = true; // transmit angular velocity packet
170  pComm->DebugPacketOn = true; // transmit debug packet
171  pComm->RPCPacketOn = true; // transmit roll, pitch, compass packet
172  pComm->AltPacketOn = true; // Altitude packet
173  pComm->AccelCalPacketOn = 0;
174  pComm->write = writeControlPort;
175  pComm->stream = CreateAndSendPackets;
176 
177 #if F_USE_WIRED_UART
178  /* Initialize WIRED UART pins below - currently duplicates code in pin_mux.c */
179  CLOCK_EnableClock(WIRED_UART_PORT_CLKEN);
182  UART_GetDefaultConfig(&config);
183 
184  config.baudRate_Bps = CONTROL_BAUDRATE;
185  config.enableTx = true;
186  config.enableRx = true;
187  config.rxFifoWatermark = 1;
188  UART_Init(WIRED_UART, &config, CLOCK_GetFreq(WIRED_UART_CLKSRC));
189 
190  /* Enable RX interrupt. */
191  UART_EnableInterrupts(WIRED_UART, kUART_RxDataRegFullInterruptEnable |
192  kUART_RxOverrunInterruptEnable);
193  EnableIRQ(WIRED_UART_IRQn);
194 #endif
195 #if F_USE_WIRELESS_UART
196  /* Initialize WIRELESS UART pins below */
197  CLOCK_EnableClock(WIRELESS_UART_PORT_CLKEN);
202 
203  UART_Init(WIRELESS_UART, &config, CLOCK_GetFreq(WIRELESS_UART_CLKSRC));
204  BlueRadios_Init();
205 
206  /* Enable RX interrupt. */
207  UART_EnableInterrupts(WIRELESS_UART, kUART_RxDataRegFullInterruptEnable |
208  kUART_RxOverrunInterruptEnable);
209  EnableIRQ(WIRELESS_UART_IRQn);
210 #endif
211 
212  return (0);
213  }
214  else
215  {
216  return (1);
217  }
218 }
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
Definition: control.h:43
void CreateAndSendPackets(SensorFusionGlobals *sfg, uint8_t *sUARTOutputBuffer)
uart_handle_t wireless_uartHandle
Definition: control.c:34
volatile uint8_t RPCPacketOn
flag to enable roll, pitch, compass packet
Definition: control.h:47
uart_handle_t wired_uartHandle
Definition: control.c:33
int8_t writeWirelessPort(uint8_t buffer[], uint16_t nbytes)
Definition: control.c:77
#define WIRED_UART_PORT
KDSK handle for the pin port associated with this UART.
Definition: frdm_k64f.h:121
void WIRED_UART_IRQHandler(void)
Definition: control.c:136
void myUART_WriteByte(UART_Type *base, uint8_t data)
Definition: control.c:46
#define WIRED_UART_IRQn
The interrupt number associated with this IRQ.
Definition: frdm_k64f.h:130
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet
Definition: control.h:45
#define CONTROL_BAUDRATE
Baudrate to be used for serial communications.
Definition: control.c:31
#define WIRED_UART_CLKSRC
KSDK instance name for the clock feeding this module.
Definition: frdm_k64f.h:129
writePort_t * write
low level function to write a char buffer to the serial stream
Definition: control.h:50
#define WIRELESS_UART_TX_PIN
The port number associated with TX.
Definition: frdm_k64f.h:137
Defines control sub-system.
The top level fusion structure.
volatile uint8_t DebugPacketOn
flag to enable debug packet
Definition: control.h:46
Receiving commands over wireless interface (momentary)
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:49
void WIRELESS_UART_IRQHandler(void)
Definition: control.c:88
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:44
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:42
#define WIRED_UART
KSDK instance name for the debug UART.
Definition: frdm_k64f.h:119
#define WIRELESS_UART_RX_PIN
The port number associated with RX.
Definition: frdm_k64f.h:136
#define WIRELESS_UART
KSDK instance name for the debug UART.
Definition: frdm_k64f.h:133
int8_t writeControlPort(ControlSubsystem *pComm, uint8_t buffer[], uint16_t nbytes)
Definition: control.c:57
The sensor_fusion.h file implements the top level programming interface.
uint8_t data[FXLS8962_DATA_SIZE]
#define WIRED_UART_RX_PIN
The port number associated with RX.
Definition: frdm_k64f.h:122
#define WIRELESS_UART_PORT
KDSK handle for the pin port associated with this UART.
Definition: frdm_k64f.h:135
setStatus_t * setStatus
change status indicator immediately
volatile uint8_t AltPacketOn
flag to enable altitude packet
Definition: control.h:48
#define WIRED_UART_MUX
If Using Orient App then use Host I/O.
Definition: frdm_k64f.h:124
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
#define WIRED_UART_TX_PIN
The port number associated with TX.
Definition: frdm_k64f.h:123
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
Definition: control.c:37
Receiving commands over wired interface (momentary)
#define WIRELESS_UART_CLKSRC
KSDK instance name for the clock feeding this module.
Definition: frdm_k64f.h:141
int8_t initializeControlPort(ControlSubsystem *pComm)
Initialize the control subsystem and all related hardware.
Definition: control.c:160
#define WIRELESS_UART_MUX
KDSK pin mux selector.
Definition: frdm_k64f.h:138
#define WIRELESS_UART_PORT_CLKEN
KDSK handle for the pin port clock enable.
Definition: frdm_k64f.h:134
void DecodeCommandBytes(SensorFusionGlobals *sfg, char iCommandBuffer[], uint8 sUART_InputBuffer[], uint16 nbytes)
void echo(uint8_t data)
Definition: control.c:127
#define WIRELESS_UART_IRQn
The interrupt number associated with this IRQ.
Definition: frdm_k64f.h:142
streamData_t * stream
function to create packets for serial stream
Definition: control.h:51
void BlueRadios_Init(void)
Definition: control.c:110
#define WIRED_UART_PORT_CLKEN
KDSK handle for the pin port clock enable.
Definition: frdm_k64f.h:120
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
Definition: control.h:49