Statistics
| Branch: | Tag: | Revision:

amiro-os / modules / NUCLEO-F103RB / module.c @ e7c4f797

History | View | Annotate | Download (10.196 KB)

1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2020  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file
21
 * @brief   Structures and constant for the NUCLEO-F103RB module.
22
 *
23
 * @addtogroup NUCLEO-F103RB_module
24
 * @{
25
 */
26

    
27
#include <amiroos.h>
28

    
29
/*===========================================================================*/
30
/**
31
 * @name Module specific functions
32
 * @{
33
 */
34
/*===========================================================================*/
35

    
36
/** @} */
37

    
38
/*===========================================================================*/
39
/**
40
 * @name ChibiOS/HAL configuration
41
 * @{
42
 */
43
/*===========================================================================*/
44

    
45
SerialConfig moduleHalProgIfConfig = {
46
  /* bit rate */ 115200,
47
  /* CR1      */ 0,
48
  /* CR1      */ 0,
49
  /* CR1      */ 0,
50
};
51

    
52
#if (BOARD_DW1000_CONNECTED == true)
53
/*! SPI (high and low speed) configuration for DW1000 */
54
SPIConfig moduleHalSpiUwbHsConfig = {
55
  /* circular buffer mode        */ false,
56
  /* callback function pointer   */ NULL,
57
  /* chip select line port       */ GPIOB,
58
  /* chip select line pad number */ GPIOB_PIN12,
59
  /* CR1                         */ 0,
60
  /* CR2                         */ 0,
61
};
62

    
63
SPIConfig moduleHalSpiUwbLsConfig = {
64
  /* circular buffer mode        */ false,
65
  /* callback function pointer   */ NULL,
66
  /* chip select line port       */ GPIOB,
67
  /* chip select line pad number */ GPIOB_PIN12,
68
  /* CR1                         */ SPI_CR1_BR_1 | SPI_CR1_BR_0,
69
  /* CR2                         */ 0,
70
};
71
#endif /* (BOARD_DW1000_CONNECTED == true) */
72

    
73
/** @} */
74

    
75
/*===========================================================================*/
76
/**
77
 * @name GPIO definitions
78
 * @{
79
 */
80
/*===========================================================================*/
81

    
82
/**
83
 * @brief   LED output signal GPIO.
84
 */
85
static apalGpio_t _gpioLed = {
86
  /* line */ LINE_LED_GREEN,
87
};
88
ROMCONST apalControlGpio_t moduleGpioLed = {
89
  /* GPIO */ &_gpioLed,
90
  /* meta */ {
91
    /* direction      */ APAL_GPIO_DIRECTION_OUTPUT,
92
    /* active state   */ APAL_GPIO_ACTIVE_HIGH,
93
    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
94
  },
95
};
96

    
97
#if (BOARD_DW1000_CONNECTED == true)
98
/**
99
 * @brief   DW1000 reset output signal GPIO.
100
 */
101
static apalGpio_t _gpioDw1000Reset = {
102
  /* line */ LINE_ARD_D15, //PAL_LINE(GPIOA, GPIOA_ARD_A0)
103
};
104
ROMCONST apalControlGpio_t moduleGpioDw1000Reset = {
105
  /* GPIO */ &_gpioDw1000Reset,
106
  /* meta */ {
107
    /* direction      */ APAL_GPIO_DIRECTION_BIDIRECTIONAL,
108
    /* active state   */ APAL_GPIO_ACTIVE_HIGH,
109
    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
110
  },
111
};
112

    
113

    
114
/**
115
 * @brief   DW1000 interrrupt input signal GPIO.
116
 */
117
static apalGpio_t _gpioDw1000Irqn = {
118
  /* line */ LINE_ARD_D14,  // PAL_LINE(GPIOB, GPIOB_ARD_D6)
119
};
120
ROMCONST apalControlGpio_t moduleGpioDw1000Irqn = {
121
  /* GPIO */ &_gpioDw1000Irqn,
122
  /* meta */ {
123
    /* direction      */ APAL_GPIO_DIRECTION_INPUT,
124
    /* active state   */ APAL_GPIO_ACTIVE_LOW,
125
    /* interrupt edge */ APAL_GPIO_EDGE_RISING,
126
  },
127
};
128

    
129

    
130
/**
131
 * @brief   DW1000 SPI chip select output signal GPIO.
132
 */
133
static apalGpio_t _gpioSpiChipSelect = {
134
  /* line */ PAL_LINE(GPIOB, GPIOB_PIN12),
135
};
136
ROMCONST apalControlGpio_t moduleGpioSpiChipSelect = {
137
  /* GPIO */ &_gpioSpiChipSelect,
138
  /* meta */ {
139
    /* direction      */ APAL_GPIO_DIRECTION_OUTPUT,
140
    /* active state   */ APAL_GPIO_ACTIVE_LOW,
141
    /* interrupt edge */ APAL_GPIO_EDGE_NONE,
142
  },
143
};
144
#endif /* (BOARD_DW1000_CONNECTED == true) */
145

    
146
/**
147
 * @brief   User button input signal GPIO.
148
 */
149
static apalGpio_t _gpioUserButton = {
150
  /* line */ LINE_BUTTON,
151
};
152
ROMCONST apalControlGpio_t moduleGpioUserButton = {
153
  /* GPIO */ &_gpioUserButton,
154
  /* meta */ {
155
    /* direction      */ APAL_GPIO_DIRECTION_INPUT,
156
    /* active state   */ APAL_GPIO_ACTIVE_LOW,
157
    /* interrupt edge */ APAL_GPIO_EDGE_BOTH,
158
  },
159
};
160

    
161
/** @} */
162

    
163
/*===========================================================================*/
164
/**
165
 * @name AMiRo-OS core configurations
166
 * @{
167
 */
168
/*===========================================================================*/
169

    
170
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
171
ROMCONST char* moduleShellPrompt = "NUCLEO-F103RB";
172
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
173

    
174
/** @} */
175

    
176
/*===========================================================================*/
177
/**
178
 * @name Startup Shutdown Synchronization Protocol (SSSP)
179
 * @{
180
 */
181
/*===========================================================================*/
182

    
183
/** @} */
184

    
185
/*===========================================================================*/
186
/**
187
 * @name Hardware specific wrappers Functions
188
 * @{
189
 */
190
/*===========================================================================*/
191

    
192
#if (BOARD_DW1000_CONNECTED == true)
193
/*! @brief TODO: Manual implementation of SPI configuration. Somehow, it is necessary in NUCLEO-F103RB  */
194
void dw1000_spi_init(void){
195
  palSetPadMode(GPIOB, GPIOB_PIN13, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
196
  palSetPadMode(GPIOB, GPIOB_PIN14, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
197
  palSetPadMode(GPIOB, GPIOB_PIN15, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
198
  palSetLineMode(moduleGpioSpiChipSelect.gpio->line, PAL_MODE_OUTPUT_PUSHPULL);
199
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
200
}
201

    
202
/*! @brief Manually reset the DW1000 module  */
203
void reset_DW1000(void){
204

    
205
  // Set the pin as output
206
  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_OUTPUT);
207

    
208
  //drive the RSTn pin low
209
  apalGpioWrite(moduleGpioDw1000Reset.gpio, APAL_GPIO_LOW);
210

    
211
  //put the pin back to tri-state ... as input
212
//  palSetLineMode(moduleGpioDw1000Reset.gpio->line, APAL_GPIO_DIRECTION_INPUT); // TODO:
213

    
214
  aosThdMSleep(2);
215
}
216

    
217
/*! @brief entry point to the IRQn event in DW1000 module
218
 *
219
 * */
220
void process_deca_irq(void){
221
  do{
222
    dwt_isr();
223
   //while IRS line active (ARM can only do edge sensitive interrupts)
224
  }while(port_CheckEXT_IRQ() == 1);
225
}
226

    
227
/*! @brief Check the current value of GPIO pin and return the value */
228
apalGpioState_t port_CheckEXT_IRQ(void) {
229
  apalGpioState_t  val;
230
  apalGpioRead(moduleGpioDw1000Irqn.gpio, &val);
231
  return val;
232
}
233

    
234
/*! @brief Manually set the chip select pin of the SPI */
235
void set_SPI_chip_select(void){
236
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_HIGH);
237
}
238

    
239
/*! @brief Manually reset the chip select pin of the SPI */
240
void clear_SPI_chip_select(void){
241
  apalGpioWrite(moduleGpioSpiChipSelect.gpio, APAL_GPIO_LOW);
242
}
243

    
244
/*! @brief Change the SPI speed configuration on the fly */
245
void setHighSpeed_SPI(bool speedValue, DW1000Driver* drv){
246

    
247
  spiStop(drv->spid);
248

    
249
  if (speedValue == FALSE){
250
    spiStart(drv->spid, &moduleHalSpiUwbLsConfig);  // low speed spi configuration
251
  }
252
  else{
253
    spiStart(drv->spid, &moduleHalSpiUwbHsConfig); // high speed spi configuration
254
  }
255
}
256
#endif /* (BOARD_DW1000_CONNECTED == true) */
257
/** @} */
258

    
259
/*===========================================================================*/
260
/**
261
 * @name Low-level drivers
262
 * @{
263
 */
264
/*===========================================================================*/
265

    
266
LEDDriver moduleLldLed = {
267
  /* LED enable Gpio */ &moduleGpioLed,
268
};
269

    
270
ButtonDriver moduleLldUserButton = {
271
  /* Button Gpio  */ &moduleGpioUserButton,
272
};
273

    
274
#if (BOARD_DW1000_CONNECTED == true)
275
DW1000Driver moduleLldDw1000 = {
276
  /* SPI driver         */ &MODULE_HAL_SPI_UWB,
277
  /* ext interrupt      */ &moduleGpioDw1000Irqn,
278
  /* RESET DW1000       */ &moduleGpioDw1000Reset,
279
};
280
#endif /* (BOARD_DW1000_CONNECTED == true) */
281

    
282
/** @} */
283

    
284
/*===========================================================================*/
285
/**
286
 * @name Tests
287
 * @{
288
 */
289
/*===========================================================================*/
290
#if (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__)
291

    
292
/*
293
 * LED
294
 */
295
#include <module_test_LED.h>
296
static int _testLedShellCmdCb(BaseSequentialStream* stream, int argc, char* argv[])
297
{
298
  return moduleTestLedShellCb(stream, argc, argv, NULL);
299
}
300
AOS_SHELL_COMMAND(moduleTestLedShellCmd, "test:LED", _testLedShellCmdCb);
301

    
302
/*
303
 * User button
304
 */
305
#include <module_test_button.h>
306
static int _testButtonShellCmdCb(BaseSequentialStream* stream, int argc, char* argv[])
307
{
308
  return moduleTestButtonShellCb(stream, argc, argv, NULL);
309
}
310
AOS_SHELL_COMMAND(moduleTestButtonShellCmd, "test:button", _testButtonShellCmdCb);
311

    
312
#if (BOARD_DW1000_CONNECTED == true) || defined(__DOXYGEN__)
313
/*
314
 * UwB Driver (DW1000)
315
 */
316
#include <module_test_DW1000.h>
317
static int _testDw1000ShellCmdCb(BaseSequentialStream* stream, int argc, char* argv[])
318
{
319
  return moduleTestDw1000ShellCb(stream, argc, argv, NULL);
320
}
321
AOS_SHELL_COMMAND(moduleTestDw1000ShellCmd, "test:DW1000", _testDw1000ShellCmdCb);
322
#endif /* (BOARD_DW1000_CONNECTED == true) */
323

    
324
/*
325
 * entire module
326
 */
327
static int _testAllShellCmdCb(BaseSequentialStream* stream, int argc, char* argv[])
328
{
329
  (void)argc;
330
  (void)argv;
331

    
332
  int status = AOS_OK;
333
  char* targv[AMIROOS_CFG_SHELL_MAXARGS] = {NULL};
334
  aos_testresult_t result_test = {0, 0};
335
  aos_testresult_t result_total = {0, 0};
336

    
337
  /* LED */
338
  status |= moduleTestLedShellCb(stream, 0, targv, &result_test);
339
  result_total = aosTestResultAdd(result_total, result_test);
340

    
341
  /* User button */
342
  status |= moduleTestButtonShellCb(stream, 0, targv, &result_test);
343
  result_total = aosTestResultAdd(result_total, result_test);
344

    
345
#if (BOARD_DW1000_CONNECTED == true) || defined(__DOXYGEN__)
346
  /* DW1000 */
347
  status |= moduleTestDw1000ShellCb(stream, 0, targv, &result_test);
348
  result_total = aosTestResultAdd(result_total, result_test);
349
#endif /* (BOARD_DW1000_CONNECTED == true) */
350

    
351
  // print total result
352
  chprintf(stream, "\n");
353
  aosTestResultPrintSummary(stream, &result_total, "entire module");
354

    
355
  return status;
356
}
357
AOS_SHELL_COMMAND(moduleTestAllShellCmd, "test:all", _testAllShellCmdCb);
358

    
359
#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) */
360

    
361
/** @} */
362
/** @} */