amiro-os / modules / NUCLEO-F103RB / module.c @ 0cfdcddc
History | View | Annotate | Download (10.271 KB)
1 |
/*
|
---|---|
2 |
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
|
3 |
Copyright (C) 2016..2019 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) || (AMIROOS_CFG_TESTS_ENABLE == true) || defined(__DOXYGEN__) |
171 |
ROMCONST char* moduleShellPrompt = "NUCLEO-F103RB"; |
172 |
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) || (AMIROOS_CFG_TESTS_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 |
/** @} */
|