implement mp_hal_delay_us() to not need interrupts, and use it
This commit is contained in:
parent
b4fd77bb7c
commit
2a0b857643
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user