Stepper-Motor-Control  v3.0.0
System on a Chip 2014 - Group 04
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
userInputTask.c
Go to the documentation of this file.
1 /**
2  *****************************************************************************
3  * @file userInputTask.c
4  * @author Michael Riedel
5  * @author Marc Kossmann
6  * @version v2.0.0
7  * @date 18.11.2014
8  * @brief Source code for User-Input-Task which is highest instance, reacts
9  * to user input and controls register and hardware access
10  *****************************************************************************
11  * @par History:
12  * @details v0.1.0 22.10.2014 Kossmann
13  * - first draft for milestone 1b
14  * @details v0.1.1 30.10.2014 Kossmann
15  * - added error handling for flags and mailboxes
16  * - changed IPC with switches ISR to message queue
17  * @details v0.1.2 30.10.2014 Riedel
18  * - changed DEBUG_ON_FLAG to DEBUG_ON_EVENT
19  * @details v0.1.3 31.10.2014 Riedel & Kossmann
20  * - moved hardwareTest() and initial printouts into userInputTask
21  * because the need OS running
22  * @details v0.1.4 03.11.2014 Kossmann
23  * - used new register-access via inline functions of registerAccess.h
24  * @details v0.1.5 04.11.2014 Riedel & Kossmann
25  * - reduced messageQueue size to 1
26  * @details v0.1.6 04.11.2014 Kossmann
27  * - used the right masks for evaluating switches
28  * @details v0.1.7 06.11.2014 Riedel
29  * - added usage of new LCD-functions
30  * @details v0.1.8 07.11.2014 Riedel & Kossmann
31  * - added DEBUG_OFF_EVENT for turning debug on heartbeatTask off
32  * @details v1.0.0 11.11.2014 Riedel & Kossmann
33  * - replaced messageQueue with SW_UPDATE_EVENT
34  * - moved PIO_SW_GetValues() in InputTask
35  * - moved 1 second wait from userOutputTask
36  * @details v1.0.1 13.11.2014 Kossmann
37  * - removed OutputTaskMailbox and using global var instead
38  * @details v1.0.2 14.11.2014 Kossmann
39  * - removed registerMutex because no longer needed with real
40  * registers
41  * - moved init IPC global var to main
42  * @details v2.0.0 18.11.2014 Riedel & Kossmann
43  * - removed unnecessary wait
44  * - added flag posting for GLOB_VAR_UPDATE @see events.h
45  * - verified functionality -> release MS2
46  *****************************************************************************
47  */
48 
49 #include "../INC/userInputTask.h"
50 
51 extern OS_FLAG_GRP *userInputTaskFlagsGrp;
52 extern OS_FLAG_GRP *heartbeatTaskFlagsGrp;
53 extern OS_FLAG_GRP *userOutputTaskFlagsGrp;
54 
55 void UserInputTask(void *pdata) {
56  uint8_t err;
57  uint32_t modeBits;
58  OS_FLAGS newFlag;
59 
60  bool newInput = true;
61 
62  // used to check for stepsReg update
63  uint32_t oldStepsReg = 0;
64  // register copies to work with
65  uint8_t ctrlReg = 0;
66  uint8_t speedReg = 0;
67  uint32_t stepsReg = 0;
68 
69  //declare and initialize local systemState
71  .activeUseCase = STOP };
72 
73  //local outputTaskData
74  outputTaskData_t outputTaskDataLocal = { .ctrlReg = 0, .speedReg = 0,
75  .stepsReg = 0, .systemState = systemState };
76 
77  // variable to store position of switches
78  uint32_t switchesReg = 0;
79 
80  // show initial terminal msg
81  printf_term("Stepper Motor - System on a Chip 2014\n");
82  printf_term("Michael Riedel & Marc Kossmann\n");
83  printf_term("Version %s - %s\n", VERSION, DATE);
84 
85  // init LC-Display and show initial screen
86  init_lcd();
87  setPos_lcd(1, 5);
88  printf_lcd("SoC 2014");
89  setPos_lcd(2, 1);
90  printf_lcd("Stepper-Control");
91  fflush_lcd();
92 
93  // Enable Interrupt
94 #ifdef INTERRUPT_ENABLE
96 #endif
98 
99  while (1) {
100  // get register copies
101  ctrlReg = ctrlRegGet();
102  speedReg = speedRegGet();
103  stepsReg = stepsRegGet();
104  // check for new events
105  newFlag =
106  OSFlagPend(userInputTaskFlagsGrp,
109  OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME, 10, &err);
110  if (OS_NO_ERR == err) {
111  newInput = true;
112  // check for key0 event
113  if (newFlag & KEY0_RS_EVENT) {
114  // toogle RS-Bit in ctrlReg
115  if (ctrlReg & CTRL_REG_RS_MSK) { //RS-Bit is 1
116  ctrlReg &= ~(CTRL_REG_RS_MSK);
117  } else { //RS-Bit is 0
118  ctrlReg |= CTRL_REG_RS_MSK;
119  }
120  }
121  // check for key2 event (decrease steps)
122  if (newFlag & KEY2_MINUS_EVENT) {
123  // is motor stopped?
124  if (!(ctrlReg & CTRL_REG_RS_MSK)) {
125  if (0 != speedReg) {
126  speedReg--;
127  }
128  }
129  }
130  // check for key3 event (increase steps)
131  if (newFlag & KEY3_PLUS_EVENT) {
132  // is motor stopped?
133  if (!(ctrlReg & CTRL_REG_RS_MSK)) {
134  if (7 != speedReg) {
135  speedReg++;
136  }
137  }
138  }
139  // check for motor stop event
140  if (newFlag & MOTOR_STOP_EVENT) {
141  ctrlReg &= ~(CTRL_REG_RS_MSK);
142  }
143  } else if (OS_TIMEOUT != err) {
144  error("INPUT_TASK_FLAG_ERR: %i\n", err);
145  }
146  // check for switches event
147  if (newFlag & SW_UPDATE_EVENT) {
148  // get current sw events
149  switchesReg = PIO_SW_GetValues();
150  // evaluate switch positions
151  if (switchesReg & PIO_SW_LR_MSK) {
152  ctrlReg |= CTRL_REG_LR_MSK;
153  } else {
154  ctrlReg &= ~(CTRL_REG_LR_MSK);
155  }
156  // is motor stopped?
157  if (!(ctrlReg & CTRL_REG_RS_MSK)) {
158  // then clear mode bits ...
159  ctrlReg &= ~(CTRL_REG_MODE_MSK);
160  // ... and set mode bits
161  ctrlReg |= ((switchesReg & PIO_SW_MODE_MSK) << 1);
162  }
163  if (switchesReg & PIO_SW_DEBUG_MSK) {
164  systemState.operationalStatus = DEBUG;
165  OSFlagPost(heartbeatTaskFlagsGrp, DEBUG_ON_EVENT, OS_FLAG_SET, &err);
166  if (OS_NO_ERR != err) {
167  error("INPUT_TASK_FLAG_ERR: %i\n", err);
168  }
169  } else {
170  if (systemState.operationalStatus == DEBUG) {
171  systemState.operationalStatus = FUNCTIONAL;
172  OSFlagPost(heartbeatTaskFlagsGrp, DEBUG_OFF_EVENT, OS_FLAG_SET, &err);
173  if (OS_NO_ERR != err) {
174  error("INPUT_TASK_FLAG_ERR: %i\n", err);
175  }
176  }
177  }
178  }
179 
180  // change systemState when Run-Bit = 1
181  if (ctrlReg & CTRL_REG_RS_MSK) {
182  modeBits = ((ctrlReg & CTRL_REG_MODE_MSK) >> 2);
183  if ((modeBits & MODE_STOP_CON_RUN_MSK) == MODE_STOP) {
184  systemState.activeUseCase = STOP;
185  } else if ((modeBits & MODE_STOP_CON_RUN_MSK) == MODE_CON_RUN) {
186  systemState.activeUseCase = CONTINOUS;
187  } else if (modeBits == MODE_CH_OF_ST_1_4) {
188  systemState.activeUseCase = QUARTER_ROTATION;
189  } else if (modeBits == MODE_CH_OF_ST_1_2) {
190  systemState.activeUseCase = HALF_ROTATION;
191  } else if (modeBits == MODE_CH_OF_ST_1) {
192  systemState.activeUseCase = FULL_ROTATION;
193  } else if (modeBits == MODE_CH_OF_ST_2) {
194  systemState.activeUseCase = DOUBLE_ROTATION;
195  }
196  }
197  // new user input or stepsReg updated when motor running
198  if (newInput | ((ctrlReg & CTRL_REG_RS_MSK) & (oldStepsReg != stepsReg))) {
199  // update content of mailbox to outputTask
200  outputTaskDataLocal.ctrlReg = ctrlReg;
201  outputTaskDataLocal.speedReg = speedReg;
202  oldStepsReg = stepsReg;
203  outputTaskDataLocal.stepsReg = stepsReg;
204  outputTaskDataLocal.systemState = systemState;
205  err = outputTaskDataTx(outputTaskDataLocal);
206  if (OS_NO_ERR != err) {
207  error("INPUT_TASK_GLOB_VAR_ERR: %i\n", err);
208  } else {
209  OSFlagPost(userOutputTaskFlagsGrp, GLOB_VAR_UPDATE, OS_FLAG_SET, &err);
210  if (OS_NO_ERR != err) {
211  error("INPUT_TASK_FLAG_ERR: %i\n", err);
212  }
213  }
214  // write values of register copies into real registers
216  ctrlRegBitSet(ctrlReg & CTRL_REG_0_6_MSK);
217  speedRegSet(speedReg);
218  newInput = false;
219  }
220  }
221 }
222 
223 void hardwareTest(void) {
224  uint32_t i;
225 
226  PIO_HEX0_Set(0x0);
227  PIO_HEX1_Set(0x0);
228  PIO_HEX2_Set(0x0);
229  PIO_HEX3_Set(0x0);
230 
231  printf_term("Starting hardwareTest!\n");
232  clear_lcd();
233  setPos_lcd(1, 1);
234  printf_lcd("Start hwTest!");
235 
236  printf_term("Begin with LED9 flashing on-off\n");
237  setPos_lcd(2, 1);
238  printf_lcd("LED9 on-off");
239  fflush_lcd();
240  OSTimeDlyHMSM(0, 0, 1, 0);
241  PIO_LED9_Set(0x1);
242  OSTimeDlyHMSM(0, 0, 1, 0);
243  PIO_LED9_Set(0x0);
244  OSTimeDlyHMSM(0, 0, 1, 0);
245  PIO_LED9_Set(0x1);
246  OSTimeDlyHMSM(0, 0, 1, 0);
247  PIO_LED9_Set(0x0);
248  OSTimeDlyHMSM(0, 0, 1, 0);
249 
250  printf_term("HEX-Display 0 all on\n");
251  setPos_lcd(2, 1);
252  printf_lcd("HEX0 all on");
253  fflush_lcd();
254  OSTimeDlyHMSM(0, 0, 1, 0);
255  PIO_HEX0_Set(0x7F);
256  OSTimeDlyHMSM(0, 0, 1, 0);
257 
258  printf_term("HEX-Display 1 all on\n");
259  setPos_lcd(2, 1);
260  printf_lcd("HEX1 all on");
261  fflush_lcd();
262  fflush_lcd();
263  PIO_HEX1_Set(0x7F);
264  OSTimeDlyHMSM(0, 0, 1, 0);
265 
266  printf_term("HEX-Display 2 all on\n");
267  setPos_lcd(2, 1);
268  printf_lcd("HEX2 all on");
269  fflush_lcd();
270  PIO_HEX2_Set(0x7F);
271  OSTimeDlyHMSM(0, 0, 1, 0);
272 
273  printf_term("HEX-Display 3 all on\n");
274  setPos_lcd(2, 1);
275  printf_lcd("HEX1 all on");
276  fflush_lcd();
277  PIO_HEX3_Set(0x7F);
278  OSTimeDlyHMSM(0, 0, 1, 0);
279 
280  PIO_HEX0_Set(0x0);
281  PIO_HEX1_Set(0x0);
282  PIO_HEX2_Set(0x0);
283  PIO_HEX3_Set(0x0);
284 
285  printf_term("HEX-Display 0 shift on-off\n");
286  setPos_lcd(2, 1);
287  printf_lcd("HEX0 shift test\n");
288  fflush_lcd();
289  for (i = 0; i < 7; i++) {
290  PIO_HEX0_Set(pow(2, i));
291  OSTimeDlyHMSM(0, 0, 0, 500);
292  PIO_HEX0_Set(0x0);
293  OSTimeDlyHMSM(0, 0, 0, 500);
294  }
295  OSTimeDlyHMSM(0, 0, 0, 500);
296  PIO_HEX0_Set(0x0);
297  clear_lcd();
298 }
#define CTRL_REG_LR_MSK
Left (0) or Right (1)-Bit.
void printf_term(const char *,...)
Writes formated string to terminal.
Struct to store state of system and use case information.
Definition: dataTypes.h:37
Motor not moving.
Definition: dataTypes.h:28
#define MODE_CH_OF_ST_2
Bits must be 0b1110
#define CTRL_REG_0_6_MSK
Bits 0..6 in ctrlReg.
Definition: userInputTask.h:57
void UserInputTask(void *pdata)
UserInputTask.
Definition: userInputTask.c:55
#define CTRL_REG_IE_MSK
Interrupt-Enable Bit.
#define MODE_CH_OF_ST_1_2
Bits must be 0b0110
void fflush_lcd()
Writes buffed data to lcd.
static __inline__ void PIO_HEX1_Set(uint32_t segmentValues)
Function to set segments on hex1 display.
#define error(...)
Prints the Error-messages in the terminal.
#define CTRL_REG_MODE_MSK
Mode-combination according to ctrlRegSet()-function.
#define PIO_SW_DEBUG_MSK
Debug mask for PIO-Switches.
uint8_t ctrlReg
copy control register
Definition: dataTypes.h:52
Motor turning one rotation.
Definition: dataTypes.h:31
#define PIO_SW_MODE_MSK
Mode mask for PIO-Switches.
#define MODE_STOP_CON_RUN_MSK
Bit 0 & 1 only.
static __inline__ void PIO_HEX2_Set(uint32_t segmentValues)
Function to set segments on hex2 display.
#define MOTOR_STOP_EVENT
the interrupt is sent via VHDL-Component, when the motor reached its end-position ...
Definition: events.h:52
#define MODE_CH_OF_ST_1
Bits must be 0b1010
state_t operationalStatus
operational status
Definition: dataTypes.h:38
debugging is active
Definition: dataTypes.h:23
static __inline__ void ctrlRegBitSet(uint8_t bitsToSet)
Sets the CtrlReg bitwise.
OS_FLAG_GRP * heartbeatTaskFlagsGrp
The flags group used in the heartbeat-task and user-input-task.
Definition: events.h:42
#define DEBUG_OFF_EVENT
deactivates the debug-mode via sw_9
Definition: events.h:44
void clear_lcd(void)
Clears display.
everything is full functional
Definition: dataTypes.h:22
uint8_t speedReg
copy of speed register
Definition: dataTypes.h:53
static __inline__ void speedRegSet(uint8_t newSpeed)
Sets the speed, how fast the Stepper-Motor-Control turns the motor.
#define DATE
global date definition
#define CTRL_REG_IR_MSK
Interrupt-Request Bit.
systemState_t systemState
stores state of system
Definition: dataTypes.h:50
uint8_t outputTaskDataTx(outputTaskData_t data)
Sends data to ipc channel.
Motor turning 1/2 rotation.
Definition: dataTypes.h:30
static __inline__ void PIO_HEX3_Set(uint32_t segmentValues)
Function to set segments on hex3 display.
static __inline__ void PIO_LED9_Set(uint32_t ledValue)
Function to set led9 for heartbeat.
#define SW_UPDATE_EVENT
signalizes that switches changed
Definition: events.h:37
OS_FLAG_GRP * userInputTaskFlagsGrp
The flags group used in the user-input-task.
Definition: events.h:32
Motor is continously running.
Definition: dataTypes.h:33
Motor turning 1/4 rotation.
Definition: dataTypes.h:29
#define KEY3_PLUS_EVENT
increases the steps to turn via key_3
Definition: events.h:35
static __inline__ uint32_t PIO_SW_GetValues(void)
Function to read content of switches data register.
#define MODE_CH_OF_ST_1_4
Bits must be 0b0010
void init_lcd(void)
Initializes lcd output.
OS_FLAG_GRP * userOutputTaskFlagsGrp
The flags group used in the user-output-task.
Definition: events.h:51
#define MODE_CON_RUN
Use "MODE_STOP_CON_RUN_MSK"; Must be 0b01
#define DEBUG_ON_EVENT
activates the debug-mode via sw_9
Definition: events.h:43
#define CTRL_REG_RS_MSK
Run (1) or Stop (0)-Bit.
#define GLOB_VAR_UPDATE
signals that data changed
Definition: events.h:53
static __inline__ uint32_t stepsRegGet(void)
Returns the actual content of the steps-register.
void printf_lcd(const char *,...)
Writes formated string to lcd.
static __inline__ uint8_t speedRegGet(void)
Returns the actual content of the speed-register.
#define VERSION
global version definition
#define PIO_SW_LR_MSK
Left/Right mask for PIO-Switches.
void setPos_lcd(int32_t row, int32_t col)
Sets the cursor position on display.
uint32_t stepsReg
copy of steps register
Definition: dataTypes.h:51
#define KEY0_RS_EVENT
runs or stops the motor via key_0
Definition: events.h:33
#define KEY2_MINUS_EVENT
decreases the steps to turn via key_2
Definition: events.h:34
static __inline__ void ctrlRegBitClr(uint8_t bitsToClr)
Clears the CtrlReg bitwise.
Motor turning two rotation.
Definition: dataTypes.h:32
useCases_t activeUseCase
active use case
Definition: dataTypes.h:39
void hardwareTest(void)
Tests hardware.
static __inline__ uint8_t ctrlRegGet(void)
Returns the actual content of the control-register.
static __inline__ void PIO_HEX0_Set(uint32_t segmentValues)
Function to set segments on hex0 display.
Datatype of global variable for transmitting information from InputTask to OutputTask.
Definition: dataTypes.h:49
#define MODE_STOP
MODE_STOP_CON_RUN_MSK; Must be 0b00