implement mp_hal_delay_us() to not need interrupts, and use it

This commit is contained in:
Dan Halbert 2018-06-29 16:01:46 -04:00
parent b4fd77bb7c
commit 2a0b857643
7 changed files with 15 additions and 38 deletions

View File

@ -99,10 +99,7 @@ void mp_hal_delay_ms(mp_uint_t delay) {
}
}
void mp_hal_delay_us(mp_uint_t delay) {
tick_delay(delay);
}
// Use mp_hal_delay_us() for timing of less than 1ms.
// Do a simple timing loop to wait for a certain number of microseconds.
// Can be used when interrupts are disabled, which makes tick_delay() unreliable.
//
@ -115,8 +112,8 @@ void mp_hal_delay_us(mp_uint_t delay) {
#define DELAY_LOOP_ITERATIONS_PER_US ( (30U*120000000U) / common_hal_mcu_processor_get_frequency())
#endif
void mp_hal_delay_us_loop(uint32_t us) {
for (uint32_t i = us*DELAY_LOOP_ITERATIONS_PER_US; i > 0; i--) {
void mp_hal_delay_us(mp_uint_t delay) {
for (uint32_t i = delay*DELAY_LOOP_ITERATIONS_PER_US; i > 0; i--) {
asm volatile("nop");
}
}

View File

@ -50,6 +50,4 @@ void mp_hal_set_interrupt_char(int c);
void mp_hal_disable_all_interrupts(void);
void mp_hal_enable_all_interrupts(void);
void mp_hal_delay_us_loop(uint32_t us);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_MPHALPORT_H

View File

@ -92,7 +92,6 @@ SRC_C = \
machine_hspi.c \
modesp.c \
modnetwork.c \
mphalport.c \
ets_alt_task.c \
fatfs_port.c \
posix_helpers.c \

View File

@ -33,6 +33,8 @@
#include "shared-bindings/microcontroller/Processor.h"
// TODO porting common_hal_mcu
// This routine should work even when interrupts are disabled. Used by OneWire
// for precise timing.
void common_hal_mcu_delay_us(uint32_t delay) {
// os_delay_us(delay);
}
@ -58,4 +60,3 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
.type = &mcu_processor_type,
},
};

View File

@ -85,17 +85,3 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
void mp_hal_stdout_tx_str(const char *str) {
mp_hal_stdout_tx_strn(str, strlen(str));
}
// Do a simple timing loop to wait for a certain number of microseconds.
// Can be used when interrupts are disabled, which makes tick_delay() unreliable.
//
// Testing done at 48 MHz on SAMD21 and 120 MHz on SAMD51 (cache on).
// TODO: Test on NRF. For now, use SAMD51 calibration, even though nRF52 runs slower.
// Fraction should compensate.
#define DELAY_LOOP_ITERATIONS_PER_US ( (30U*120000000U) / common_hal_mcu_processor_get_frequency())
void mp_hal_delay_us_loop(uint32_t us) {
for (uint32_t i = us*DELAY_LOOP_ITERATIONS_PER_US; i > 0; i--) {
asm volatile("nop");
}
}

View File

@ -52,7 +52,6 @@ static inline uint32_t hal_tick_fake(void) {
extern const unsigned char mp_hal_status_to_errno_table[4];
NORETURN void mp_hal_raise(HAL_StatusTypeDef status);
void mp_hal_set_interrupt_char(int c); // -1 to disable
@ -70,7 +69,6 @@ bool mp_hal_stdin_any(void);
#define mp_hal_pin_od_high(p) mp_hal_pin_high(p)
#define mp_hal_pin_open_drain(p) hal_gpio_cfg_pin(p->port, p->pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_PULL_DISABLED)
void mp_hal_delay_us_loop(uint32_t us);
// TODO: empty implementation for now. Used by machine_spi.c:69
#define mp_hal_delay_us_fast(p)

View File

@ -24,8 +24,6 @@
* THE SOFTWARE.
*/
#include "mphalport.h"
#include "common-hal/microcontroller/Pin.h"
#include "shared-bindings/bitbangio/OneWire.h"
#include "shared-bindings/microcontroller/__init__.h"
@ -51,17 +49,17 @@ void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self) {
common_hal_digitalio_digitalinout_deinit(&self->pin);
}
// We can't use common_hal_mcu_delay_us() here because it needs interrupts to be accurate
// due to SysTick rollover checking, done by an interrupt.
// We use common_hal_mcu_delay_us(). It should not be dependent on interrupts
// to do accurate timekeeping, since we disable interrupts during the delays below.
bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) {
common_hal_mcu_disable_interrupts();
common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN);
mp_hal_delay_us_loop(480);
common_hal_mcu_delay_us(480);
common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE);
mp_hal_delay_us_loop(70);
common_hal_mcu_delay_us(70);
bool value = common_hal_digitalio_digitalinout_get_value(&self->pin);
mp_hal_delay_us_loop(410);
common_hal_mcu_delay_us(410);
common_hal_mcu_enable_interrupts();
return value;
}
@ -69,14 +67,14 @@ bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) {
bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self) {
common_hal_mcu_disable_interrupts();
common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN);
mp_hal_delay_us_loop(6);
common_hal_mcu_delay_us(6);
common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE);
// TODO(tannewt): Test with more devices and maybe make the delays
// configurable. This should be 9 by the datasheet but all bits read as 1
// then.
mp_hal_delay_us_loop(6);
common_hal_mcu_delay_us(6);
bool value = common_hal_digitalio_digitalinout_get_value(&self->pin);
mp_hal_delay_us_loop(55);
common_hal_mcu_delay_us(55);
common_hal_mcu_enable_interrupts();
return value;
}
@ -85,8 +83,8 @@ void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self,
bool bit) {
common_hal_mcu_disable_interrupts();
common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN);
mp_hal_delay_us_loop(bit? 6 : 60);
common_hal_mcu_delay_us(bit? 6 : 60);
common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE);
mp_hal_delay_us_loop(bit? 64 : 10);
common_hal_mcu_delay_us(bit? 64 : 10);
common_hal_mcu_enable_interrupts();
}