diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2019-07-12 23:39:00 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2019-07-12 23:39:00 -0400 |
commit | be2d0abbab03667404c784f8543df858af82e7fe (patch) | |
tree | c8f4ec3dc81c645bb5cf2af02ecd579f065114c6 /src/neopixel.c | |
parent | b7bc96c3b298a1efd36a38e20f49ce61c90f3d97 (diff) | |
download | kutter-be2d0abbab03667404c784f8543df858af82e7fe.tar.gz kutter-be2d0abbab03667404c784f8543df858af82e7fe.tar.xz kutter-be2d0abbab03667404c784f8543df858af82e7fe.zip |
neopixel: Optimize the update loop
Optimize the transmit code so it can run on some slower ARM cpus.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/neopixel.c')
-rw-r--r-- | src/neopixel.c | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/src/neopixel.c b/src/neopixel.c index 41ca98dc..2fc02dd7 100644 --- a/src/neopixel.c +++ b/src/neopixel.c @@ -35,7 +35,7 @@ timer_from_ns(uint32_t ns) } static int -send_data(struct neopixel_s *n, uint8_t *data, uint_fast8_t data_len) +send_data(struct neopixel_s *n, uint32_t data) { // Make sure at least 50us has passed since last request uint32_t last_req_time = n->last_req_time, cur = timer_read_time(); @@ -46,45 +46,42 @@ send_data(struct neopixel_s *n, uint8_t *data, uint_fast8_t data_len) struct gpio_out pin = n->pin; uint32_t expire_time = cur + 0x40000000; - while (data_len--) { - uint_fast8_t byte = *data++; - uint_fast8_t bits = 8; - while (bits--) { - // Calculate pulse duration - uint32_t on, off; - if (byte & 0x80) { - on = timer_from_ns(700 - 150); - off = timer_from_ns(600 - 150); - } else { - on = timer_from_ns(350 - 150); - off = timer_from_ns(800 - 150); - } - byte <<= 1; + uint_fast8_t bits = 24; + while (bits--) { + // Calculate pulse duration + uint32_t on, off; + if (data & 0x800000) { + on = timer_from_ns(700 - 150); + off = timer_from_ns(600 - 150); + } else { + on = timer_from_ns(350 - 150); + off = timer_from_ns(800 - 150); + } + data <<= 1; - // Set output high - gpio_out_toggle(pin); - uint32_t on_start_time = timer_read_time(); - if (timer_is_before(expire_time, on_start_time)) - goto fail; - cur = on_start_time; - while (timer_is_before(cur, on_start_time + on)) { - irq_poll(); - cur = timer_read_time(); - } + // Set output high + gpio_out_write(pin, 1); + uint32_t on_start_time = timer_read_time(); + if (timer_is_before(expire_time, on_start_time)) + goto fail; + cur = on_start_time; + while (timer_is_before(cur, on_start_time + on)) { + irq_poll(); + cur = timer_read_time(); + } - // Set output low - gpio_out_toggle(pin); - uint32_t off_start_time = timer_read_time(); - expire_time = on_start_time + on + timer_from_ns(300); - if (timer_is_before(expire_time, off_start_time)) - goto fail; - cur = off_start_time; - while (timer_is_before(cur, off_start_time + off)) { - irq_poll(); - cur = timer_read_time(); - } - expire_time = off_start_time + off + timer_from_ns(300); + // Set output low + gpio_out_write(pin, 0); + uint32_t off_start_time = timer_read_time(); + expire_time = on_start_time + on + timer_from_ns(300); + if (timer_is_before(expire_time, off_start_time)) + goto fail; + cur = off_start_time; + while (timer_is_before(cur, off_start_time + off)) { + irq_poll(); + cur = timer_read_time(); } + expire_time = off_start_time + off + timer_from_ns(300); } n->last_req_time = cur; return 0; @@ -99,16 +96,15 @@ command_neopixel_send(uint32_t *args) { uint8_t oid = args[0]; struct neopixel_s *n = oid_lookup(oid, command_config_neopixel); - uint_fast8_t data_len = args[1]; - uint8_t *data = (void*)(size_t)args[2]; + uint32_t data = args[1]; uint_fast8_t retry = 8; while (retry--) { - int ret = send_data(n, data, data_len); + int ret = send_data(n, data); if (!ret) break; } } #if !CONFIG_MACH_AVR -DECL_COMMAND(command_neopixel_send, "neopixel_send oid=%c data=%*s"); +DECL_COMMAND(command_neopixel_send, "neopixel_send oid=%c data=%u"); #endif |