-
-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pbio/drv/uart: Refactor async read and write #275
base: master
Are you sure you want to change the base?
Changes from all commits
97df378
e88360a
ff18d74
6a606d3
4f2ed8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) 2024 The Pybricks Authors | ||
|
||
// Internal common adc functions. | ||
|
||
#ifndef _INTERNAL_PBDRV_ADC_H_ | ||
#define _INTERNAL_PBDRV_ADC_H_ | ||
|
||
#include <pbdrv/config.h> | ||
|
||
#if PBDRV_CONFIG_ADC | ||
|
||
void pbdrv_adc_init(void); | ||
|
||
#else // PBDRV_CONFIG_ADC | ||
|
||
#define pbdrv_adc_init() | ||
|
||
#endif // PBDRV_CONFIG_ADC | ||
|
||
#endif // _INTERNAL_PBDRV_ADC_H_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,28 +9,18 @@ | |
#include <pbio/error.h> | ||
|
||
#include <pbdrv/config.h> | ||
#include <pbdrv/uart.h> | ||
|
||
#if PBDRV_CONFIG_IOPORT_DEBUG_UART | ||
|
||
extern struct pt printf_thread; | ||
extern char debug_buffer[]; | ||
extern struct pt debug_printf_thread; | ||
extern pbdrv_uart_dev_t *debug_uart; | ||
extern pbio_error_t debug_err; | ||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a namespace prefix to public symbols. |
||
|
||
/** | ||
* Prints debug information on the last ioport. | ||
* | ||
* Will not print anything if the debug uart is already in use by another | ||
* debug message, to avoid blocking. | ||
* | ||
* Useful outside of a protothread or when timing is more critical while | ||
* complete information is not. | ||
* | ||
* @param [in] format Format string. | ||
* @param [in] ... Arguments. | ||
* | ||
* @return Error code. | ||
*/ | ||
pbio_error_t pbdrv_ioport_debug_uart_printf(const char *format, ...); | ||
PT_THREAD(pbdrv_ioport_debug_uart_debug_printf_thread(struct pt *pt, const char *format, ...)); | ||
|
||
PT_THREAD(pbdrv_ioport_debug_uart_printf_thread(struct pt *pt, const char *format, ...)); | ||
void pbdrv_ioport_debug_uart_printf_buffer(const char *format, ...); | ||
|
||
/** | ||
* Spawns a task to print debug information on the last ioport. | ||
|
@@ -42,13 +32,14 @@ PT_THREAD(pbdrv_ioport_debug_uart_printf_thread(struct pt *pt, const char *forma | |
* @param [in] ... Format string and arguments. | ||
*/ | ||
#define PBDRV_IOPORT_DEBUG_UART_PT_PRINTF(pt, ...) \ | ||
PT_SPAWN(pt, &printf_thread, pbdrv_ioport_debug_uart_printf_thread(&printf_thread, __VA_ARGS__)) | ||
pbdrv_ioport_debug_uart_printf_buffer(__VA_ARGS__); \ | ||
if (debug_uart) { \ | ||
PT_SPAWN(pt, &debug_printf_thread, pbdrv_uart_write(&debug_printf_thread, debug_uart, (uint8_t *)debug_buffer, strlen(debug_buffer), 250, &debug_err)); \ | ||
} \ | ||
|
||
#else // PBDRV_CONFIG_IOPORT_DEBUG_UART | ||
pbio_error_t pbdrv_ioport_debug_uart_init(pbdrv_uart_poll_callback_t callback); | ||
|
||
static inline pbio_error_t pbdrv_ioport_debug_uart_printf(const char *format, ...) { | ||
return PBIO_ERROR_NOT_SUPPORTED; | ||
} | ||
#else // PBDRV_CONFIG_IOPORT_DEBUG_UART | ||
|
||
#define PBDRV_IOPORT_DEBUG_UART_PT_PRINTF(pt, ...) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
#include <contiki.h> | ||
|
||
#include <pbdrv/gpio.h> | ||
#include <pbdrv/uart.h> | ||
|
||
#include <pbsys/status.h> | ||
|
||
|
@@ -107,6 +108,11 @@ static void legodev_pup_enable_uart(const pbdrv_ioport_pup_pins_t *pins) { | |
pbdrv_gpio_out_low(&pins->uart_buf); | ||
} | ||
|
||
static void legodev_pup_disable_uart(const pbdrv_ioport_pup_pins_t *pins) { | ||
// REVISIT: Move to ioport. | ||
pbdrv_gpio_out_high(&pins->uart_buf); | ||
} | ||
|
||
// This is the device connection manager (dcm). It monitors the ID1 and ID2 pins | ||
// on the port to see when devices are connected or disconnected. | ||
// It is expected for there to be a 2ms delay between calls to this function. | ||
|
@@ -343,6 +349,7 @@ static PT_THREAD(pbdrv_legodev_pup_thread(ext_dev_t * dev)) { | |
while (true) { | ||
|
||
// Initially assume nothing is connected. | ||
legodev_pup_disable_uart(dev->pins); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't dig into it, but this looks suspect to me. It seems like this could interfere with the device detection code that expects pins to be in a certain state. |
||
dev->dcm.connected_type_id = PBDRV_LEGODEV_TYPE_ID_NONE; | ||
dev->dcm.dev_id_match_count = 0; | ||
|
||
|
@@ -369,6 +376,7 @@ static PT_THREAD(pbdrv_legodev_pup_thread(ext_dev_t * dev)) { | |
// disconnects, as observed by the UART process not getting valid data. | ||
legodev_pup_enable_uart(dev->pins); | ||
PT_SPAWN(&dev->pt, &dev->child, pbdrv_legodev_pup_uart_thread(&dev->child, dev->uart_dev)); | ||
|
||
} | ||
PT_END(&dev->pt); | ||
} | ||
|
@@ -405,6 +413,14 @@ PROCESS_THREAD(pbio_legodev_pup_process, ev, data) { | |
PROCESS_END(); | ||
} | ||
|
||
/** | ||
* We get notified when the uart driver has completed sending or receiving data. | ||
*/ | ||
static void uart_poll_callback(pbdrv_uart_dev_t *uart) { | ||
// REVISIT: Only need to poll the specified uart device. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could add a flag that gets set here so that we only poke the uart instances that need it in the poll handler. |
||
process_poll(&pbio_legodev_pup_process); | ||
} | ||
|
||
void pbdrv_legodev_init(void) { | ||
#if PBDRV_CONFIG_LEGODEV_PUP_NUM_INT_DEV > 0 | ||
for (uint8_t i = 0; i < PBDRV_CONFIG_LEGODEV_PUP_NUM_INT_DEV; i++) { | ||
|
@@ -431,7 +447,15 @@ void pbdrv_legodev_init(void) { | |
pbio_dcmotor_get_dcmotor(legodev, &dcmotor); | ||
legodev->ext_dev->uart_dev = pbdrv_legodev_pup_uart_configure(legodev_data->ioport_index, port_data->uart_driver_index, dcmotor); | ||
|
||
// legodev driver is started after all other drivers, so we | ||
// assume that we do not need to wait for this to be ready. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would add an assert statement here so that we could at least catch this in debug builds to catch future changes that might break this assumption. |
||
pbdrv_uart_dev_t *uart; | ||
pbdrv_uart_get(port_data->uart_driver_index, &uart); | ||
|
||
// Set callback for uart driver. | ||
pbdrv_uart_set_poll_callback(uart, uart_poll_callback); | ||
} | ||
|
||
process_start(&pbio_legodev_pup_process); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why delay boot for 100 ms?
It should be fine to just yield here and skip the timer.