diff --git a/examples/tests/adc/adc/main.c b/examples/tests/adc/adc/main.c index de7a70904..4dcda758e 100644 --- a/examples/tests/adc/adc/main.c +++ b/examples/tests/adc/adc/main.c @@ -5,9 +5,6 @@ #include #include -#include -#include -#include int reference_voltage; @@ -51,15 +48,15 @@ int main(void) { printf("[Tock] ADC Test\n"); // check if ADC driver exists - if (!libtock_adc_exists()) { + if (!libtocksync_adc_exists()) { printf("No ADC driver!\n"); return -1; } int count; - libtock_adc_channel_count(&count); + libtocksync_adc_channel_count(&count); printf("ADC driver exists with %d channels\n", count); - libtock_adc_command_get_reference_voltage((uint32_t*) &reference_voltage); + libtocksync_adc_reference_voltage((uint32_t*) &reference_voltage); if (reference_voltage > 0) { printf("ADC reference voltage %d.%dV\n", reference_voltage / 1000, reference_voltage % 1000); } else { @@ -68,7 +65,7 @@ int main(void) { } uint32_t resolution; - libtock_adc_command_get_resolution_bits(&resolution); + libtocksync_adc_resolution_bits(&resolution); printf("ADC resolution %lu bits\n", resolution); while (1) { diff --git a/examples/tests/adc/adc_single_samples/main.c b/examples/tests/adc/adc_single_samples/main.c index d829ec584..c4df3b36f 100644 --- a/examples/tests/adc/adc_single_samples/main.c +++ b/examples/tests/adc/adc_single_samples/main.c @@ -5,21 +5,19 @@ #include #include -#include -#include int main(void) { printf("[Tock] ADC Sample All Channels Test\n"); // check if ADC driver exists - if (!libtock_adc_exists()) { + if (!libtocksync_adc_exists()) { printf("No ADC driver!\n"); return -1; } int channel_count; - libtock_adc_channel_count(&channel_count); + libtocksync_adc_channel_count(&channel_count); printf("ADC driver exists with %d channels\n\n", channel_count); while (1) { diff --git a/examples/tests/crc/main.c b/examples/tests/crc/main.c index 67700b270..48bdc40ca 100644 --- a/examples/tests/crc/main.c +++ b/examples/tests/crc/main.c @@ -40,7 +40,7 @@ int main(void) { exit(1); } - if (!libtock_crc_exists()) { + if (!libtocksync_crc_exists()) { printf("CRC driver does not exist\n"); exit(1); } diff --git a/examples/tests/gpio/gpio_sync/Makefile b/examples/tests/gpio/gpio_sync/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/gpio/gpio_sync/Makefile @@ -0,0 +1,11 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +# Include userland master makefile. Contains rules and flags for actually +# building the application. +include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/tests/gpio/gpio_sync/README.md b/examples/tests/gpio/gpio_sync/README.md new file mode 100644 index 000000000..aac831259 --- /dev/null +++ b/examples/tests/gpio/gpio_sync/README.md @@ -0,0 +1,21 @@ +GPIO Sync Interrupt Test App +============= + +Test the libtock-sync/peripherals/gpio synchronous interrupt +event functions. + +Expected Output +--------------- + +``` +[Test] GPIO Sync Interrupt +Jump GPIO pin 0 low to start test. +Then move the jumper to VCC +tock$ +Pin 0 went high +Now jumper back to ground +Pin 0 went low +Now jumper back to high +Pin 0 went back high +Success! Test done +``` diff --git a/examples/tests/gpio/gpio_sync/main.c b/examples/tests/gpio/gpio_sync/main.c new file mode 100644 index 000000000..da1d5a471 --- /dev/null +++ b/examples/tests/gpio/gpio_sync/main.c @@ -0,0 +1,34 @@ +#include + +#include +#include +#include + +int main(void) { + returncode_t ret; + + printf("[Test] GPIO Sync Interrupt\n"); + printf("Jump GPIO pin 0 low to start test.\n"); + printf("Then move the jumper to VCC\n"); + + ret = libtocksync_gpio_wait_until_high(0, libtock_pull_down); + if (ret != RETURNCODE_SUCCESS) { + printf("[ERROR] %s\n", tock_strrcode(ret)); + return -1; + } + + printf("Pin 0 went high\n"); + printf("Now jumper back to ground\n"); + + libtocksync_gpio_wait_until_low(0, libtock_pull_up); + + printf("Pin 0 went low\n"); + printf("Now jumper back to high\n"); + + libtocksync_gpio_wait_until_changed(0, libtock_pull_down); + + printf("Pin 0 went back high\n"); + printf("Success! Test done\n"); + + return 0; +} diff --git a/examples/tests/usb/main.c b/examples/tests/usb/main.c index 9a2d5c636..7de54cf59 100644 --- a/examples/tests/usb/main.c +++ b/examples/tests/usb/main.c @@ -6,7 +6,7 @@ int main(void) { returncode_t ret; printf("[TEST] UDP\n"); - if (!libtock_usb_exists()) { + if (!libtocksync_usb_exists()) { printf("USB test: driver is not present\n"); return -1; } diff --git a/libtock-sync/peripherals/adc.c b/libtock-sync/peripherals/adc.c index 30dfe6be5..5879980b6 100644 --- a/libtock-sync/peripherals/adc.c +++ b/libtock-sync/peripherals/adc.c @@ -1,90 +1,48 @@ +#include #include #include "adc.h" -// used for creating synchronous versions of functions -// -// fired - set when the callback has been called -// channel - channel that the collected sample corresponds to -// sample - collected sample value, valid if single sample operation -// length - number of collected sample values, valid if multiple sample -// operation -// buffer - pointer to buffer filled with samples, valid if multiple sample -// operation -// error - set to FAIL if an invalid callback type is detected -struct adc_data { - bool fired; - uint8_t channel; - uint16_t sample; - uint32_t length; - uint16_t* buffer; - int error; -}; +#include "syscalls/adc_syscalls.h" -static struct adc_data result; - - -static void sample(uint8_t channel, uint16_t sample) { - result.fired = true; - result.channel = channel; - result.sample = sample; +bool libtocksync_adc_exists(void) { + return libtock_adc_driver_exists(); } -static void buffered_sample(uint8_t channel, uint32_t length, uint16_t* buffer) { - result.fired = true; - result.channel = channel; - result.length = length; - result.buffer = buffer; +returncode_t libtocksync_adc_channel_count(int* count) { + return libtock_adc_command_channel_count(count); } +returncode_t libtocksync_adc_reference_voltage(uint32_t* reference_voltage) { + return libtock_adc_command_get_reference_voltage(reference_voltage); +} -static libtock_adc_callbacks callbacks = { - .single_sample_callback = sample, - .continuous_sample_callback = sample, - .buffered_sample_callback = buffered_sample, - .continuous_buffered_sample_callback = buffered_sample, -}; - - -bool libtocksync_adc_exists(void) { - return libtock_adc_driver_exists(); +returncode_t libtocksync_adc_resolution_bits(uint32_t* resolution) { + return libtock_adc_command_get_resolution_bits(resolution); } returncode_t libtocksync_adc_sample(uint8_t channel, uint16_t* sample) { - int err; - result.fired = false; - result.error = RETURNCODE_SUCCESS; + returncode_t err; - err = libtock_adc_single_sample(channel, &callbacks); + err = libtock_adc_command_single_sample(channel); if (err != RETURNCODE_SUCCESS) return err; - // wait for callback - yield_for(&result.fired); - - // copy over result - *sample = result.sample; - - return result.error; + err = libtocksync_adc_yield_wait_for_single_sample(sample); + return err; } returncode_t libtocksync_adc_sample_buffer(uint8_t channel, uint32_t frequency, uint16_t* buffer, uint32_t length) { returncode_t err; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = libtock_adc_set_buffer(buffer, length); - if (err < RETURNCODE_SUCCESS) return err; + uint32_t actual_length; - err = libtock_adc_buffered_sample(channel, frequency, &callbacks); + err = libtock_adc_set_readwrite_allow_set_buffer((uint8_t*) buffer, length * 2); if (err != RETURNCODE_SUCCESS) return err; - - // wait for callback - yield_for(&result.fired); - - // copy over result - if (result.buffer != buffer) { - return RETURNCODE_FAIL; + defer { libtock_adc_set_readwrite_allow_set_buffer(NULL, 0); } - return result.error; + err = libtock_adc_command_buffered_sample(channel, frequency); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtocksync_adc_yield_wait_for_buffered_sample(&actual_length); + return err; } diff --git a/libtock-sync/peripherals/adc.h b/libtock-sync/peripherals/adc.h index 2aaca97c2..e720e9290 100644 --- a/libtock-sync/peripherals/adc.h +++ b/libtock-sync/peripherals/adc.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus @@ -9,6 +8,15 @@ extern "C" { bool libtocksync_adc_exists(void); +// Query the number of ADC channels available. +returncode_t libtocksync_adc_channel_count(int* count); + +// Query the ADC reference voltage in millivolts. Returns 0 if not available. +returncode_t libtocksync_adc_reference_voltage(uint32_t* reference_voltage); + +// Query the ADC resolution in bits. +returncode_t libtocksync_adc_resolution_bits(uint32_t* resolution); + returncode_t libtocksync_adc_sample(uint8_t channel, uint16_t* sample); returncode_t libtocksync_adc_sample_buffer(uint8_t channel, uint32_t frequency, uint16_t* buffer, uint32_t length); diff --git a/libtock-sync/peripherals/crc.c b/libtock-sync/peripherals/crc.c index ca59d4bc3..71beef3a3 100644 --- a/libtock-sync/peripherals/crc.c +++ b/libtock-sync/peripherals/crc.c @@ -1,20 +1,9 @@ +#include #include #include "crc.h" -struct crc_data { - bool fired; - int status; - uint32_t crc; -}; - -static struct crc_data result = {.fired = false}; - -static void crc_callback(returncode_t ret, uint32_t crc) { - result.fired = true; - result.status = ret; - result.crc = crc; -} +#include "syscalls/crc_syscalls.h" bool libtocksync_crc_exists(void) { return libtock_crc_driver_exists(); @@ -22,18 +11,15 @@ bool libtocksync_crc_exists(void) { returncode_t libtocksync_crc_compute(const uint8_t* buf, size_t buflen, libtock_crc_alg_t algorithm, uint32_t* crc) { returncode_t ret; - result.fired = false; - ret = libtock_crc_compute(buf, buflen, algorithm, crc_callback); + ret = libtock_crc_set_readonly_allow(buf, buflen); if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_crc_set_readonly_allow(NULL, 0); + } - yield_for(&result.fired); - if (result.status != RETURNCODE_SUCCESS) return result.status; - - ret = libtock_crc_set_readonly_allow(NULL, 0); + ret = libtock_crc_command_request((uint32_t) algorithm, buflen); if (ret != RETURNCODE_SUCCESS) return ret; - *crc = result.crc; - - return RETURNCODE_SUCCESS; + ret = libtocksync_crc_yield_wait_for(crc); + return ret; } diff --git a/libtock-sync/peripherals/crc.h b/libtock-sync/peripherals/crc.h index dda7422b7..d7add6591 100644 --- a/libtock-sync/peripherals/crc.h +++ b/libtock-sync/peripherals/crc.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #ifdef __cplusplus diff --git a/libtock-sync/peripherals/gpio.c b/libtock-sync/peripherals/gpio.c index 7869c1083..89e664e81 100644 --- a/libtock-sync/peripherals/gpio.c +++ b/libtock-sync/peripherals/gpio.c @@ -2,42 +2,27 @@ #include "gpio.h" -struct gpio_data { - bool fired; - uint32_t pin; - bool value; -}; - -static struct gpio_data result = { .fired = false }; - -static void cb(uint32_t pin, bool value) { - result.fired = true; - result.pin = pin; - result.value = value; -} +#include "syscalls/gpio_syscalls.h" static returncode_t wait_until(uint32_t pin, libtock_gpio_input_mode_t pin_config, libtock_gpio_interrupt_mode_t mode) { returncode_t ret; - result.fired = false; - - ret = libtock_gpio_set_interrupt_callback(cb); - if (ret != RETURNCODE_SUCCESS) return ret; + uint32_t irq_pin; + bool value; - ret = libtock_gpio_enable_input(pin, pin_config); + ret = libtock_gpio_command_enable_input(pin, (uint32_t) pin_config); if (ret != RETURNCODE_SUCCESS) return ret; - ret = libtock_gpio_enable_interrupt(pin, mode); + ret = libtock_gpio_command_enable_interrupt(pin, (uint32_t) mode); if (ret != RETURNCODE_SUCCESS) return ret; while (1) { - yield_for(&result.fired); + libtocksync_gpio_yield_wait_for(&irq_pin, &value); - if (result.pin == pin) { - if (mode == libtock_rising_edge && result.value == true) break; - if (mode == libtock_falling_edge && result.value == false) break; + if (irq_pin == pin) { + if (mode == libtock_rising_edge && value == true) break; + if (mode == libtock_falling_edge && value == false) break; if (mode == libtock_change) break; } - result.fired = false; } return RETURNCODE_SUCCESS; } @@ -46,6 +31,34 @@ bool libtocksync_gpio_exists(void) { return libtock_gpio_driver_exists(); } +returncode_t libtocksync_gpio_count(int* count) { + return libtock_gpio_command_count((uint32_t*) count); +} + +returncode_t libtocksync_gpio_enable_output(uint32_t pin) { + return libtock_gpio_command_enable_output(pin); +} + +returncode_t libtocksync_gpio_enable_input(uint32_t pin, libtock_gpio_input_mode_t pin_config) { + return libtock_gpio_command_enable_input(pin, (uint32_t) pin_config); +} + +returncode_t libtocksync_gpio_set(uint32_t pin) { + return libtock_gpio_command_set(pin); +} + +returncode_t libtocksync_gpio_clear(uint32_t pin) { + return libtock_gpio_command_clear(pin); +} + +returncode_t libtocksync_gpio_toggle(uint32_t pin) { + return libtock_gpio_command_toggle(pin); +} + +returncode_t libtocksync_gpio_read(uint32_t pin, int* pin_value) { + return libtock_gpio_command_read(pin, (uint32_t*) pin_value); +} + returncode_t libtocksync_gpio_wait_until_high(uint32_t pin, libtock_gpio_input_mode_t pin_config) { return wait_until(pin, pin_config, libtock_rising_edge); } diff --git a/libtock-sync/peripherals/gpio.h b/libtock-sync/peripherals/gpio.h index 674cf22a4..f865911a6 100644 --- a/libtock-sync/peripherals/gpio.h +++ b/libtock-sync/peripherals/gpio.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #ifdef __cplusplus @@ -9,6 +9,27 @@ extern "C" { bool libtocksync_gpio_exists(void); +// Returns the number of GPIO pins configured on the board. +returncode_t libtocksync_gpio_count(int* count); + +// Configure a GPIO pin as an output. +returncode_t libtocksync_gpio_enable_output(uint32_t pin); + +// Configure a GPIO pin as an input. +returncode_t libtocksync_gpio_enable_input(uint32_t pin, libtock_gpio_input_mode_t pin_config); + +// Set an output pin high. +returncode_t libtocksync_gpio_set(uint32_t pin); + +// Set an output pin low. +returncode_t libtocksync_gpio_clear(uint32_t pin); + +// Toggle an output pin. +returncode_t libtocksync_gpio_toggle(uint32_t pin); + +// Read the current state of a GPIO input pin. +returncode_t libtocksync_gpio_read(uint32_t pin, int* pin_value); + // Configure a GPIO pin as an input and then wait until a rising interrupt // occurs. returncode_t libtocksync_gpio_wait_until_high(uint32_t pin, libtock_gpio_input_mode_t pin_config); diff --git a/libtock-sync/peripherals/rng.c b/libtock-sync/peripherals/rng.c index 656af9800..81c01f6b6 100644 --- a/libtock-sync/peripherals/rng.c +++ b/libtock-sync/peripherals/rng.c @@ -1,21 +1,9 @@ +#include #include #include "rng.h" -struct rng_data { - bool fired; - returncode_t ret; - int received; -}; - -// Global state for faking synchronous reads using a callback and yield. -static struct rng_data result = { .fired = false }; - -static void rng_cb(returncode_t ret, int received) { - result.fired = true; - result.ret = ret; - result.received = received; -} +#include "syscalls/rng_syscalls.h" bool libtocksync_rng_exists(void) { return libtock_rng_driver_exists(); @@ -24,19 +12,14 @@ bool libtocksync_rng_exists(void) { returncode_t libtocksync_rng_get_random_bytes(uint8_t* buf, uint32_t len, uint32_t num, int* num_received) { returncode_t ret; - result.fired = false; - - ret = libtock_rng_get_random_bytes(buf, len, num, rng_cb); + ret = libtock_rng_set_allow_readwrite(buf, len); if (ret != RETURNCODE_SUCCESS) return ret; + defer { libtock_rng_set_allow_readwrite(NULL, 0); + } - yield_for(&result.fired); - - ret = libtock_rng_set_allow_readwrite(NULL, 0); + ret = libtock_rng_command_get_random(num); if (ret != RETURNCODE_SUCCESS) return ret; - if (result.ret != RETURNCODE_SUCCESS) return result.ret; - - *num_received = result.received; - - return RETURNCODE_SUCCESS; + ret = libtocksync_rng_yield_wait_for(num_received); + return ret; } diff --git a/libtock-sync/peripherals/rng.h b/libtock-sync/peripherals/rng.h index 1db80297a..b373dc048 100644 --- a/libtock-sync/peripherals/rng.h +++ b/libtock-sync/peripherals/rng.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus diff --git a/libtock-sync/peripherals/rtc.c b/libtock-sync/peripherals/rtc.c index abd92c793..28d2fd543 100644 --- a/libtock-sync/peripherals/rtc.c +++ b/libtock-sync/peripherals/rtc.c @@ -2,30 +2,7 @@ #include "rtc.h" -struct rtc_date_data { - bool fired; - returncode_t ret; - libtock_rtc_date_t date; -}; -struct rtc_done_data { - bool fired; - returncode_t ret; -}; - -static struct rtc_date_data result = { .fired = false }; -static struct rtc_done_data result_done = { .fired = false }; - - -static void rtc_date_cb(returncode_t ret, libtock_rtc_date_t date) { - result.fired = true; - result.ret = ret; - result.date = date; -} - -static void rtc_done_cb(returncode_t ret) { - result_done.fired = true; - result_done.ret = ret; -} +#include "syscalls/rtc_syscalls.h" bool libtocksync_rtc_exists(void) { return libtock_rtc_driver_exists(); @@ -34,27 +11,22 @@ bool libtocksync_rtc_exists(void) { returncode_t libtocksync_rtc_get_date(libtock_rtc_date_t* date) { returncode_t ret; - result.fired = false; - - ret = libtock_rtc_get_date(rtc_date_cb); + ret = libtock_rtc_command_get_date(); if (ret != RETURNCODE_SUCCESS) return ret; - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; - - *date = result.date; - return RETURNCODE_SUCCESS; + ret = libtocksync_rtc_yield_wait_for_get(date); + return ret; } returncode_t libtocksync_rtc_set_date(libtock_rtc_date_t* set_date) { returncode_t ret; + uint32_t date = set_date->year * (1 << 9) + set_date->month * (1 << 5) + set_date->day; + uint32_t time = set_date->day_of_week * + (1 << 17) + set_date->hour * (1 << 12) + set_date->minute * (1 << 6) + set_date->seconds; - result_done.fired = false; - - ret = libtock_rtc_set_date(set_date, rtc_done_cb); + ret = libtock_rtc_command_set_date(date, time); if (ret != RETURNCODE_SUCCESS) return ret; - yield_for(&result_done.fired); - - return result_done.ret; + ret = libtocksync_rtc_yield_wait_for_set(); + return ret; } diff --git a/libtock-sync/peripherals/rtc.h b/libtock-sync/peripherals/rtc.h index cb0bfbc83..3961e0c21 100644 --- a/libtock-sync/peripherals/rtc.h +++ b/libtock-sync/peripherals/rtc.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #ifdef __cplusplus diff --git a/libtock-sync/peripherals/spi_controller.c b/libtock-sync/peripherals/spi_controller.c index c37d521e5..ca12de1af 100644 --- a/libtock-sync/peripherals/spi_controller.c +++ b/libtock-sync/peripherals/spi_controller.c @@ -1,19 +1,9 @@ +#include #include #include "spi_controller.h" -struct spi_data { - bool fired; - returncode_t ret; -}; - -static struct spi_data result = { .fired = false }; - - -static void cb(returncode_t ret) { - result.fired = true; - result.ret = ret; -} +#include "syscalls/spi_controller_syscalls.h" bool libtocksync_spi_controller_exists(void) { return libtock_spi_controller_driver_exists(); @@ -22,15 +12,16 @@ bool libtocksync_spi_controller_exists(void) { returncode_t libtocksync_spi_controller_write(const uint8_t* write, size_t len) { returncode_t err; - result.fired = false; - err = libtock_spi_controller_write(write, len, cb); + err = libtock_spi_controller_allow_readonly_write((uint8_t*) write, len); if (err != RETURNCODE_SUCCESS) return err; + defer { libtock_spi_controller_allow_readonly_write(NULL, 0); + } - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; + err = libtock_spi_controller_command_read_write_bytes(len); + if (err != RETURNCODE_SUCCESS) return err; - err = libtock_spi_controller_allow_readonly_write(NULL, 0); + err = libtocksync_spi_controller_yield_wait_for(); return err; } @@ -38,18 +29,20 @@ returncode_t libtocksync_spi_controller_read_write(const uint8_t* write, uint8_t* read, size_t len) { returncode_t err; - result.fired = false; - err = libtock_spi_controller_read_write(write, read, len, cb); + err = libtock_spi_controller_allow_readwrite_read(read, len); if (err != RETURNCODE_SUCCESS) return err; + defer { libtock_spi_controller_allow_readwrite_read(NULL, 0); + } - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; - - err = libtock_spi_controller_allow_readonly_write(NULL, 0); + err = libtock_spi_controller_allow_readonly_write((uint8_t*) write, len); if (err != RETURNCODE_SUCCESS) return err; - err = libtock_spi_controller_allow_readwrite_read(NULL, 0); + defer { libtock_spi_controller_allow_readonly_write(NULL, 0); + } + + err = libtock_spi_controller_command_read_write_bytes(len); if (err != RETURNCODE_SUCCESS) return err; + err = libtocksync_spi_controller_yield_wait_for(); return err; } diff --git a/libtock-sync/peripherals/spi_controller.h b/libtock-sync/peripherals/spi_controller.h index 728e5d3ef..372092e35 100644 --- a/libtock-sync/peripherals/spi_controller.h +++ b/libtock-sync/peripherals/spi_controller.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus diff --git a/libtock-sync/peripherals/spi_peripheral.c b/libtock-sync/peripherals/spi_peripheral.c index f7c1c3f82..5c4470eef 100644 --- a/libtock-sync/peripherals/spi_peripheral.c +++ b/libtock-sync/peripherals/spi_peripheral.c @@ -1,19 +1,9 @@ +#include #include #include "spi_peripheral.h" -struct spi_peripheral_data { - bool fired; - returncode_t ret; -}; - -static struct spi_peripheral_data result = { .fired = false }; - - -static void cb(returncode_t ret) { - result.fired = true; - result.ret = ret; -} +#include "syscalls/spi_peripheral_syscalls.h" bool libtocksync_spi_peripheral_exists(void) { return libtock_spi_peripheral_driver_exists(); @@ -22,15 +12,16 @@ bool libtocksync_spi_peripheral_exists(void) { returncode_t libtocksync_spi_peripheral_write(const uint8_t* write, size_t len) { returncode_t err; - result.fired = false; - err = libtock_spi_peripheral_write(write, len, cb); + err = libtock_spi_peripheral_allow_readonly_write((uint8_t*) write, len); if (err != RETURNCODE_SUCCESS) return err; + defer { libtock_spi_peripheral_allow_readonly_write(NULL, 0); + } - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; + err = libtock_spi_peripheral_command_write(len); + if (err != RETURNCODE_SUCCESS) return err; - err = libtock_spi_peripheral_allow_readonly_write(NULL, 0); + err = libtocksync_spi_peripheral_yield_wait_for(); return err; } @@ -38,18 +29,20 @@ returncode_t libtocksync_spi_peripheral_read_write(const uint8_t* write, uint8_t* read, size_t len) { returncode_t err; - result.fired = false; - err = libtock_spi_peripheral_read_write(write, read, len, cb); + err = libtock_spi_peripheral_allow_readwrite_read(read, len); if (err != RETURNCODE_SUCCESS) return err; + defer { libtock_spi_peripheral_allow_readwrite_read(NULL, 0); + } - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; - - err = libtock_spi_peripheral_allow_readonly_write(NULL, 0); + err = libtock_spi_peripheral_allow_readonly_write((uint8_t*) write, len); if (err != RETURNCODE_SUCCESS) return err; - err = libtock_spi_peripheral_allow_readwrite_read(NULL, 0); + defer { libtock_spi_peripheral_allow_readonly_write(NULL, 0); + } + + err = libtock_spi_peripheral_command_write(len); if (err != RETURNCODE_SUCCESS) return err; + err = libtocksync_spi_peripheral_yield_wait_for(); return err; } diff --git a/libtock-sync/peripherals/spi_peripheral.h b/libtock-sync/peripherals/spi_peripheral.h index 70995acfa..e4d751fe4 100644 --- a/libtock-sync/peripherals/spi_peripheral.h +++ b/libtock-sync/peripherals/spi_peripheral.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus diff --git a/libtock-sync/peripherals/syscalls/adc_syscalls.c b/libtock-sync/peripherals/syscalls/adc_syscalls.c new file mode 100644 index 000000000..842bc47a4 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/adc_syscalls.c @@ -0,0 +1,15 @@ +#include "adc_syscalls.h" + +returncode_t libtocksync_adc_yield_wait_for_single_sample(uint16_t* sample) { + yield_waitfor_return_t ret; + ret = yield_wait_for(DRIVER_NUM_ADC, 0); + *sample = (uint16_t) ret.data2; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_adc_yield_wait_for_buffered_sample(uint32_t* length) { + yield_waitfor_return_t ret; + ret = yield_wait_for(DRIVER_NUM_ADC, 0); + *length = (ret.data1 >> 8) & 0xFFFFFF; + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/syscalls/adc_syscalls.h b/libtock-sync/peripherals/syscalls/adc_syscalls.h new file mode 100644 index 000000000..f3d9ab388 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/adc_syscalls.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a single ADC sample to complete. +returncode_t libtocksync_adc_yield_wait_for_single_sample(uint16_t* sample); + +// Wait for a buffered ADC sample to complete. +returncode_t libtocksync_adc_yield_wait_for_buffered_sample(uint32_t* length); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/crc_syscalls.c b/libtock-sync/peripherals/syscalls/crc_syscalls.c new file mode 100644 index 000000000..2cdc2581e --- /dev/null +++ b/libtock-sync/peripherals/syscalls/crc_syscalls.c @@ -0,0 +1,11 @@ +#include "crc_syscalls.h" + +returncode_t libtocksync_crc_yield_wait_for(uint32_t* crc) { + yield_waitfor_return_t ywf; + returncode_t ret; + ywf = yield_wait_for(DRIVER_NUM_CRC, 0); + ret = (returncode_t) ywf.data0; + if (ret != RETURNCODE_SUCCESS) return ret; + *crc = (uint32_t) ywf.data1; + return ret; +} diff --git a/libtock-sync/peripherals/syscalls/crc_syscalls.h b/libtock-sync/peripherals/syscalls/crc_syscalls.h new file mode 100644 index 000000000..1c1b3f2dc --- /dev/null +++ b/libtock-sync/peripherals/syscalls/crc_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a CRC computation to complete. +returncode_t libtocksync_crc_yield_wait_for(uint32_t* crc); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/gpio_syscalls.c b/libtock-sync/peripherals/syscalls/gpio_syscalls.c new file mode 100644 index 000000000..0091c8607 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/gpio_syscalls.c @@ -0,0 +1,9 @@ +#include "gpio_syscalls.h" + +returncode_t libtocksync_gpio_yield_wait_for(uint32_t* pin, bool* value) { + yield_waitfor_return_t ret; + ret = yield_wait_for(GPIO_DRIVER_NUM, 0); + *pin = (uint32_t) ret.data0; + *value = ret.data1 == 1; + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/syscalls/gpio_syscalls.h b/libtock-sync/peripherals/syscalls/gpio_syscalls.h new file mode 100644 index 000000000..8b7f0b469 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/gpio_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a GPIO interrupt and return the pin and its level. +returncode_t libtocksync_gpio_yield_wait_for(uint32_t* pin, bool* value); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/rng_syscalls.c b/libtock-sync/peripherals/syscalls/rng_syscalls.c new file mode 100644 index 000000000..41d3221ae --- /dev/null +++ b/libtock-sync/peripherals/syscalls/rng_syscalls.c @@ -0,0 +1,8 @@ +#include "rng_syscalls.h" + +returncode_t libtocksync_rng_yield_wait_for(int* received) { + yield_waitfor_return_t ret; + ret = yield_wait_for(DRIVER_NUM_RNG, 0); + *received = (int) ret.data1; + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/syscalls/rng_syscalls.h b/libtock-sync/peripherals/syscalls/rng_syscalls.h new file mode 100644 index 000000000..0cd029c1f --- /dev/null +++ b/libtock-sync/peripherals/syscalls/rng_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a random bytes request to complete. +returncode_t libtocksync_rng_yield_wait_for(int* received); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/rtc_syscalls.c b/libtock-sync/peripherals/syscalls/rtc_syscalls.c new file mode 100644 index 000000000..64ac68cdd --- /dev/null +++ b/libtock-sync/peripherals/syscalls/rtc_syscalls.c @@ -0,0 +1,31 @@ +#include "rtc_syscalls.h" + +// DateTime codifies Date structure into two u32 numbers: +// date: year (12 bits) | month (4 bits) | day (5 bits) +// time: day_of_week (3 bits) | hour (5 bits) | minute (6 bits) | seconds (6 bits) +static void rtc_decode(uint32_t date, uint32_t time, libtock_rtc_date_t* out) { + out->year = (date >> 9) & 0xFFF; + out->month = (date >> 5) & 0xF; + out->day = date & 0x1F; + + out->day_of_week = (time >> 17) & 0x7; + out->hour = (time >> 12) & 0x1F; + out->minute = (time >> 6) & 0x3F; + out->seconds = time & 0x3F; +} + +returncode_t libtocksync_rtc_yield_wait_for_get(libtock_rtc_date_t* date) { + yield_waitfor_return_t ywf; + returncode_t ret; + ywf = yield_wait_for(DRIVER_NUM_RTC, 0); + ret = (returncode_t) ywf.data0; + if (ret != RETURNCODE_SUCCESS) return ret; + rtc_decode((uint32_t) ywf.data1, (uint32_t) ywf.data2, date); + return ret; +} + +returncode_t libtocksync_rtc_yield_wait_for_set(void) { + yield_waitfor_return_t ywf; + ywf = yield_wait_for(DRIVER_NUM_RTC, 0); + return (returncode_t) ywf.data0; +} diff --git a/libtock-sync/peripherals/syscalls/rtc_syscalls.h b/libtock-sync/peripherals/syscalls/rtc_syscalls.h new file mode 100644 index 000000000..8303152cc --- /dev/null +++ b/libtock-sync/peripherals/syscalls/rtc_syscalls.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for an RTC get date operation to complete. +returncode_t libtocksync_rtc_yield_wait_for_get(libtock_rtc_date_t* date); + +// Wait for an RTC set date operation to complete. +returncode_t libtocksync_rtc_yield_wait_for_set(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/spi_controller_syscalls.c b/libtock-sync/peripherals/syscalls/spi_controller_syscalls.c new file mode 100644 index 000000000..40d3b63d8 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/spi_controller_syscalls.c @@ -0,0 +1,6 @@ +#include "spi_controller_syscalls.h" + +returncode_t libtocksync_spi_controller_yield_wait_for(void) { + yield_wait_for(DRIVER_NUM_SPI_CONTROLLER, 0); + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/syscalls/spi_controller_syscalls.h b/libtock-sync/peripherals/syscalls/spi_controller_syscalls.h new file mode 100644 index 000000000..c45f7f180 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/spi_controller_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for an SPI controller operation to complete. +returncode_t libtocksync_spi_controller_yield_wait_for(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.c b/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.c new file mode 100644 index 000000000..b39830728 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.c @@ -0,0 +1,6 @@ +#include "spi_peripheral_syscalls.h" + +returncode_t libtocksync_spi_peripheral_yield_wait_for(void) { + yield_wait_for(DRIVER_NUM_SPI_PERIPHERAL, 1); + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.h b/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.h new file mode 100644 index 000000000..186982243 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/spi_peripheral_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for an SPI peripheral operation to complete. +returncode_t libtocksync_spi_peripheral_yield_wait_for(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/syscalls/usb_syscalls.c b/libtock-sync/peripherals/syscalls/usb_syscalls.c new file mode 100644 index 000000000..c05e8ecd3 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/usb_syscalls.c @@ -0,0 +1,7 @@ +#include "usb_syscalls.h" + +returncode_t libtocksync_usb_yield_wait_for(void) { + yield_waitfor_return_t ywf; + ywf = yield_wait_for(DRIVER_NUM_USB, 0); + return (returncode_t) ywf.data0; +} diff --git a/libtock-sync/peripherals/syscalls/usb_syscalls.h b/libtock-sync/peripherals/syscalls/usb_syscalls.h new file mode 100644 index 000000000..c363c4307 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/usb_syscalls.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a USB operation to complete. +returncode_t libtocksync_usb_yield_wait_for(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/usb.c b/libtock-sync/peripherals/usb.c index e5fda1de7..6bae28d1e 100644 --- a/libtock-sync/peripherals/usb.c +++ b/libtock-sync/peripherals/usb.c @@ -1,31 +1,18 @@ #include +#include "syscalls/usb_syscalls.h" #include "usb.h" -struct usb_data { - bool fired; - returncode_t ret; -}; - -static struct usb_data result = { .fired = false }; - -static void usb_callback(returncode_t ret) { - result.fired = true; - result.ret = ret; -} - bool libtocksync_usb_exists(void) { return libtock_usb_driver_exists(); } returncode_t libtocksync_usb_enable_and_attach(void) { - int err; - - result.fired = false; + returncode_t err; - err = libtock_usb_enable_and_attach(usb_callback); + err = libtock_usb_command_enable_and_attach(); if (err != RETURNCODE_SUCCESS) return err; - yield_for(&result.fired); - return result.ret; + err = libtocksync_usb_yield_wait_for(); + return err; } diff --git a/libtock-sync/peripherals/usb.h b/libtock-sync/peripherals/usb.h index 1fd5f5b64..5f7f5810c 100644 --- a/libtock-sync/peripherals/usb.h +++ b/libtock-sync/peripherals/usb.h @@ -1,6 +1,5 @@ #pragma once -#include #include #ifdef __cplusplus diff --git a/libtock/peripherals/crc.h b/libtock/peripherals/crc.h index 64459053d..95874d26b 100644 --- a/libtock/peripherals/crc.h +++ b/libtock/peripherals/crc.h @@ -1,6 +1,7 @@ #pragma once #include "../tock.h" +#include "crc_types.h" #ifdef __cplusplus extern "C" { @@ -12,22 +13,6 @@ extern "C" { // - `arg2` (`uint32_t`): CRC result. typedef void (*libtock_crc_callback_computed)(returncode_t, uint32_t); -// CRC algorithms -// -// In all cases, input bytes are bit-reversed (i.e., consumed from LSB to MSB.) -// -// Algorithms prefixed with `SAM4L_` are native to that chip and thus require -// no software post-processing on platforms using it. -// -typedef enum { - // Polynomial 0x04C11DB7, output reversed then inverted ("CRC-32") - LIBTOCK_CRC_32, - // Polynomial 0x1EDC6F41, output reversed then inverted ("CRC-32C" / "Castagnoli") - LIBTOCK_CRC_32C, - /// Polynomial 0x1021, no output post-processing - LIBTOCK_CRC_16CCITT, -} libtock_crc_alg_t; - // Check if the driver exists. bool libtock_crc_exists(void); diff --git a/libtock/peripherals/crc_types.h b/libtock/peripherals/crc_types.h new file mode 100644 index 000000000..c9b9ebf54 --- /dev/null +++ b/libtock/peripherals/crc_types.h @@ -0,0 +1,27 @@ +#pragma once + +#include "../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// CRC algorithms +// +// In all cases, input bytes are bit-reversed (i.e., consumed from LSB to MSB.) +// +// Algorithms prefixed with `SAM4L_` are native to that chip and thus require +// no software post-processing on platforms using it. +// +typedef enum { + // Polynomial 0x04C11DB7, output reversed then inverted ("CRC-32") + LIBTOCK_CRC_32, + // Polynomial 0x1EDC6F41, output reversed then inverted ("CRC-32C" / "Castagnoli") + LIBTOCK_CRC_32C, + /// Polynomial 0x1021, no output post-processing + LIBTOCK_CRC_16CCITT, +} libtock_crc_alg_t; + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/gpio.h b/libtock/peripherals/gpio.h index 076c14608..26a47049e 100644 --- a/libtock/peripherals/gpio.h +++ b/libtock/peripherals/gpio.h @@ -1,6 +1,7 @@ #pragma once #include "../tock.h" +#include "gpio_types.h" #ifdef __cplusplus extern "C" { @@ -12,18 +13,6 @@ extern "C" { // - `arg2` (`bool`): If the value is high (true) or low (false). typedef void (*libtock_gpio_callback_interrupt)(uint32_t, bool); -typedef enum { - libtock_pull_none=0, - libtock_pull_up, - libtock_pull_down, -} libtock_gpio_input_mode_t; - -typedef enum { - libtock_change=0, - libtock_rising_edge, - libtock_falling_edge, -} libtock_gpio_interrupt_mode_t; - // Check if the driver exists. bool libtock_gpio_exists(void); diff --git a/libtock/peripherals/gpio_types.h b/libtock/peripherals/gpio_types.h new file mode 100644 index 000000000..ec9475875 --- /dev/null +++ b/libtock/peripherals/gpio_types.h @@ -0,0 +1,21 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + libtock_pull_none=0, + libtock_pull_up, + libtock_pull_down, +} libtock_gpio_input_mode_t; + +typedef enum { + libtock_change=0, + libtock_rising_edge, + libtock_falling_edge, +} libtock_gpio_interrupt_mode_t; + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/rtc.h b/libtock/peripherals/rtc.h index 83763cc5a..7af7a70c2 100644 --- a/libtock/peripherals/rtc.h +++ b/libtock/peripherals/rtc.h @@ -1,43 +1,12 @@ #pragma once #include "../tock.h" +#include "rtc_types.h" #ifdef __cplusplus extern "C" { #endif -#define JANUARY 1 -#define FEBRUARY 2 -#define MARCH 3 -#define APRIL 4 -#define MAY 5 -#define JUNE 6 -#define JULY 7 -#define AUGUST 8 -#define SEPTEMBER 9 -#define OCTOBER 10 -#define NOVEMBER 11 -#define DECEMBER 12 - -#define SUNDAY 0 -#define MONDAY 1 -#define TUESDAY 2 -#define WENSDAY 3 -#define THURSDAY 4 -#define FRIDAY 5 -#define SATURDAY 6 - -// Date structure to store date and time -typedef struct { - int year; - int month; - int day; - int day_of_week; - int hour; - int minute; - int seconds; -} libtock_rtc_date_t; - // Function signature for get date callbacks. // // - `arg1` (`returncode_t`): Returncode indicating status. diff --git a/libtock/peripherals/rtc_types.h b/libtock/peripherals/rtc_types.h new file mode 100644 index 000000000..eff034a9c --- /dev/null +++ b/libtock/peripherals/rtc_types.h @@ -0,0 +1,47 @@ +#pragma once + +#include "../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define JANUARY 1 +#define FEBRUARY 2 +#define MARCH 3 +#define APRIL 4 +#define MAY 5 +#define JUNE 6 +#define JULY 7 +#define AUGUST 8 +#define SEPTEMBER 9 +#define OCTOBER 10 +#define NOVEMBER 11 +#define DECEMBER 12 + +#define SUNDAY 0 +#define MONDAY 1 +#define TUESDAY 2 +#define WENSDAY 3 +#define THURSDAY 4 +#define FRIDAY 5 +#define SATURDAY 6 + +// Date structure to store date and time +typedef struct { + int year; + int month; + int day; + int day_of_week; + int hour; + int minute; + int seconds; +} libtock_rtc_date_t; + + + +#ifdef __cplusplus +} +#endif