diff --git a/AppMakefile.mk b/AppMakefile.mk index 4879bfded..6bb866b31 100644 --- a/AppMakefile.mk +++ b/AppMakefile.mk @@ -32,6 +32,10 @@ include $(TOCK_USERLAND_BASE_DIR)/Precompiled.mk # library when needed. include $(TOCK_USERLAND_BASE_DIR)/libtock/Makefile +# Include the libtock-sync Makefile. Adds rules that will rebuild the core +# libtock-sync library when needed. +include $(TOCK_USERLAND_BASE_DIR)/libtock-sync/Makefile + # Include the makefile that has the programming functions for each board. include $(TOCK_USERLAND_BASE_DIR)/Program.mk diff --git a/Configuration.mk b/Configuration.mk index 469447733..f7408f70e 100644 --- a/Configuration.mk +++ b/Configuration.mk @@ -170,6 +170,11 @@ override WLFLAGS += \ -Wl,--gc-sections\ -Wl,--build-id=none +# Include path for all architectures. To support `#include ` and +# `#include ` in app source files, we include the root +# libtock-c folder in the preprocessor's search path. +override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR) + # Flags to improve the quality and information in listings (debug target) OBJDUMP_FLAGS += --disassemble-all --source -C --section-headers diff --git a/doc/guide.md b/doc/guide.md new file mode 100644 index 000000000..b893d9fd0 --- /dev/null +++ b/doc/guide.md @@ -0,0 +1,353 @@ +Writing a libtock-c System Call Driver +====================================== + +This guide covers how to implement support in `libtock` for a new system call +driver. + + +## Setup + + +- `[name]`: String which identifies the system call driver. +- `[category]`: The general type of the system call. + +The categories are: + +- `crypto`: Cryptography interfaces. +- `display`: Screens and other displays. +- `interface`: Human-computer interfaces. +- `kernel`: Tock-specific kernel-level drivers. +- `net`: Networking drivers. +- `peripherals`: Interfaces for chip peripherals. +- `sensors`: Sensors. +- `storage`: Various storage drivers. + + +## Syscall APIs + +All supported system calls (i.e., command, allow, subscribe, etc.) for a +particular driver must be wrapped in simple functions. + +| Characteristic | Value | +|------------------|-------------------------------------------------| +| Location | `libtock/[category]/syscalls` | +| Source File Name | `libtock/[category]/syscalls/[name]_syscalls.c` | +| Header File Name | `libtock/[category]/syscalls/[name]_syscalls.h` | + +### Header File + +The `[name]_syscalls.h` file must contain a `#define` called `DRIVER_NUM_[NAME]` +with the driver number. + +_All_ header files must be wrapped in `extern "C" { ... }` if the header file +is used in a C++ app. + +#### Example: + +```c +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_[NAME] 0x00000 + +// Other defines and signatures go here. + +#ifdef __cplusplus +} +#endif +``` + +### Upcalls + +Each supported upcall must have its own function. + +The signature is: + +```c +returncode_t libtock_[name]_set_upcall(subscribe_upcall callback, void* opaque); +``` + +If only one upcall is supported, the function name must be `[name]_set_upcall`. + +If more than one upcall is supported, the function names must start with +`libtock_[name]_set_upcall_` followed by a description of what the upcall is +used for. + + +#### Example: + +```c +returncode_t libtock_[name]_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_[NAME], 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} +``` + +### Allows + +Each supported allow (readonly, readwrite, userspace_read) must have its own +function. + +The signature is: + +- Read-Only Allow: + ```c + returncode_t libtock_[name]_set_readonly_allow(const uint8_t* buffer, uint32_t len); + ``` + +- Read-Write Allow: + ```c + returncode_t libtock_[name]_set_readwrite_allow(uint8_t* buffer, uint32_t len); + ``` + +- Userspace Read Allow: + ```c + returncode_t libtock_[name]_set_userspace_read_allow(uint8_t* buffer, uint32_t len); + ``` + +If only one allow is supported, the function name must be +`libtock_[name]_set_[type]_allow`. + +If more than one allow is supported, the function names must start with +`libtock_[name]_set_[type]_allow_` followed by a description of what the allow +is used for. + +#### Example: + +```c +returncode_t libtock_[name]_set_readonly_allow_[desc](const uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_[NAME], 0, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} +``` + +```c +returncode_t libtock_[name]_set_readwrite_allow_[desc](uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_[NAME], 0, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} +``` + +```c +returncode_t libtock_[name]_set_userspace_read_allow_[desc](uint8_t* buffer, uint32_t len) { + allow_userspace_r_return_t aval = allow_userspace_read(DRIVER_NUM_[NAME], 0, (void*) buffer, len); + return tock_allow_userspace_r_return_to_returncode(aval); +} +``` + +### Commands + +Each supported command must have its own function. + +The signature is: + +```c +returncode_t libtock_[name]_command_[desc](); +``` + +For every command, the function names must start with `libtock_[name]_command_` +followed by a description of what the command is used for. + +### Example: + +```c +returncode_t libtock_[name]_command_[desc](void) { + syscall_return_t cval = command(DRIVER_NUM_[NAME], 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} +``` + + +### Exists + +There must be a function to check for syscall driver existence. + +Signature: + +``` +bool libtock_[name]_exists(void); +``` + +Example: + +```c +bool libtock_[name]_exists(void) { + return driver_exists(DRIVER_NUM_[NAME]); +} +``` + + +## Asynchronous APIs + +All common system call operations should have asynchronous versions. + +These asynchronous APIs must not use or include any internal/global state. + +| Characteristic | Value | +|------------------|-------------------------------| +| Location | `libtock/[category]` | +| Source File Name | `libtock/[category]/[name].c` | +| Header File Name | `libtock/[category]/[name].h` | + +### Header Files + +The `[name].h` header file must look like: + +```c +#pragma once + +#include "../tock.h" +#include "syscalls/[name]_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signatures go here. + +#ifdef __cplusplus +} +#endif +``` + +The `[name].h` header file must include the syscalls header. + +### Defining a Callback for Asynchronous Operations + +For every type of callback the system call can generate, the library must have a +function signature defined as a type. The format is: + +```c +typedef void (*libtock_[name]_callback_[desc])(returncode_t, int); +``` + +### Functions for Operations + +Every operation the libtock library should expose must be defined. The return +type should generally be `returncode_t`. As these are asynchronous operations, +they should have the last argument be a callback function pointer. + +```c +returncode_t libtock_[name]_[desc](, libtock_[name]_callback_[desc] cb); +``` + +### Example + + +For example, a library called "sensor" with a sensor read operation should look +like this: + +Define a suitable callback for the library: + +```c +typedef void (*libtock_sensor_callback_reading)(returncode_t, int); +``` + +Define a upcall function to be passed to the kernel: + +```c +static void sensor_temp_upcall(int ret, + int val, + __attribute__ ((unused)) int unused0, + void* opaque) { + libtock_sensor_callback_reading cb = (libtock_sensor_callback_reading) opaque; + cb(ret, val); +} +``` + +Define an external function for applications to use to run the asynchronous +operation: + +```c +returncode_t libtock_sensor_read(libtock_sensor_callback_reading cb) { + returncode_t ret; + + ret = libtock_sensor_set_upcall(sensor_temp_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sensor_command_read(); + return ret; +} +``` + +## Synchronous APIs + +Most system call interfaces will want to provide a synchronous API as well. + +| Characteristic | Value | +|------------------|------------------------------------| +| Location | `libtock-sync/[category]` | +| Source File Name | `libtock-sync/[category]/[name].c` | +| Header File Name | `libtock-sync/[category]/[name].h` | + +### Header Files + +The libtock-sync `[name].h` header file must look like: + +```c +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signatures go here. + +#ifdef __cplusplus +} +#endif +``` + +### Synchronous APIs + +For our sensor example: + +Create a struct to be set by the asynchronous callback: + +```c +struct data { + bool fired; + int val; + returncode_t result; +}; + +static struct data result = { .fired = false }; +``` + +Define a static callback function to pass to the asynchronous implementation: + +```c +static void sensor_cb(returncode_t ret, int val) { + result.val = val; + result.fired = true; + result.result = ret; +} +``` + +Define the external function in the `libtocksync_` name space for the sync +operation: + +```c +returncode_t libtocksync_sensor_read(int* val) { + int err; + result.fired = false; + + err = libtock_sensor_read(sensor_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.result != RETURNCODE_SUCCESS) return result.result; + + *val = result.val; + return RETURNCODE_SUCCESS; +} +``` diff --git a/examples/accel-leds/main.c b/examples/accel-leds/main.c index a4641ee4a..34e4f9a52 100644 --- a/examples/accel-leds/main.c +++ b/examples/accel-leds/main.c @@ -1,15 +1,15 @@ #include #include -#include -#include +#include +#include int main(void) { printf("[App] Accelerometer -> LEDs\n"); while (1) { int x, y, z; - ninedof_read_acceleration_sync(&x, &y, &z); + libtocksync_ninedof_read_accelerometer(&x, &y, &z); // abs() if (x < 0) x *= -1; @@ -23,19 +23,19 @@ int main(void) { if (z > largest) largest = z; if (x == largest) { - led_on(0); + libtock_led_on(0); } else { - led_off(0); + libtock_led_off(0); } if (y == largest) { - led_on(1); + libtock_led_on(1); } else { - led_off(1); + libtock_led_off(1); } if (z == largest) { - led_on(2); + libtock_led_on(2); } else { - led_off(2); + libtock_led_off(2); } } diff --git a/examples/adc/README.md b/examples/adc/README.md deleted file mode 100644 index ad2f4ac26..000000000 --- a/examples/adc/README.md +++ /dev/null @@ -1,6 +0,0 @@ -ADC App -========= - -The canonical "adc" app for an embedded platform. This app will -read all the ADC channels of the board that are registered with the kernel. - diff --git a/examples/adc/main.c b/examples/adc/main.c deleted file mode 100644 index 670ed93d1..000000000 --- a/examples/adc/main.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -int main(void) { - // Ask the kernel how many ADC channels are on this board. - int num_adc; - int err = adc_channel_count(&num_adc); - if (err < 0) { - printf("No ADC on this board.\n"); - return err; - } - - printf("ADC Channels: %d\n", num_adc); - - while (true) { - for (int channel = 0; channel < num_adc; channel++) { - uint16_t value; - err = adc_sample_sync(channel, &value); - if (err == RETURNCODE_SUCCESS) { - printf("Channel %d: %d\n", channel, value); - } else { - printf("Channel %d: error(%i) %s \n", channel, err, tock_strrcode(err)); - } - } - printf("\n"); - delay_ms(1000); - } -} diff --git a/examples/ble-uart/main.c b/examples/ble-uart/main.c index d371cf6b4..ce64df3bc 100644 --- a/examples/ble-uart/main.c +++ b/examples/ble-uart/main.c @@ -12,10 +12,11 @@ #include #include -#include +#include -#include -#include +#include +#include +#include #include "ble_nus.h" #include "nrf.h" @@ -63,9 +64,10 @@ void ble_evt_user_handler (ble_evt_t* p_ble_evt) { // This gets called with the serial data from the BLE central. static void nus_data_handler(ble_nus_t* p_nus, uint8_t* p_data, uint16_t length) { UNUSED_PARAMETER(p_nus); + int bytes_written; // In this app, just print it to the console. - putnstr((char*) p_data, length); + libtocksync_console_write(p_data, length, &bytes_written); } void ble_evt_connected(ble_evt_t* p_ble_evt) { diff --git a/examples/ble_advertising/main.c b/examples/ble_advertising/main.c index 523131aba..51e3135cd 100644 --- a/examples/ble_advertising/main.c +++ b/examples/ble_advertising/main.c @@ -1,8 +1,10 @@ -#include -#include #include #include -#include + +#include + +#include +#include // Sizes in bytes #define DEVICE_NAME_SIZE 6 diff --git a/examples/ble_passive_scanning/main.cpp b/examples/ble_passive_scanning/main.cpp index 85242d6fd..99f55419b 100644 --- a/examples/ble_passive_scanning/main.cpp +++ b/examples/ble_passive_scanning/main.cpp @@ -1,7 +1,9 @@ +#include + +#include + #include "advertisement.h" #include "advertisement_list.h" -#include -#include /* * BLE Demo Application diff --git a/examples/blink/main.c b/examples/blink/main.c index b72ab6f47..ac89930b0 100644 --- a/examples/blink/main.c +++ b/examples/blink/main.c @@ -1,10 +1,10 @@ -#include -#include +#include +#include int main(void) { // Ask the kernel how many LEDs are on this board. int num_leds; - int err = led_count(&num_leds); + int err = libtock_led_count(&num_leds); if (err < 0) return err; // Blink the LEDs in a binary count pattern and scale @@ -12,13 +12,13 @@ int main(void) { for (int count = 0; ; count++) { for (int i = 0; i < num_leds; i++) { if (count & (1 << i)) { - led_on(i); + libtock_led_on(i); } else { - led_off(i); + libtock_led_off(i); } } - // This delay uses an underlying timer in the kernel. - delay_ms(250); + // This delay uses an underlying alarm in the kernel. + libtocksync_alarm_delay_ms(250); } } diff --git a/examples/buttons/README.md b/examples/buttons/README.md index 0f4418d43..dc6b3c8f0 100644 --- a/examples/buttons/README.md +++ b/examples/buttons/README.md @@ -1,6 +1,8 @@ # Buttons -This application ties each button on a board to an LED. When the user presses a -button, the associated LED is toggled. The program works with any number of -buttons and LEDs on a board. +This program waits for button presses on each of the buttons attached to a board +and toggles the LED with the same index. For example, if the first button is +pressed, the first LED is toggled. If the third button is pressed, the third LED +is toggled. +The program works with any number of buttons and LEDs on a board. diff --git a/examples/buttons/main.c b/examples/buttons/main.c index 3de739dbc..23339d75b 100644 --- a/examples/buttons/main.c +++ b/examples/buttons/main.c @@ -1,37 +1,23 @@ -// \file -// This program waits for button presses on each of the buttons attached -// to a board and toggles the LED with the same index. For example, if the first -// button is pressed, the first LED is toggled. If the third button is pressed, -// the third LED is toggled. - -#include -#include +#include +#include // Callback for button presses. -// btn_num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_callback(int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - if (val == 1) { - led_toggle(btn_num); +static void button_callback(__attribute__ ((unused)) returncode_t ret, int btn_num, bool pressed) { + if (pressed) { + libtock_led_toggle(btn_num); } } int main(void) { int err; - err = button_subscribe(button_callback, NULL); - if (err < 0) return err; - // Enable interrupts on each button. int count; - err = button_count(&count); + err = libtock_button_count(&count); if (err < 0) return err; for (int i = 0; i < count; i++) { - button_enable_interrupt(i); + libtock_button_notify_on_press(i, button_callback); } while (1) { diff --git a/examples/c_hello/main.c b/examples/c_hello/main.c index a0954cf2f..c70b2c4c0 100644 --- a/examples/c_hello/main.c +++ b/examples/c_hello/main.c @@ -5,18 +5,16 @@ #include #include -#include +#include char hello[] = "Hello World!\r\n"; static void nop( - int a __attribute__((unused)), - int b __attribute__((unused)), - int c __attribute__((unused)), - void* d __attribute__((unused))) {} + returncode_t ret __attribute__((unused)), + uint32_t bytes_written __attribute__((unused))) {} int main(void) { - putnstr_async(hello, strlen(hello), nop, NULL); + libtock_console_write((uint8_t*) hello, strlen(hello), nop); // Because we used the async method (as opposed to something synchronous, // such as printf), we must explicitly wait for the asynchronous write to complete. yield(); diff --git a/examples/cxx_hello/main.cc b/examples/cxx_hello/main.cc index 8c6ae7919..2f60f40d5 100644 --- a/examples/cxx_hello/main.cc +++ b/examples/cxx_hello/main.cc @@ -1,6 +1,6 @@ #include -#include +#include class Base { public: @@ -40,7 +40,7 @@ int main() { } test_branch++; - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } return 0; diff --git a/examples/find_north/main.c b/examples/find_north/main.c index 232e8b7c9..6f70939fb 100644 --- a/examples/find_north/main.c +++ b/examples/find_north/main.c @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include int main(void) { int x, y, z; @@ -12,7 +12,7 @@ int main(void) { // second in RGB), but will take anything. int led = 0; int num_leds; - err = led_count(&num_leds); + err = libtock_led_count(&num_leds); if (err < 0) { printf("No LEDs on this board.\n"); return err; @@ -20,7 +20,7 @@ int main(void) { if (num_leds > 1) led = 1; while (1) { - err = ninedof_read_magnetometer_sync(&x, &y, &z); + err = libtocksync_ninedof_read_magnetometer(&x, &y, &z); if (err < 0) { printf("No magnetometer on this board.\n"); return err; @@ -37,9 +37,9 @@ int main(void) { // Turn the LED on if the board is pointing in a certain range. if (angle > 50 && angle < 310) { - led_off(led); + libtock_led_off(led); } else { - led_on(led); + libtock_led_on(led); } } diff --git a/examples/i2c-usb-bridge/main.c b/examples/i2c-usb-bridge/main.c index 9b6a58972..857b0e7e3 100644 --- a/examples/i2c-usb-bridge/main.c +++ b/examples/i2c-usb-bridge/main.c @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #define DATA_LEN 64 @@ -12,6 +12,19 @@ char command_buf[DATA_LEN]; uint8_t recieve_buf[DATA_LEN]; uint8_t send_buf[DATA_LEN]; +static int getch(void) { + uint8_t buffer[1]; + int number_read; + libtocksync_console_read(buffer, 1, &number_read); + return buffer[0]; +} + +static int putnstr(char* str, int len) { + int number_written; + libtocksync_console_read((uint8_t*) str, len, &number_written); + return number_written; +} + static int get_command(void) { int idx = 0; memset(command_buf, 0, DATA_LEN); diff --git a/examples/ip_sense/main.c b/examples/ip_sense/main.c index 5d9dc6a98..c3d2c900a 100644 --- a/examples/ip_sense/main.c +++ b/examples/ip_sense/main.c @@ -1,13 +1,13 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include +#include +#include static unsigned char BUF_BIND_CFG[2 * sizeof(sock_addr_t)]; @@ -24,17 +24,17 @@ int main(void) { printf("[IPv6_Sense] Starting IPv6 Sensors App.\n"); printf("[IPv6_Sense] Sensors will be sampled and transmitted.\n"); - unsigned int humi = 0; + int humi = 0; int temp = 0; int lux = 0; char packet[64]; - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_handle_t handle; sock_addr_t addr = { @@ -45,7 +45,7 @@ int main(void) { printf("Opening socket on "); print_ipv6(&ifaces[0]); printf(" : %d, and binding to that socket.\n", addr.port); - int bind_return = udp_bind(&handle, &addr, BUF_BIND_CFG); + int bind_return = libtock_udp_bind(&handle, &addr, BUF_BIND_CFG); if (bind_return < 0) { printf("Failed to bind to port: failure=%d\n", bind_return); @@ -58,14 +58,14 @@ int main(void) { }; while (1) { - temperature_read_sync(&temp); - humidity_read_sync(&humi); - ambient_light_read_intensity_sync(&lux); + libtocksync_temperature_read(&temp); + libtocksync_humidity_read(&humi); + libtocksync_ambient_light_read_intensity(&lux); int len = snprintf(packet, sizeof(packet), "%d deg C; %d%% humidity; %d lux;\n", temp / 100, humi / 100, lux); int max_tx_len; - udp_get_max_tx_len(&max_tx_len); + libtock_udp_get_max_tx_len(&max_tx_len); if (len > max_tx_len) { printf("Cannot send packets longer than %d bytes without changing" " constants in kernel\n", max_tx_len); @@ -74,7 +74,7 @@ int main(void) { printf("Sending packet (length %d) --> ", len); print_ipv6(&(destination.addr)); printf(" : %d\n", destination.port); - ssize_t result = udp_send_to(packet, len, &destination); + ssize_t result = libtocksync_udp_send(packet, len, &destination); switch (result) { case RETURNCODE_SUCCESS: @@ -83,6 +83,6 @@ int main(void) { default: printf("Error sending packet %d\n\n", result); } - delay_ms(4000); + libtocksync_alarm_delay_ms(4000); } } diff --git a/examples/lua-hello/main.c b/examples/lua-hello/main.c index 13a3887b5..d7d6d95cc 100644 --- a/examples/lua-hello/main.c +++ b/examples/lua-hello/main.c @@ -1,7 +1,8 @@ #include #include #include -#include + +#include #include "lauxlib.h" #include "lua.h" @@ -11,7 +12,7 @@ // Linux/OS X/BSD for testing. #if defined(__unix__) #include -void delay_ms(int ms) { +void libtocksync_alarm_delay_ms(int ms) { struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = (long)ms * 1000 * 1000; @@ -56,7 +57,7 @@ int main(void) { int kb = lua_gc(L, LUA_GCCOUNT, 0); int bytes = lua_gc(L, LUA_GCCOUNT, 0); printf("> %dKB and %d bytes used\n", kb, bytes); - delay_ms(500); + libtocksync_alarm_delay_ms(500); } // Close lua diff --git a/examples/lvgl/lvgl_driver.c b/examples/lvgl/lvgl_driver.c index d16de5db1..9a476315c 100644 --- a/examples/lvgl/lvgl_driver.c +++ b/examples/lvgl/lvgl_driver.c @@ -1,3 +1,8 @@ +#include +#include +#include +#include + #include "lvgl_driver.h" static lv_disp_draw_buf_t disp_buf; @@ -7,8 +12,11 @@ static lv_disp_t *display_device; static lv_indev_drv_t indev_drv; static lv_indev_t *touch_input_device; -static int touch_status = TOUCH_STATUS_UNSTARTED; -static int touch_x = 0, touch_y = 0; +static int touch_status = LIBTOCK_TOUCH_STATUS_UNSTARTED; +static uint16_t touch_x = 0, touch_y = 0; + +static int buffer_size = 0; +static uint8_t* buffer; /* screen driver */ static void screen_lvgl_driver(lv_disp_drv_t * disp, const lv_area_t * area, @@ -19,13 +27,13 @@ static void screen_lvgl_driver(lv_disp_drv_t * disp, const lv_area_t * area, y = area->y1; int w = area->x2 - area->x1 + 1; int h = area->y2 - area->y1 + 1; - screen_set_frame(x, y, w, h); - screen_write((w * h) * sizeof(lv_color_t)); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_write(buffer, buffer_size, (w * h) * sizeof(lv_color_t)); lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ } -static void touch_event (int status, int x, int y, __attribute__((unused)) void* ud) { +static void touch_event (int status, uint16_t x, uint16_t y) { touch_status = status; touch_x = x; touch_y = y; @@ -33,7 +41,7 @@ static void touch_event (int status, int x, int y, __attribute__((unused)) void* static void my_input_read(__attribute__((unused)) lv_indev_drv_t * drv, lv_indev_data_t*data) { - if (touch_status == TOUCH_STATUS_PRESSED || touch_status == TOUCH_STATUS_MOVED) { + if (touch_status == LIBTOCK_TOUCH_STATUS_PRESSED || touch_status == LIBTOCK_TOUCH_STATUS_MOVED) { data->point.x = touch_x; data->point.y = touch_y; data->state = LV_INDEV_STATE_PRESSED; @@ -42,38 +50,41 @@ static void my_input_read(__attribute__((unused)) lv_indev_drv_t * drv, lv_indev } } + + int lvgl_driver_init (int buffer_lines) { - size_t width, height; - int error = screen_get_resolution(&width, &height); - if (error == RETURNCODE_SUCCESS) { - error = screen_init(width * buffer_lines * sizeof(lv_color_t)); - if (error == RETURNCODE_SUCCESS) { - /* share the frame buffer with littlevgl */ - lv_color_t *buf = (lv_color_t*)screen_buffer(); - - /* initialize littlevgl */ - lv_init(); - lv_disp_drv_init(&disp_drv); - disp_drv.flush_cb = screen_lvgl_driver; - disp_drv.hor_res = width; - disp_drv.ver_res = height; - lv_disp_draw_buf_init(&disp_buf, buf, NULL, width * buffer_lines); - disp_drv.draw_buf = &disp_buf; - display_device = lv_disp_drv_register(&disp_drv); - - int touches; - if (get_number_of_touches(&touches) == RETURNCODE_SUCCESS && touches >= 1) { - enable_single_touch(); - single_touch_set_callback(touch_event, NULL); - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = my_input_read; - touch_input_device = lv_indev_drv_register(&indev_drv); - } - } + uint32_t width, height; + int error = libtock_screen_get_resolution(&width, &height); + if (error != RETURNCODE_SUCCESS) return error; + + buffer_size = width * buffer_lines * sizeof(lv_color_t); + error = libtock_screen_buffer_init(buffer_size, &buffer); + if (error != RETURNCODE_SUCCESS) return error; + + /* share the frame buffer with littlevgl */ + lv_color_t *buf = (lv_color_t*) buffer; + + /* initialize littlevgl */ + lv_init(); + lv_disp_drv_init(&disp_drv); + disp_drv.flush_cb = screen_lvgl_driver; + disp_drv.hor_res = width; + disp_drv.ver_res = height; + lv_disp_draw_buf_init(&disp_buf, buf, NULL, width * buffer_lines); + disp_drv.draw_buf = &disp_buf; + display_device = lv_disp_drv_register(&disp_drv); + + int touches; + if (libtock_touch_get_number_of_touches(&touches) == RETURNCODE_SUCCESS && touches >= 1) { + libtock_touch_enable_single_touch(touch_event); + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = my_input_read; + touch_input_device = lv_indev_drv_register(&indev_drv); } - return error; + + return RETURNCODE_SUCCESS; } void lvgl_driver_event (int millis) { diff --git a/examples/lvgl/lvgl_driver.h b/examples/lvgl/lvgl_driver.h index 828e05a16..1563a606e 100644 --- a/examples/lvgl/lvgl_driver.h +++ b/examples/lvgl/lvgl_driver.h @@ -1,9 +1,4 @@ #pragma once -#include -#include -#include -#include - int lvgl_driver_init (int buffer_size); void lvgl_driver_event (int mills); diff --git a/examples/lvgl/main.c b/examples/lvgl/main.c index e81efc257..d4ece729a 100644 --- a/examples/lvgl/main.c +++ b/examples/lvgl/main.c @@ -1,6 +1,11 @@ -#include "lvgl_driver.h" #include -#include + +#include +#include + +#include + +#include "lvgl_driver.h" static void event_handler(lv_event_t * e) { @@ -19,7 +24,7 @@ int main (void) { unsigned int seconds = 0; - screen_set_brightness(100); + libtocksync_screen_set_brightness(100); int status = lvgl_driver_init(5); if (status == RETURNCODE_SUCCESS) { /* LittlevGL's Hello World tutorial example */ @@ -53,7 +58,7 @@ int main (void) snprintf(buffer, 99, "Seconds: %d", seconds / 200); lv_label_set_text(label1, buffer); } - delay_ms(5); + libtocksync_alarm_delay_ms(5); lvgl_driver_event(5); } } else { diff --git a/examples/music/main.c b/examples/music/main.c index 69db57e14..e001bea27 100644 --- a/examples/music/main.c +++ b/examples/music/main.c @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include // Adapted from https://github.com/robsoncouto/arduino-songs @@ -34,7 +34,7 @@ int melody[] = { #define TEMPO 114 int main(void) { - if (!buzzer_exists()) { + if (!libtock_buzzer_exists()) { printf("There is no available buzzer\n"); return -1; } @@ -57,6 +57,6 @@ int main(void) { } // we only play the note for 90% of the duration, leaving 10% as a pause - tone_sync(melody[note], note_duration * 0.9); + libtocksync_buzzer_tone(melody[note], note_duration * 0.9); } } diff --git a/examples/rot13_client/main.c b/examples/rot13_client/main.c index 318b26e44..1dc2926d4 100644 --- a/examples/rot13_client/main.c +++ b/examples/rot13_client/main.c @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include size_t rot13_svc_num = 0; @@ -18,7 +18,7 @@ static void rot13_callback(__attribute__ ((unused)) int pid, __attribute__ ((unused)) int arg2, void* ud) { struct rot13_buf *rb = (struct rot13_buf*)ud; printf("%d: %.*s\n", rb->length, rb->length, rb->buf); - delay_ms(500); + libtocksync_alarm_delay_ms(500); ipc_notify_service(rot13_svc_num); } diff --git a/examples/rot13_service/main.c b/examples/rot13_service/main.c index 7aa802e36..be33ac289 100644 --- a/examples/rot13_service/main.c +++ b/examples/rot13_service/main.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include struct rot13_buf { int8_t length; diff --git a/examples/screen/Makefile b/examples/screen/Makefile deleted file mode 100644 index c9229d3e2..000000000 --- a/examples/screen/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Makefile for user application - -# Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../.. - -# Which files to compile. -C_SRCS := $(wildcard *.c) - -APP_HEAP_SIZE := 20000 - -# Include userland master makefile. Contains rules and flags for actually -# building the application. -include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/screen/main.c b/examples/screen/main.c deleted file mode 100644 index ba8c13d63..000000000 --- a/examples/screen/main.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -#define BUFFER_SIZE 10 * 1024 - -int main(void) { - int err; - - printf("available resolutions\n"); - int resolutions; - err = screen_get_supported_resolutions(&resolutions); - if (err < 0) return -1; - for (int idx = 0; idx < resolutions; idx++) { - size_t width, height; - screen_get_supported_resolution(idx, &width, &height); - printf(" %d x %d\n", width, height); - } - - printf("available colors depths\n"); - int pixel_format; - err = screen_get_supported_pixel_formats(&pixel_format); - if (err < 0) return -1; - for (int idx = 0; idx < pixel_format; idx++) { - int format; - screen_get_supported_pixel_format(idx, &format); - size_t bits = screen_get_bits_per_pixel(format); - printf(" %d bpp\n", bits); - } - - err = screen_init(BUFFER_SIZE); - if (err < 0) { - printf("buffer allocation failed\n"); - return -1; - } - - printf("screen init\n"); - screen_set_brightness(100); - size_t width, height; - screen_get_resolution(&width, &height); - screen_set_frame(0, 0, width, height); - screen_fill(0); - bool invert = false; - for (int i = 0; ; i++) { - if (i % 4 == 3) { - invert = !invert; - if (invert) { - screen_invert_on(); - } else { - screen_invert_off(); - } - } - screen_set_rotation(i % 4); - screen_set_frame(10, 20, 30, 30); - screen_fill(0xF800); - screen_set_frame(88, 20, 30, 30); - screen_fill(0); - delay_ms(1000); - screen_set_frame(10, 20, 30, 30); - screen_fill(0); - screen_set_frame(88, 20, 30, 30); - screen_fill(0x07F0); - delay_ms(1000); - screen_set_frame(0, 0, width, height); - screen_fill(0x0000); - } - - return 0; -} diff --git a/examples/security_app/main.c b/examples/security_app/main.c index 8b674fd8f..7815a3d62 100644 --- a/examples/security_app/main.c +++ b/examples/security_app/main.c @@ -4,13 +4,13 @@ #include #include -#include "console.h" -#include "gpio.h" -#include "led.h" -#include "tock.h" +#include +#include +#include +#include typedef struct { - uint8_t pir; + bool pir; uint8_t reed_switch; } SensorData_t; @@ -20,10 +20,8 @@ static SensorData_t sensor_data = { }; // callback for gpio interrupts -static void gpio_cb (int pin_num, - int pin_val, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) void* userdata) { +static void gpio_cb (uint32_t pin_num, + bool pin_val) { // save sensor data if (pin_num == 1) { @@ -46,11 +44,11 @@ int main(void) { printf("Security Application\n"); // configure pins - gpio_interrupt_callback(gpio_cb, NULL); - gpio_enable_input(0, PullNone); - gpio_enable_interrupt(0, Change); - gpio_enable_input(1, PullUp); - gpio_enable_interrupt(1, Change); + libtock_gpio_set_interrupt_callback(gpio_cb); + libtock_gpio_enable_input(0, libtock_pull_none); + libtock_gpio_enable_interrupt(0, libtock_change); + libtock_gpio_enable_input(1, libtock_pull_up); + libtock_gpio_enable_interrupt(1, libtock_change); // configure accelerometer // TODO @@ -60,7 +58,7 @@ int main(void) { while (1) { yield(); - led_toggle(0); + libtock_led_toggle(0); printf("\tPIR:\t\t%d\n\tReed Switch:\t%d\n\n", sensor_data.pir, sensor_data.reed_switch); diff --git a/examples/sensors/main.c b/examples/sensors/main.c index 98067e45c..f674dba38 100644 --- a/examples/sensors/main.c +++ b/examples/sensors/main.c @@ -1,21 +1,17 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -static tock_timer_t timer; +static libtock_alarm_t alarm; static bool light = false; -static bool tsl2561 = false; -static bool lps25hb = false; static bool temperature = false; static bool humidity = false; static bool ninedof = false; @@ -24,15 +20,12 @@ static bool ninedof_mag = false; static bool ninedof_gyro = false; static bool proximity = false; static bool sound_pressure = false; -static void timer_fired(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* ud) { +static void alarm_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { int lite = 0; - int tsl2561_lux = 0; - int lps25hb_pressure = 0; int temp = 0; - unsigned humi = 0; + int humi = 0; int ninedof_accel_x = 0, ninedof_accel_y = 0, ninedof_accel_z = 0; int ninedof_magneto_x = 0, ninedof_magneto_y = 0, ninedof_magneto_z = 0; int ninedof_gyro_x = 0, ninedof_gyro_y = 0, ninedof_gyro_z = 0; @@ -40,20 +33,16 @@ static void timer_fired(__attribute__ ((unused)) int arg0, unsigned char sound_pressure_reading = 0; /* *INDENT-OFF* */ - if (light) ambient_light_read_intensity_sync(&lite); - if (tsl2561) tsl2561_get_lux_sync(&tsl2561_lux); - if (lps25hb) lps25hb_get_pressure_sync(&lps25hb_pressure); - if (temperature) temperature_read_sync(&temp); - if (humidity) humidity_read_sync(&humi); - if (ninedof_accel) ninedof_read_acceleration_sync(&ninedof_accel_x, &ninedof_accel_y, &ninedof_accel_z); - if (ninedof_mag) ninedof_read_magnetometer_sync(&ninedof_magneto_x, &ninedof_magneto_y, &ninedof_magneto_z); - if (ninedof_gyro) ninedof_read_gyroscope_sync(&ninedof_gyro_x, &ninedof_gyro_y, &ninedof_gyro_z); - if (proximity) proximity_read_sync(&prox_reading); - if (sound_pressure) sound_pressure_read_sync(&sound_pressure_reading); + if (light) libtocksync_ambient_light_read_intensity(&lite); + if (temperature) libtocksync_temperature_read(&temp); + if (humidity) libtocksync_humidity_read(&humi); + if (ninedof_accel) libtocksync_ninedof_read_accelerometer(&ninedof_accel_x, &ninedof_accel_y, &ninedof_accel_z); + if (ninedof_mag) libtocksync_ninedof_read_magnetometer(&ninedof_magneto_x, &ninedof_magneto_y, &ninedof_magneto_z); + if (ninedof_gyro) libtocksync_ninedof_read_gyroscope(&ninedof_gyro_x, &ninedof_gyro_y, &ninedof_gyro_z); + if (proximity) libtocksync_proximity_read(&prox_reading); + if (sound_pressure) libtocksync_sound_pressure_read(&sound_pressure_reading); if (light) printf("Amb. Light: Light Intensity: %d\n", lite); - if (tsl2561) printf("TSL2561: Light: %d lux\n", tsl2561_lux); - if (lps25hb) printf("LPS25HB: Pressure: %d\n", lps25hb_pressure); if (temperature) printf("Temperature: %d deg C\n", temp/100); if (humidity) printf("Humidity: %u%%\n", humi/100); if (ninedof_accel) printf("Acceleration: X: %d Y: %d Z: %d\n", ninedof_accel_x, ninedof_accel_y, ninedof_accel_z); @@ -65,7 +54,7 @@ static void timer_fired(__attribute__ ((unused)) int arg0, /* *INDENT-ON* */ printf("\n"); - timer_in(1000, timer_fired, NULL, &timer); + libtock_alarm_in_ms(1000, alarm_cb, NULL, &alarm); } int main(void) { @@ -73,27 +62,23 @@ int main(void) { printf("[Sensors] All available sensors on the platform will be sampled.\n"); /* *INDENT-OFF* */ - light = driver_exists(DRIVER_NUM_AMBIENT_LIGHT); - tsl2561 = driver_exists(DRIVER_NUM_TSL2561); - lps25hb = driver_exists(DRIVER_NUM_LPS25HB); - temperature = driver_exists(DRIVER_NUM_TEMPERATURE); - humidity = driver_exists(DRIVER_NUM_HUMIDITY); - ninedof = driver_exists(DRIVER_NUM_NINEDOF); - proximity = driver_exists(DRIVER_NUM_PROXIMITY); - sound_pressure = driver_exists(DRIVER_NUM_SOUND_PRESSURE); + light = libtock_ambient_light_exists(); + temperature = libtock_temperature_exists(); + humidity = libtock_humidity_exists(); + ninedof = libtock_ninedof_exists(); + proximity = libtock_proximity_exists(); + sound_pressure = libtock_sound_pressure_exists(); /* *INDENT-ON* */ if (ninedof) { int buffer; - ninedof_accel = (ninedof_read_acceleration_sync(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); - ninedof_mag = (ninedof_read_magnetometer_sync(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); - ninedof_gyro = (ninedof_read_gyroscope_sync(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); + ninedof_accel = (libtocksync_ninedof_read_accelerometer(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); + ninedof_mag = (libtocksync_ninedof_read_magnetometer(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); + ninedof_gyro = (libtocksync_ninedof_read_gyroscope(&buffer, &buffer, &buffer) == RETURNCODE_SUCCESS); } /* *INDENT-OFF* */ if (light) printf("[Sensors] Sampling Ambient Light sensor.\n"); - if (tsl2561) printf("[Sensors] Sampling TSL2561 Light sensor.\n"); - if (lps25hb) printf("[Sensors] Sampling LPS25HB pressure sensor.\n"); if (temperature) printf("[Sensors] Sampling Temperature sensor.\n"); if (humidity) printf("[Sensors] Sampling Humidity sensor.\n"); if (ninedof_accel) printf("[Sensors] Sampling Accelerometer.\n"); @@ -104,11 +89,11 @@ int main(void) { /* *INDENT-ON* */ if (sound_pressure) { - sound_pressure_enable(); + libtock_sound_pressure_command_enable(); } - // Setup periodic timer to sample the sensors. - timer_in(1000, timer_fired, NULL, &timer); + // Setup periodic alarm to sample the sensors. + libtock_alarm_in_ms(1000, alarm_cb, NULL, &alarm); while (1) { yield(); diff --git a/examples/services/ble-env-sense/main.c b/examples/services/ble-env-sense/main.c index 85444ab4e..1c26dea76 100644 --- a/examples/services/ble-env-sense/main.c +++ b/examples/services/ble-env-sense/main.c @@ -6,16 +6,16 @@ #include #include +#include #include #include #include #include -#include -#include -#include -#include +#include +#include +#include #include "env_sense_service.h" diff --git a/examples/services/ble-env-sense/test-with-sensors/main.c b/examples/services/ble-env-sense/test-with-sensors/main.c index 56d1bb550..37c31f75f 100644 --- a/examples/services/ble-env-sense/test-with-sensors/main.c +++ b/examples/services/ble-env-sense/test-with-sensors/main.c @@ -1,12 +1,12 @@ #include #include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include size_t _svc_num = 0; @@ -24,7 +24,7 @@ typedef struct { } sensor_update_t; bool _ipc_done = false; -tock_timer_t _timer; +libtock_alarm_t _alarm; static void ipc_callback(__attribute__ ((unused)) int pid, __attribute__ ((unused)) int len, @@ -33,21 +33,21 @@ static void ipc_callback(__attribute__ ((unused)) int pid, _ipc_done = true; } -static void do_sensing_cb(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) void* ud) { + +static void do_sensing_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { printf("[BLE ESS Test] Sampling Sensors\n"); sensor_update_t *update = (sensor_update_t*) buf; - int light = 0; - int temp = 0; - unsigned humi = 0; + int light = 0; + int temp = 0; + int humi = 0; if (driver_exists(DRIVER_NUM_AMBIENT_LIGHT)) { - ambient_light_read_intensity_sync(&light); + libtocksync_ambient_light_read_intensity(&light); update->type = SENSOR_IRRADIANCE; update->value = light; @@ -57,7 +57,7 @@ static void do_sensing_cb(__attribute__ ((unused)) int now, } if (driver_exists(DRIVER_NUM_TEMPERATURE)) { - temperature_read_sync(&temp); + libtocksync_temperature_read(&temp); update->type = SENSOR_TEMPERATURE; update->value = temp; @@ -67,7 +67,7 @@ static void do_sensing_cb(__attribute__ ((unused)) int now, } if (driver_exists(DRIVER_NUM_HUMIDITY)) { - humidity_read_sync(&humi); + libtocksync_humidity_read(&humi); update->type = SENSOR_HUMIDITY; update->value = humi; @@ -81,8 +81,7 @@ static void do_sensing_cb(__attribute__ ((unused)) int now, printf(" temp: %i\n", temp); printf(" humi: %i\n", humi); - timer_in(3000, do_sensing_cb, NULL, &_timer); - + libtock_alarm_in_ms(3000, do_sensing_cb, NULL, &_alarm); } @@ -96,13 +95,13 @@ int main(void) { printf("Found BLE ESS service (%u)\n", _svc_num); - delay_ms(1500); + libtocksync_alarm_delay_ms(1500); sensor_update_t *update = (sensor_update_t*) buf; ipc_register_client_callback(_svc_num, ipc_callback, update); ipc_share(_svc_num, buf, 64); - timer_in(1000, do_sensing_cb, NULL, &_timer); + libtock_alarm_in_ms(1000, do_sensing_cb, NULL, &_alarm); return 0; } diff --git a/examples/services/ble-env-sense/test/main.c b/examples/services/ble-env-sense/test/main.c index 48d3ba7ba..6213b2cc9 100644 --- a/examples/services/ble-env-sense/test/main.c +++ b/examples/services/ble-env-sense/test/main.c @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include size_t _svc_num = 0; @@ -35,7 +35,7 @@ int main(void) { printf("Found BLE ESS service (%u)\n", _svc_num); - delay_ms(1500); + libtocksync_alarm_delay_ms(1500); sensor_update_t *update = (sensor_update_t*) buf; ipc_register_client_callback(_svc_num, ipc_callback, update); diff --git a/examples/services/unit_test_supervisor/main.c b/examples/services/unit_test_supervisor/main.c index 43dba70dd..75a3b5f9b 100644 --- a/examples/services/unit_test_supervisor/main.c +++ b/examples/services/unit_test_supervisor/main.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include int main(void) { unit_test_service(); diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/Makefile b/examples/tests/adc/adc/Makefile similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/Makefile rename to examples/tests/adc/adc/Makefile diff --git a/examples/tests/adc/README.md b/examples/tests/adc/adc/README.md similarity index 100% rename from examples/tests/adc/README.md rename to examples/tests/adc/adc/README.md diff --git a/examples/tests/adc/main.c b/examples/tests/adc/adc/main.c similarity index 75% rename from examples/tests/adc/main.c rename to examples/tests/adc/adc/main.c index ece57659c..9c953e7b4 100644 --- a/examples/tests/adc/main.c +++ b/examples/tests/adc/adc/main.c @@ -3,10 +3,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include int reference_voltage; @@ -16,7 +16,7 @@ const uint32_t FREQS[10] = {25, 100, 500, 1000, 5000, 10000, 44100, 100000, 1500 static void test_single_samples(uint8_t channel) { uint16_t sample; - int err = adc_sample_sync(channel, &sample); + int err = libtocksync_adc_sample(channel, &sample); if (err < 0) { printf("Error sampling ADC: %d\n", err); @@ -34,7 +34,7 @@ static void test_sampling_buffer(uint8_t channel, int index) { memset(buf, 0, length); printf("%lu ADC samples at %lu Hz\n", length, FREQS[index]); - int err = adc_sample_buffer_sync(channel, FREQS[index], buf, length); + int err = libtocksync_adc_sample_buffer(channel, FREQS[index], buf, length); if (err < 0) { printf("Error sampling ADC: %d\n", err); @@ -52,15 +52,15 @@ int main(void) { printf("[Tock] ADC Test\n"); // check if ADC driver exists - if (!adc_exists()) { + if (!libtock_adc_exists()) { printf("No ADC driver!\n"); return -1; } int count; - adc_channel_count(&count); + libtock_adc_channel_count(&count); printf("ADC driver exists with %d channels\n", count); - reference_voltage = adc_get_reference_voltage(); + libtock_adc_command_get_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,8 +68,9 @@ int main(void) { printf("ADC no reference voltage, assuming 3.3V\n"); } - int resolution = adc_get_resolution_bits(); - printf("ADC resolution %d bits\n", resolution); + uint32_t resolution; + libtock_adc_command_get_resolution_bits(&resolution); + printf("ADC resolution %lu bits\n", resolution); while (1) { // iterate through the channels @@ -78,13 +79,13 @@ int main(void) { printf("\nSingle Samples - Channel %u\n", channel); for (uint32_t i = 0; i < 10; i++) { test_single_samples(channel); - delay_ms(100); + libtocksync_alarm_delay_ms(100); } printf("\nBuffered Samples - Channel %u\n", channel); for (uint32_t i = 0; i < 10; i++) { test_sampling_buffer(channel, i); - delay_ms(100); + libtocksync_alarm_delay_ms(100); } } } diff --git a/examples/tests/spi/spi_buf/Makefile b/examples/tests/adc/adc_continuous/Makefile similarity index 100% rename from examples/tests/spi/spi_buf/Makefile rename to examples/tests/adc/adc_continuous/Makefile diff --git a/examples/tests/adc_continuous/README.md b/examples/tests/adc/adc_continuous/README.md similarity index 100% rename from examples/tests/adc_continuous/README.md rename to examples/tests/adc/adc_continuous/README.md diff --git a/examples/tests/adc_continuous/main.c b/examples/tests/adc/adc_continuous/main.c similarity index 68% rename from examples/tests/adc_continuous/main.c rename to examples/tests/adc/adc_continuous/main.c index 31e2a1e42..8be4aef74 100644 --- a/examples/tests/adc_continuous/main.c +++ b/examples/tests/adc/adc_continuous/main.c @@ -3,10 +3,9 @@ #include #include -#include -#include -#include -#include +#include +#include +#include // Sample the first channel. On Hail, this is external pin A0 (AD0) #define ADC_CHANNEL 0 @@ -25,9 +24,23 @@ static uint16_t sample_buffer1[BUF_SIZE] = {0}; static uint16_t sample_buffer2[BUF_SIZE] = {0}; -static void continuous_sample_cb(uint8_t channel, - uint16_t sample, - __attribute__ ((unused)) void* callback_args) { +static void continuous_sample_cb(uint8_t channel, + uint16_t sample); +static void continuous_buffered_sample_cb(uint8_t channel, + uint32_t length, + uint16_t* buf_ptr); + +static libtock_adc_callbacks callbacks = { + .single_sample_callback = NULL, + .continuous_sample_callback = continuous_sample_cb, + .buffered_sample_callback = NULL, + .continuous_buffered_sample_callback = continuous_buffered_sample_cb, +}; + + + +static void continuous_sample_cb(uint8_t channel, + uint16_t sample) { // single ADC sample is ready static uint8_t counter = 0; @@ -42,7 +55,7 @@ static void continuous_sample_cb(uint8_t channel, counter = 0; // stop single sampling - int err = adc_stop_sampling(); + int err = libtock_adc_stop_sampling(); if (err < RETURNCODE_SUCCESS) { printf("Failed to stop sampling: %d\n", err); return; @@ -51,7 +64,7 @@ static void continuous_sample_cb(uint8_t channel, // start buffered sampling printf("Beginning buffered sampling on channel %d at %d Hz\n", ADC_CHANNEL, ADC_HIGHSPEED_FREQUENCY); - err = adc_continuous_buffered_sample(ADC_CHANNEL, ADC_HIGHSPEED_FREQUENCY); + err = libtock_adc_continuous_buffered_sample(ADC_CHANNEL, ADC_HIGHSPEED_FREQUENCY, &callbacks); if (err < RETURNCODE_SUCCESS) { printf("continuous buffered sample error: %d\n", err); return; @@ -59,10 +72,9 @@ static void continuous_sample_cb(uint8_t channel, } } -static void continuous_buffered_sample_cb(uint8_t channel, - uint32_t length, - uint16_t* buf_ptr, - __attribute__ ((unused)) void* callback_args) { +static void continuous_buffered_sample_cb(uint8_t channel, + uint32_t length, + uint16_t* buf_ptr) { // buffer of ADC samples is ready static uint8_t counter = 0; @@ -89,7 +101,7 @@ static void continuous_buffered_sample_cb(uint8_t channel counter = 0; // stop single sampling - int err = adc_stop_sampling(); + int err = libtock_adc_stop_sampling(); if (err < RETURNCODE_SUCCESS) { printf("Failed to stop sampling: %d\n", err); return; @@ -98,7 +110,7 @@ static void continuous_buffered_sample_cb(uint8_t channel // start single sampling printf("Beginning continuous sampling on channel %d at %d Hz\n", ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY); - err = adc_continuous_sample(ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY); + err = libtock_adc_continuous_sample(ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY, &callbacks); if (err < RETURNCODE_SUCCESS) { printf("continuous sample error: %d\n", err); return; @@ -111,28 +123,16 @@ int main(void) { printf("[Tock] ADC Continuous Test\n"); // check if ADC driver exists - if (!adc_exists()) { + if (!libtock_adc_exists()) { printf("No ADC driver!\n"); return -1; } int count; - adc_channel_count(&count); + libtock_adc_channel_count(&count); printf("ADC driver exists with %d channels\n", count); - // set ADC callbacks - err = adc_set_continuous_sample_callback(continuous_sample_cb, NULL); - if (err < RETURNCODE_SUCCESS) { - printf("set continuous sample callback error: %d\n", err); - return -1; - } - err = adc_set_continuous_buffered_sample_callback(continuous_buffered_sample_cb, NULL); - if (err < RETURNCODE_SUCCESS) { - printf("set continuous buffered sample callback error: %d\n", err); - return -1; - } - // set main buffer for ADC samples - err = adc_set_buffer(sample_buffer1, BUF_SIZE); + err = libtock_adc_set_buffer(sample_buffer1, BUF_SIZE); if (err < RETURNCODE_SUCCESS) { printf("set buffer error: %d\n", err); return -1; @@ -140,7 +140,7 @@ int main(void) { // set secondary buffer for ADC samples. In continuous mode, the ADC will // automatically switch between the two each callback - err = adc_set_double_buffer(sample_buffer2, BUF_SIZE); + err = libtock_adc_set_double_buffer(sample_buffer2, BUF_SIZE); if (err < RETURNCODE_SUCCESS) { printf("set double buffer error: %d\n", err); return -1; @@ -149,7 +149,7 @@ int main(void) { // begin continuous sampling printf("Beginning continuous sampling on channel %d at %d Hz\n", ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY); - err = adc_continuous_sample(ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY); + err = libtock_adc_continuous_sample(ADC_CHANNEL, ADC_LOWSPEED_FREQUENCY, &callbacks); if (err < RETURNCODE_SUCCESS) { printf("continuous sample error: %d\n", err); return -1; diff --git a/examples/tests/spi/spi_byte/Makefile b/examples/tests/adc/adc_single_samples/Makefile similarity index 100% rename from examples/tests/spi/spi_byte/Makefile rename to examples/tests/adc/adc_single_samples/Makefile diff --git a/examples/tests/adc_single_samples/README.md b/examples/tests/adc/adc_single_samples/README.md similarity index 100% rename from examples/tests/adc_single_samples/README.md rename to examples/tests/adc/adc_single_samples/README.md diff --git a/examples/tests/adc_single_samples/main.c b/examples/tests/adc/adc_single_samples/main.c similarity index 70% rename from examples/tests/adc_single_samples/main.c rename to examples/tests/adc/adc_single_samples/main.c index c7e54411e..d829ec584 100644 --- a/examples/tests/adc_single_samples/main.c +++ b/examples/tests/adc/adc_single_samples/main.c @@ -3,23 +3,23 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include int main(void) { printf("[Tock] ADC Sample All Channels Test\n"); // check if ADC driver exists - if (!adc_exists()) { + if (!libtock_adc_exists()) { printf("No ADC driver!\n"); return -1; } int channel_count; - adc_channel_count(&channel_count); + libtock_adc_channel_count(&channel_count); printf("ADC driver exists with %d channels\n\n", channel_count); while (1) { @@ -29,7 +29,7 @@ int main(void) { for (uint8_t channel = 0; channel < channel_count; channel++) { uint16_t sample; - int err = adc_sample_sync(channel, &sample); + int err = libtocksync_adc_sample(channel, &sample); if (err != 0) { printf("ERROR READING ADC VALUE: %i\n", err); } @@ -38,7 +38,7 @@ int main(void) { } printf("\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } return 0; diff --git a/examples/tests/adc_single_samples/Makefile b/examples/tests/adc_single_samples/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/adc_single_samples/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/aes/main.c b/examples/tests/aes/main.c index a9467c581..95bbaef16 100644 --- a/examples/tests/aes/main.c +++ b/examples/tests/aes/main.c @@ -2,8 +2,7 @@ #include #include -#include -#include +#include #define KEY_LEN 16 #define IV_LEN 16 @@ -70,53 +69,53 @@ static void aes_ctr_test(void) { printf("[TEST] AES CTR Example Test\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_check_status()); + TOCK_EXPECT(true, libtock_aes_exists()); /*** Encryption ***/ // Set AES128Ctr as the encryption algorithm - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_algorithm(0, true)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_algorithm(0, true)); printf("Loading in the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_key_buffer(key_buf, KEY_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_key_buffer(key_buf, KEY_LEN)); printf(" done\r\n"); printf("Loading in the IV buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_iv_buffer(iv_buf, IV_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_iv_buffer(iv_buf, IV_LEN)); printf(" done\r\n"); printf("Loading in the first half of the source buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_source_buffer(&data_buf[0], DATA_LEN / 2)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_source_buffer(&data_buf[0], DATA_LEN / 2)); printf(" done\r\n"); printf("Setting up the first half of the dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_dest_buffer(&dest_buf[0], 128)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readwrite_allow_dest_buffer(&dest_buf[0], 128)); printf(" done\r\n"); printf("Setting up the callback...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_callback(aes_cb, &con)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_upcall(aes_cb, &con)); printf(" done\r\n"); printf("Starting the initial run...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_setup()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_setup()); printf(" done\r\n"); yield_for(&con); con = false; printf("Loading in second half of the source buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_source_buffer(&data_buf[DATA_LEN / 2], 128)); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_dest_buffer(&dest_buf[128], DEST_LEN - 128)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_source_buffer(&data_buf[DATA_LEN / 2], 128)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readwrite_allow_dest_buffer(&dest_buf[128], DEST_LEN - 128)); printf(" done\r\n"); printf("Running AES twice...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_crypt()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_crypt()); printf(" done\r\n"); yield_for(&con); con = false; printf("Finish AES operation...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_finish()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_finish()); printf(" done\r\n"); for (i = 0; i < CHECK_LEN; i++) { @@ -133,25 +132,25 @@ static void aes_ctr_test(void) { /*** Decryption ***/ // Set AES128Ctr as the decryption algorithm - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_algorithm(0, true)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_algorithm(0, true)); printf("Loading in the decryption source buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_source_buffer(dest_buf, DEST_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_source_buffer(dest_buf, DEST_LEN)); printf(" done\r\n"); printf("Setting up the decryption dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_dest_buffer(dest_buf, DEST_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readwrite_allow_dest_buffer(dest_buf, DEST_LEN)); printf(" done\r\n"); printf("Running decryption...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_setup()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_setup()); printf(" done\r\n"); yield_for(&con); con = false; printf("Finish AES operation...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_finish()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_finish()); printf(" done\r\n"); printf("Original text: '%s'\r\n", dest_buf); @@ -163,42 +162,42 @@ static void aes_ccm_test(void) { printf("[TEST] AES CCM Example Test\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_check_status()); + TOCK_EXPECT(true, libtock_aes_exists()); /*** Encryption ***/ // Set AES128CCM as the encryption algorithm - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_algorithm(3, true)); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_ccm_set_mic_len(8)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_algorithm(3, true)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_ccm_set_mic_len(8)); printf("Loading in the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_key_buffer(key_buf, KEY_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_key_buffer(key_buf, KEY_LEN)); printf(" done\r\n"); printf("Loading in the nonce buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_nonce_buffer(iv_buf, IV_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_nonce_buffer(iv_buf, IV_LEN)); printf(" done\r\n"); printf("Loading in the source buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_source_buffer(data_buf, 96)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_source_buffer(data_buf, 96)); printf(" done\r\n"); printf("Setting up the dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_dest_buffer(dest_buf, 96)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readwrite_allow_dest_buffer(dest_buf, 96)); printf(" done\r\n"); printf("Setting up the callback...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_callback(aes_cb, &con)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_upcall(aes_cb, &con)); printf(" done\r\n"); printf("Starting the initial run...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_setup()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_setup()); printf(" done\r\n"); yield_for(&con); con = false; printf("Finish AES operation...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_finish()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_finish()); printf(" done\r\n"); for (i = 0; i < 96; i++) { @@ -215,25 +214,25 @@ static void aes_ccm_test(void) { /*** Decryption ***/ // Set AES128CCM as the decryption algorithm - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_algorithm(3, false)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_algorithm(3, false)); printf("Loading in the decryption source buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_source_buffer(dest_buf, 96)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readonly_allow_source_buffer(dest_buf, 96)); printf(" done\r\n"); printf("Setting up the decryption dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_set_dest_buffer(dest_buf, 96)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_set_readwrite_allow_dest_buffer(dest_buf, 96)); printf(" done\r\n"); printf("Running decryption...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_setup()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_setup()); printf(" done\r\n"); yield_for(&con); con = false; printf("Finish AES operation...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, aes_finish()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_aes_finish()); printf(" done\r\n"); printf("Original text: '%s'\r\n", dest_buf); diff --git a/examples/tests/ambient_light/main.c b/examples/tests/ambient_light/main.c index 39ffc2aab..d10a427a1 100644 --- a/examples/tests/ambient_light/main.c +++ b/examples/tests/ambient_light/main.c @@ -1,8 +1,8 @@ #include -#include -#include -#include +#include +#include +#include int main (void) { printf("[Ambient Light] Test\n"); @@ -10,7 +10,7 @@ int main (void) { while (1) { // Start a light measurement int lux; - int ret = ambient_light_read_intensity_sync(&lux); + int ret = libtocksync_ambient_light_read_intensity(&lux); if (ret == RETURNCODE_ENODEVICE) { printf("ERROR: No ambient light sensor on this board.\n"); } else if (ret < 0) { @@ -19,6 +19,6 @@ int main (void) { // Print the lux value printf("\tValue(%d lux) [0x%X]\n\n", lux, lux); } - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/analog_comparator/main.c b/examples/tests/analog_comparator/main.c index 8731ac623..be2933584 100644 --- a/examples/tests/analog_comparator/main.c +++ b/examples/tests/analog_comparator/main.c @@ -2,9 +2,10 @@ #include #include -#include -#include -#include +#include +#include +#include + static int callback_channel; static void analog_comparator_comparison_polling(uint8_t channel) { @@ -12,14 +13,14 @@ static void analog_comparator_comparison_polling(uint8_t channel) { while (1) { count++; bool result; - analog_comparator_comparison(channel, &result); + libtock_analog_comparator_comparison(channel, &result); printf("Try %d. Result = %d.\n", count, result); if (result == 1) { printf("This means Vinp > Vinn!\n\n"); } else { printf("This means Vinp < Vinn!\n\n"); } - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } @@ -35,11 +36,11 @@ static void analog_comparator_callback (int arg0, static void analog_comparator_comparison_interrupt(uint8_t channel) { // Enable AC interrupts on the desired channel (i.e. two pins) - analog_comparator_start_comparing(channel); + libtock_analog_comparator_start_comparing(channel); static bool resume = 0; // Set callback for AC interrupts - analog_comparator_interrupt_callback(analog_comparator_callback, &resume); + libtock_analog_comparator_set_upcall(analog_comparator_callback, &resume); while (1) { yield_for(&resume); @@ -51,13 +52,13 @@ static void analog_comparator_comparison_interrupt(uint8_t channel) { int main(void) { printf("\nAnalog Comparator test application\n"); - if (!analog_comparator_exists()) { + if (!libtock_analog_comparator_exists()) { printf("Analog Comparator driver does not exist\n"); exit(1); } int count; - analog_comparator_count(&count); + libtock_analog_comparator_count(&count); printf("Analog Comparator driver exists with %d channels\n", count); // Set mode according to which implementation you want. diff --git a/examples/tests/app_state/main.c b/examples/tests/app_state/main.c index e30ba4e78..5aa1685fe 100644 --- a/examples/tests/app_state/main.c +++ b/examples/tests/app_state/main.c @@ -1,7 +1,7 @@ #include -#include -#include +#include +#include #define MAGIC 0xcafe @@ -20,12 +20,12 @@ struct demo_app_state_t { // `app_state_load_sync()`. It can the write the struct like any normal // variable. When the app wishes to "checkpoint" the state and write it back to // the persistent flash, it should call `app_state_save_sync()`. -APP_STATE_DECLARE(struct demo_app_state_t, app_state); +LIBTOCK_APP_STATE_DECLARE(struct demo_app_state_t, app_state); int main(void) { int ret; - ret = app_state_load_sync(); + ret = libtock_app_state_load(); if (ret < 0) { printf("Error loading application state: %s\n", tock_strrcode(ret)); return ret; @@ -44,7 +44,7 @@ int main(void) { app_state.count += 1; } - ret = app_state_save_sync(); + ret = libtocksync_app_state_save(); if (ret != 0) { printf("ERROR saving application state: %s\n", tock_strrcode(ret)); return ret; diff --git a/examples/tests/ble/ble_advertise/main.c b/examples/tests/ble/ble_advertise/main.c index 464c2761a..469b78ed5 100644 --- a/examples/tests/ble/ble_advertise/main.c +++ b/examples/tests/ble/ble_advertise/main.c @@ -1,7 +1,8 @@ -#include #include #include -#include + +#include +#include /******************************************************************************* * MAIN diff --git a/examples/tests/ble/ble_gap_library/main.c b/examples/tests/ble/ble_gap_library/main.c index 49ad3b656..94dfec443 100644 --- a/examples/tests/ble/ble_gap_library/main.c +++ b/examples/tests/ble/ble_gap_library/main.c @@ -1,9 +1,10 @@ -#include -#include #include #include -#include -#include + +#include + +#include +#include int test_off_by_one_name(void); int test_off_by_one_service_data(void); diff --git a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser1/main.c b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser1/main.c index caa626224..c0c4e9490 100644 --- a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser1/main.c +++ b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser1/main.c @@ -1,8 +1,11 @@ -#include -#include #include #include -#include + +#include + +#include +#include +#include int main(void) { static uint8_t adv_data_buf[ADV_DATA_MAX_SIZE]; @@ -10,11 +13,11 @@ int main(void) { // declarations of variables to be used in this BLE example application uint16_t advertising_interval_ms = 100; - uint8_t device_name[] = "Advertiser1"; + uint8_t device_name[] = "Advertiser1"; // configure device name as Advertiser1 printf(" - Setting the device name... %s\n", device_name); - int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name)-1); + int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name) - 1); if (err < RETURNCODE_SUCCESS) printf("ble_advertise_name, error: %s\r\n", tock_strrcode(err)); diff --git a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser2/main.c b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser2/main.c index 0f36735f9..81c83c1e3 100644 --- a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser2/main.c +++ b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser2/main.c @@ -1,8 +1,11 @@ -#include -#include #include #include -#include + +#include + +#include +#include +#include int main(void) { static uint8_t adv_data_buf[ADV_DATA_MAX_SIZE]; @@ -10,11 +13,11 @@ int main(void) { // declarations of variables to be used in this BLE example application uint16_t advertising_interval_ms = 300; - uint8_t device_name[] = "Advertiser2"; + uint8_t device_name[] = "Advertiser2"; // configure device name as Advertiser2 printf(" - Setting the device name... %s\n", device_name); - int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name)-1); + int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name) - 1); if (err < RETURNCODE_SUCCESS) printf("ble_advertise_name, error: %s\r\n", tock_strrcode(err)); diff --git a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser3/main.c b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser3/main.c index eed041f7d..5ade1b2dd 100644 --- a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser3/main.c +++ b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser3/main.c @@ -1,8 +1,11 @@ -#include -#include #include #include -#include + +#include + +#include +#include +#include int main(void) { static uint8_t adv_data_buf[ADV_DATA_MAX_SIZE]; @@ -10,11 +13,11 @@ int main(void) { // declarations of variables to be used in this BLE example application uint16_t advertising_interval_ms = 20; - uint8_t device_name[] = "Advertiser3"; + uint8_t device_name[] = "Advertiser3"; // configure device name as Advertiser3 printf(" - Setting the device name... %s\n", device_name); - int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name)-1); + int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name) - 1); if (err < RETURNCODE_SUCCESS) printf("ble_advertise_name, error: %s\r\n", tock_strrcode(err)); diff --git a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser4/main.c b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser4/main.c index f7e3ee90f..9393cbd4e 100644 --- a/examples/tests/ble/ble_nrf5x_concurrency/Advertiser4/main.c +++ b/examples/tests/ble/ble_nrf5x_concurrency/Advertiser4/main.c @@ -1,8 +1,11 @@ -#include -#include #include #include -#include + +#include + +#include +#include +#include int main(void) { static uint8_t adv_data_buf[ADV_DATA_MAX_SIZE]; @@ -10,11 +13,11 @@ int main(void) { // declarations of variables to be used in this BLE example application uint16_t advertising_interval_ms = 1000; - uint8_t device_name[] = "Advertiser4"; + uint8_t device_name[] = "Advertiser4"; // configure device name as Advertiser4 printf(" - Setting the device name... %s\n", device_name); - int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name)-1); + int err = gap_add_device_name(&adv_data, device_name, sizeof(device_name) - 1); if (err < RETURNCODE_SUCCESS) printf("ble_advertise_name, error: %s\r\n", tock_strrcode(err)); diff --git a/examples/tests/ble/ble_test_tx_power/main.c b/examples/tests/ble/ble_test_tx_power/main.c index f2a82c593..5ebc12d62 100644 --- a/examples/tests/ble/ble_test_tx_power/main.c +++ b/examples/tests/ble/ble_test_tx_power/main.c @@ -1,9 +1,9 @@ -#include -#include #include #include -#include -#include + +#include +#include +#include #define NRF5X_POS_4_DBM 0x04 #define NRF5X_POS_3_DBM 0x03 diff --git a/examples/tests/button_print/main.c b/examples/tests/button_print/main.c index 7ee6be585..e6208b33e 100644 --- a/examples/tests/button_print/main.c +++ b/examples/tests/button_print/main.c @@ -1,36 +1,30 @@ #include -#include -#include +#include -// Callback for button presses. -// btn_num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_callback(__attribute__ ((unused)) int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - if (val == 1) { - printf("Button Press! App address: %p\n", tock_app_flash_begins_at()); +static void button_callback(returncode_t ret, + int btn_num, + bool val) { + if (val) { + printf("Button Press! Button: %i Status: %i\n", btn_num, ret); + printf("App address: %p\n", tock_app_flash_begins_at()); } } int main(void) { - button_subscribe(button_callback, NULL); + returncode_t ret; + printf("[TEST] Button Press\n"); - // Enable interrupts on each button. - int count; - button_count(&count); - if (count < 0) { - printf("Error detecting buttons: %i\n", count); - return -1; - } else if (count < 1) { + if (!libtock_button_exists()) { printf("No buttons on this board!\n"); return -2; } - // Enable the button interrupt - button_enable_interrupt(0); + ret = libtock_button_notify_on_press(0, button_callback); + if (ret != RETURNCODE_SUCCESS) { + printf("Could not subscribe to button presses.\n"); + return -3; + } while (1) { yield(); diff --git a/examples/tests/callback_remove_test01/main.c b/examples/tests/callback_remove_test01/main.c index d022601dc..a2faaadb2 100644 --- a/examples/tests/callback_remove_test01/main.c +++ b/examples/tests/callback_remove_test01/main.c @@ -1,14 +1,15 @@ #include #include -#include -#include +#include volatile int a = 0; int b = 0; bool callback_fired = false; +// NOTE: This test intentionally uses the direct, low-level +// alarm APIs instead of the virtualised interface. static void cb(__attribute__ ((unused)) int now, __attribute__ ((unused)) int expiration, __attribute__ ((unused)) int unused, @@ -27,12 +28,12 @@ int main(void) { // Setup an alarm for 500 ms in the future. uint32_t frequency; - alarm_internal_frequency(&frequency); + libtock_alarm_command_get_frequency(&frequency); uint32_t interval = (500 / 1000) * frequency + (500 % 1000) * (frequency / 1000); uint32_t now; - alarm_internal_read(&now); - alarm_internal_subscribe((subscribe_upcall*) cb, NULL); - alarm_internal_set(now, interval); + libtock_alarm_command_read(&now); + libtock_alarm_set_upcall((subscribe_upcall*) cb, NULL); + libtock_alarm_command_set_absolute(now, interval); // Now block in this app for a while. This should give the timer time to // expire but not allow the kernel to deliver the callback to us just yet. @@ -43,14 +44,14 @@ int main(void) { // Eventually we disable the callback. If things have gone the way this test // hopes, then the callback for the timer should be pending when this gets // called. - alarm_internal_subscribe(NULL, NULL); + libtock_alarm_set_upcall(NULL, NULL); // Set a flag so we are sure that we have unsubscribed from the callback (aka - // `alarm_internal_subscribe` has returned). + // `libtock_alarm_set_upcall` has returned). b = 1; // Wait for a bit...if the callback doesn't fire then this test succeeded! - yield_for_with_timeout(&callback_fired, 2000); + libtocksync_alarm_yield_for_with_timeout(&callback_fired, 2000); if (callback_fired == false) { printf("[SUCCESS] The callback was successfully canceled\n"); } diff --git a/examples/tests/console/Makefile b/examples/tests/console/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/console/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/adc_continuous/Makefile b/examples/tests/console/console/Makefile similarity index 89% rename from examples/tests/adc_continuous/Makefile rename to examples/tests/console/console/Makefile index 54d6a7969..b9cdd0fa3 100644 --- a/examples/tests/adc_continuous/Makefile +++ b/examples/tests/console/console/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/console/README.md b/examples/tests/console/console/README.md similarity index 100% rename from examples/tests/console/README.md rename to examples/tests/console/console/README.md diff --git a/examples/tests/console/main.c b/examples/tests/console/console/main.c similarity index 66% rename from examples/tests/console/main.c rename to examples/tests/console/console/main.c index 03564b253..61b5f43bc 100644 --- a/examples/tests/console/main.c +++ b/examples/tests/console/console/main.c @@ -3,7 +3,14 @@ #include #include -#include +#include + +static int getch(void) { + uint8_t buffer[1]; + int number_read; + libtocksync_console_read(buffer, 1, &number_read); + return buffer[0]; +} int main(void) { // Repeatedly read a character from the console diff --git a/examples/tests/adc/Makefile b/examples/tests/console/console_recv_long/Makefile similarity index 89% rename from examples/tests/adc/Makefile rename to examples/tests/console/console_recv_long/Makefile index 54d6a7969..b9cdd0fa3 100644 --- a/examples/tests/adc/Makefile +++ b/examples/tests/console/console_recv_long/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/console_recv_long/README.md b/examples/tests/console/console_recv_long/README.md similarity index 100% rename from examples/tests/console_recv_long/README.md rename to examples/tests/console/console_recv_long/README.md diff --git a/examples/tests/console/console_recv_long/main.c b/examples/tests/console/console_recv_long/main.c new file mode 100644 index 000000000..2a3d5afa6 --- /dev/null +++ b/examples/tests/console/console_recv_long/main.c @@ -0,0 +1,22 @@ +#include + +#include + +uint8_t buf[100]; + +int main(void) { + int number_read; + int ret = libtocksync_console_read(buf, 61, &number_read); + if (ret != RETURNCODE_SUCCESS) { + printf("[SHORT] Error doing UART receive: %i\n", ret); + return -1; + } + + printf("\n\nconsole_recv_long: "); + for (int i = 0; i < number_read; i++) { + printf("%c", buf[i]); + } + printf("\n"); + + return 0; +} diff --git a/examples/rtc_app/Makefile b/examples/tests/console/console_recv_short/Makefile similarity index 89% rename from examples/rtc_app/Makefile rename to examples/tests/console/console_recv_short/Makefile index 2ba0a589a..b9cdd0fa3 100644 --- a/examples/rtc_app/Makefile +++ b/examples/tests/console/console_recv_short/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../ +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/console_recv_short/README.md b/examples/tests/console/console_recv_short/README.md similarity index 100% rename from examples/tests/console_recv_short/README.md rename to examples/tests/console/console_recv_short/README.md diff --git a/examples/tests/console/console_recv_short/main.c b/examples/tests/console/console_recv_short/main.c new file mode 100644 index 000000000..97a3569ca --- /dev/null +++ b/examples/tests/console/console_recv_short/main.c @@ -0,0 +1,22 @@ +#include + +#include + +uint8_t buf[100]; + +int main(void) { + int number_read; + int ret = libtocksync_console_read(buf, 11, &number_read); + if (ret != RETURNCODE_SUCCESS) { + printf("[SHORT] Error doing UART receive: %i\n", ret); + return -1; + } + + printf("\n\nconsole_recv_short: "); + for (int i = 0; i < number_read; i++) { + printf("%c", buf[i]); + } + printf("\n"); + + return 0; +} diff --git a/examples/tests/console/console_timeout/Makefile b/examples/tests/console/console_timeout/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/console/console_timeout/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/console_timeout/README.md b/examples/tests/console/console_timeout/README.md similarity index 95% rename from examples/tests/console_timeout/README.md rename to examples/tests/console/console_timeout/README.md index 5789acae1..89a0789d2 100644 --- a/examples/tests/console_timeout/README.md +++ b/examples/tests/console/console_timeout/README.md @@ -2,7 +2,7 @@ Console Receive Timeout Test ======================= This app tests canceling asynchronous reads from the console. The application -reads from the console and sets a 5 second time. When the timer fires, it +reads from the console and sets a 5 second time. When the alarm fires, it aborts the read from the console. If aborts are working correctly, this should result in a receive callback containing anything that was read so far. diff --git a/examples/tests/console/console_timeout/main.c b/examples/tests/console/console_timeout/main.c new file mode 100644 index 000000000..20fb72463 --- /dev/null +++ b/examples/tests/console/console_timeout/main.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +#include +#include + +char buf[100]; + +libtock_alarm_t t; + +static void getnstr_cb(returncode_t result __attribute__ ((unused)), + uint32_t len) { + printf("Userspace call to read console returned: "); + for (uint32_t i = 0; i < len; i++) { + printf("%c", buf[i]); + } + printf("\n"); + + exit(0); +} + +static void alarm_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { + libtock_console_abort_read(); +} + +int main(void) { + + int ret = libtock_console_read((uint8_t*) buf, 60, getnstr_cb); + if (ret != RETURNCODE_SUCCESS) { + printf("Error doing UART receive.\n"); + } + + // Generate a timeout to abort the receive call. + libtock_alarm_in_ms(5000, alarm_cb, NULL, &t); + + while (1) { + yield(); + } +} diff --git a/examples/tests/console_recv_long/Makefile b/examples/tests/console_recv_long/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/console_recv_long/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/console_recv_long/main.c b/examples/tests/console_recv_long/main.c deleted file mode 100644 index a7679627b..000000000 --- a/examples/tests/console_recv_long/main.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include - -#include - -char buf[100]; - -static void getnstr_cb(int result __attribute__ ((unused)), - int len, - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - printf("\n\nconsole_recv_long: "); - for (int i = 0; i < len; i++) { - printf("%c", buf[i]); - } - printf("\n"); -} - - -int main(void) { - int ret = getnstr_async(buf, 61, getnstr_cb, NULL); - if (ret != RETURNCODE_SUCCESS) { - printf("[LONG] Error doing UART receive: %i\n", ret); - return -1; - } - - return 0; -} diff --git a/examples/tests/console_recv_short/Makefile b/examples/tests/console_recv_short/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/console_recv_short/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/console_recv_short/main.c b/examples/tests/console_recv_short/main.c deleted file mode 100644 index 2198537ba..000000000 --- a/examples/tests/console_recv_short/main.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include - -#include - -char buf[100]; - -static void getnstr_cb(int result __attribute__ ((unused)), - int len, - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - printf("\n\nconsole_recv_short: "); - for (int i = 0; i < len; i++) { - printf("%c", buf[i]); - } - printf("\n"); -} - - -int main(void) { - int ret = getnstr_async(buf, 11, getnstr_cb, NULL); - if (ret != RETURNCODE_SUCCESS) { - printf("[SHORT] Error doing UART receive: %i\n", ret); - return -1; - } - - return 0; -} diff --git a/examples/tests/console_timeout/Makefile b/examples/tests/console_timeout/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/console_timeout/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/console_timeout/main.c b/examples/tests/console_timeout/main.c deleted file mode 100644 index ea3cec538..000000000 --- a/examples/tests/console_timeout/main.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -char buf[100]; - -tock_timer_t t; - -static void getnstr_cb(int result __attribute__ ((unused)), - int len, - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - printf("Userspace call to read console returned: "); - for (int i = 0; i < len; i++) { - printf("%c", buf[i]); - } - printf("\n"); -} - -static void timer_cb(int result __attribute__ ((unused)), - int _y __attribute__ ((unused)), - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - getnstr_abort(); - - exit(0); -} - -int main(void) { - - int ret = getnstr_async(buf, 60, getnstr_cb, NULL); - if (ret != RETURNCODE_SUCCESS) { - printf("Error doing UART receive.\n"); - } - - // Generate a timeout to abort the receive call. - timer_in(5000, timer_cb, NULL, &t); - - while (1) { - yield(); - } -} diff --git a/examples/tests/crash_dummy/main.c b/examples/tests/crash_dummy/main.c index 21ecc30d3..d8eace0aa 100644 --- a/examples/tests/crash_dummy/main.c +++ b/examples/tests/crash_dummy/main.c @@ -1,19 +1,17 @@ // Crash on button press. -#include +#include volatile int* nullptr = 0; -static void button_callback(__attribute__ ((unused)) int btn_num, - __attribute__ ((unused)) int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { +static void button_callback(__attribute__ ((unused)) returncode_t ret, + __attribute__ ((unused)) int btn_num, + __attribute__ ((unused)) bool val) { __attribute__ ((unused)) volatile int k = *nullptr; } int main(void) { - button_subscribe(button_callback, NULL); - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); while (1) { yield(); diff --git a/examples/tests/crc/main.c b/examples/tests/crc/main.c index 82f7a9cbb..fc831b89b 100644 --- a/examples/tests/crc/main.c +++ b/examples/tests/crc/main.c @@ -2,12 +2,12 @@ #include #include -#include -#include -#include +#include +#include +#include struct test_case { - enum crc_alg alg; + libtock_crc_alg_t alg; uint32_t output; char *input; }; @@ -34,13 +34,13 @@ int main(void) { // Get a random number to distinguish this app instance int num_bytes; - r = rng_sync((uint8_t *) &procid, 4, 4, &num_bytes); + r = libtocksync_rng_get_random_bytes((uint8_t *) &procid, 4, 4, &num_bytes); if (r != RETURNCODE_SUCCESS || num_bytes != 4) { printf("RNG failure\n"); exit(1); } - if (!crc_exists()) { + if (!libtock_crc_exists()) { printf("CRC driver does not exist\n"); exit(1); } @@ -49,7 +49,7 @@ int main(void) { for (int test_index = 0; test_index < n_test_cases; test_index++) { struct test_case *t = &test_cases[test_index]; uint32_t result; - if ((r = crc_compute(t->input, strlen(t->input), t->alg, &result)) != RETURNCODE_SUCCESS) { + if ((r = libtocksync_crc_compute((uint8_t*) t->input, strlen(t->input), t->alg, &result)) != RETURNCODE_SUCCESS) { printf("CRC compute failed: %s\n", tock_strrcode(r)); exit(1); } @@ -69,6 +69,6 @@ int main(void) { } printf("\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/crc/test_cases.h b/examples/tests/crc/test_cases.h index 86438eb5f..e7d25f3d7 100644 --- a/examples/tests/crc/test_cases.h +++ b/examples/tests/crc/test_cases.h @@ -17,31 +17,31 @@ // Polynomial: 0x1021, no post-processing -CASE(CRC_16CCITT, 0x00001541, "ABCDEFG") -CASE(CRC_16CCITT, 0x0000B34B, "ABCD") -CASE(CRC_16CCITT, 0x00001C2D, "0123456") -CASE(CRC_16CCITT, 0x0000D5A8, "0123") -CASE(CRC_16CCITT, 0x0000C21F, "01234567") -CASE(CRC_16CCITT, 0x000035B3, "012345678") -CASE(CRC_16CCITT, 0x000057C4, "01234567A") -CASE(CRC_16CCITT, 0x0000E06E, "01234567ABCDE") -CASE(CRC_16CCITT, 0x0000EC86, "0000000000000") -CASE(CRC_16CCITT, 0x00007B2E, "00000000000000") -CASE(CRC_16CCITT, 0x0000DFCA, "01234567ABCDEF") -CASE(CRC_16CCITT, 0x00002DFE, "01234567ABCDEFG") -CASE(CRC_16CCITT, 0x000039BC, "01234567ABCDEFGH") -CASE(CRC_16CCITT, 0x0000B881, "01234567ABCDEFGHI") +CASE(LIBTOCK_CRC_16CCITT, 0x00001541, "ABCDEFG") +CASE(LIBTOCK_CRC_16CCITT, 0x0000B34B, "ABCD") +CASE(LIBTOCK_CRC_16CCITT, 0x00001C2D, "0123456") +CASE(LIBTOCK_CRC_16CCITT, 0x0000D5A8, "0123") +CASE(LIBTOCK_CRC_16CCITT, 0x0000C21F, "01234567") +CASE(LIBTOCK_CRC_16CCITT, 0x000035B3, "012345678") +CASE(LIBTOCK_CRC_16CCITT, 0x000057C4, "01234567A") +CASE(LIBTOCK_CRC_16CCITT, 0x0000E06E, "01234567ABCDE") +CASE(LIBTOCK_CRC_16CCITT, 0x0000EC86, "0000000000000") +CASE(LIBTOCK_CRC_16CCITT, 0x00007B2E, "00000000000000") +CASE(LIBTOCK_CRC_16CCITT, 0x0000DFCA, "01234567ABCDEF") +CASE(LIBTOCK_CRC_16CCITT, 0x00002DFE, "01234567ABCDEFG") +CASE(LIBTOCK_CRC_16CCITT, 0x000039BC, "01234567ABCDEFGH") +CASE(LIBTOCK_CRC_16CCITT, 0x0000B881, "01234567ABCDEFGHI") // Polynomial: 0x04C11DB7, output reversed then inverted -CASE(CRC_32, 0x0E6F94BC, "ABCDEFG") -CASE(CRC_32, 0xA6669D7D, "0123") -CASE(CRC_32, 0x44050CDA, "A man, a plan, a canal, Panama") -CASE(CRC_32, 0x595B8BC2, "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 ") - +CASE(LIBTOCK_CRC_32, 0x0E6F94BC, "ABCDEFG") +CASE(LIBTOCK_CRC_32, 0xA6669D7D, "0123") +CASE(LIBTOCK_CRC_32, 0x44050CDA, "A man, a plan, a canal, Panama") +CASE(LIBTOCK_CRC_32, 0x595B8BC2, "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 ") + // Polynomial 0x1EDC6F41, output reversed then inverted -CASE(CRC_32C, 0x2C775665, "ABCDEFG") -CASE(CRC_32C, 0x063962B9, "0123") -CASE(CRC_32C, 0xB5DDEB44, "A man, a plan, a canal, Panama") +CASE(LIBTOCK_CRC_32C, 0x2C775665, "ABCDEFG") +CASE(LIBTOCK_CRC_32C, 0x063962B9, "0123") +CASE(LIBTOCK_CRC_32C, 0xB5DDEB44, "A man, a plan, a canal, Panama") diff --git a/examples/tests/dac/main.c b/examples/tests/dac/main.c index 34d112fba..a40487141 100644 --- a/examples/tests/dac/main.c +++ b/examples/tests/dac/main.c @@ -1,8 +1,8 @@ #include -#include -#include -#include +#include +#include +#include uint16_t sine_samples[100] = { 512, 544, 576, 607, 639, 670, 700, 729, 758, 786, @@ -18,11 +18,11 @@ uint16_t sine_samples[100] = { }; int main(void) { - int ret; + returncode_t ret; - printf("[DAC] Sine test app\n"); + printf("[TEST] DAC: Sine test app\n"); - ret = dac_initialize(); + ret = libtock_dac_initialize(); if (ret != RETURNCODE_SUCCESS) { printf("ERROR initializing DAC\n"); return 1; @@ -30,12 +30,12 @@ int main(void) { while (1) { for (int i = 0; i < 100; i++) { - ret = dac_set_value(sine_samples[i]); + ret = libtock_dac_set_value(sine_samples[i]); if (ret != RETURNCODE_SUCCESS) { printf("ERROR setting DAC value\n"); return 1; } - delay_ms(100); + libtocksync_alarm_delay_ms(100); } } diff --git a/examples/tests/eui64/main.c b/examples/tests/eui64/main.c index 2e5c69b12..4fe43a876 100644 --- a/examples/tests/eui64/main.c +++ b/examples/tests/eui64/main.c @@ -1,6 +1,6 @@ #include -#include +#include int main(void) { int ret; diff --git a/examples/tests/exit/main.c b/examples/tests/exit/main.c index 97b64585a..12312ad4e 100644 --- a/examples/tests/exit/main.c +++ b/examples/tests/exit/main.c @@ -1,11 +1,11 @@ #include -#include -#include +#include +#include int main(void) { printf("Testing exit.\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Exiting.\n"); tock_exit(0); printf("SHOULD NOT BE PRINTED.\n"); diff --git a/examples/tests/fault/main.c b/examples/tests/fault/main.c index daa828459..039ef2dbb 100644 --- a/examples/tests/fault/main.c +++ b/examples/tests/fault/main.c @@ -1,11 +1,11 @@ #include -#include -#include +#include +#include int main(void) { printf("Testing fault behavior by faulting.\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); int* x = (int*)(0xffffff00); *x = 1; } diff --git a/examples/tests/fxos8700cq/Makefile b/examples/tests/fxos8700cq/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/fxos8700cq/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/fxos8700cq/main.c b/examples/tests/fxos8700cq/main.c deleted file mode 100644 index 1c2d56ccb..000000000 --- a/examples/tests/fxos8700cq/main.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ninedof.h" - -const double g = -9.8; - -// Step counter app -// TODO get sqrt working -int main(void) { - printf("Step counter init\n"); - unsigned num_measurements = 100; - double accel_mags[num_measurements]; - - for (unsigned ii = 0; ii < num_measurements; ii++) { - unsigned accel_mag = ninedof_read_accel_mag(); - printf("accel square = %u\n", accel_mag); - printf("********************\n"); - accel_mags[ii] = accel_mag + g; - delay_ms(2000); - } - - unsigned steps = 0; - for (unsigned ii = 0; ii < num_measurements - 1; ii++) { - if (accel_mags[ii] < 0 && accel_mags[ii + 1] > 0) { - // step occurred - steps++; - } - } - - printf("%u steps occurred.\n", steps); - - return 0; -} diff --git a/examples/tests/gpio/Makefile b/examples/tests/gpio/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/gpio/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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_interrupt/Makefile b/examples/tests/gpio/gpio_interrupt/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/gpio/gpio_interrupt/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_interrupt/README.md b/examples/tests/gpio/gpio_interrupt/README.md similarity index 100% rename from examples/tests/gpio_interrupt/README.md rename to examples/tests/gpio/gpio_interrupt/README.md diff --git a/examples/tests/gpio/gpio_interrupt/main.c b/examples/tests/gpio/gpio_interrupt/main.c new file mode 100644 index 000000000..0d143e362 --- /dev/null +++ b/examples/tests/gpio/gpio_interrupt/main.c @@ -0,0 +1,27 @@ +#include + +#include +#include +#include + +static void gpio_cb (__attribute__ ((unused)) uint32_t pin_num, + __attribute__ ((unused)) bool val) {} + +int main(void) { + printf("[Test] GPIO Interrupt\n"); + printf("Jump GPIO pin 0 high to test.\n"); + + // set callback for GPIO interrupts + libtock_gpio_set_interrupt_callback(gpio_cb); + + // set GPIO 0 as input and enable interrupts on it + libtock_gpio_enable_input(0, libtock_pull_down); + libtock_gpio_enable_interrupt(0, libtock_change); + + while (1) { + yield(); + printf("\tGPIO Interrupt! (App: %p)\n", tock_app_flash_begins_at()); + } + + return 0; +} diff --git a/examples/tests/gpio/gpio_loopback_test/Makefile b/examples/tests/gpio/gpio_loopback_test/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/gpio/gpio_loopback_test/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_loopback_test/README.md b/examples/tests/gpio/gpio_loopback_test/README.md similarity index 100% rename from examples/tests/gpio_loopback_test/README.md rename to examples/tests/gpio/gpio_loopback_test/README.md diff --git a/examples/tests/gpio_loopback_test/main.c b/examples/tests/gpio/gpio_loopback_test/main.c similarity index 79% rename from examples/tests/gpio_loopback_test/main.c rename to examples/tests/gpio/gpio_loopback_test/main.c index eb894b00a..57fa1c7ab 100644 --- a/examples/tests/gpio_loopback_test/main.c +++ b/examples/tests/gpio/gpio_loopback_test/main.c @@ -3,22 +3,21 @@ #include #include -#include -#include -#include +#include +#include +#include -int loopback(GPIO_Pin_t out, GPIO_Pin_t in); -int loopback(GPIO_Pin_t out, GPIO_Pin_t in) { +static int loopback(uint32_t out, uint32_t in) { int ret; // Setup pin directions - ret = gpio_enable_output(out); + ret = libtock_gpio_enable_output(out); if (ret != RETURNCODE_SUCCESS) { printf("ERROR: Unable to configure output: %s\n", tock_strrcode(ret)); return -1; } - ret = gpio_enable_input(in, PullNone); + ret = libtock_gpio_enable_input(in, libtock_pull_none); if (ret != RETURNCODE_SUCCESS) { printf("ERROR: Unable to configure input: %s\n", tock_strrcode(ret)); return -1; @@ -26,14 +25,14 @@ int loopback(GPIO_Pin_t out, GPIO_Pin_t in) { for (int i = 0; i < 10; i++) { if (i % 2) { - ret = gpio_set(out); + ret = libtock_gpio_set(out); if (ret != RETURNCODE_SUCCESS) { printf("ERROR: Unable to set output: %s\n", tock_strrcode(ret)); return -1; } int read; - ret = gpio_read(in, &read); + ret = libtock_gpio_read(in, &read); if (ret < 0) { printf("ERROR: Unable to read input: %s\n", tock_strrcode(ret)); return -1; @@ -44,14 +43,14 @@ int loopback(GPIO_Pin_t out, GPIO_Pin_t in) { return -1; } } else { - ret = gpio_clear(out); + ret = libtock_gpio_clear(out); if (ret != RETURNCODE_SUCCESS) { printf("ERROR: Unable to clear output: %s\n", tock_strrcode(ret)); return -1; } int read; - ret = gpio_read(in, &read); + ret = libtock_gpio_read(in, &read); if (ret < 0) { printf("ERROR: Unable to read input: %s\n", tock_strrcode(ret)); return -1; @@ -63,7 +62,7 @@ int loopback(GPIO_Pin_t out, GPIO_Pin_t in) { } } - delay_ms(300); + libtocksync_alarm_delay_ms(300); } printf("SUCCESS\n"); @@ -74,12 +73,12 @@ int main(void) { int ret; printf("******************************\n"); - printf("GPIO Loopback Test Application\n"); + printf("[TEST] GPIO Loopback\n"); printf("******************************\n"); // Check that we have two GPIO pins to connect. int count; - gpio_count(&count); + libtock_gpio_count(&count); if (count < 2) { printf("ERROR: This board does not have at least two GPIO pins for this test.\n"); return -1; diff --git a/examples/tests/gpio/gpio_original/Makefile b/examples/tests/gpio/gpio_original/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/gpio/gpio_original/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/README.md b/examples/tests/gpio/gpio_original/README.md similarity index 100% rename from examples/tests/gpio/README.md rename to examples/tests/gpio/gpio_original/README.md diff --git a/examples/tests/gpio/main.c b/examples/tests/gpio/gpio_original/main.c similarity index 56% rename from examples/tests/gpio/main.c rename to examples/tests/gpio/gpio_original/main.c index 1d18ccf07..a5f45322e 100644 --- a/examples/tests/gpio/main.c +++ b/examples/tests/gpio/gpio_original/main.c @@ -15,20 +15,24 @@ #include #include -#include -#include -#include -#include -#include - -int callback_count = 0; -// callback for timers -static void timer_cb (__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* userdata) { - callback_count = callback_count + 1; - *((bool*)userdata) = 1; +#include +#include +#include +#include +#include + +struct alarm_cb_data { + bool fired; + int callback_count; +}; + +static struct alarm_cb_data data = { .fired = false, .callback_count = 0 }; + +static void alarm_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { + data.callback_count = data.callback_count + 1; + data.fired = true; } // ************************************************** @@ -37,16 +41,16 @@ static void timer_cb (__attribute__ ((unused)) int arg0, static void gpio_output(void) { printf("Periodically toggling pin\n"); - gpio_enable_output(0); - // Start repeating timer - static bool resume = 0; - tock_timer_t timer; - timer_every(1000, timer_cb, &resume, &timer); + libtock_gpio_enable_output(0); + // Start repeating alarm + data.fired = false; + libtock_alarm_repeating_t alarm_repeating; + libtock_alarm_repeating_every(1000, alarm_cb, NULL, &alarm_repeating); while (1) { - yield_for(&resume); - resume = 0; - gpio_toggle(0); + yield_for(&data.fired); + data.fired = false; + libtock_gpio_toggle(0); } } @@ -57,31 +61,30 @@ static void gpio_input(void) { printf("Periodically reading value of the GPIO 0 pin\n"); printf("Jump pin high to test (defaults to low)\n"); - // set userspace pin 0 as input and start repeating timer + // set userspace pin 0 as input and start repeating alarm // pin is configured with a pull-down resistor, so it should read 0 as default - gpio_enable_input(0, PullDown); - tock_timer_t timer; - static bool resume = 0; - timer_every(500, timer_cb, &resume, &timer); + libtock_gpio_enable_input(0, libtock_pull_down); + libtock_alarm_repeating_t alarm_repeating; + data.fired = false; + libtock_alarm_repeating_every(500, alarm_cb, NULL, &alarm_repeating); while (1) { // print pin value int pin_val; - gpio_read(0, &pin_val); + libtock_gpio_read(0, &pin_val); printf("\tValue(%d)\n", pin_val); - yield_for(&resume); - resume = 0; + yield_for(&data.fired); + data.fired = 0; } } // ************************************************** // GPIO interrupt example // ************************************************** -static void gpio_cb (__attribute__ ((unused)) int pin_num, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void* userdata) { - *((bool*) userdata) = true; +static bool gpio_interrupt_fired = false; +static void gpio_cb (__attribute__ ((unused)) uint32_t pin_num, + __attribute__ ((unused)) bool arg2) { + gpio_interrupt_fired = true; } static void gpio_interrupt(void) { @@ -89,16 +92,16 @@ static void gpio_interrupt(void) { printf("Jump pin high to test\n"); // set callback for GPIO interrupts - static bool resume = 0; - gpio_interrupt_callback(gpio_cb, &resume); + libtock_gpio_set_interrupt_callback(gpio_cb); // set userspace pin 0 as input and enable interrupts on it - gpio_enable_input(0, PullDown); - gpio_enable_interrupt(0, Change); + libtock_gpio_enable_input(0, libtock_pull_down); + libtock_gpio_enable_interrupt(0, libtock_change); + gpio_interrupt_fired = false; while (1) { - yield_for(&resume); - resume = 0; + yield_for(&gpio_interrupt_fired); + gpio_interrupt_fired = false; printf("\tGPIO Interrupt!\n"); } } diff --git a/examples/tests/gpio_async/main.c b/examples/tests/gpio_async/main.c index 0905c05bf..54c593440 100644 --- a/examples/tests/gpio_async/main.c +++ b/examples/tests/gpio_async/main.c @@ -1,40 +1,36 @@ #include -#include -#include -#include +#include +#include int interrupt_count = 0; -static void gpio_async_cb(__attribute__ ((unused)) int callback_type, - __attribute__ ((unused)) int value, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) void* ud) { - printf("INTERRUPT\n"); +static void gpio_async_cb(uint32_t port, uint32_t pin, bool value) { + printf("INTERRUPT port:%li pin:%li val:%i\n", port, pin, value); interrupt_count++; if (interrupt_count > 5) { printf("Now disabling interrupt\n"); - gpio_async_disable_interrupt(0, 1); + libtocksync_gpio_async_disable_interrupt(0, 1); } } int main (void) { - printf("GPIO Async Test App\n"); + printf("[TEST] GPIO Async\n"); printf("Enabling rising edge interrupt on port 0 pin 1\n"); - gpio_async_interrupt_callback(gpio_async_cb, NULL); - gpio_async_make_input_sync(0, 1, PullNone); - gpio_async_enable_interrupt(0, 1, RisingEdge); + libtock_gpio_async_set_interrupt_callback(gpio_async_cb); + libtocksync_gpio_async_make_input(0, 1, libtock_pull_none); + libtocksync_gpio_async_enable_interrupt(0, 1, libtock_rising_edge); printf("Toggling port 0 pin 0\n"); - gpio_async_make_output_sync(0, 0); + libtocksync_gpio_async_make_output(0, 0); while (1) { - gpio_async_set(0, 0); - delay_ms(500); - gpio_async_clear(0, 0); - delay_ms(500); + libtocksync_gpio_async_set(0, 0); + libtocksync_alarm_delay_ms(500); + libtocksync_gpio_async_clear(0, 0); + libtocksync_alarm_delay_ms(500); } return 0; diff --git a/examples/tests/gpio_interrupt/Makefile b/examples/tests/gpio_interrupt/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/gpio_interrupt/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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_interrupt/main.c b/examples/tests/gpio_interrupt/main.c deleted file mode 100644 index 2a7c53602..000000000 --- a/examples/tests/gpio_interrupt/main.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#include -#include -#include - -static void gpio_cb (__attribute__ ((unused)) int pin_num, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - __attribute__ ((unused)) void* userdata) {} - -int main(void) { - printf("[GPIO Interrupt Test]\n"); - printf("Jump GPIO pin 0 high to test.\n"); - - // set callback for GPIO interrupts - gpio_interrupt_callback(gpio_cb, NULL); - - // set GPIO 0 as input and enable interrupts on it - gpio_enable_input(0, PullDown); - gpio_enable_interrupt(0, Change); - - while (1) { - yield(); - printf("\tGPIO Interrupt! (App: %p)\n", tock_app_flash_begins_at()); - } - - return 0; -} diff --git a/examples/tests/gpio_loopback_test/Makefile b/examples/tests/gpio_loopback_test/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/gpio_loopback_test/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/hail/main.c b/examples/tests/hail/main.c index edbc7d1e7..60d6428e5 100644 --- a/examples/tests/hail/main.c +++ b/examples/tests/hail/main.c @@ -8,18 +8,18 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ///////////////////////////////////////////////////////////////////// @@ -62,71 +62,69 @@ void ble_address_set (void) { // Callback for button presses. // btn_num: The index of the button associated with the callback // val: 1 if pressed, 0 if depressed -static void button_callback(__attribute__ ((unused)) int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { +static void button_callback(__attribute__ ((unused)) returncode_t ret, + __attribute__ ((unused)) int btn_num, + bool val) { if (val == 1) { - led_on(1); // green + libtock_led_on(1); // green } else { - led_off(1); + libtock_led_off(1); } } // Callback for gpio interrupts. // - pin_num: The index of the pin associated with the callback. // - pin_state: 1 if high, 0 if low. -static void gpio_callback( int pin_num, - int pin_state, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - printf("GPIO Interrupt: pin: %i, state: %i\n", pin_num, pin_state); +static void gpio_callback( uint32_t pin_num, + bool pin_state) { + printf("GPIO Interrupt: pin: %li, state: %i\n", pin_num, pin_state); } static void sample_sensors (void) { // Sensors: temperature/humidity, acceleration, light int temp; - temperature_read_sync(&temp); - unsigned humi; - humidity_read_sync(&humi); - uint32_t accel_mag = ninedof_read_accel_mag(); + libtocksync_temperature_read(&temp); + int humi; + libtocksync_humidity_read(&humi); + double accel_mag; + libtocksync_ninedof_read_accelerometer_magnitude(&accel_mag); int light; - ambient_light_read_intensity_sync(&light); + libtocksync_ambient_light_read_intensity(&light); // Analog inputs: A0-A5 uint16_t val; - adc_sample_sync(0, &val); + libtocksync_adc_sample(0, &val); int a0 = (val * 3300) / (4095 << 4); - adc_sample_sync(1, &val); + libtocksync_adc_sample(1, &val); int a1 = (val * 3300) / (4095 << 4); - adc_sample_sync(2, &val); + libtocksync_adc_sample(2, &val); int a2 = (val * 3300) / (4095 << 4); - adc_sample_sync(3, &val); + libtocksync_adc_sample(3, &val); int a3 = (val * 3300) / (4095 << 4); - adc_sample_sync(4, &val); + libtocksync_adc_sample(4, &val); int a4 = (val * 3300) / (4095 << 4); - adc_sample_sync(5, &val); + libtocksync_adc_sample(5, &val); int a5 = (val * 3300) / (4095 << 4); // Digital inputs: D0, D1, D6, D7 int d0; - gpio_read(0, &d0); + libtock_gpio_read(0, &d0); int d1; - gpio_read(1, &d1); + libtock_gpio_read(1, &d1); int d6; - gpio_read(2, &d6); + libtock_gpio_read(2, &d6); int d7; - gpio_read(3, &d7); + libtock_gpio_read(3, &d7); // Random bytes uint8_t rand[5]; int count; - rng_sync(rand, 5, 5, &count); + libtocksync_rng_get_random_bytes(rand, 5, 5, &count); // CRC of the random bytes uint32_t crc; - crc_compute(rand, 5, CRC_32, &crc); + libtocksync_crc_compute(rand, 5, LIBTOCK_CRC_32, &crc); uint32_t reference_crc = 0; reference_crc32(rand, 5, &reference_crc); @@ -135,7 +133,7 @@ static void sample_sensors (void) { printf(" Temperature: %d 1/100 degrees C\n", temp); printf(" Humidity: %u 0.01%%\n", humi); printf(" Light: %d\n", light); - printf(" Acceleration: %lu\n", accel_mag); + printf(" Acceleration: %f\n", accel_mag); printf(" A0: %d mV\n", a0); printf(" A1: %d mV\n", a1); printf(" A2: %d mV\n", a2); @@ -152,7 +150,7 @@ static void sample_sensors (void) { printf("\n"); // toggle the blue LED - led_toggle(2); + libtock_led_toggle(2); } int main(void) { @@ -166,22 +164,21 @@ int main(void) { simple_adv_only_name(); // Enable button callbacks - button_subscribe(button_callback, NULL); - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); // Setup D0, D1, D6, D7 - gpio_enable_input(0, PullDown); // D0 - gpio_enable_input(1, PullDown); // D1 - gpio_enable_input(2, PullDown); // D6 - gpio_enable_input(3, PullDown); // D7 + libtock_gpio_enable_input(0, libtock_pull_down); // D0 + libtock_gpio_enable_input(1, libtock_pull_down); // D1 + libtock_gpio_enable_input(2, libtock_pull_down); // D6 + libtock_gpio_enable_input(3, libtock_pull_down); // D7 // Enable interrupts on D7 - gpio_interrupt_callback(gpio_callback, NULL); - gpio_enable_interrupt(3, Change); + libtock_gpio_set_interrupt_callback(gpio_callback); + libtock_gpio_enable_interrupt(3, libtock_change); // sample sensors every second while (1) { sample_sensors(); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/hello_loop/main.c b/examples/tests/hello_loop/main.c index 2b2312e37..97be460eb 100644 --- a/examples/tests/hello_loop/main.c +++ b/examples/tests/hello_loop/main.c @@ -2,12 +2,12 @@ #include -#include -#include +#include +#include int main(void) { while (1) { printf("Hello\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/hifive1b/main.c b/examples/tests/hifive1b/main.c index 99d395aad..146a7a727 100644 --- a/examples/tests/hifive1b/main.c +++ b/examples/tests/hifive1b/main.c @@ -3,18 +3,16 @@ #include #include -#include +#include char hello[] = "Hello from HiFive1b!\r\n"; static void nop( - int a __attribute__((unused)), - int b __attribute__((unused)), - int c __attribute__((unused)), - void* d __attribute__((unused))) {} + returncode_t a __attribute__((unused)), + uint32_t b __attribute__((unused))) {} int main(void) { - putnstr_async(hello, strlen(hello), nop, NULL); + libtock_console_write((uint8_t*) hello, strlen(hello), nop); while (1) { yield(); diff --git a/examples/tests/hmac/main.c b/examples/tests/hmac/main.c index 4d362a6ac..fe8dc0093 100644 --- a/examples/tests/hmac/main.c +++ b/examples/tests/hmac/main.c @@ -1,7 +1,8 @@ #include +#include -#include -#include +#include +#include #define KEY_LEN 32 #define DATA_LEN 256 @@ -11,47 +12,25 @@ uint8_t key_buf[KEY_LEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x uint8_t data_buf[DATA_LEN] = "A language empowering everyone to build reliable and efficient software."; uint8_t dest_buf[DEST_LEN]; -static void hmac_cb(__attribute__((unused)) int result, - __attribute__ ((unused)) int digest, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) void* userdata) { - int i; - printf("Operation complete\r\n"); - - for (i = 0; i < DEST_LEN; i++) { - printf("%d: 0x%x\r\n", i, dest_buf[i]); - } - -} int main(void) { - printf("[TEST] HMAC Example Test\r\n"); - - // Set SHA256 as the algorithm - hmac_set_algorithm(0); - - printf("Loading in the 0 key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, hmac_set_key_buffer(key_buf, KEY_LEN)); - printf(" done\r\n"); + returncode_t ret; + printf("[TEST] HMAC\r\n"); - printf("Loading in the data buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, hmac_set_data_buffer(data_buf, DATA_LEN)); - printf(" done\r\n"); - - printf("Setting up the dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, hmac_set_dest_buffer(dest_buf, DEST_LEN)); - printf(" done\r\n"); - - printf("Setting up the callback...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, hmac_set_callback(hmac_cb, NULL)); - printf(" done\r\n"); - - printf("Running HMAC...\r\n"); - hmac_run(); - printf(" done\r\n"); + if (!libtock_hmac_exists()) { + printf("No HMAC driver.\n"); + return -2; + } - yield(); + ret = libtocksync_hmac_simple(LIBTOCK_HMAC_SHA256, + key_buf, 11, + data_buf, strlen((const char*) data_buf), + dest_buf, DEST_LEN); + if (ret != RETURNCODE_SUCCESS) { + printf("Unable to compute HMAC.\n"); + return -1; + } return 0; } diff --git a/examples/tests/i2c/i2c_master_ping_pong/main.c b/examples/tests/i2c/i2c_master_ping_pong/main.c index 4288906bb..3c4e1f4c4 100644 --- a/examples/tests/i2c/i2c_master_ping_pong/main.c +++ b/examples/tests/i2c/i2c_master_ping_pong/main.c @@ -3,9 +3,9 @@ #include #include -#include -#include -#include +#include +#include +#include #define BUF_SIZE 16 #define FOLLOW_ADDRESS 0x41 @@ -16,11 +16,11 @@ uint8_t master_write_buf[BUF_SIZE]; // A button press indicates that this device should start the ping-pong // exchange. First, change the address to the BUTTON_ADDRESS to avoid // conflict with the other node, then send a message. -static void button_cb(__attribute__((unused)) int btn_num, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* userdata) { - // Only the first press is meaningfull +static void button_cb( + __attribute__((unused)) returncode_t ret, + __attribute__((unused)) int btn_num, + __attribute__ ((unused)) bool val) { + // Only the first press is meaningful static bool pressed = false; if (!pressed) { @@ -45,10 +45,9 @@ int main(void) { // Set up I2C peripheral // Set up button peripheral to grab any button press - TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); int nbuttons; - button_count(&nbuttons); + libtock_button_count(&nbuttons); if (nbuttons < 1) { printf("ERROR: This app requires that a board have at least one button.\n"); exit(-1); @@ -56,7 +55,7 @@ int main(void) { int j; for (j = 0; j < nbuttons; j++) { - TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_button_notify_on_press(j, button_cb)); } while (1) { diff --git a/examples/tests/i2c/i2c_master_slave_ping_pong/main.c b/examples/tests/i2c/i2c_master_slave_ping_pong/main.c index 71e498502..53d87c06c 100644 --- a/examples/tests/i2c/i2c_master_slave_ping_pong/main.c +++ b/examples/tests/i2c/i2c_master_slave_ping_pong/main.c @@ -3,9 +3,9 @@ #include #include -#include -#include -#include +#include +#include +#include #define BUF_SIZE 16 #define LEADER_ADDRESS 0x40 @@ -29,10 +29,10 @@ static void i2c_callback(int callback_type, static bool any_message = false; if (!any_message) { int nbuttons; - button_count(&nbuttons); + libtock_button_count(&nbuttons); int j; for (j = 0; j < nbuttons; j++) { - button_disable_interrupt(j); + libtock_button_command_disable_interrupt(j); } } @@ -41,7 +41,7 @@ static void i2c_callback(int callback_type, TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); } else if (callback_type == TOCK_I2C_CB_SLAVE_WRITE) { printf("CB: Slave write\n"); - delay_ms(2500); + libtocksync_alarm_delay_ms(2500); printf("%s sending\n", is_leader ? "Leader" : "Follower"); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_write(is_leader ? FOLLOW_ADDRESS : LEADER_ADDRESS, BUF_SIZE)); @@ -54,10 +54,10 @@ static void i2c_callback(int callback_type, // A button press indicates that this device should start the ping-pong // exchange. First, change the address to the BUTTON_ADDRESS to avoid // conflict with the other node, then send a message. -static void button_cb(__attribute__((unused)) int btn_num, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* userdata) { +static void button_cb( + __attribute__((unused)) returncode_t ret, + __attribute__((unused)) int btn_num, + __attribute__ ((unused)) bool val) { // Only the first press is meaningfull static bool pressed = false; @@ -91,11 +91,8 @@ int main(void) { TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_set_slave_address(FOLLOW_ADDRESS)); TOCK_EXPECT(RETURNCODE_SUCCESS, i2c_master_slave_listen()); - // Set up button peripheral to grab any button press - TOCK_EXPECT(RETURNCODE_SUCCESS, button_subscribe(button_cb, NULL)); - int nbuttons; - button_count(&nbuttons); + libtock_button_count(&nbuttons); if (nbuttons < 1) { printf("ERROR: This app requires that a board have at least one button.\n"); exit(-1); @@ -103,7 +100,7 @@ int main(void) { int j; for (j = 0; j < nbuttons; j++) { - TOCK_EXPECT(RETURNCODE_SUCCESS, button_enable_interrupt(j)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_button_notify_on_press(j, button_cb)); } while (1) { diff --git a/examples/tests/ieee802154/radio_ack/main.c b/examples/tests/ieee802154/radio_ack/main.c index 69fd886e4..7c25512de 100644 --- a/examples/tests/ieee802154/radio_ack/main.c +++ b/examples/tests/ieee802154/radio_ack/main.c @@ -1,16 +1,17 @@ #include #include -#include "ieee802154.h" -#include "led.h" -#include "timer.h" +#include +#include +#include +#include // IEEE 802.15.4 sample packet transmission/ack app. // Continually transmits frames at the specified short address to the specified // destination address. Blinks the LED only if the transmitted frame is also acked. #define BUF_SIZE 60 -char packet_tx[BUF_SIZE]; +uint8_t packet_tx[BUF_SIZE]; bool toggle = true; int main(void) { @@ -19,19 +20,19 @@ int main(void) { for (i = 0; i < BUF_SIZE; i++) { packet_tx[i] = i; } - ieee802154_set_address(0x1540); - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); + libtock_ieee802154_set_address_short(0x1540); + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); while (1) { - int err = ieee802154_send(0x0802, + int err = libtocksync_ieee802154_send(0x0802, SEC_LEVEL_NONE, 0, NULL, packet_tx, BUF_SIZE); if (err == RETURNCODE_SUCCESS) { - led_toggle(0); + libtock_led_toggle(0); printf("Packet sent and acked.\n"); } else if (err == RETURNCODE_ENOACK) { printf("Packet sent, but not acked.\n"); @@ -40,6 +41,6 @@ int main(void) { } counter++; packet_tx[0] = counter; - delay_ms(4000); + libtocksync_alarm_delay_ms(4000); } } diff --git a/examples/tests/ieee802154/radio_rx/main.c b/examples/tests/ieee802154/radio_rx/main.c index b07dc9633..ff32fe12a 100644 --- a/examples/tests/ieee802154/radio_rx/main.c +++ b/examples/tests/ieee802154/radio_rx/main.c @@ -2,10 +2,10 @@ #include #include -#include "ieee802154.h" -#include "led.h" -#include "timer.h" -#include "tock.h" +#include +#include +#include +#include // IEEE 802.15.4 sample packet reception app. // Continually receives frames at the specified short address. Setting the @@ -16,26 +16,26 @@ // Optionally uses the packet inspection functions to print out relevant // information from the frame. (Set PRINT_PAYLOAD to 1) -ieee802154_rxbuf rx_ring_buf; +libtock_ieee802154_rxbuf rx_ring_buf; + +static void callback(__attribute__ ((unused)) int pans, + __attribute__ ((unused)) int dst_addr, + __attribute__ ((unused)) int src_addr) { + libtock_led_toggle(0); -static void callback(__attribute__ ((unused)) int pans, - __attribute__ ((unused)) int dst_addr, - __attribute__ ((unused)) int src_addr, - __attribute__ ((unused)) void* ud) { - led_toggle(0); // Before accessing an "allowed" buffer, we must request it back. // We do this with the reset_ring_buf function. Because this example // only uses one ring buffer, we pass null values to unallow the ringbuffer. - reset_ring_buf(NULL, NULL, NULL); + libtock_reset_ring_buf(NULL, NULL, NULL); - char* packet_rx = ieee802154_read_next_frame(&rx_ring_buf); + uint8_t* packet_rx = libtock_ieee802154_read_next_frame(&rx_ring_buf); #define PRINT_PAYLOAD 1 #define PRINT_STRING 0 while (packet_rx) { #if PRINT_PAYLOAD - int payload_offset = ieee802154_frame_get_payload_offset(packet_rx); - int payload_length = ieee802154_frame_get_payload_length(packet_rx); + int payload_offset = libtock_ieee802154_frame_get_payload_offset(packet_rx); + int payload_length = libtock_ieee802154_frame_get_payload_length(packet_rx); printf("Received packet with payload of %d bytes from offset %d\n", payload_length, payload_offset); #if PRINT_STRING printf("%.*s\n", payload_length, packet_rx + payload_offset); @@ -52,13 +52,13 @@ static void callback(__attribute__ ((unused)) int pans, unsigned char long_addr[8]; addr_mode_t mode; - if (ieee802154_frame_get_dst_pan(packet_rx, &pan)) { + if (libtock_ieee802154_frame_get_dst_pan(packet_rx, &pan)) { printf("Packet destination PAN ID: 0x%04x\n", pan); } else { printf("Packet destination PAN ID: not present\n"); } - mode = ieee802154_frame_get_dst_addr(packet_rx, &short_addr, long_addr); + mode = libtock_ieee802154_frame_get_dst_addr(packet_rx, &short_addr, long_addr); if (mode == ADDR_NONE) { printf("Packet destination address: not present\n"); } else if (mode == ADDR_SHORT) { @@ -71,13 +71,13 @@ static void callback(__attribute__ ((unused)) int pans, printf("\n"); } - if (ieee802154_frame_get_src_pan(packet_rx, &pan)) { + if (libtock_ieee802154_frame_get_src_pan(packet_rx, &pan)) { printf("Packet source PAN ID: 0x%04x\n", pan); } else { printf("Packet source PAN ID: not present\n"); } - mode = ieee802154_frame_get_src_addr(packet_rx, &short_addr, long_addr); + mode = libtock_ieee802154_frame_get_src_addr(packet_rx, &short_addr, long_addr); if (mode == ADDR_NONE) { printf("Packet source address: not present\n"); } else if (mode == ADDR_SHORT) { @@ -91,20 +91,20 @@ static void callback(__attribute__ ((unused)) int pans, } #endif - packet_rx = ieee802154_read_next_frame(&rx_ring_buf); + packet_rx = libtock_ieee802154_read_next_frame(&rx_ring_buf); } - ieee802154_receive(callback, &rx_ring_buf, NULL); + libtock_ieee802154_receive(&rx_ring_buf, callback); } int main(void) { - memset(rx_ring_buf, 0, IEEE802154_RING_BUFFER_LEN); - ieee802154_set_address(0x802); - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); - ieee802154_receive(callback, &rx_ring_buf, NULL); + memset(rx_ring_buf, 0, libtock_ieee802154_RING_BUFFER_LEN); + libtock_ieee802154_set_address_short(0x802); + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); + libtock_ieee802154_receive(&rx_ring_buf, callback); while (1) { - delay_ms(4000); + libtocksync_alarm_delay_ms(4000); } } diff --git a/examples/tests/ieee802154/radio_rxtx/main.c b/examples/tests/ieee802154/radio_rxtx/main.c index 14a2b64c4..354fc68ee 100644 --- a/examples/tests/ieee802154/radio_rxtx/main.c +++ b/examples/tests/ieee802154/radio_rxtx/main.c @@ -1,54 +1,55 @@ #include #include -#include "ieee802154.h" -#include "led.h" -#include "timer.h" +#include +#include +#include +#include // IEEE 802.15.4 sample packet echo app. // Continually receives packets at the specified short address, then retransmits them. // Use this in conjunction with the radio_tx app. -ieee802154_rxbuf rx_ring_buf; +libtock_ieee802154_rxbuf rx_ring_buf; bool toggle = true; int main(void) { unsigned short ADDR = 0x0802; unsigned short PAN = 0xABCD; - ieee802154_set_address(ADDR); - ieee802154_set_pan(PAN); - ieee802154_config_commit(); - ieee802154_up(); + libtock_ieee802154_set_address_short(ADDR); + libtock_ieee802154_set_pan(PAN); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); while (1) { - if (ieee802154_receive_sync(&rx_ring_buf) >= 0) { + if (libtocksync_ieee802154_receive(&rx_ring_buf) >= 0) { unsigned short pan; unsigned short short_addr; - char* packet_rx = ieee802154_read_next_frame(&rx_ring_buf); + uint8_t* packet_rx = libtock_ieee802154_read_next_frame(&rx_ring_buf); while (packet_rx) { - if (!ieee802154_frame_get_dst_pan(packet_rx, &pan) || pan != PAN) { + if (!libtock_ieee802154_frame_get_dst_pan(packet_rx, &pan) || pan != PAN) { continue; } - addr_mode_t mode = ieee802154_frame_get_dst_addr(packet_rx, &short_addr, NULL); + addr_mode_t mode = libtock_ieee802154_frame_get_dst_addr(packet_rx, &short_addr, NULL); if (mode != ADDR_SHORT || short_addr != ADDR) { continue; } // Only retransmit the payload if this packet was meant for us. - int payload_offset = ieee802154_frame_get_payload_offset(packet_rx); - int payload_length = ieee802154_frame_get_payload_length(packet_rx); - delay_ms(250); + int payload_offset = libtock_ieee802154_frame_get_payload_offset(packet_rx); + int payload_length = libtock_ieee802154_frame_get_payload_length(packet_rx); + libtocksync_alarm_delay_ms(250); printf("Retransmitting received packet.\n"); - ieee802154_send(0xFFFF, + libtocksync_ieee802154_send(0xFFFF, SEC_LEVEL_NONE, 0, NULL, packet_rx + payload_offset, payload_length); - packet_rx = ieee802154_read_next_frame(&rx_ring_buf); + packet_rx = libtock_ieee802154_read_next_frame(&rx_ring_buf); } - led_toggle(0); + libtock_led_toggle(0); } } } diff --git a/examples/tests/ieee802154/radio_tx/main.c b/examples/tests/ieee802154/radio_tx/main.c index 5c5139575..4da77f03f 100644 --- a/examples/tests/ieee802154/radio_tx/main.c +++ b/examples/tests/ieee802154/radio_tx/main.c @@ -1,18 +1,18 @@ #include #include -#include "gpio.h" -#include "ieee802154.h" -#include "led.h" -#include "timer.h" -#include "tock.h" +#include +#include +#include +#include +#include // IEEE 802.15.4 sample packet transmission app. // Continually transmits frames at the specified short address to the specified // destination address. #define BUF_SIZE 60 -char packet[BUF_SIZE]; +uint8_t packet[BUF_SIZE]; bool toggle = true; int main(void) { @@ -20,14 +20,14 @@ int main(void) { for (i = 0; i < BUF_SIZE; i++) { packet[i] = i; } - gpio_enable_output(0); - ieee802154_set_address(0x1540); - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); + libtock_gpio_enable_output(0); + libtock_ieee802154_set_address_short(0x1540); + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); while (1) { - led_toggle(0); - int err = ieee802154_send(0x0802, + libtock_led_toggle(0); + int err = libtocksync_ieee802154_send(0x0802, SEC_LEVEL_NONE, 0, NULL, @@ -37,11 +37,11 @@ int main(void) { printf("Transmitted successfully.\n"); } else if (err == RETURNCODE_ENOACK) { printf("Transmitted but packet not acknowledged.\n"); - gpio_toggle(0); + libtock_gpio_toggle(0); } else { printf("Transmit failed with error %i.\n", err); - gpio_toggle(0); + libtock_gpio_toggle(0); } - delay_ms(250); + libtocksync_alarm_delay_ms(250); } } diff --git a/examples/tests/ieee802154/radio_tx_raw/main.c b/examples/tests/ieee802154/radio_tx_raw/main.c index c089462bf..be735c87a 100644 --- a/examples/tests/ieee802154/radio_tx_raw/main.c +++ b/examples/tests/ieee802154/radio_tx_raw/main.c @@ -1,11 +1,11 @@ #include #include -#include "gpio.h" -#include "ieee802154.h" -#include "led.h" -#include "timer.h" -#include "tock.h" +#include +#include +#include +#include +#include // IEEE 802.15.4 sample packet transmission app. // Continually transmits frames at the specified short address to the specified @@ -14,29 +14,29 @@ #define BUF_SIZE 3 // Generic ACK packet for demonstration purposes -char packet[BUF_SIZE] = {2, 0, 1}; +uint8_t packet[BUF_SIZE] = {2, 0, 1}; bool toggle = true; int main(void) { - gpio_enable_output(0); - ieee802154_set_address(0x1540); - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); + libtock_gpio_enable_output(0); + libtock_ieee802154_set_address_short(0x1540); + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); while (1) { - led_toggle(0); - int err = ieee802154_send_raw( + libtock_led_toggle(0); + int err = libtocksync_ieee802154_send_raw( packet, BUF_SIZE); if (err == RETURNCODE_SUCCESS) { printf("Transmitted successfully.\n"); } else if (err == RETURNCODE_ENOACK) { printf("Transmitted but packet not acknowledged.\n"); - gpio_toggle(0); + libtock_gpio_toggle(0); } else { printf("Transmit failed with error %i.\n", err); - gpio_toggle(0); + libtock_gpio_toggle(0); } - delay_ms(3000); + libtocksync_alarm_delay_ms(3000); } } diff --git a/examples/tests/imix/main.c b/examples/tests/imix/main.c index 94a4a4951..477fb7e39 100644 --- a/examples/tests/imix/main.c +++ b/examples/tests/imix/main.c @@ -1,4 +1,4 @@ -#include "math.h" +#include #include #include @@ -9,17 +9,18 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Intervals for BLE advertising and connections simple_ble_config_t ble_config = { @@ -39,14 +40,14 @@ void ble_address_set (void) { // Callback for button presses. // btn_num: The index of the button associated with the callback // val: 1 if pressed, 0 if depressed -static void button_callback(__attribute__ ((unused)) int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - if (val == 1) { - led_on(0); +static void button_callback( + __attribute__ ((unused)) returncode_t ret, + __attribute__ ((unused)) int btn_num, + bool val) { + if (val) { + libtock_led_on(0); } else { - led_off(0); + libtock_led_off(0); } } @@ -54,24 +55,25 @@ static void sample_sensors (void) { printf("[imix Sensor Reading]\n"); // Sensors: temperature/humidity, acceleration, light int temp; - temperature_read_sync(&temp); + libtocksync_temperature_read(&temp); printf(" Temperature: %d.%02d degrees C\n", temp / 100, temp % 100); - unsigned humi; - humidity_read_sync(&humi); + int humi; + libtocksync_humidity_read(&humi); printf(" Humidity: %u.%02u%%\n", humi / 100, humi % 100); - uint32_t accel_mag = ninedof_read_accel_mag(); - printf(" Acceleration: %lu\n", accel_mag); + double accel_mag; + libtocksync_ninedof_read_accelerometer_magnitude(&accel_mag); + printf(" Acceleration: %f\n", accel_mag); int light; - ambient_light_read_intensity_sync(&light); + libtocksync_ambient_light_read_intensity(&light); printf(" Light: %d\n", light); // Analog inputs: A0-A5 for (int a = 0; a < 6; a++) { uint16_t val; - adc_sample_sync(a, &val); + libtocksync_adc_sample(a, &val); int ival = (val * 3300) / (4095 << 4); printf(" A%i: %d mV\n", a, ival); } @@ -79,13 +81,13 @@ static void sample_sensors (void) { // Digital inputs: D0, D1, D6, D7 for (int d = 0; d < 4; d++) { int val; - gpio_read(0, &val); + libtock_gpio_read(0, &val); printf(" D%i: %d\n", d, val); } printf("\n"); // toggle the user LED - led_toggle(1); + libtock_led_toggle(1); } int main(void) { @@ -101,15 +103,14 @@ int main(void) { printf("[imix] BLE advertising.\n"); // Enable button callbacks - button_subscribe(button_callback, NULL); - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); printf("[imix] Button initialized.\n"); // Setup D0, D1, D6, D7 - gpio_enable_input(0, PullDown); // D0 - gpio_enable_input(1, PullDown); // D1 - gpio_enable_input(2, PullDown); // D6 - gpio_enable_input(3, PullDown); // D7 + libtock_gpio_enable_input(0, libtock_pull_down); // D0 + libtock_gpio_enable_input(1, libtock_pull_down); // D1 + libtock_gpio_enable_input(2, libtock_pull_down); // D6 + libtock_gpio_enable_input(3, libtock_pull_down); // D7 printf("[imix] GPIO D0, D1, D6, D7 configured to be pulldown.\n"); // Should add UDP here @@ -118,6 +119,6 @@ int main(void) { while (1) { printf("[imix] Sampling sensors.\n"); sample_sensors(); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/keyboard_hid/main.c b/examples/tests/keyboard_hid/main.c index 05be43c92..96ef6b518 100644 --- a/examples/tests/keyboard_hid/main.c +++ b/examples/tests/keyboard_hid/main.c @@ -1,36 +1,31 @@ #include #include -#include -#include +#include +#include - -// Callback for button presses. -// btn_num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_callback(__attribute__ ((unused)) int btn_num, - __attribute__ ((unused)) int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - - char message[] = "Hi from Tock!"; - int ret; - - ret = usb_keyboard_hid_send_string_sync(message, strlen(message)); - if (ret < 0) { - printf("ERROR sending string with USB keyboard HID: %i\n", ret); - } -} +char message[] = "Hi from Tock!"; int main(void) { - int err; - - err = button_subscribe(button_callback, NULL); - if (err < 0) return err; + returncode_t ret; + printf("[TEST] USB Keyboard HID\n"); - button_enable_interrupt(0); + if (!libtock_usb_keyboard_hid_exists()) { + printf("No USB keyboard HID on this board!\n"); + return -2; + } while (1) { - yield(); + ret = libtocksync_button_wait_for_press(0); + if (ret != RETURNCODE_SUCCESS) { + printf("Could not wait for button presses.\n"); + return -3; + } + + ret = libtocksync_usb_keyboard_hid_send_string(message, strlen(message)); + if (ret != RETURNCODE_SUCCESS) { + printf("ERROR sending string with USB keyboard HID: %i\n", ret); + return -4; + } } } diff --git a/examples/tests/kv/kv_check/Makefile b/examples/tests/kv/kv_check/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/kv/kv_check/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/kv_check/README.md b/examples/tests/kv/kv_check/README.md similarity index 100% rename from examples/tests/kv_check/README.md rename to examples/tests/kv/kv_check/README.md diff --git a/examples/tests/kv_check/main.c b/examples/tests/kv/kv_check/main.c similarity index 63% rename from examples/tests/kv_check/main.c rename to examples/tests/kv/kv_check/main.c index b073deeca..2a355e818 100644 --- a/examples/tests/kv_check/main.c +++ b/examples/tests/kv/kv_check/main.c @@ -1,13 +1,12 @@ #include #include -#include -#include +#include int main(void) { - printf("[KV] Check for Key-Value Support\n"); + printf("[TEST] Check for Key-Value Support\n"); - if (kv_check_status() == RETURNCODE_SUCCESS) { + if (libtock_kv_exists()) { printf("Key-Value support is enabled.\n"); tock_exit(0); } else { diff --git a/examples/tests/kv/kv_interactive/Makefile b/examples/tests/kv/kv_interactive/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/kv/kv_interactive/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/kv_interactive/README.md b/examples/tests/kv/kv_interactive/README.md similarity index 100% rename from examples/tests/kv_interactive/README.md rename to examples/tests/kv/kv_interactive/README.md diff --git a/examples/tests/kv_interactive/main.c b/examples/tests/kv/kv_interactive/main.c similarity index 88% rename from examples/tests/kv_interactive/main.c rename to examples/tests/kv/kv_interactive/main.c index 3e2d99a32..9c339b3f2 100644 --- a/examples/tests/kv_interactive/main.c +++ b/examples/tests/kv/kv_interactive/main.c @@ -2,8 +2,9 @@ #include #include -#include -#include +#include +#include +#include #define KEY_LEN 64 #define DATA_LEN 64 @@ -14,6 +15,13 @@ uint8_t value_buf[DATA_LEN]; char read_buf[DATA_LEN]; +static int getch(void) { + uint8_t buffer[1]; + int number_read; + libtocksync_console_read(buffer, 1, &number_read); + return buffer[0]; +} + static int get_command(void) { int idx = 0; memset(read_buf, 0, 64); @@ -58,7 +66,7 @@ static int find_end(int start) { int main(void) { int ret; - printf("[KV Interactive] Text interface to KV store\n"); + printf("[TEST] Text interface to KV store\n"); printf("\n"); printf("Please enter a command: get, set/add/update, or delete\n"); printf(" get \n"); @@ -86,7 +94,7 @@ int main(void) { printf("Getting %s\n", key_buf); - ret = kv_get_sync(key_buf, key_len, data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, key_len, data_buf, DATA_LEN, &value_len); if (ret < 0) { printf("Could not get key: %i\n", ret); } else { @@ -117,7 +125,7 @@ int main(void) { printf("Setting %s=%s\n", key_buf, value_buf); - ret = kv_set_sync(key_buf, key_len, value_buf, value_len); + ret = libtocksync_kv_set(key_buf, key_len, value_buf, value_len); if (ret < 0) { printf("Error setting key %i\n", ret); } else { @@ -144,7 +152,7 @@ int main(void) { printf("Adding %s=%s\n", key_buf, value_buf); - ret = kv_add_sync(key_buf, key_len, value_buf, value_len); + ret = libtocksync_kv_add(key_buf, key_len, value_buf, value_len); if (ret < 0) { printf("Error adding key %i\n", ret); } else { @@ -171,7 +179,7 @@ int main(void) { printf("Updating %s=%s\n", key_buf, value_buf); - ret = kv_update_sync(key_buf, key_len, value_buf, value_len); + ret = libtocksync_kv_update(key_buf, key_len, value_buf, value_len); if (ret < 0) { printf("Error updating key %i\n", ret); } else { @@ -188,7 +196,7 @@ int main(void) { printf("Deleting %s\n", key_buf); - ret = kv_delete_sync(key_buf, key_len); + ret = libtocksync_kv_delete(key_buf, key_len); if (ret < 0) { printf("Could not delete key: %i\n", ret); } else { diff --git a/examples/tests/kv_permissions/kv_no_modify/Makefile b/examples/tests/kv/kv_permissions/kv_no_modify/Makefile similarity index 89% rename from examples/tests/kv_permissions/kv_no_modify/Makefile rename to examples/tests/kv/kv_permissions/kv_no_modify/Makefile index a0047b8a0..999799a91 100644 --- a/examples/tests/kv_permissions/kv_no_modify/Makefile +++ b/examples/tests/kv/kv_permissions/kv_no_modify/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../../.. +TOCK_USERLAND_BASE_DIR = ../../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/kv_permissions/kv_no_modify/README.md b/examples/tests/kv/kv_permissions/kv_no_modify/README.md similarity index 100% rename from examples/tests/kv_permissions/kv_no_modify/README.md rename to examples/tests/kv/kv_permissions/kv_no_modify/README.md diff --git a/examples/tests/kv_permissions/kv_no_modify/main.c b/examples/tests/kv/kv_permissions/kv_no_modify/main.c similarity index 73% rename from examples/tests/kv_permissions/kv_no_modify/main.c rename to examples/tests/kv/kv_permissions/kv_no_modify/main.c index f32b378df..13e39a5f3 100644 --- a/examples/tests/kv_permissions/kv_no_modify/main.c +++ b/examples/tests/kv/kv_permissions/kv_no_modify/main.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #define KEY_LEN 200 #define DATA_LEN 3000 @@ -14,8 +14,8 @@ uint8_t value_buf[DATA_LEN]; static bool test_exists(void) { - int ret = kv_check_status(); - CHECK(ret == RETURNCODE_SUCCESS); + bool ret = libtock_kv_exists(); + CHECK(ret == true); return true; } @@ -30,10 +30,10 @@ static bool test_set_get(void) { } // If key exists this should fail. - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); - ret = kv_get_sync(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_SUCCESS); return true; @@ -49,10 +49,10 @@ static bool test_set_set(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -68,10 +68,10 @@ static bool test_set_delete(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; diff --git a/examples/tests/kv_permissions/kv_no_read/Makefile b/examples/tests/kv/kv_permissions/kv_no_read/Makefile similarity index 89% rename from examples/tests/kv_permissions/kv_no_read/Makefile rename to examples/tests/kv/kv_permissions/kv_no_read/Makefile index 96e416d17..2ae29d3c4 100644 --- a/examples/tests/kv_permissions/kv_no_read/Makefile +++ b/examples/tests/kv/kv_permissions/kv_no_read/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../../.. +TOCK_USERLAND_BASE_DIR = ../../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/kv_permissions/kv_no_read/README.md b/examples/tests/kv/kv_permissions/kv_no_read/README.md similarity index 100% rename from examples/tests/kv_permissions/kv_no_read/README.md rename to examples/tests/kv/kv_permissions/kv_no_read/README.md diff --git a/examples/tests/kv_permissions/kv_no_read/main.c b/examples/tests/kv/kv_permissions/kv_no_read/main.c similarity index 72% rename from examples/tests/kv_permissions/kv_no_read/main.c rename to examples/tests/kv/kv_permissions/kv_no_read/main.c index bc1f9e3ac..ed8454bfd 100644 --- a/examples/tests/kv_permissions/kv_no_read/main.c +++ b/examples/tests/kv/kv_permissions/kv_no_read/main.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #define KEY_LEN 200 #define DATA_LEN 3000 @@ -14,8 +14,8 @@ uint8_t value_buf[DATA_LEN]; static bool test_exists(void) { - int ret = kv_check_status(); - CHECK(ret == RETURNCODE_SUCCESS); + bool ret = libtock_kv_exists(); + CHECK(ret == true); return true; } @@ -29,10 +29,10 @@ static bool test_set_get_no_permissions(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; diff --git a/examples/tests/kv_permissions/kv_no_write/Makefile b/examples/tests/kv/kv_permissions/kv_no_write/Makefile similarity index 89% rename from examples/tests/kv_permissions/kv_no_write/Makefile rename to examples/tests/kv/kv_permissions/kv_no_write/Makefile index 4cd46d340..763399faa 100644 --- a/examples/tests/kv_permissions/kv_no_write/Makefile +++ b/examples/tests/kv/kv_permissions/kv_no_write/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../../.. +TOCK_USERLAND_BASE_DIR = ../../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/kv_permissions/kv_no_write/README.md b/examples/tests/kv/kv_permissions/kv_no_write/README.md similarity index 100% rename from examples/tests/kv_permissions/kv_no_write/README.md rename to examples/tests/kv/kv_permissions/kv_no_write/README.md diff --git a/examples/tests/kv_permissions/kv_no_write/main.c b/examples/tests/kv/kv_permissions/kv_no_write/main.c similarity index 77% rename from examples/tests/kv_permissions/kv_no_write/main.c rename to examples/tests/kv/kv_permissions/kv_no_write/main.c index e0e885bc5..82ee29e4f 100644 --- a/examples/tests/kv_permissions/kv_no_write/main.c +++ b/examples/tests/kv/kv_permissions/kv_no_write/main.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #define KEY_LEN 200 #define DATA_LEN 3000 @@ -14,8 +14,8 @@ uint8_t value_buf[DATA_LEN]; static bool test_exists(void) { - int ret = kv_check_status(); - CHECK(ret == RETURNCODE_SUCCESS); + bool ret = libtock_kv_exists(); + CHECK(ret == true); return true; } @@ -29,7 +29,7 @@ static bool test_set_no_permissions(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_EINVAL); return true; diff --git a/examples/tests/kv/kv_system/Makefile b/examples/tests/kv/kv_system/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/kv/kv_system/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/kv_system/README.md b/examples/tests/kv/kv_system/README.md similarity index 100% rename from examples/tests/kv_system/README.md rename to examples/tests/kv/kv_system/README.md diff --git a/examples/tests/kv_system/main.c b/examples/tests/kv/kv_system/main.c similarity index 65% rename from examples/tests/kv_system/main.c rename to examples/tests/kv/kv_system/main.c index 9aaaeb0de..375a7b152 100644 --- a/examples/tests/kv_system/main.c +++ b/examples/tests/kv/kv_system/main.c @@ -1,16 +1,15 @@ #include #include -#include -#include +#include +#include #define KEY_LEN 16 #define DATA_LEN 32 uint8_t key_buf[KEY_LEN] = "First Key"; -uint8_t data_buf[DATA_LEN] = \ - "My secret key, that no one knows"; -uint8_t out_buf[DATA_LEN] = "Just junk"; +uint8_t data_buf[DATA_LEN] = "My secret key, that no one knows"; +uint8_t out_buf[DATA_LEN] = "Just junk"; static void kv_cb(int result, __attribute__ ((unused)) int length, @@ -30,22 +29,22 @@ int main(void) { printf("[TEST] KV System Example Test\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_check_status()); + TOCK_EXPECT(true, libtock_kv_exists()); printf("Loading in the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_set_key_buffer(key_buf, KEY_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_set_readonly_allow_key_buffer(key_buf, KEY_LEN)); printf(" done\r\n"); printf("Loading in the input buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_set_input_buffer(data_buf, DATA_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_set_readonly_allow_input_buffer(data_buf, DATA_LEN)); printf(" done\r\n"); printf("Setting up the callback...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_set_callback(kv_cb, &con)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_set_upcall(kv_cb, &con)); printf(" done\r\n"); printf("Adding the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_set()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_command_set()); printf(" done\r\n"); yield_for(&con); @@ -54,11 +53,11 @@ int main(void) { printf("Finish adding the key\r\n"); printf("Loading in the output buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_set_output_buffer(out_buf, DATA_LEN)); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_set_readwrite_allow_output_buffer(out_buf, DATA_LEN)); printf(" done\r\n"); printf("Getting the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_get()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_command_get()); printf(" done\r\n"); yield_for(&con); @@ -76,13 +75,13 @@ int main(void) { } printf("Deleting the key...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_delete()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_command_delete()); yield_for(&con); con = false; printf(" done\r\n"); printf("Getting the key, again...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, kv_get()); + TOCK_EXPECT(RETURNCODE_SUCCESS, libtock_kv_command_get()); printf("This should fail\r\n"); yield_for(&con); diff --git a/examples/tests/kv/Makefile b/examples/tests/kv/kv_unit_tests/Makefile similarity index 90% rename from examples/tests/kv/Makefile rename to examples/tests/kv/kv_unit_tests/Makefile index ceb72ff60..964886043 100644 --- a/examples/tests/kv/Makefile +++ b/examples/tests/kv/kv_unit_tests/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/kv/README.md b/examples/tests/kv/kv_unit_tests/README.md similarity index 100% rename from examples/tests/kv/README.md rename to examples/tests/kv/kv_unit_tests/README.md diff --git a/examples/tests/kv/kv_unit_tests/gen_keys.py b/examples/tests/kv/kv_unit_tests/gen_keys.py new file mode 100755 index 000000000..c0894b446 --- /dev/null +++ b/examples/tests/kv/kv_unit_tests/gen_keys.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + + +import binascii +import siphash +import string + + +key = "HKANfdlksiqiovcHIFoihASIU" + + +NUM_REGIONS = 32 + + +keys = {} + + +for r in range(0, NUM_REGIONS): + for c1 in string.ascii_letters + string.digits: + for c2 in string.ascii_letters + string.digits: + test_key = key + c1 + c2 + + key_buffer = test_key.encode("utf-8") + h = siphash.SipHash_2_4(bytearray(16), key_buffer).digest() + + lower = (h[6] << 8) | h[7] + + if lower % NUM_REGIONS == r: + keys[r] = test_key + break + + if r in keys: + break + + else: + print("UNABLE TO FIND KEY FOR REGION {}".format(r)) + +# print(binascii.hexlify(h).decode("utf-8")) + + +print(keys) + +for k, v in keys.items(): + print('"{}",'.format(v)) diff --git a/examples/tests/kv/main.c b/examples/tests/kv/kv_unit_tests/main.c similarity index 75% rename from examples/tests/kv/main.c rename to examples/tests/kv/kv_unit_tests/main.c index 011bb830b..af3a9ffea 100644 --- a/examples/tests/kv/main.c +++ b/examples/tests/kv/kv_unit_tests/main.c @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #define KEY_LEN 200 #define DATA_LEN 3000 @@ -14,7 +14,7 @@ uint8_t value_buf[DATA_LEN]; static bool test_exists(void) { - int ret = kv_check_status(); + bool ret = libtock_kv_exists(); CHECK(ret == RETURNCODE_SUCCESS); return true; } @@ -29,10 +29,10 @@ static bool test_set_get(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_SUCCESS); CHECK(value_len == 45); for (uint32_t i = 0; i < value_len; i++) { @@ -52,10 +52,10 @@ static bool test_set_get_too_long(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, 2, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, 2, &value_len); CHECK(ret == RETURNCODE_ESIZE); CHECK(value_len == 10); for (uint32_t i = 0; i < 2; i++) { @@ -69,18 +69,18 @@ static bool test_key_too_long(void) { int ret; uint32_t value_len = 0; - ret = kv_get_sync(key_buf, KEY_LEN, value_buf, 50, &value_len); + ret = libtocksync_kv_get(key_buf, KEY_LEN, value_buf, 50, &value_len); CHECK(ret == RETURNCODE_ESIZE); value_buf[0] = 'V'; - ret = kv_set_sync(key_buf, KEY_LEN, value_buf, 1); + ret = libtocksync_kv_set(key_buf, KEY_LEN, value_buf, 1); CHECK(ret == RETURNCODE_ESIZE); - ret = kv_add_sync(key_buf, KEY_LEN, value_buf, 1); + ret = libtocksync_kv_add(key_buf, KEY_LEN, value_buf, 1); CHECK(ret == RETURNCODE_ESIZE); - ret = kv_update_sync(key_buf, KEY_LEN, value_buf, 1); + ret = libtocksync_kv_update(key_buf, KEY_LEN, value_buf, 1); CHECK(ret == RETURNCODE_ESIZE); - ret = kv_delete_sync(key_buf, KEY_LEN); + ret = libtocksync_kv_delete(key_buf, KEY_LEN); CHECK(ret == RETURNCODE_ESIZE); return true; @@ -90,7 +90,7 @@ static bool test_set_value_too_long(void) { int ret; key_buf[0] = 'K'; - ret = kv_set_sync(key_buf, 1, value_buf, DATA_LEN); + ret = libtocksync_kv_set(key_buf, 1, value_buf, DATA_LEN); CHECK(ret == RETURNCODE_ESIZE); return true; @@ -102,7 +102,7 @@ static bool test_get_not_found(void) { strcpy((char*) key_buf, random_key); uint32_t value_len = 0; - ret = kv_get_sync(key_buf, strlen(random_key), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(random_key), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -114,7 +114,7 @@ static bool test_get_not_found2(void) { strcpy((char*) key_buf, random_key); uint32_t value_len = 0; - ret = kv_get_sync(key_buf, strlen(random_key), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(random_key), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -125,7 +125,7 @@ static bool test_add(void) { char key[] = "kvtestapp"; strcpy((char*) key_buf, key); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); uint32_t value_len = 10; @@ -133,7 +133,7 @@ static bool test_add(void) { value_buf[i] = (uint8_t) i; } - ret = kv_add_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_add(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); return true; @@ -144,7 +144,7 @@ static bool test_add_add(void) { char key[] = "kvtestapp"; strcpy((char*) key_buf, key); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); uint32_t value_len = 10; @@ -152,10 +152,10 @@ static bool test_add_add(void) { value_buf[i] = (uint8_t) i; } - ret = kv_add_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_add(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_add_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_add(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -171,17 +171,17 @@ static bool test_update(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); for (uint32_t i = 0; i < value_len; i++) { value_buf[i] = (uint8_t) (10 - i); } - ret = kv_update_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_update(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, 100, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, 100, &value_len); CHECK(ret == RETURNCODE_SUCCESS); CHECK(value_len == 10); for (uint32_t i = 0; i < 10; i++) { @@ -196,7 +196,7 @@ static bool test_update_no_exist(void) { char key[] = "kvtestapp"; strcpy((char*) key_buf, key); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); uint32_t value_len = 10; @@ -204,7 +204,7 @@ static bool test_update_no_exist(void) { value_buf[i] = (uint8_t) i; } - ret = kv_update_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_update(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -220,13 +220,13 @@ static bool test_delete(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, 100, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, 100, &value_len); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -242,13 +242,13 @@ static bool test_delete_delete(void) { value_buf[i] = (uint8_t) i; } - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_ENOSUPPORT); return true; @@ -259,7 +259,7 @@ static bool test_add_update_set(void) { char key[] = "kvtestapp"; strcpy((char*) key_buf, key); - ret = kv_delete_sync(key_buf, strlen(key)); + ret = libtocksync_kv_delete(key_buf, strlen(key)); CHECK(ret == RETURNCODE_SUCCESS || ret == RETURNCODE_ENOSUPPORT); uint32_t value_len = 30; @@ -267,7 +267,7 @@ static bool test_add_update_set(void) { value_buf[i] = (uint8_t) i; } - ret = kv_add_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_add(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); value_len = 15; @@ -275,17 +275,17 @@ static bool test_add_update_set(void) { value_buf[i] = (uint8_t) i + 10; } - ret = kv_update_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_update(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); value_len = 2; value_buf[0] = 'H'; value_buf[1] = 'I'; - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(key), data_buf, 100, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(key), data_buf, 100, &value_len); CHECK(ret == RETURNCODE_SUCCESS); CHECK(value_len == 2); CHECK(value_buf[0] == 'H'); @@ -300,7 +300,7 @@ static bool test_set_zero_value(void) { strcpy((char*) key_buf, key); uint32_t value_len = 0; - ret = kv_set_sync(key_buf, strlen(key), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(key), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); return true; @@ -352,10 +352,10 @@ static bool subtest_set_get_region(uint32_t start, uint32_t stop) { value_buf[j] = (uint8_t) (j + i); } - ret = kv_set_sync(key_buf, strlen(keys[i]), value_buf, value_len); + ret = libtocksync_kv_set(key_buf, strlen(keys[i]), value_buf, value_len); CHECK(ret == RETURNCODE_SUCCESS); - ret = kv_get_sync(key_buf, strlen(keys[i]), data_buf, DATA_LEN, &value_len); + ret = libtocksync_kv_get(key_buf, strlen(keys[i]), data_buf, DATA_LEN, &value_len); CHECK(ret == RETURNCODE_SUCCESS); CHECK(value_len == i + 32); for (uint32_t j = 0; j < value_len; j++) { diff --git a/examples/tests/kv_check/Makefile b/examples/tests/kv_check/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/kv_check/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/kv_interactive/Makefile b/examples/tests/kv_interactive/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/kv_interactive/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/kv_system/Makefile b/examples/tests/kv_system/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/kv_system/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/l3gd20/Makefile b/examples/tests/l3gd20/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/l3gd20/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/l3gd20/main.c b/examples/tests/l3gd20/main.c deleted file mode 100644 index b1e07e045..000000000 --- a/examples/tests/l3gd20/main.c +++ /dev/null @@ -1,40 +0,0 @@ -/* vim: set sw=2 expandtab tw=80: */ - -#include -#include -#include -#include - -static int decimals (float f, int n) -{ - return (int)((fabs(f - (int)(f))) * pow(10, n)); -} - -int main(void) { - L3GD20XYZ xyz; - int temp; - - if (!l3gd20_is_present()) { - printf("L3GD20 sensor driver not present\n"); - return -1; - } - - if (!l3gd20_power_on()) { - printf("L3GD20 device is not present\n"); - return -1; - } - - l3gd20_set_hpf_parameters(L3GD20_HPF_MODE_NORMAL, L3GD20_HPF_DIV_64); - l3gd20_enable_hpf(true); - while (1) { - if (l3gd20_read_xyz(&xyz) == RETURNCODE_SUCCESS && l3gd20_read_temperature(&temp) == RETURNCODE_SUCCESS) { - printf("temperature %d x %d.%d y %d.%d z %d.%d\r\n", temp, (int)xyz.x, decimals(xyz.x, 3), - (int)xyz.y, decimals(xyz.y, 3), (int)xyz.z, decimals(xyz.z, 3)); - } else { - printf("Error while reading gyroscope and temperature\n"); - } - delay_ms(10); - } - - return 0; -} diff --git a/examples/tests/lps25hb/Makefile b/examples/tests/lps25hb/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/lps25hb/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/lps25hb/main.c b/examples/tests/lps25hb/main.c deleted file mode 100644 index e080b23a3..000000000 --- a/examples/tests/lps25hb/main.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int main (void) { - printf("[LPS25HB] Test\n"); - - // Start a pressure measurement - unsigned pressure; - int rc = lps25hb_get_pressure_sync((int*) &pressure); - - if (rc < 0) { - printf("Error getting pressure: %d\n", rc); - return rc; - } else { - // Print the pressure value - printf("\tValue(%u ubar) [0x%X]\n\n", pressure, pressure); - return 0; - } -} diff --git a/examples/tests/lsm303dlhc/Makefile b/examples/tests/lsm303dlhc/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/lsm303dlhc/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/lsm303dlhc/main.c b/examples/tests/lsm303dlhc/main.c deleted file mode 100644 index 57a5822d2..000000000 --- a/examples/tests/lsm303dlhc/main.c +++ /dev/null @@ -1,61 +0,0 @@ -/* vim: set sw=2 expandtab tw=80: */ - -#include -#include -#include -#include - -#define SIGN(f) (f < 0 ? '-' : ' ') - -static int decimals (float f, int n) -{ - return (int)((fabs(f - (int)(f))) * pow(10, n)); -} - -int main(void) { - LSM303DLHCXYZ xyz; - float temp; - - if (lsm303dlhc_is_present()) { - printf("LSM303DLHC sensor is present\n"); - } else { - printf("LSM303DLHC sensor driver not present\n"); - return -1; - } - - if (lsm303dlhc_set_power_mode(LSM303DLHC_100HZ, LSM303DLHC_NORMAL)) { - printf("LSM303DLHC device set power mode\n"); - } else { - printf("LSM303DLHC device set power mode failed\n"); - } - - if (lsm303dlhc_set_accelerometer_scale_and_resolution(LSM303DLHC_SCALE_8G, false)) { - printf("LSM303DLHC device set scale\n"); - lsm303dlhc_set_temperature_and_magnetometer_rate(true, LSM303DLHC_M_220_0HZ); - lsm303dlhc_set_magnetometer_range(LSM303DLHC_RANGE_4_7G); - while (1) { - if (lsm303dlhc_read_acceleration_xyz(&xyz) == RETURNCODE_SUCCESS) { - printf("acceleration x %c%d.%d y %c%d.%d z %c%d.%d\n", SIGN(xyz.x), (int)xyz.x, decimals(xyz.x, 3), - SIGN(xyz.y), (int)xyz.y, decimals(xyz.y, 3), SIGN(xyz.z), (int)xyz.z, decimals(xyz.z, 3)); - } else { - printf("Error while reading acceleration\n"); - } - if (lsm303dlhc_read_temperature(&temp) == RETURNCODE_SUCCESS) { - printf("temperature %c%d.%d\n", SIGN(temp), (int)temp, decimals(temp, 1)); - } else { - printf("Error while reading temperature\n"); - } - if (lsm303dlhc_read_magnetometer_xyz(&xyz) == RETURNCODE_SUCCESS) { - printf("magnetometer x %c%d.%d y %c%d.%d z %c%d.%d\n", SIGN(xyz.x), (int)xyz.x, decimals(xyz.x, 3), - SIGN(xyz.y), (int)xyz.y, decimals(xyz.y, 3), SIGN(xyz.z), (int)xyz.z, decimals(xyz.z, 3)); - } else { - printf("Error while reading magnetometer\n"); - } - delay_ms(1000); - } - } else { - printf("LSM303DLHC device set scale failed\n"); - } - - return 0; -} diff --git a/examples/tests/max17205/Makefile b/examples/tests/max17205/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/max17205/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/max17205/README.md b/examples/tests/max17205/README.md deleted file mode 100644 index 743fc0633..000000000 --- a/examples/tests/max17205/README.md +++ /dev/null @@ -1,9 +0,0 @@ -MAX17205 Battery Monitor Test App -================================ - -This application tests the 5 functions of the max17205 battery monitor. - -It should return valid values (depending on the batter you are plugged into). - -When run when it is not connected to a max17205 it should return TOCK_ENOACK. - diff --git a/examples/tests/max17205/main.c b/examples/tests/max17205/main.c deleted file mode 100644 index 4e4091809..000000000 --- a/examples/tests/max17205/main.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int main (void) { - printf("[MAX17205] Test App\n"); - - uint64_t rom_id; - int rc = max17205_read_rom_id_sync(&rom_id); - if (rc == RETURNCODE_SUCCESS) { - printf("Found ROM ID: 0x%llX\n", rom_id); - } else { - printf("Got error: %s\n", tock_strrcode(rc)); - } - - printf("\n"); - - uint16_t status; - rc = max17205_read_status_sync(&status); - if (rc == RETURNCODE_SUCCESS) { - printf("Status: 0x%04X\n", status); - } else { - printf("Got error: %d - %s\n", rc, tock_strrcode(rc)); - } - - printf("\n"); - - uint16_t percent, soc_mah, soc_mah_full; - rc = max17205_read_soc_sync(&percent, &soc_mah, &soc_mah_full); - if (rc == RETURNCODE_SUCCESS) { - printf("Percent (.001%%): %ld\n", lrint(max17205_get_percentage_mP(percent))); - printf("State of charge in uAh: %ld\n", lrint(max17205_get_capacity_uAh(soc_mah))); - printf("Full charge in uAh: %ld\n", lrint(max17205_get_capacity_uAh(soc_mah_full))); - } else { - printf("Got error: %d - %s\n", rc, tock_strrcode(rc)); - } - - printf("\n"); - - uint16_t voltage; - int16_t current; - rc = max17205_read_voltage_current_sync(&voltage, ¤t); - if (rc == RETURNCODE_SUCCESS) { - printf("Voltage (mV): %ld\n", lrint(max17205_get_voltage_mV(voltage))); - printf("Current (uA): %ld\n", lrint(max17205_get_current_uA(current))); - } else { - printf("Got error: %d - %s\n", rc, tock_strrcode(rc)); - } -} diff --git a/examples/tests/microbit_v2/main.c b/examples/tests/microbit_v2/main.c index ca944d43c..ec2dda31d 100644 --- a/examples/tests/microbit_v2/main.c +++ b/examples/tests/microbit_v2/main.c @@ -3,19 +3,23 @@ #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include static int check_err(int retval, const char* func_name) { @@ -35,14 +39,14 @@ static void tone_callback(void) { static void light_leds(int leds[], int len) { for (int i = 0; i < len; i++) { - check_err(led_on(leds[i]), "led_on"); + check_err(libtock_led_on(leds[i]), "libtock_led_on"); } } -static void button_callback(int btn_num, - int button_pressed, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { +static void button_callback( + __attribute__ ((unused)) returncode_t ret, + int btn_num, + bool button_pressed) { // Do not run if this was a button release or if tone is not finished if (!button_pressed || !tone_complete) { @@ -56,58 +60,60 @@ static void button_callback(int btn_num, tone_complete = false; if (btn_num == 0) { // When playing notes, note that the minimum frequency the Microbit can play is 489 Hz. - check_err(tone(NOTE_C5, 500, tone_callback), "tone"); + check_err(libtock_buzzer_tone(NOTE_C5, 500, tone_callback), "libtock_buzzer_tone"); int leds[10] = {2, 6, 8, 11, 12, 13, 16, 18, 21, 23}; light_leds(leds, 10); } else if (btn_num == 1) { - check_err(tone(NOTE_E5, 500, tone_callback), "tone"); + check_err(libtock_buzzer_tone(NOTE_E5, 500, tone_callback), "libtock_buzzer_tone"); int leds[11] = {1, 2, 6, 8, 11, 12, 13, 16, 18, 21, 22}; light_leds(leds, 11); } } static void sample_sensors(void) { - check_err(led_toggle(0), "led_toggle"); // Blink top left LED + check_err(libtock_led_toggle(0), "led_toggle"); // Blink top left LED for (int i = 1; i < 25; i++) { - check_err(led_off(i), "led_off"); + check_err(libtock_led_off(i), "led_off"); } // Sensors: temperature, acceleration, sound pressure int temp = 0; - check_err(temperature_read_sync(&temp), "temperature_read_sync"); - uint32_t accel_mag = check_err(ninedof_read_accel_mag(), "ninedof_read_accel_mag"); + check_err(libtocksync_temperature_read(&temp), "temperature_read_sync"); + double accel_mag; + check_err(libtocksync_ninedof_read_accelerometer_magnitude( + &accel_mag), "libtocksync_ninedof_read_accelerometer_magnitude"); int x = 0; int y = 0; int z = 0; - check_err(ninedof_read_magnetometer_sync(&x, &y, &z), "ninedof_read_magnetometer_sync"); + check_err(libtocksync_ninedof_read_magnetometer(&x, &y, &z), "libtocksync_ninedof_read_magnetometer"); unsigned char sound_pres; - check_err(sound_pressure_read_sync(&sound_pres), "sound_pressure_read_sync"); + check_err(libtocksync_sound_pressure_read(&sound_pres), "libtocksync_sound_pressure_read"); // Analog inputs: P0-P2 uint16_t val = 0; - check_err(adc_sample_sync(0, &val), "adc_sample_sync"); + check_err(libtocksync_adc_sample(0, &val), "libtocksync_adc_sample"); int p0 = (val * 3300) / (4095 << 4); - check_err(adc_sample_sync(1, &val), "adc_sample_sync"); + check_err(libtocksync_adc_sample(1, &val), "libtocksync_adc_sample"); int p1 = (val * 3300) / (4095 << 4); - check_err(adc_sample_sync(2, &val), "adc_sample_sync"); + check_err(libtocksync_adc_sample(2, &val), "libtocksync_adc_sample"); int p2 = (val * 3300) / (4095 << 4); if (p0 < 10 || p1 < 10 || p2 < 10) { // pin is connected to gnd - check_err(led_on(20), "led_on"); + check_err(libtock_led_on(20), "led_on"); } // Digital inputs: P8, P9, P16 int p8 = 0; - check_err(gpio_read(8, &p8), "gpio_read"); + check_err(libtock_gpio_read(8, &p8), "gpio_read"); int p9 = 0; - check_err(gpio_read(9, &p9), "gpio_read"); + check_err(libtock_gpio_read(9, &p9), "gpio_read"); int p16 = 0; - check_err(gpio_read(16, &p16), "gpio_read"); + check_err(libtock_gpio_read(16, &p16), "gpio_read"); // print results printf("[Micro:bit Sensor Reading]\n"); // Temp is given in hundredths of a degree C, in format XX00 printf(" Temperature: reading: %d.0 degrees C\n", temp / 100); - printf(" Acceleration: %lu\n", accel_mag); + printf(" Acceleration: %f\n", accel_mag); printf(" Magnetometer: X: %d, Y: %d, Z: %d\n", x, y, z); printf(" Ambient Sound: %i\n", sound_pres); printf("ADC:\n"); @@ -138,25 +144,24 @@ int main(void) { printf("Now advertising every %d ms as '%s'\n", advertising_interval_ms, device_name); // Enable button callbacks - check_err(button_subscribe(button_callback, NULL), "button_subscribe"); - check_err(button_enable_interrupt(0), "button_enable_interrupt"); - check_err(button_enable_interrupt(1), "button_enable_interrupt"); + check_err(libtock_button_notify_on_press(0, button_callback), "libtock_button_notify_on_press"); + check_err(libtock_button_notify_on_press(1, button_callback), "libtock_button_notify_on_press"); printf("Set up button callbacks!\n"); // Enable sound pressure sensor - check_err(sound_pressure_enable(), "sound_pressure_enable"); + check_err(libtock_sound_pressure_command_enable(), "libtock_sound_pressure_command_enable"); printf("Enabled sound pressure!\n"); // Setup P8, P9, P16 - check_err(gpio_enable_input(8, PullDown), "gpio_enable_input"); // P8 - check_err(gpio_enable_input(9, PullDown), "gpio_enable_input"); // P9 - check_err(gpio_enable_input(16, PullDown), "gpio_enable_input"); // P16 + check_err(libtock_gpio_enable_input(8, libtock_pull_down), "libtock_gpio_enable_input"); // P8 + check_err(libtock_gpio_enable_input(9, libtock_pull_down), "libtock_gpio_enable_input"); // P9 + check_err(libtock_gpio_enable_input(16, libtock_pull_down), "libtock_gpio_enable_input"); // P16 printf("Set up gpio pins!\n"); printf("Setup complete!\n"); // sample sensors every second while (1) { sample_sensors(); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/mpu/Makefile b/examples/tests/mpu/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/mpu/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/mpu/README.md b/examples/tests/mpu/README.md new file mode 100644 index 000000000..cb03c4457 --- /dev/null +++ b/examples/tests/mpu/README.md @@ -0,0 +1,4 @@ +MPU Tests +========= + +Test that the MPU restricts process accesses correctly. diff --git a/examples/tests/mpu/main.c b/examples/tests/mpu/main.c deleted file mode 100644 index 6c68a8004..000000000 --- a/examples/tests/mpu/main.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include - -int main(void) { - __attribute__ ((unused)) uint8_t *memory_start = tock_app_memory_begins_at(); - __attribute__ ((unused)) uint8_t *memory_end = tock_app_memory_ends_at(); - __attribute__ ((unused)) uint8_t *flash_start = tock_app_flash_begins_at(); - __attribute__ ((unused)) uint8_t *flash_end = tock_app_flash_ends_at(); - __attribute__ ((unused)) uint8_t *grant_start = tock_app_grant_begins_at(); - - printf("\n[TEST] MPU Access\n"); - - printf("This test checks whether a read or write to a given\n"); - printf("address causes an MPU fault or not. Uncomment the\n"); - printf("memory access that you want to test.\n\n"); - - /* Example valid accesses. */ - - // Valid Access 1: Write to start of PAM - // *memory_start = 0; - - // Valid Access 2: Read from start of PAM - // uint8_t byte = *memory_start; - // printf("First byte of PAM: %X\n", byte); - - // Valid Access 3: Read from start of flash - // uint8_t byte = *flash_start; - // printf("First byte of flash: %X\n", byte); - - /* Example invalid accesses. */ - - // Invalid Access 1: Write to start of flash - // *flash_start = 0; - - // Invalid Access 2: Write to start of grant - // *grant_start = 0; - - // Invalid Access 3: Read from start of grant - // uint8_t byte = *grant_start; - // printf("Inaccesible byte: %X\n", byte); - - // Invalid Access 4: Write past process memory - // *memory_end = 0; - - // Invalid Access 5: Read past process memory - // uint8_t byte = *memory_end; - // printf("Inaccesible byte: %X\n", byte); -} diff --git a/examples/tests/mpu_walk_region/Makefile b/examples/tests/mpu/mpu_flash_end/Makefile similarity index 89% rename from examples/tests/mpu_walk_region/Makefile rename to examples/tests/mpu/mpu_flash_end/Makefile index 8f3698b98..693427774 100644 --- a/examples/tests/mpu_walk_region/Makefile +++ b/examples/tests/mpu/mpu_flash_end/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/mpu_flash_end/README.md b/examples/tests/mpu/mpu_flash_end/README.md similarity index 100% rename from examples/tests/mpu_flash_end/README.md rename to examples/tests/mpu/mpu_flash_end/README.md diff --git a/examples/tests/mpu_flash_end/main.c b/examples/tests/mpu/mpu_flash_end/main.c similarity index 94% rename from examples/tests/mpu_flash_end/main.c rename to examples/tests/mpu/mpu_flash_end/main.c index 332b52e41..e69249be4 100644 --- a/examples/tests/mpu_flash_end/main.c +++ b/examples/tests/mpu/mpu_flash_end/main.c @@ -1,6 +1,6 @@ #include -#include +#include int main(void) { printf("[TEST] MPU Flash End\n"); diff --git a/examples/tests/mpu_heap_end/Makefile b/examples/tests/mpu/mpu_flash_start/Makefile similarity index 89% rename from examples/tests/mpu_heap_end/Makefile rename to examples/tests/mpu/mpu_flash_start/Makefile index 8f3698b98..693427774 100644 --- a/examples/tests/mpu_heap_end/Makefile +++ b/examples/tests/mpu/mpu_flash_start/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/mpu/mpu_flash_start/README.md b/examples/tests/mpu/mpu_flash_start/README.md new file mode 100644 index 000000000..b14d90331 --- /dev/null +++ b/examples/tests/mpu/mpu_flash_start/README.md @@ -0,0 +1,5 @@ +MPU Flash Start +=============== + +This test verifies that an application cannot write to the beginning of its +flash region. diff --git a/examples/tests/mpu/mpu_flash_start/main.c b/examples/tests/mpu/mpu_flash_start/main.c new file mode 100644 index 000000000..be54bdb7e --- /dev/null +++ b/examples/tests/mpu/mpu_flash_start/main.c @@ -0,0 +1,13 @@ +#include + +#include + +int main(void) { + printf("[TEST] MPU Flash Start Write\n"); + + uint8_t* flash_start = tock_app_flash_begins_at(); + + printf("Writing first byte in flash...\n"); + *flash_start = 0; + printf("FAIL! Should not be able to write start of flash!!\n"); +} diff --git a/examples/tests/mpu_ram_end/Makefile b/examples/tests/mpu/mpu_grant_start/Makefile similarity index 89% rename from examples/tests/mpu_ram_end/Makefile rename to examples/tests/mpu/mpu_grant_start/Makefile index 8f3698b98..693427774 100644 --- a/examples/tests/mpu_ram_end/Makefile +++ b/examples/tests/mpu/mpu_grant_start/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../../.. +TOCK_USERLAND_BASE_DIR = ../../../.. # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/tests/mpu/mpu_grant_start/README.md b/examples/tests/mpu/mpu_grant_start/README.md new file mode 100644 index 000000000..29481865e --- /dev/null +++ b/examples/tests/mpu/mpu_grant_start/README.md @@ -0,0 +1,5 @@ +MPU Grant Start +=============== + +This test checks whether an application can read the first byte of the grant +region. diff --git a/examples/tests/mpu/mpu_grant_start/main.c b/examples/tests/mpu/mpu_grant_start/main.c new file mode 100644 index 000000000..c960a7512 --- /dev/null +++ b/examples/tests/mpu/mpu_grant_start/main.c @@ -0,0 +1,14 @@ +#include + +#include + +int main(void) { + printf("[TEST] MPU Grant Start\n"); + + uint8_t* grant_start = tock_app_grant_begins_at(); + + printf("Reading from grant region\n"); + uint8_t value = *grant_start; + printf("Address: %p, value: %02x\n", grant_start, value); + printf("FAIL! Should not be able to read grant region!!\n"); +} diff --git a/examples/tests/mpu/mpu_heap_end/Makefile b/examples/tests/mpu/mpu_heap_end/Makefile new file mode 100644 index 000000000..693427774 --- /dev/null +++ b/examples/tests/mpu/mpu_heap_end/Makefile @@ -0,0 +1,13 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +STACK_SIZE := 1024 + +# 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/mpu_heap_end/README.md b/examples/tests/mpu/mpu_heap_end/README.md similarity index 100% rename from examples/tests/mpu_heap_end/README.md rename to examples/tests/mpu/mpu_heap_end/README.md diff --git a/examples/tests/mpu_heap_end/main.c b/examples/tests/mpu/mpu_heap_end/main.c similarity index 96% rename from examples/tests/mpu_heap_end/main.c rename to examples/tests/mpu/mpu_heap_end/main.c index d505687ab..e57639b80 100644 --- a/examples/tests/mpu_heap_end/main.c +++ b/examples/tests/mpu/mpu_heap_end/main.c @@ -1,6 +1,6 @@ #include -#include +#include int main(void) { printf("[TEST] MPU test end of readable RAM\n"); diff --git a/examples/tests/mpu/mpu_ram_end/Makefile b/examples/tests/mpu/mpu_ram_end/Makefile new file mode 100644 index 000000000..693427774 --- /dev/null +++ b/examples/tests/mpu/mpu_ram_end/Makefile @@ -0,0 +1,13 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +STACK_SIZE := 1024 + +# 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/mpu_ram_end/README.md b/examples/tests/mpu/mpu_ram_end/README.md similarity index 100% rename from examples/tests/mpu_ram_end/README.md rename to examples/tests/mpu/mpu_ram_end/README.md diff --git a/examples/tests/mpu_ram_end/main.c b/examples/tests/mpu/mpu_ram_end/main.c similarity index 95% rename from examples/tests/mpu_ram_end/main.c rename to examples/tests/mpu/mpu_ram_end/main.c index 0b658c930..59d59f9ab 100644 --- a/examples/tests/mpu_ram_end/main.c +++ b/examples/tests/mpu/mpu_ram_end/main.c @@ -1,6 +1,6 @@ #include -#include +#include int main(void) { printf("[TEST] MPU RAM End\n"); diff --git a/examples/tests/mpu/mpu_stack_growth/Makefile b/examples/tests/mpu/mpu_stack_growth/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/examples/tests/mpu/mpu_stack_growth/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/mpu_stack_growth/main.c b/examples/tests/mpu/mpu_stack_growth/main.c similarity index 98% rename from examples/tests/mpu_stack_growth/main.c rename to examples/tests/mpu/mpu_stack_growth/main.c index 8b50eaee9..ebb409ff8 100644 --- a/examples/tests/mpu_stack_growth/main.c +++ b/examples/tests/mpu/mpu_stack_growth/main.c @@ -5,7 +5,7 @@ #include #include -#include +#include #define GROW_BY 0x100 diff --git a/examples/tests/mpu/mpu_walk_region/Makefile b/examples/tests/mpu/mpu_walk_region/Makefile new file mode 100644 index 000000000..693427774 --- /dev/null +++ b/examples/tests/mpu/mpu_walk_region/Makefile @@ -0,0 +1,13 @@ +# Makefile for user application + +# Specify this directory relative to the current application. +TOCK_USERLAND_BASE_DIR = ../../../.. + +# Which files to compile. +C_SRCS := $(wildcard *.c) + +STACK_SIZE := 1024 + +# 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/mpu_walk_region/README.md b/examples/tests/mpu/mpu_walk_region/README.md similarity index 100% rename from examples/tests/mpu_walk_region/README.md rename to examples/tests/mpu/mpu_walk_region/README.md diff --git a/examples/tests/mpu_walk_region/main.c b/examples/tests/mpu/mpu_walk_region/main.c similarity index 89% rename from examples/tests/mpu_walk_region/main.c rename to examples/tests/mpu/mpu_walk_region/main.c index a3bca382f..a4151d071 100644 --- a/examples/tests/mpu_walk_region/main.c +++ b/examples/tests/mpu/mpu_walk_region/main.c @@ -5,9 +5,9 @@ #include #include -#include -#include -#include +#include +#include +#include #if defined(__thumb__) static uint32_t read_cpsr(void) { @@ -58,9 +58,9 @@ static void dowork(uint8_t* from, uint8_t* to, uint32_t incr) { // the state of the first button if one is present on the board. static bool overrun(void) { int count, read, res; - res = button_count(&count); + res = libtock_button_count(&count); if (res == RETURNCODE_SUCCESS && count) { - button_read(0, &read); + libtock_button_read(0, &read); return read; } return false; @@ -90,7 +90,7 @@ int main(void) { putchar('\n'); dowork(flash_start, flash_end + ((do_overrun) ? 0x1000 : 0x0), 0x100); - delay_ms(2000); + libtocksync_alarm_delay_ms(2000); do_overrun = overrun(); printf("\nWalking memory\n"); @@ -99,6 +99,6 @@ int main(void) { dowork(memory_start, memory_limit + ((do_overrun) ? 0x1000 : 0x0), 0x100); - delay_ms(2000); + libtocksync_alarm_delay_ms(2000); } } diff --git a/examples/tests/mpu_stack_growth/Makefile b/examples/tests/mpu_stack_growth/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/mpu_stack_growth/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/multi_alarm_test/main.c b/examples/tests/multi_alarm_test/main.c index 23bffb784..01a8ad7e0 100644 --- a/examples/tests/multi_alarm_test/main.c +++ b/examples/tests/multi_alarm_test/main.c @@ -1,45 +1,47 @@ -#include #include -#include + +#include +#include static int interval; typedef struct { int led; - tock_timer_t timer; + libtock_alarm_t timer; + libtock_alarm_repeating_t repeating; } timer_data; static void toggle(int led_num) { - led_on(led_num); - delay_ms(300); - led_off(led_num); + libtock_led_on(led_num); + libtocksync_alarm_delay_ms(300); + libtock_led_off(led_num); } -static void event_cb(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, void* ud) { +static void event_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t expiration, + void* ud) { timer_data* td = (timer_data*)ud; toggle(td->led); } -static void start_cb(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, void* ud) { +static void start_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t expiration, + void* ud) { timer_data* td = (timer_data*)ud; - timer_every(interval, event_cb, ud, &td->timer); + libtock_alarm_repeating_every(interval, event_cb, ud, &td->repeating); toggle(td->led); } int main(void) { int spacing = 1000; // 1 second between each led int num_leds; - led_count(&num_leds); + libtock_led_count(&num_leds); interval = spacing * num_leds; for (int i = 0; i < num_leds; i++) { timer_data* td = (timer_data*)malloc(sizeof(timer_data)); td->led = i; - timer_in(spacing * (i + 1), start_cb, td, &td->timer); + libtock_alarm_in_ms(spacing * (i + 1), start_cb, td, &td->timer); } while (1) { diff --git a/examples/tests/nonvolatile_storage/main.c b/examples/tests/nonvolatile_storage/main.c index fe9b2ecc9..0b26f6df5 100644 --- a/examples/tests/nonvolatile_storage/main.c +++ b/examples/tests/nonvolatile_storage/main.c @@ -1,31 +1,13 @@ #include #include -#include +#include static int test_all(void); static int test(uint8_t *readbuf, uint8_t *writebuf, size_t size, size_t offset, size_t len); -static bool done = false; - -static void read_done(int length, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* ud) { - printf("\tFinished read! %i\n", length); - done = true; -} - -static void write_done(int length, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void* ud) { - printf("\tFinished write! %i\n", length); - done = true; -} - int main (void) { - printf("[Nonvolatile Storage] Test App\n"); + printf("[TEST] Nonvolatile Storage\n"); int r = test_all(); if (r == 0) { @@ -39,7 +21,7 @@ int main (void) { static int test_all(void) { int num_bytes; - nonvolatile_storage_internal_get_number_bytes(&num_bytes); + libtock_nonvolatile_storage_get_number_bytes((uint32_t*) &num_bytes); printf("Have %i bytes of nonvolatile storage\n", num_bytes); int r; @@ -61,53 +43,25 @@ static int test_all(void) { static int test(uint8_t *readbuf, uint8_t *writebuf, size_t size, size_t offset, size_t len) { int ret; + int length_written, length_read; printf("Test with size %d ...\n", size); - ret = nonvolatile_storage_internal_read_buffer(readbuf, size); - if (ret != RETURNCODE_SUCCESS) { - printf("\tERROR setting read buffer\n"); - return ret; - } - - ret = nonvolatile_storage_internal_write_buffer(writebuf, size); - if (ret != RETURNCODE_SUCCESS) { - printf("\tERROR setting write buffer\n"); - return ret; - } - - // Setup callbacks - ret = nonvolatile_storage_internal_read_done_subscribe(read_done, NULL); - if (ret != RETURNCODE_SUCCESS) { - printf("\tERROR setting read done callback\n"); - return ret; - } - - ret = nonvolatile_storage_internal_write_done_subscribe(write_done, NULL); - if (ret != RETURNCODE_SUCCESS) { - printf("\tERROR setting write done callback\n"); - return ret; - } - for (size_t i = 0; i < len; i++) { writebuf[i] = i; } - done = false; - ret = nonvolatile_storage_internal_write(offset, len); - if (ret != 0) { + ret = libtocksync_nonvolatile_storage_write(offset, len, writebuf, size, &length_written); + if (ret != RETURNCODE_SUCCESS) { printf("\tERROR calling write\n"); return ret; } - yield_for(&done); - done = false; - ret = nonvolatile_storage_internal_read(offset, len); - if (ret != 0) { + ret = libtocksync_nonvolatile_storage_read(offset, len, writebuf, size, &length_read); + if (ret != RETURNCODE_SUCCESS) { printf("\tERROR calling read\n"); return ret; } - yield_for(&done); for (size_t i = 0; i < len; i++) { if (readbuf[i] != writebuf[i]) { diff --git a/examples/tests/number_guess_game/main.c b/examples/tests/number_guess_game/main.c index 142fb237b..ab36bde71 100644 --- a/examples/tests/number_guess_game/main.c +++ b/examples/tests/number_guess_game/main.c @@ -3,12 +3,23 @@ #include #include -#include -#include +#include +#include + +static int getch(void) { + uint8_t buffer[1]; + int number_read; + libtocksync_console_read(buffer, 1, &number_read); + return buffer[0]; +} -int get_number(void); +static int putnstr(const char* str, int len) { + int number_written; + libtocksync_console_read((uint8_t*) str, len, &number_written); + return number_written; +} -int get_number(void) { +static int get_number(void) { char buffer[10] = {0}; int idx = 0; @@ -48,12 +59,13 @@ int get_number(void) { } int main(void) { + returncode_t ret; printf("Welcome to the number guessing game!\n\n"); // Get some random number uint16_t random; int count; - int ret = rng_sync((uint8_t*) &random, 2, 2, &count); + ret = libtocksync_rng_get_random_bytes((uint8_t*) &random, 2, 2, &count); if (ret != RETURNCODE_SUCCESS || count != 2) { printf("Error getting random number! There is a bug in this game :(\n"); return -1; diff --git a/examples/tests/proximity/main.c b/examples/tests/proximity/main.c index 19aadc7d5..0ed842ced 100644 --- a/examples/tests/proximity/main.c +++ b/examples/tests/proximity/main.c @@ -2,26 +2,24 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include -int main(void){ - - printf("Proximity Sensor Test\n"); +int main(void) { + returncode_t ret; + printf("[TEST] Proximity Sensor\n"); // Check if driver/sensor is on the board - if ( driver_exists(DRIVER_NUM_PROXIMITY) ) { - printf("Driver exists\n"); - } else { - printf("Driver does not exist\n"); + if (!libtock_proximity_exists()) { + printf("Proximity sensor does not exist\n"); return -1; } // Check led count int num_leds; - led_count(&num_leds); + libtock_led_count(&num_leds); printf("Number of LEDs on the board: %d\n", num_leds); // Blink LED lights faster as proximity reading increases. @@ -30,21 +28,23 @@ int main(void){ uint8_t frequency = 255; int period = 1000; - proximity_set_interrupt_thresholds(0, 175); - proximity_read_on_interrupt_sync(&frequency); + ret = libtocksync_proximity_read_on_interrupt(0, 175, &frequency); + if (ret != RETURNCODE_SUCCESS) { + printf("Unable to setup proximity interrupts\n"); + return -2; + } while (true) { - for (int led = 0; led < num_leds; led++) { - led_on(led); - delay_ms(period / (frequency + 1)); - led_off(led); + libtock_led_on(led); + libtocksync_alarm_delay_ms(period / (frequency + 1)); + libtock_led_off(led); } - if (proximity_read_sync(&frequency) < 0) { + ret = libtocksync_proximity_read(&frequency); + if (ret != RETURNCODE_SUCCESS) { printf("Could not read proximity"); - return -1; + return -3; } - } -} \ No newline at end of file +} diff --git a/examples/tests/restart/main.c b/examples/tests/restart/main.c index fad74fff7..e7dec374d 100644 --- a/examples/tests/restart/main.c +++ b/examples/tests/restart/main.c @@ -1,7 +1,7 @@ #include -#include -#include +#include +#include int x = 1; int z = 0; @@ -9,7 +9,7 @@ int main(void) { printf("Testing restart. x=%d (should be 1), z=%d (should be 0)\n", x, z); x++; z++; - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Restarting.\n"); tock_restart(0); return 0; diff --git a/examples/tests/rf233/Makefile b/examples/tests/rf233/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/rf233/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/rf233/main.c b/examples/tests/rf233/main.c deleted file mode 100644 index d7336660d..000000000 --- a/examples/tests/rf233/main.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Example rf233 send/receive application. - * Callback function is supplied by user - * and is called by rf233 interrupt handler. - */ - -#include -#include -#include -#include -#include - -#include "rf233-arch.h" -#include "rf233-config.h" -#include "rf233-const.h" -#include "rf233.h" -#include "trx_access.h" - -// Callback function supplied by user -int callback(void*, int, uint16_t, uint16_t, uint16_t); - -int main(void) { - char buf[2] = { 0xde, 0xad }; - - rf233_init(0xab, 0xbc, 0xcd); - rf233_rx_data(callback); - - while (1) { - led_on(0); - printf("--------Cycle Start----\n"); - rf233_tx_data(0x00, buf, 2); - delay_ms(10); - rf233_sleep(); - delay_ms(1000); - rf233_on(); - led_off(1); - delay_ms(10000); - printf("--------Cycle End----\n"); - } -} - -int callback(void* buffer, - int buffer_len, - __attribute__ ((unused)) uint16_t src, - __attribute__ ((unused)) uint16_t dest, - __attribute__ ((unused)) uint16_t pan_id) { - printf("Rx callback!\n"); - uint8_t* bytes = (uint8_t*) buffer; - for (int i = 0; i < buffer_len; i++) { - printf(" Byte %i = %02x\n", i, bytes[i]); - } - return 0; -} diff --git a/examples/tests/rf233/rf233-arch.h b/examples/tests/rf233/rf233-arch.h deleted file mode 100644 index c1f6f0170..000000000 --- a/examples/tests/rf233/rf233-arch.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _RF233_ARCH_H_ -#define _RF233_ARCH_H_ - -#include -#include -#include -void wake_from_sleep(void); -void goto_sleep(void); -/* -void rf233_arch_init(void); -void rf233_arch_reset(void); -uint8_t rf233_arch_status(void); - -int rf233_arch_spi_busy(void); -uint8_t rf233_arch_read_reg(uint8_t reg); -int rf233_arch_write_reg(uint8_t reg, uint8_t val); -int rf233_arch_read_frame(uint8_t *buf, uint8_t len); -int rf233_arch_write_frame(uint8_t *buf, uint8_t len); -int rf233_arch_burstread_sram(uint8_t *buf, uint8_t offset, uint8_t len); -int rf233_arch_burstwrite_sram(uint8_t *buf, uint8_t offset, uint8_t len);*/ - -#endif /* _RF233_ARCH_H_ */ diff --git a/examples/tests/rf233/rf233-config.h b/examples/tests/rf233/rf233-config.h deleted file mode 100644 index 3cfcab4e0..000000000 --- a/examples/tests/rf233/rf233-config.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _RF233_CONFIG_H_ -#define _RF233_CONFIG_H_ -/*---------------------------------------------------------------------------*/ -/* Set radio channel, default channel 26 as it is not overlapping with Wi-Fi */ -#define PHY_CC_CCA_CONF (26 | PHY_CC_CCA_MODE_CS_OR_ED) -/*---------------------------------------------------------------------------*/ -/* - * Define whether to use hardware (RF233) CRC/FCS check. If >0, the radio FCS is - * taken into account and the frame is dropped if not CRC/FCS passes. - * If 0, the frame is passed to higher layers even if corrupt. This setting is - * used if the radio is used with non-802.15.4-2006 frames, or if the FCS check - * is performed in layers above this. - */ -/*---------------------------------------------------------------------------*/ -#define RF233_REG_TRX_CTRL_1_CONF (TRX_CTRL_1_DIG34_RXTX_INDICATOR | TRX_CTRL_1_SPI_CMD_TRX_STATUS | TRX_CTRL_1_AUTO_CRC) -#define RF233_REG_PHY_TX_PWR_CONF (TXP_4) -#define RF233_REG_PHY_CC_CCA_CONF (PHY_CC_CCA_CONF) /* see above */ -#define RF233_REG_TRX_CTRL_2_CONF (TRX_CTRL_2_RX_SAFE_MODE | DATA_RATE_250) /* disallow overwriting rxfifo until prev has been read */ -#define RF233_REG_IRQ_MASK_CONF (IRQ_TRXBUF_ACCESS_VIOLATION | IRQ_TRX_DONE | IRQ_PLL_LOCK) // - -#endif /* _RF233_CONFIG_H_ */ diff --git a/examples/tests/rf233/rf233-const.h b/examples/tests/rf233/rf233-const.h deleted file mode 100644 index 154456561..000000000 --- a/examples/tests/rf233/rf233-const.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _RF233_CONST_H_ -#define _RF233_CONST_H_ - -/* AT86RF233 register addresses and some bit fields */ -#define RF233_REG_TRX_STATUS (0x01) - #define TRX_CCA_DONE (1 << 7) - #define TRX_CCA_STATUS (1 << 6) - #define TRX_STATUS (0x1F) /* radio status bit field */ - #define STATE_P_ON (0x00) - #define STATE_BUSY_RX (0x01) - #define STATE_BUSY_TX (0x02) /* 7.2 - 13.8 mA */ - #define STATE_RX_ON (0x06) /* 11.8 mA */ - #define STATE_TRX_OFF (0x08) /* 300 uA */ - #define STATE_PLL_ON (0x09) /* 5.2 mA */ - #define STATE_SLEEP (0x0F) /* 0.2 uA */ - #define STATE_PREP_DEEP_SLEEP (0x10) - #define STATE_BUSY_RX_AACK (0x11) - #define STATE_BUSY_TX_ARET (0x12) - #define STATE_RX_AACK_ON (0x16) - #define STATE_TX_ARET_ON (0x19) - #define STATE_TRANSITION (0x1F) - #define RF233_REG_TRX_STATE (0x02) - /** Access parameters for sub-register RX_PDT_DIS in register @ref RG_RX_SYN */ - #define SR_RX_PDT_DIS 0x15, 0x80, 7 - /** Constant RX_ENABLE for sub-register @ref SR_RX_PDT_DIS in register RX_SYN */ - #define RX_ENABLE (0) - /** Access parameters for sub-register RND_VALUE in register @ref RG_PHY_RSSI */ - #define SR_RND_VALUE 0x06, 0x60, 5 - /** Access parameters for sub-register MAX_FRAME_RETRIES in register @ref RG_XAH_CTRL_0 */ - #define SR_MAX_FRAME_RETRIES 0x2C, 0xF0, 4 - /** Access parameters for sub-register MAX_CSMA_RETRIES in register @ref RG_XAH_CTRL_0 */ - #define SR_MAX_CSMA_RETRIES 0x2C, 0X0E, 1 - - #define TRX_STATE_TRAC_STATUS (0xE0) /* result of transaction in extended mode */ - #define TRAC_SUCCESS (0 << 5) - #define TRAC_SUCCESS_DATA_PENDING (1 << 5) - #define TRAC_SUCCESS_WAIT_FOR_ACK (2 << 5) - #define TRAC_CHANNEL_ACCESS_FAIL (3 << 5) - #define TRAC_NO_ACK (5 << 5) - #define TRAC_INVALID (7 << 5) - #define TRX_STATE_TRX_COMMAND (0x1F) - #define TRXCMD_NOP (0x00) - #define TRXCMD_TX_START (0x02) - #define TRXCMD_FORCE_TRX_OFF (0x03) - #define TRXCMD_FORCE_PLL_ON (0x04) - #define TRXCMD_RX_ON (0x06) - #define TRXCMD_TRX_OFF (0x08) - #define TRXCMD_PLL_ON (0x09) - #define TRXCMD_PREP_DEEP_SLEEP (0x10) - #define TRXCMD_RX_AACK_ON (0x16) - #define TRXCMD_TX_ARET_ON (0x19) -#define RF233_REG_TRX_CTRL_0 (0x03) -#define RF233_REG_TRX_CTRL_1 (0x04) - #define TRX_CTRL_1_PA_EXT_EN (1 << 7) /* pin DIG3/DIG4 indicates tx/rx mode */ - #define TRX_CTRL_1_DIG34_RXTX_INDICATOR TRX_CTRL_1_PA_EXT_EN /* synonym */ - #define TRX_CTRL_1_DIG2_TIMESTAMPING (1 << 6) /* pin DIG2 goes high ca 200us after SFD finished */ - #define TRX_CTRL_1_AUTO_CRC (1 << 5) - #define TRX_CTRL_1_FRAME_BUF_EMPTY_EN (1 << 4) /* IRQ pin turns into indicator during frame buffer reads */ - #define TRX_CTRL_1_SPI_CMD_TRX_STATUS (1 << 2) - #define TRX_CTRL_1_SPI_CMD_RSSI (2 << 2) - #define TRX_CTRL_1_SPI_CMD_IRQ_STATUS (3 << 2) - #define TRX_CTRL_1_IRQ_MASK_MODE (1 << 1) /* irqs shown in IRQ_STATUS even if not in IRQ_MASK */ - #define TRX_CTRL_1_IRQ_POL_ACTIVE_LOW (1 << 0) -#define RF233_REG_PHY_TX_PWR (0x05) - #define PHY_TX_PWR_TXP (0x0F) - #define TXP_4 (0x00) - #define TXP_3P7 (0x01) - #define TXP_3P4 (0x02) - #define TXP_3 (0x03) - #define TXP_2P5 (0x04) - #define TXP_2 (0x05) - #define TXP_1 (0x06) - #define TXP_0 (0x07) - #define TXP_M1 (0x08) - #define TXP_M2 (0x09) - #define TXP_M3 (0x0A) - #define TXP_M4 (0x0B) - #define TXP_M6 (0x0C) - #define TXP_M8 (0x0D) - #define TXP_M12 (0x0E) - #define TXP_M17 (0x0F) -#define RF233_REG_PHY_RSSI (0x06) - #define PHY_RSSI_CRC_VALID (1 << 7) /* FCS/CRC valid if set */ - #define PHY_RSSI_RNG (0x60) /* two-bit RNG */ - #define PHY_RSSI_RSSI (0x1F) /* RSSI measurement */ -#define RF233_REG_PHY_ED_LEVEL (0x07) -#define RF233_REG_PHY_CC_CCA (0x08) - #define PHY_CC_CCA_CHANNEL (0x1F) - #define PHY_CC_CCA_DO_CCA (1 << 7) /* starts manual CCA */ - #define PHY_CC_CCA_MODE_CS_OR_ED (0 << 5) - #define PHY_CC_CCA_MODE_ED (1 << 5) - #define PHY_CC_CCA_MODE_CS (2 << 5) - #define PHY_CC_CCA_MODE_CS_AND_ED (3 << 5) -#define RF233_REG_CCA_THRES (0x09) -#define RF233_REG_RX_CTRL (0x0A) -#define RF233_REG_SFD_VALUE (0x0B) -#define RF233_REG_TRX_CTRL_2 (0x0C) -#define FTN_START (0x80) - #define TRX_CTRL_2_RX_SAFE_MODE (1 << 7) /* disallow rx buffer overwrites */ - #define DATA_RATE_250 (0) - #define DATA_RATE_500 (1) - #define DATA_RATE_1000 (2) - #define DATA_RATE_2000 (3) - #define DATA_RATE_2000_SCRAM_EN (1 << 5) /* enable additional scrambling, mandatory for 2k data rate */ -#define RF233_REG_ANT_DIV (0x0D) -#define RF233_REG_IRQ_MASK (0x0E) - #define IRQ_BAT_LOW (1 << 7) - #define IRQ_TRX_UR (1 << 6) /* frame buffer violation */ - #define IRQ_TRXBUF_ACCESS_VIOLATION IRQ_TRX_UR /* synonym */ - #define IRQ_AMI (1 << 5) /* address matching on rx */ - #define IRQ_RX_ADDRESS_MATCH IRQ_AMI /* synonym */ - #define IRQ_CCA_ED_DONE (1 << 4) /* CCA or ED is done */ - #define IRQ_TRX_END (1 << 3) /* frame tx or rx complete */ - #define IRQ_TRX_DONE IRQ_TRX_END /* synonym */ - #define IRQ_RX_START (1 << 2) /* frame rx started, frame len can be read from fifo[0] */ - #define IRQ_FRAME_RX_START IRQ_RX_START /* synonym */ - #define IRQ_PLL_UNLOCK (1 << 1) - #define IRQ_PLL_LOCK (1 << 0) -#define RF233_REG_IRQ_STATUS (0x0F) /* reading this also clears it */ -#define RF233_REG_VREG_CTRL (0x10) -#define RF233_REG_BATMON (0x11) -#define RF233_REG_XOSC_CTRL (0x12) -#define RF233_REG_CC_CTRL_0 (0x13) -#define RF233_REG_CC_CTRL_1 (0x14) -#define RF233_REG_RX_SYN (0x15) -#define RF233_REG_TRX_RPC (0x16) -#define RF233_REG_XAH_CTRL_1 (0x17) - #define AACK_PROM_MODE (1 << 1) -#define RF233_REG_FTN_CTRL (0x18) -#define RF233_REG_XAH_CTRL_2 (0x19) -#define RF233_REG_PLL_CF (0x1A) - #define PLL_CF_START_CAL (1 << 7) /* start manual calibration; reads one until done */ - #define PLL_CF_DO_MANUAL_CAL (0xD7) /* to do manual calibration, write this value to the reg (includes defaults) */ -#define RF233_REG_PLL_DCU (0x1B) -#define RF233_REG_PART_NUM (0x1C) -#define RF233_REG_VERSION_NUM (0x1D) -#define RF233_REG_MAN_ID_0 (0x1E) -#define RF233_REG_MAN_ID_1 (0x1F) -#define RF233_REG_SHORT_ADDR_0 (0x20) -#define RF233_REG_SHORT_ADDR_1 (0x21) -#define RF233_REG_PAN_ID_0 (0x22) -#define RF233_REG_PAN_ID_1 (0x23) -#define RF233_REG_IEEE_ADDR_0 (0x24) -#define RF233_REG_IEEE_ADDR_1 (0x25) -#define RF233_REG_IEEE_ADDR_2 (0x26) -#define RF233_REG_IEEE_ADDR_3 (0x27) -#define RF233_REG_IEEE_ADDR_4 (0x28) -#define RF233_REG_IEEE_ADDR_5 (0x29) -#define RF233_REG_IEEE_ADDR_6 (0x2A) -#define RF233_REG_IEEE_ADDR_7 (0x2B) -#define RF233_REG_XAH_CTRL_0 (0x2C) -#define RF233_REG_CSMA_SEED_0 (0x2D) -#define RF233_REG_CSMA_SEED_1 (0x2E) -#define RF233_REG_CSMA_BE (0x2F) -#define RF233_REG_TST_CTRL_DIGI (0x36) -#define RF233_REG_TST_AGC (0x3C) -#define RF233_REG_TST_SDM (0x3D) -#define RF233_REG_PHY_TX_TIME (0x3B) - -#define RF233_REG_ADDR_MIN (0x00) /* lowest register address */ -#define RF233_REG_ADDR_MAX (0x3D) /* highest register address */ - -/* datasheet 6.3, SPI access and first SPI byte */ -/* - * Following Atmel nomenclature, - * Register access is single-register-read access - * Frame Buffer access is access to the shared rx/tx data buffer, always from 0 - * SRAM access is access to the same buffer but from a given offset, and to access the - * AES buffer. - * - * This means, registers can only be read/written in single r/w mode. - * SRAM is the same as Frame buffer access, but can also read AES, and from an offset - * Frame Buffer reads the trx-fifo, and first byte is the Length byte, then up - * to 128 bytes data, followed by 3 bytes metadata (LQI, ED, RX_STATUS). - * - */ -#define READ_ACCESS (0 << 6) -#define WRITE_ACCESS (1 << 6) - -#define REGISTER_ACCESS (1 << 7) -#define FRAME_BUFFER_ACCESS (1 << 5) -#define SRAM_ACCESS (0 << 5) - -#define FRAMEBUF_ADDR_LO (0x00) -#define FRAMEBUF_ADDR_HI (0x7F) /* ie the trx-fifo is 128B long */ -#define AES_ADDR_LO (0x82) -#define AES_ADDR_HI (0x94) - -/* bit fields of RX_STATUS (last byte when reading packet buffer) */ -#define RX_STATUS_CRC_OK (1 << 7) /* CRC/FCS */ -#define RX_STATUS_TRAC_STATUS (0x70) - -/* - * buffer is shared between Rx and Tx; rxdata rx is overwritten by new rx-data - * or any write access. - */ -#define TRX_BUFFER_LENGTH 128 /* bytes */ - -#endif /* _RF233_CONST_H_ */ diff --git a/examples/tests/rf233/rf233.c b/examples/tests/rf233/rf233.c deleted file mode 100644 index 4109e1c86..000000000 --- a/examples/tests/rf233/rf233.c +++ /dev/null @@ -1,956 +0,0 @@ -// Implementation of an RF233 radio stack for the Tock operating -// system. Adapted from the Contiki RF233 stack provided as part -// of Atmel Studio. The licenses for the original code are at the -// bottom of the file to reduce clutter. -// -// Author: Philip Levis -// Date: April 18 2016 - - -#include -#include -#include -#include - -#include "rf233-arch.h" -#include "rf233-config.h" -#include "rf233-const.h" -#include "rf233.h" -#include "trx_access.h" - -#define RADIO_SLP 8 -#define RADIO_RST 9 -#define RADIO_IRQ 10 - -/*---------------------------------------------------------------------------*/ -static int on(void); -static int off(void); -static void rf_generate_random_seed(void); -static void flush_buffer(void); -static uint8_t flag_transmit = 0; -static uint8_t ack_status = 0; -static volatile int radio_is_on = 0; -static volatile int pending_frame = 0; -static volatile int sleep_on = 0; -static int rf233_prepare_without_header(const uint8_t *data, unsigned short data_len); -static int rf233_setup(void); -static int rf233_prepare(const void *payload, unsigned short payload_len); -static int rf233_transmit(void); -static int (*rx_callback)(void*, int, uint16_t, uint16_t, uint16_t); -static int set_callback = 0; - -#define IEEE802154_CONF_PANID 0x1111 - -enum { - RADIO_TX_OK = 0, - RADIO_TX_ERR = 1, - RADIO_TX_NOACK = 2, - RADIO_TX_COLLISION = 3 -}; - -typedef struct { - uint16_t fcf; - uint8_t seq; - uint16_t pan; - uint16_t dest; - uint16_t src; - char payload[]; -} __attribute__((packed)) header_t; - -static header_t radio_header; - -/*---------------------------------------------------------------------------*/ -int rf233_read(void *buf, unsigned short bufsize); -int rf233_receiving_packet(void); -int rf233_pending_packet(void); - -/*---------------------------------------------------------------------------*/ -/* convenience macros */ -// #define RF233_STATUS() rf233_arch_status() -#define RF233_COMMAND(c) trx_reg_write(RF233_REG_TRX_STATE, c) - -/* each frame has a footer consisting of LQI, ED, RX_STATUS added by the radio */ -// #define FOOTER_LEN 3 /* bytes */ -#define MAX_PACKET_LEN 127 /* bytes, excluding the length (first) byte */ -#define PACKETBUF_SIZE 128 /* bytes, for even int writes */ -#define HEADER_SIZE 9 /* bytes */ - -/*---------------------------------------------------------------------------*/ -#define _DEBUG_ 0 -#define DEBUG_PRINTDATA 0 /* print frames to/from the radio; requires DEBUG == 1 */ -#if _DEBUG_ -#define PRINTF(...) printf(__VA_ARGS__) - -// Used for debugging output -static const char* state_str(uint8_t state) { - switch (state) { - case STATE_P_ON: - return "STATE_POWER_ON"; - case STATE_BUSY_RX: - return "STATE_BUSY_RX"; - case STATE_BUSY_TX: - return "STATE_BUSY_TX"; - case STATE_RX_ON: - return "STATE_RX_ON"; - case STATE_TRX_OFF: - return "STATE_TRX_OFF"; - case STATE_PLL_ON: - return "STATE_PLL_ON"; - case STATE_SLEEP: - return "STATE_SLEEP"; - case STATE_PREP_DEEP_SLEEP: - return "STATE_PREP_DEEP_SLEEP"; - case STATE_BUSY_RX_AACK: - return "STATE_BUSY_RX_AACK"; - case STATE_BUSY_TX_ARET: - return "STATE_BUSY_TX_ARET"; - case STATE_RX_AACK_ON: - return "STATE_RX_AACK_ON"; - case STATE_TX_ARET_ON: - return "STATE_TX_ARET_ON"; - case STATE_TRANSITION: - return "STATE_TRANSITION"; - default: - return "STATE UNKNOWN!!!"; - } -} - -#else -#define PRINTF(...) -#endif - - -// Section 9.8 of the RF233 manual suggests recalibrating filters at -// least every 5 minutes of operation. Transitioning out of sleep -// resets the filters automatically. -#pragma GCC diagnostic ignored "-Wunused-function" -static void calibrate_filters(void) { - PRINTF("RF233: Calibrating filters.\n"); - trx_reg_write(RF233_REG_FTN_CTRL, 0x80); - while (trx_reg_read(RF233_REG_FTN_CTRL) & 0x80); -} - -uint8_t recv_data[PACKETBUF_SIZE]; -uint8_t packetbuf[PACKETBUF_SIZE]; - -static void* packetbuf_dataptr(void) { - return (void*)packetbuf; -} - -static void packetbuf_clear(void) { - int* ptr = (int*)packetbuf; - for (int i = 0; i < PACKETBUF_SIZE / 4; i++) { - *ptr++ = 0x00000000; - } -} - -uint8_t trx_reg_read(uint8_t addr) { - uint8_t command = addr | READ_ACCESS_COMMAND; - char buf[2]; - buf[0] = command; - buf[1] = 0; - spi_read_write_sync(buf, buf, 2); - return buf[1]; -} - -uint8_t trx_bit_read(uint8_t addr, uint8_t mask, uint8_t pos) { - uint8_t ret; - ret = trx_reg_read(addr); - ret &= mask; - ret >>= pos; - return ret; -} - -void trx_reg_write(uint8_t addr, uint8_t data) { - uint8_t command = addr | WRITE_ACCESS_COMMAND; - char buf[2]; - buf[0] = command; - buf[1] = data; - spi_write_sync(buf, 2); - return; -} - -void trx_bit_write(uint8_t reg_addr, - uint8_t mask, - uint8_t pos, - uint8_t new_value) { - uint8_t current_reg_value; - current_reg_value = trx_reg_read(reg_addr); - current_reg_value &= ~mask; - new_value <<= pos; - new_value &= mask; - new_value |= current_reg_value; - trx_reg_write(reg_addr, new_value); -} - -void trx_sram_read(uint8_t addr, uint8_t *data, uint8_t length) { - spi_hold_low(); - /* Send the command byte */ - uint8_t __attribute__ ((unused)) tmp1 = spi_write_byte(TRX_CMD_SR); - /* Send the command byte */ - uint8_t __attribute__ ((unused)) tmp2 = spi_write_byte(addr); - PRINTF("RF233: SRAM read"); - PRINTF("0x%x 0x%x, ", tmp1, tmp2); - /* Send the address from which the read operation should start */ - /* Upload the received byte in the user provided location */ - for (uint8_t i = 0; i < length; i++) { - PRINTF("%02x ", data[i]); - data[i] = spi_write_byte(0); - } - spi_release_low(); - PRINTF("\n"); - -} - -void trx_frame_read(uint8_t *data, uint8_t length) { - spi_hold_low(); - spi_write_byte(TRX_CMD_FR); - for (uint8_t i = 0; i < length; i++) { - data[i] = spi_write_byte(0); - } - spi_release_low(); -} - -void trx_frame_write(uint8_t *data, uint8_t length) { - spi_hold_low(); - spi_write_byte(TRX_CMD_FW); - for (uint8_t i = 0; i < length; i++) { - spi_write_byte(data[i]); - } - spi_release_low(); -} - - -/*---------------------------------------------------------------------------*/ -/** - * \brief Get radio channel - * \return The radio channel - */ -int rf_get_channel(void) { - uint8_t channel; - channel = trx_reg_read(RF233_REG_PHY_CC_CCA) & PHY_CC_CCA_CHANNEL; - // printf("rf233 channel%d\n",channel); - return (int)channel; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Set radio channel - * \param ch The radio channel - * \retval -1 Fail: channel number out of bounds - * \retval 0 Success - */ -int rf_set_channel(uint8_t ch) { - uint8_t temp; - PRINTF("RF233: setting channel %u\n", ch); - if (ch > 26 || ch < 11) { - return -1; - } - - /* read-modify-write to conserve other settings */ - temp = trx_reg_read(RF233_REG_PHY_CC_CCA); - temp &= ~PHY_CC_CCA_CHANNEL; - temp |= ch; - trx_reg_write(RF233_REG_PHY_CC_CCA, temp); - return 0; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Get transmission power - * \return The transmission power - */ -int rf233_get_txp(void) { - PRINTF("RF233: get txp\n"); - return trx_reg_read(RF233_REG_PHY_TX_PWR_CONF) & PHY_TX_PWR_TXP; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Set transmission power - * \param txp The transmission power - * \retval -1 Fail: transmission power out of bounds - * \retval 0 Success - */ -int rf233_set_txp(uint8_t txp) { - PRINTF("RF233: setting txp %u\n", txp); - if (txp > TXP_M17) { - /* undefined */ - return -1; - } - - trx_reg_write(RF233_REG_PHY_TX_PWR_CONF, txp); - return 0; -} - -static bool radio_pll; -static bool radio_tx; -static bool radio_rx; - -static void interrupt_callback(int _a __attribute__((unused)), - int _b __attribute__((unused)), - int _c __attribute__((unused)), - void* _ud __attribute__((unused))) { - volatile uint8_t irq_source; - PRINTF("RF233: interrupt handler.\n"); - /* handle IRQ source (for what IRQs are enabled, see rf233-config.h) */ - irq_source = trx_reg_read(RF233_REG_IRQ_STATUS); - PRINTF(" interrupt sources: 0x%x\n", (int)irq_source); - if (irq_source & IRQ_PLL_LOCK) { - PRINTF("RF233: PLL locked.\n"); - radio_pll = true; - } - - if (irq_source & IRQ_RX_START) { - PRINTF("RF233: Interrupt receive start.\n"); - } else if (irq_source & IRQ_TRX_DONE) { - PRINTF("RF233: TRX_DONE handler.\n"); - // Completed a transmission - if (flag_transmit != 0) { - PRINTF("RF233: Interrupt transmit.\n"); - flag_transmit = 0; - if (!(trx_reg_read(RF233_REG_TRX_STATE) & TRX_STATE_TRAC_STATUS)) { - flag_transmit = ack_status = 1; - } - RF233_COMMAND(TRXCMD_RX_ON); - PRINTF("RF233: TX complete, go back to RX with acks on.\n"); - radio_tx = true; - return; - } else { - // PRINTF("RF233: Interrupt receive.\n"); - packetbuf_clear(); - pending_frame = 1; - int len = rf233_read(packetbuf_dataptr(), MAX_PACKET_LEN); - if (len > 0) { - PRINTF("RF233: Received packet and read from device.\n\n"); - } else { - PRINTF("RF233: Read failed.\n\n"); - } - radio_rx = true; - return; - } - } -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief Initialize the radio library - * \return Returns success/fail - * \retval 0 Success - */ -int rf233_init(uint16_t channel, uint16_t from_addr, uint16_t pan_id) { - PRINTF("RF233: init.\n"); - // 0x61 0xAA - radio_header.dest = channel; // TODO ?? - radio_header.fcf = 0xAA61; // TODO verify - radio_header.src = from_addr; - radio_header.pan = pan_id; - spi_set_chip_select(1); - spi_set_rate(1000000); - spi_set_phase(0); - spi_set_polarity(0); - return rf233_setup(); -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief Sets callback function for radio receive - * \return Returns success/fail - * \retval 0 Success - */ -int rf233_rx_data(int (*callback)(void*, int, uint16_t, uint16_t, uint16_t)) { - rx_callback = callback; - set_callback = 1; - return 0; -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief Send data over radio - * \return Returns success/fail - * \retval 0 Success - */ -int rf233_tx_data(uint16_t to_addr, void* payload, int payload_len) { - PRINTF("RF233: send %u\n", payload_len); - radio_header.dest = to_addr; - if (rf233_prepare_without_header(payload, payload_len) != RADIO_TX_OK) { - return RADIO_TX_ERR; - } - return rf233_transmit(); -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief Setup and turn on the radio - * \return Returns success/fail - * \retval 0 Success - */ -int rf233_setup(void) { - volatile uint8_t regtemp; - volatile uint8_t radio_state; /* don't optimize this away, it's important */ - - /* init SPI and GPIOs, wake up from sleep/power up. */ - spi_init(); - // RF233 expects line low for CS, this is default SAM4L behavior - // POL = 0 means idle is low - spi_set_chip_select(3); - spi_set_rate(400000); - spi_set_polarity(0); - // PHASE = 0 means sample leading edge - spi_set_phase(0); - - /* reset will put us into TRX_OFF state */ - /* reset the radio core */ - gpio_enable_output(RADIO_RST); - gpio_enable_output(RADIO_SLP); - gpio_clear(RADIO_RST); - delay_ms(1); - gpio_set(RADIO_RST); - gpio_clear(RADIO_SLP); /* be awake from sleep*/ - - /* Read the PART_NUM register to verify that the radio is - * working/responding. Could check in software, I just look at - * the bus. If this is working, the first write should be 0x9C x00 - * and the return bytes should be 0x00 0x0B. - pal*/ - PRINTF("Reading part num...\n"); - regtemp = trx_reg_read(RF233_REG_PART_NUM); - PRINTF("RegTemp Is: %u\n", regtemp); // on the wire thing right, but in - // something is off by one. - - /* before enabling interrupts, make sure we have cleared IRQ status */ - regtemp = trx_reg_read(RF233_REG_IRQ_STATUS); - PRINTF("RF233: After wake from sleep\n"); - radio_state = rf233_status(); - PRINTF("RF233: Radio state 0x%04x\n", radio_state); - // calibrate_filters(); - if (radio_state == STATE_P_ON) { - trx_reg_write(RF233_REG_TRX_STATE, TRXCMD_TRX_OFF); - } - /* Assign regtemp to regtemp to avoid compiler warnings */ - regtemp = regtemp; - // Set up interrupts - gpio_interrupt_callback(interrupt_callback, NULL); - gpio_enable_input(RADIO_IRQ, PullNone); - gpio_clear(RADIO_IRQ); - gpio_enable_input(RADIO_IRQ, PullNone); - gpio_enable_interrupt(RADIO_IRQ, RisingEdge); - - /* Configure the radio using the default values except these. */ - trx_reg_write(RF233_REG_TRX_CTRL_1, RF233_REG_TRX_CTRL_1_CONF); - trx_reg_write(RF233_REG_PHY_CC_CCA, RF233_REG_PHY_CC_CCA_CONF); - trx_reg_write(RF233_REG_PHY_TX_PWR, RF233_REG_PHY_TX_PWR_CONF); - trx_reg_write(RF233_REG_TRX_CTRL_2, RF233_REG_TRX_CTRL_2_CONF); - trx_reg_write(RF233_REG_IRQ_MASK, RF233_REG_IRQ_MASK_CONF); - trx_reg_write(RF233_REG_XAH_CTRL_1, 0x02); - trx_bit_write(SR_MAX_FRAME_RETRIES, 0); - trx_bit_write(SR_MAX_CSMA_RETRIES, 0); - PRINTF("RF233: Configured transciever.\n"); - { - PRINTF("Configuring Addresses...\n"); - uint8_t addr[8]; - addr[0] = 0x22; - addr[1] = 0x22; - addr[2] = 0x22; - addr[3] = 0x22; - addr[4] = 0x22; - addr[5] = 0x22; - addr[6] = 0x22; - addr[7] = 0x22; - SetPanId(IEEE802154_CONF_PANID); - - SetIEEEAddr(addr); // I think it breaks here - SetShortAddr(0x2222); - - } - rf_generate_random_seed(); - - for (uint8_t i = 0; i < 8; i++) { - regtemp = trx_reg_read(0x24 + i); - } - - /* 11_09_rel */ - trx_reg_write(RF233_REG_TRX_RPC, 0xFF); /* Enable RPC feature by default */ - PRINTF("RF233: Installed addresses. Turning on radio.\n"); - rf233_on(); - return 0; -} - -/* - * \brief Generates a 16-bit random number used as initial seed for srand() - * - */ -static void rf_generate_random_seed(void) { - srand(55); -} - -/*---------------------------------------------------------------------------*/ -// Append header with FCF, sequence number, -static int rf233_prepare_without_header(const uint8_t *data, unsigned short data_len) { - if ((data_len + HEADER_SIZE) > MAX_PACKET_LEN) { - PRINTF("RF233: error, data too large (%u) (prepare_without_header)\n", data_len); - return RADIO_TX_ERR; - } - - // append mac header with length 9 - uint8_t data_with_header[MAX_PACKET_LEN]; - data_with_header[0] = 0x61; - data_with_header[1] = 0xAA; - data_with_header[2] = radio_header.seq & 0xFF; - // note: sequence number is incremented in rf233_prepare - *((uint16_t *)(data_with_header + 3)) = radio_header.pan; - *((uint16_t *)(data_with_header + 5)) = radio_header.dest; - *((uint16_t *)(data_with_header + 7)) = radio_header.src; - - int i; - // Copy over data into new buffer with header - for (i = 0; i < data_len; i++) { - data_with_header[i + HEADER_SIZE] = ((uint8_t*)data)[i]; - } - - for (i = 0; i < data_len + HEADER_SIZE; i++) { - PRINTF(" data[%i] = %x\n", i, (uint8_t) data_with_header[i]); - } - // first 9 bytes are now MAC header - return rf233_prepare(data_with_header, data_len + HEADER_SIZE); -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief prepare a frame and the radio for immediate transmission - * \param payload Pointer to data to copy/send - * \param payload_len length of data to copy - * \return Returns success/fail, refer to radio.h for explanation - */ -int rf233_prepare(const void *payload, unsigned short payload_len) { - int i; - // Frame length is number of bytes in MPDU - uint8_t templen; - uint8_t radio_status; - uint8_t data[1 + MAX_PACKET_LEN + 2]; // Length + Payload + FCS - - PRINTF("RF233: prepare %u\n", payload_len); - if (payload_len > MAX_PACKET_LEN) { - PRINTF("RF233: error, frame too large to tx\n"); - return RADIO_TX_ERR; - } - - /* Add length of the FCS (2 bytes) */ - templen = payload_len + 2; - data[0] = templen; - for (i = 0; i < templen; i++) { - data[i + 1] = ((uint8_t*)payload)[i]; - } - // TODO verify this is unnecessary bc of append_header? - data[3] = (uint8_t)(radio_header.seq & 0xff); - radio_header.seq++; - -#if DEBUG_PRINTDATA - PRINTF("RF233 prepare (%u/%u): 0x", payload_len, templen); - for (i = 0; i < templen; i++) { - PRINTF("%02x", *(uint8_t *)(payload + i)); - } - PRINTF("\n"); -#endif /* DEBUG_PRINTDATA */ - - /* check that the FIFO is clear to access */ - radio_status = rf233_status(); - if (radio_status == STATE_BUSY_RX_AACK || - radio_status == STATE_BUSY_RX || - radio_status == STATE_BUSY_TX_ARET) { - PRINTF("RF233: TRX buffer unavailable: prep when state %s\n", state_str(radio_status)); - return RADIO_TX_ERR; - } - - /* Write packet to TX FIFO. */ - PRINTF("RF233: sqno: %02x len = %u\n", radio_header.seq, payload_len); - trx_frame_write((uint8_t *)data, templen + 1); - return RADIO_TX_OK; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Transmit a frame already put in the radio with 'prepare' - * \param payload_len Length of the frame to send - * \return Returns success/fail, refer to radio.h for explanation - */ -static int rf233_transmit(void) { - static uint8_t status_now; - - status_now = rf233_status(); - PRINTF("RF233: attempting transmit, in state %s\n", state_str(status_now)); - - if (status_now == STATE_BUSY_RX_AACK || - status_now == STATE_BUSY_TX_ARET) { - PRINTF("RF233: collision, was in state %s\n", state_str(status_now)); - /* NOTE: to avoid loops */ - return RADIO_TX_ERR; - ; - } - - if (status_now != STATE_PLL_ON) { - trx_reg_write(RF233_REG_TRX_STATE, STATE_PLL_ON); - do { // I think this code is broken, does nothing -pal - status_now = trx_bit_read(RF233_REG_TRX_STATUS, 0x1F, 0); - } while (status_now == 0x1f); - } - - if (rf233_status() != STATE_PLL_ON) { - /* failed moving into PLL_ON state, gracefully try to recover */ - PRINTF("RF233: failed going to STATE_PLL_ON\n"); - RF233_COMMAND(TRXCMD_PLL_ON); /* try again */ - static uint8_t state; - state = rf233_status(); - if (state != STATE_PLL_ON) { - PRINTF("RF233: graceful recovery (in tx) failed, giving up. State: 0x%02X\n", rf233_status()); - return RADIO_TX_ERR; - } - } - - /* perform transmission */ - flag_transmit = 1; - radio_tx = false; - RF233_COMMAND(TRXCMD_TX_ARET_ON); - RF233_COMMAND(TRXCMD_TX_START); - - PRINTF("RF233:: Issued TX_START, wait for completion interrupt.\n"); - yield_for(&radio_tx); - PRINTF("RF233: tx ok\n\n"); - - return RADIO_TX_OK; -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief read a received frame out of the radio buffer - * \param buf pointer to where to copy received data - * \param bufsize Maximum size we can copy into bufsize - * \return Returns length of data read (> 0) if successful - * \retval -1 Failed, was transmitting so FIFO is invalid - * \retval -2 Failed, rx timed out (stuck in rx?) - * \retval -3 Failed, too large frame for buffer - * \retval -4 Failed, CRC/FCS failed (if USE_HW_FCS_CHECK is true) - */ -int rf233_read(void *buf, unsigned short bufsize) { - // uint8_t radio_state; - // uint8_t ed; /* frame metadata */ - uint8_t frame_len = 0; - uint8_t len = 0; - - PRINTF("RF233: Receiving.\n"); - - if (pending_frame == 0) { - PRINTF("RF233: No frame pending, abort.\n"); - return 0; - } - pending_frame = 0; - - /* get length of data in FIFO */ - spi_hold_low(); - spi_write_byte(TRX_CMD_FR); - frame_len = spi_write_byte(0); - - if (frame_len <= 2 || - (frame_len - 2) > bufsize) { - spi_release_low(); - flush_buffer(); - PRINTF("Frame (is not long enough or too large for buffer, abort.\n"); - return 0; - } - - len = frame_len - 2; - - if (len > bufsize) { - spi_release_low(); - /* too large frame for the buffer, drop */ - PRINTF("RF233: too large frame for buffer, dropping (%u > %u).\n", frame_len, bufsize); - - return 0; - } - - /* read out the data into the buffer, disregarding the length and metadata bytes */ - // spi_read_write_sync(wbuf, (char*)buf, len - 1); - // TODO len or len - 1 - for (uint8_t i = 0; i < len; i++) { - uint8_t val = spi_write_byte(0); - ((uint8_t*)buf)[i] = val; - PRINTF("%02x ", ((uint8_t*)buf)[i]); - if (i % 10 == 9) { - PRINTF("\n"); - } - } - - PRINTF("\n"); - spi_release_low(); - - // trx_sram_read(1, (uint8_t *)buf, len); - if (len >= 10) { - header_t* header = (header_t*)buf; - PRINTF(" FCF: %x\n", header->fcf); - PRINTF(" SEQ: %x\n", header->seq); - PRINTF(" PAN: %x\n", header->pan); - PRINTF(" DST: %x\n", header->dest); - PRINTF(" SRC: %x\n", header->src); - - // skip first 9 bytes of header - for (int i = 0; i < PACKETBUF_SIZE; i++) { - recv_data[i] = 0; - } - for (int i = 0; i < len; i++) { - recv_data[i] = header->payload[i]; - } - // Call user callback function - if (set_callback) { - rx_callback(recv_data, len, header->src, header->dest, header->pan); - } - } - // PRINTF("RF233: Final state = %s = %i\n", state_str(rf233_status()), rf233_status()); - - flush_buffer(); - - rf233_off(); - delay_ms(100); - rf233_sleep(); - delay_ms(100); - rf233_on(); - delay_ms(100); - - return len; -} - -/*---------------------------------------------------------------------------*/ -/** - * \brief check whether we are currently receiving a frame - * \retval >0 we are currently receiving a frame - * \retval 0 we are not currently receiving a frame - */ -int rf233_receiving_packet(void) { - uint8_t trx_state; - trx_state = rf233_status(); - if (trx_state == STATE_BUSY_RX_AACK) { - PRINTF("RF233: Receiving frame\n"); - return 1; - } - PRINTF("RF233: not Receiving frame\n"); - return 0; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief check whether we have a frame awaiting processing - * \retval >0 we have a frame awaiting processing - * \retval 0 we have not a frame awaiting processing - */ -int rf233_pending_packet(void) { - PRINTF("RF233: Frame %spending\n", pending_frame ? "" : "not "); - return pending_frame; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief switch the radio on to listen (rx) mode - * \retval 0 Success - */ -int rf233_on(void) { - PRINTF( - "RF233: turning on from state %s\n - sleeping radio will be POWER_ON since it doesn't respond to SPI and 0x0 is POWER_ON", - state_str(rf233_status())); - on(); - return 0; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief switch the radio off - * \retval 0 Success - */ -int rf233_off(void) { - PRINTF("RF233: turning off from state %s\n", state_str(rf233_status())); - off(); - return 0; -} - -void SetIEEEAddr(uint8_t *ieee_addr) { - uint8_t *ptr_to_reg = ieee_addr; - // for (uint8_t i = 0; i < 8; i++) { - trx_reg_write((0x2b), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x2a), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x29), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x28), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x27), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x26), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x25), *ptr_to_reg); - ptr_to_reg++; - trx_reg_write((0x24), *ptr_to_reg); - ptr_to_reg++; - // } -} - -void SetPanId(uint16_t panId) { - uint8_t *d = (uint8_t *)&panId; - - trx_reg_write(0x22, d[0]); - trx_reg_write(0x23, d[1]); -} - -void SetShortAddr(uint16_t addr) { - uint8_t *d = (uint8_t *)&addr; - - trx_reg_write(0x20, d[0]); - trx_reg_write(0x21, d[1]); - trx_reg_write(0x2d, d[0] + d[1]); -} - -/*---------------------------------------------------------------------------*/ -/* switch the radio on */ -int on(void) { - /* Check whether radio is in sleep */ - if (sleep_on) { - /* Wake the radio. It'll move to TRX_OFF state */ - gpio_clear(RADIO_SLP); - delay_ms(1); - PRINTF("RF233: Wake from sleep\n"); - sleep_on = 0; - } - uint8_t state_now = rf233_status(); - if (state_now != STATE_PLL_ON && - state_now != STATE_TRX_OFF && - state_now != STATE_TX_ARET_ON) { - PRINTF("RF233: Failed to turn radio on, state is %s.\n", state_str(state_now)); - return -1; - } - - PRINTF("RF233: State is %s, transitioning to PLL_ON.\n", state_str(rf233_status())); - radio_pll = false; - RF233_COMMAND(TRXCMD_PLL_ON); - yield_for(&radio_pll); - delay_ms(1); - PRINTF("RF233: State is %s, transitioning to RX_ON.\n", state_str(rf233_status())); - /* go to RX_ON state */ - RF233_COMMAND(TRXCMD_RX_ON); - radio_is_on = 1; - PRINTF("RF233: Radio is on, state is %s.\n", state_str(rf233_status())); - return 0; -} -/*---------------------------------------------------------------------------*/ -/* switch the radio off */ -int off(void) { - if (rf233_status() != STATE_RX_ON ) { - /* fail, we need the radio transceiver to be in this state */ - return -1; - } - - /* turn off the radio transceiver */ - RF233_COMMAND(TRXCMD_TRX_OFF); - radio_is_on = 0; - return 0; -} -/*---------------------------------------------------------------------------*/ -/* Put the Radio in sleep mode */ - -int rf233_sleep(void) { - /* Check whether we're already sleeping */ - if (!sleep_on) { - PRINTF("RF233: Putting to sleep.\n"); - // delay_ms(1); - sleep_on = 1; - /* Turn off the Radio */ - rf233_off(); - /* Set the SLP_PIN to high */ - gpio_set(RADIO_SLP); - } - - return 0; -} - -/*---------------------------------------------------------------------------*/ -/* - * Crude way of flushing the Tx/Rx FIFO: write the first byte as 0, indicating - * a zero-length frame in the buffer. This is interpreted by the driver as an - * empty buffer. - */ -static void flush_buffer(void) { - /* NB: tentative untested implementation */ - uint8_t temp = 0; - trx_frame_write(&temp, 1); -} - -void goto_sleep(void) {} - -void wake_from_sleep(void) { - /* - * Triggers a radio state transition - assumes that the radio already is in - * state SLEEP or DEEP_SLEEP and SLP pin is low. Refer to datasheet 6.6. - * - * Note: this is the only thing that can get the radio from state SLEEP or - * state DEEP_SLEEP! - */ -} - -uint8_t rf233_status(void) { - return trx_reg_read(RF233_REG_TRX_STATUS) & TRX_STATUS; -} -/*---------------------------------------------------------------------------*/ - -/* - * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * Copyright (c) 2015 Atmel Corporation and - * 2012 - 2013, Thingsquare, http://www.thingsquare.com/. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Atmel nor the name of Thingsquare nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller or Atmel wireless product. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ diff --git a/examples/tests/rf233/rf233.h b/examples/tests/rf233/rf233.h deleted file mode 100644 index 655333b63..000000000 --- a/examples/tests/rf233/rf233.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013, Thingsquare, http://www.thingsquare.com/. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _RF233_H_ -#define _RF233_H_ - -#include -/*---------------------------------------------------------------------------*/ - -int rf233_init(uint16_t channel, uint16_t from_addr, uint16_t pan_id); -int rf233_tx_data(uint16_t to_addr, void* payload, int payload_len); -int rf233_rx_data(int (*callback)(void*, int, uint16_t, uint16_t, uint16_t)); -// TODO assume callback passes buffer that is long enough? - -// TODO moved to .h -int rf233_on(void); -int rf233_off(void); -int rf233_sleep(void); - -int rf233_interrupt_poll(void); -int rf_get_channel(void); -int rf_set_channel(uint8_t ch); -int rf233_get_txp(void); -int rf233_set_txp(uint8_t txp); -uint8_t rf233_status(void); -void SetIEEEAddr(uint8_t *ieee_addr); -void SetPanId(uint16_t panId); -void SetShortAddr(uint16_t addr); -/*---------------------------------------------------------------------------*/ -#endif /* _RF233_H_ */ diff --git a/examples/tests/rf233/trx_access.h b/examples/tests/rf233/trx_access.h deleted file mode 100644 index c7959a5e4..000000000 --- a/examples/tests/rf233/trx_access.h +++ /dev/null @@ -1,315 +0,0 @@ -/** - * @file trx_access.h - * - * @brief HAL related APIs for externally plugged transceivers - * - * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - * - */ - -/* - * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. - * - * Licensed under Atmel's Limited License Agreement --> EULA.txt - */ - -/* Prevent double inclusion */ -#ifndef TRX_ACCESS_H -#define TRX_ACCESS_H - -/* - * NOTE:- Include 'return_val.h' before this file, as return_val.h has the - * all return value enums. - */ - -/** - * \defgroup group_trx_access - * This module includes api's and defenitions required for Devices with - * externally plugged transceivers(Non Soc's) - * @{ - */ -/* === Includes ============================================================ */ - -//#include "compiler.h" -//#include "conf_trx_access.h" -//#if SAMD || SAMR21 || SAML21 -//#include "port.h" -//#include "extint.h" -//#else -//#include "ioport.h" -//#endif -//#include "board.h" -/* === Macros =============================================================== */ - -/** - * Write access command of the transceiver - */ -#define WRITE_ACCESS_COMMAND (0xC0) - -/** - * Read access command to the tranceiver - */ -#define READ_ACCESS_COMMAND (0x80) - -/** - * Frame write command of transceiver - */ -#define TRX_CMD_FW (0x60) - -/** - * Frame read command of transceiver - */ -#define TRX_CMD_FR (0x20) - -/** - * SRAM write command of transceiver - */ -#define TRX_CMD_SW (0x40) - -/** - * SRAM read command of transceiver - */ -#define TRX_CMD_SR (0x00) - -#define TRX_TRIG_DELAY() {nop(); nop(); } - -/** - * Set TRX GPIO pins. - */ -#if SAMD || SAMR21 || SAML21 -#define RST_HIGH() port_pin_set_output_level( \ - AT86RFX_RST_PIN, true) -#define RST_LOW() port_pin_set_output_level( \ - AT86RFX_RST_PIN, false) -#define SLP_TR_HIGH() port_pin_set_output_level( \ - AT86RFX_SLP_PIN, true) -#define SLP_TR_LOW() port_pin_set_output_level( \ - AT86RFX_SLP_PIN, false) -#define IRQ_PINGET() port_pin_get_input_level(AT86RFX_IRQ_PIN) -#else -#define RST_HIGH() ioport_set_pin_level(AT86RFX_RST_PIN, \ - HIGH) -#define RST_LOW() ioport_set_pin_level(AT86RFX_RST_PIN, \ - LOW) -#define SLP_TR_HIGH() ioport_set_pin_level(AT86RFX_SLP_PIN, \ - HIGH) -#define SLP_TR_LOW() ioport_set_pin_level(AT86RFX_SLP_PIN, \ - LOW) -#define IRQ_PINGET() ioport_get_pin_level(AT86RFX_IRQ_PIN) -#endif - -/** - * @brief Clears the transceiver main interrupt - * - */ -#define trx_irq_flag_clr() CLEAR_TRX_IRQ() - -/** - * This macro is used for handling endianness among the different CPUs. - */ -#if (UC3) -#define U16_TO_TARGET(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF)) -#else -#define U16_TO_TARGET(x) (x) -#endif - -typedef void (*irq_handler_t)(void); -/* === Types =============================================================== */ - -/* - * The smallest timeout in microseconds - */ -/* #define MIN_TIMEOUT (0x80) */ - -/* This macro saves the global interrupt status */ -#define ENTER_TRX_CRITICAL_REGION() {uint8_t flags \ - = cpu_irq_save(); - -/* This macro restores the global interrupt status */ -#define LEAVE_TRX_CRITICAL_REGION() cpu_irq_restore(flags); } - -/* === Externals ============================================================ */ - -/* === Prototypes =========================================================== */ - -void trx_irq_init(void (*trx_irq_cb)(void)); - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Macros for TRX GPIO pins access. - */ -/** Macro to set Reset pin to high */ -#define TRX_RST_HIGH() RST_HIGH() -/** Macro to set Reset pin to low */ -#define TRX_RST_LOW() RST_LOW() -/** Macro to set SLP_TR pin to high */ -#define TRX_SLP_TR_HIGH() SLP_TR_HIGH() -/** Macro to set SLP_TR pin to low */ -#define TRX_SLP_TR_LOW() SLP_TR_LOW() -/** Macro to get the transceiver's main IRQ status */ -#define TRX_IRQ_HIGH() IRQ_PINGET() - -/** - * @brief Reads frame buffer of the transceiver - * - * This function reads the frame buffer of the transceiver. - * - * @param[out] data Pointer to the location to store frame - * @param[in] length Number of bytes to be read from the frame - * buffer. - */ -void trx_frame_read(uint8_t *data, uint8_t length); - -/** - * @brief Writes data into frame buffer of the transceiver - * - * This function writes data into the frame buffer of the transceiver - * - * @param[in] data Pointer to data to be written into frame buffer - * @param[in] length Number of bytes to be written into frame buffer - */ -void trx_frame_write(uint8_t *data, uint8_t length); - -/** - * @brief Reads current value from a transceiver register - * - * This function reads the current value from a transceiver register. - * - * @param addr Specifies the address of the trx register - * from which the data shall be read - * - * @return value of the register read - */ -uint8_t trx_reg_read(uint8_t addr); - -/** - * @brief Writes data into a transceiver register - * - * This function writes a value into transceiver register. - * - * @param addr Address of the trx register - * @param data Data to be written to trx register - * - */ -void trx_reg_write(uint8_t addr, uint8_t data); - -/** - * @brief Subregister read - * - * @param addr offset of the register - * @param mask bit mask of the subregister - * @param pos bit position of the subregister - * - * @return value of the read bit(s) - */ -uint8_t trx_bit_read(uint8_t addr, uint8_t mask, uint8_t pos); - -/** - * @brief Subregister write - * - * @param[in] reg_addr Offset of the register - * @param[in] mask Bit mask of the subregister - * @param[in] pos Bit position of the subregister - * @param[out] new_value Data, which is muxed into the register - */ -void trx_bit_write(uint8_t reg_addr, uint8_t mask, uint8_t pos, - uint8_t new_value); - -/** - * @brief Reads data from SRAM of the transceiver - * - * This function reads from the SRAM of the transceiver - * - * @param[in] addr Start address in SRAM for read operation - * @param[out] data Pointer to the location where data stored - * @param[in] length Number of bytes to be read from SRAM - */ -void trx_sram_read(uint8_t addr, uint8_t *data, uint8_t length); - -/** - * @brief Writes data into SRAM of the transceiver - * - * This function writes data into the SRAM of the transceiver - * - * @param addr Start address in the SRAM for the write operation - * @param data Pointer to the data to be written into SRAM - * @param length Number of bytes to be written into SRAM - */ -void trx_sram_write(uint8_t addr, uint8_t *data, uint8_t length); - -/** - * @brief Writes and reads data into/from SRAM of the transceiver - * - * This function writes data into the SRAM of the transceiver and - * simultaneously reads the bytes. - * - * @param addr Start address in the SRAM for the write operation - * @param idata Pointer to the data written/read into/from SRAM - * @param length Number of bytes written/read into/from SRAM - */ -void trx_aes_wrrd(uint8_t addr, uint8_t *idata, uint8_t length); - -#if defined(NON_BLOCKING_SPI) || defined(__DOXYGEN__) - -/** - * @brief SPI done callback initialization - * - * @param spi_done_cb Pointer to SPI done callback function - */ -void trx_spi_done_cb_init(void *spi_done_cb); - -#endif - -/** - * @brief Initializes the SPI interface for communication with the transceiver - */ -void trx_spi_init(void); - -/** - * @brief Resets the TRX radio - */ -void PhyReset(void); - -/* ! @} */ -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRX_ACCESS_H */ -/* EOF */ diff --git a/examples/tests/rng/main.c b/examples/tests/rng/main.c index b31ec7b9f..f9d9329be 100644 --- a/examples/tests/rng/main.c +++ b/examples/tests/rng/main.c @@ -1,17 +1,17 @@ #include #include -#include -#include +#include +#include uint8_t randbuf[256]; int main (void) { - printf("[RNG] Test App\n"); + printf("[TEST] RNG\n"); while (1) { int count; - rng_sync(randbuf, 256, 256, &count); + libtocksync_rng_get_random_bytes(randbuf, 256, 256, &count); // Print the 256 bytes of randomness. char buf[600]; @@ -23,6 +23,6 @@ int main (void) { len -= snprintf(buf + (600 - len), len, "\n\n"); printf("%s\n", buf); - delay_ms(500); + libtocksync_alarm_delay_ms(500); } } diff --git a/examples/adc/Makefile b/examples/tests/rtc/Makefile similarity index 89% rename from examples/adc/Makefile rename to examples/tests/rtc/Makefile index cfe30ad8e..1b77816a6 100644 --- a/examples/adc/Makefile +++ b/examples/tests/rtc/Makefile @@ -1,7 +1,7 @@ # Makefile for user application # Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../.. +TOCK_USERLAND_BASE_DIR = ../../../ # Which files to compile. C_SRCS := $(wildcard *.c) diff --git a/examples/rtc_app/main.c b/examples/tests/rtc/main.c similarity index 70% rename from examples/rtc_app/main.c rename to examples/tests/rtc/main.c index 95ecafd76..6e3de1714 100644 --- a/examples/rtc_app/main.c +++ b/examples/tests/rtc/main.c @@ -1,10 +1,11 @@ -#include #include -#include + +#include +#include int main(void){ // Initialises a date struct with a certain timestamp - struct Date date = { + libtock_rtc_date_t date = { .year = 2023, .month = JANUARY, .day = 1, @@ -15,17 +16,17 @@ int main(void){ .seconds = 1 }; - set_date(&date); + libtocksync_rtc_set_date(&date); // Clock has a small delay before starting to count seconds - delay_ms(2000); + libtocksync_alarm_delay_ms(2000); while (1) { - get_date(&date); + libtocksync_rtc_get_date(&date); printf("Date: {year: %d, month: %d, day: %d, day_of_week: %d, hour: %d, minute: %d, seconds: %d}\n\n", date.year, date.month, date.day, date.day_of_week, date.hour, date.minute, date.seconds); // This delay uses an underlying timer in the kernel - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } return 0; } diff --git a/examples/tests/screen-tock/main.c b/examples/tests/screen-tock/main.c index 5727338c3..70fbc5eaa 100644 --- a/examples/tests/screen-tock/main.c +++ b/examples/tests/screen-tock/main.c @@ -1,28 +1,23 @@ -#include #include #include -#include -#define BUFFER_SIZE 10 * 1024 +#include +#include -int main(void) { - int err; +#define BUFFER_SIZE 10 * 1024 - err = screen_init(BUFFER_SIZE); - if (err < 0) { - printf("buffer allocation failed\n"); - return -1; - } +uint8_t screen_buffer[BUFFER_SIZE]; - printf("screen init\n"); +int main(void) { + printf("[SCREEN-TOCK] Test Screen Display\n"); - size_t width, height; - screen_get_resolution(&width, &height); + uint32_t width, height; + libtock_screen_get_resolution(&width, &height); - screen_set_brightness(32000); + libtocksync_screen_set_brightness(32000); - screen_set_frame(0, 0, width, height); - screen_fill(0); + libtocksync_screen_set_frame(0, 0, width, height); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0); size_t char_width = width / 4; size_t x, y, w, h; @@ -34,15 +29,15 @@ int main(void) { y = 0; w = char_width - 2; h = height / 5; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + char_width / 3; y = 0; w = char_width / 3; h = height; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); // O x_offset = char_width; @@ -51,15 +46,15 @@ int main(void) { y = 0; w = char_width - 2; h = height; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + (char_width / 3); y = height / 5; w = char_width / 3; h = (height / 5) * 4; - screen_set_frame(x, y, w, h); - screen_fill(0); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0); // C x_offset = char_width * 2; @@ -68,15 +63,15 @@ int main(void) { y = 0; w = char_width - 2; h = height; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + (char_width / 3); y = height / 5; w = 2 * (char_width / 3) + 1; h = (height / 5) * 4; - screen_set_frame(x, y, w, h); - screen_fill(0); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0); // K x_offset = char_width * 3; @@ -85,29 +80,29 @@ int main(void) { y = 0; w = char_width / 3; h = height; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + 1; y = (height / 5) * 2; w = char_width - 2; h = height / 5; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + ((char_width / 3) * 2); y = 16; w = char_width / 3; h = 16; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); x = x_offset + ((char_width / 3) * 2); y = 32; w = char_width / 3; h = 16; - screen_set_frame(x, y, w, h); - screen_fill(0xFFFF); + libtocksync_screen_set_frame(x, y, w, h); + libtocksync_screen_fill(screen_buffer, BUFFER_SIZE, 0xFFFF); printf("TOCK on screen!\n"); diff --git a/examples/tests/mpu_flash_end/Makefile b/examples/tests/screen/Makefile similarity index 93% rename from examples/tests/mpu_flash_end/Makefile rename to examples/tests/screen/Makefile index 8f3698b98..a92109392 100644 --- a/examples/tests/mpu_flash_end/Makefile +++ b/examples/tests/screen/Makefile @@ -6,7 +6,7 @@ TOCK_USERLAND_BASE_DIR = ../../.. # Which files to compile. C_SRCS := $(wildcard *.c) -STACK_SIZE := 1024 +APP_HEAP_SIZE := 20000 # Include userland master makefile. Contains rules and flags for actually # building the application. diff --git a/examples/tests/screen/main.c b/examples/tests/screen/main.c new file mode 100644 index 000000000..289d4a1f9 --- /dev/null +++ b/examples/tests/screen/main.c @@ -0,0 +1,72 @@ +#include +#include + +#include +#include + +#define BUFFER_SIZE 10 * 1024 +uint8_t* buffer; + +int main(void) { + int err; + + printf("available resolutions\n"); + uint32_t resolutions; + err = libtock_screen_get_supported_resolutions(&resolutions); + if (err < 0) return -1; + for (uint32_t idx = 0; idx < resolutions; idx++) { + uint32_t width, height; + libtock_screen_get_supported_resolution(idx, &width, &height); + printf(" %ld x %ld\n", width, height); + } + + printf("available colors depths\n"); + uint32_t pixel_format; + err = libtock_screen_get_supported_pixel_formats(&pixel_format); + if (err < 0) return -1; + for (uint32_t idx = 0; idx < pixel_format; idx++) { + libtock_screen_format_t format; + libtock_screen_get_supported_pixel_format(idx, &format); + int bits = libtock_screen_get_bits_per_pixel(format); + printf(" %d bpp\n", bits); + } + + err = libtock_screen_buffer_init(BUFFER_SIZE, &buffer); + if (err < 0) { + printf("buffer allocation failed\n"); + return -1; + } + + printf("screen init\n"); + libtocksync_screen_set_brightness(100); + uint32_t width, height; + libtock_screen_get_resolution(&width, &height); + libtocksync_screen_set_frame(0, 0, width, height); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0); + bool invert = false; + for (int i = 0; ; i++) { + if (i % 4 == 3) { + invert = !invert; + if (invert) { + libtocksync_screen_invert_on(); + } else { + libtocksync_screen_invert_off(); + } + } + libtocksync_screen_set_rotation(i % 4); + libtocksync_screen_set_frame(10, 20, 30, 30); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0xF800); + libtocksync_screen_set_frame(88, 20, 30, 30); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0); + libtocksync_alarm_delay_ms(1000); + libtocksync_screen_set_frame(10, 20, 30, 30); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0); + libtocksync_screen_set_frame(88, 20, 30, 30); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0x07F0); + libtocksync_alarm_delay_ms(1000); + libtocksync_screen_set_frame(0, 0, width, height); + libtocksync_screen_fill(buffer, BUFFER_SIZE, 0x0000); + } + + return 0; +} diff --git a/examples/tests/sdcard/main.c b/examples/tests/sdcard/main.c index 6021f4237..85d4b549a 100644 --- a/examples/tests/sdcard/main.c +++ b/examples/tests/sdcard/main.c @@ -3,25 +3,19 @@ #include #include -#include -#include -#include -#include +#include +#include +#include uint8_t read_buf[512] = {0}; uint8_t write_buf[512] = {0}; int main (void) { int err = 0; - printf("[TOCK] SD Card Test\n"); + printf("[TEST] SD Card Test\n"); // Check if an SD card is installed - err = sdcard_is_installed(); - if (err < 0) { - printf("Is installed error: %d\n", err); - return -1; - } - if (err == 0) { + if (libtock_sdcard_exists()) { printf("No SD card installed\n"); return 0; } @@ -30,7 +24,7 @@ int main (void) { // Set up the SD card uint32_t block_size = 0; uint32_t size_in_kB = 0; - err = sdcard_initialize_sync(&block_size, &size_in_kB); + err = libtocksync_sdcard_initialize(&block_size, &size_in_kB); if (err < 0) { printf("Init error: %d\n", err); return -1; @@ -39,20 +33,8 @@ int main (void) { printf("\tBlock size: %lu bytes\n\tSize: %lu kB\n\n", block_size, size_in_kB); - // Give buffers to SD card - err = sdcard_set_read_buffer(read_buf, 512); - if (err < 0) { - printf("Allow read error: %d\n", err); - return -1; - } - err = sdcard_set_write_buffer(write_buf, 512); - if (err < 0) { - printf("Allow write error: %d\n", err); - return -1; - } - // read first block of the SD card - err = sdcard_read_block_sync(0); + err = libtocksync_sdcard_read_block(0, read_buf, 512); if (err < 0) { printf("Read error: %d\n", err); return -1; @@ -66,7 +48,7 @@ int main (void) { write_buf[1] = 0xB1; write_buf[2] = 0x10; write_buf[3] = i; - err = sdcard_write_block_sync(0); + err = libtocksync_sdcard_write_block(0, write_buf, 512); if (err < 0) { printf("Write error: %d\n", err); return -1; @@ -75,7 +57,7 @@ int main (void) { write_buf[0], write_buf[1], write_buf[2], write_buf[3]); // read first block of the SD card again - err = sdcard_read_block_sync(0); + err = libtocksync_sdcard_read_block(0, read_buf, 512); if (err < 0) { printf("Read error: %d\n", err); return -1; @@ -91,7 +73,7 @@ int main (void) { } } printf("Buffers match!\n\n"); - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } // test complete diff --git a/examples/tests/sha/main.c b/examples/tests/sha/main.c index 6913b3cc3..4f1e4e114 100644 --- a/examples/tests/sha/main.c +++ b/examples/tests/sha/main.c @@ -1,7 +1,7 @@ #include +#include -#include -#include +#include #define DATA_LEN 256 #define DEST_LEN 32 @@ -9,43 +9,22 @@ uint8_t data_buf[DATA_LEN] = "A language empowering everyone to build reliable and efficient software."; uint8_t dest_buf[DEST_LEN]; -static void sha_cb(__attribute__((unused)) int result, - __attribute__ ((unused)) int digest, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) void* userdata) { - int i; - - printf("Operation complete\r\n"); - - for (i = 0; i < DEST_LEN; i++) { - printf("%d: 0x%x\r\n", i, dest_buf[i]); - } - -} - int main(void) { - printf("[TEST] SHA Example Test\r\n"); + returncode_t ret; + printf("[TEST] SHA\r\n"); - // Set SHA256 as the algorithm - sha_set_algorithm(0); - - printf("Loading in the data buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, sha_set_data_buffer(data_buf, DATA_LEN)); - printf(" done\r\n"); - - printf("Setting up the dest buf...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, sha_set_dest_buffer(dest_buf, DEST_LEN)); - printf(" done\r\n"); - - printf("Setting up the callback...\r\n"); - TOCK_EXPECT(RETURNCODE_SUCCESS, sha_set_callback(sha_cb, NULL)); - printf(" done\r\n"); - - printf("Running SHA...\r\n"); - sha_run(); - printf(" done\r\n"); + if (!libtock_sha_exists()) { + printf("No SHA driver.\n"); + return -2; + } - yield(); + ret = libtocksync_sha_simple_hash(LIBTOCK_SHA256, + data_buf, strlen((char*) data_buf), + dest_buf, DEST_LEN); + if (ret != RETURNCODE_SUCCESS) { + printf("Unable to compute SHA.\n"); + return -1; + } return 0; } diff --git a/examples/tests/text_screen/main.c b/examples/tests/text_screen/main.c index 135a6499c..0ae00f35d 100644 --- a/examples/tests/text_screen/main.c +++ b/examples/tests/text_screen/main.c @@ -1,31 +1,29 @@ -/* - Example for text_screen library - Tested on NUCLEO-F429ZI - */ - -#include +#include #include -#include -#include -#include + +#include +#include +#include int main(void) { - int ret = text_screen_init(15); - uint8_t *buffer = text_screen_buffer(); - ret = text_screen_display_on(); + returncode_t ret; + + uint8_t* buffer = calloc(15, 1); + + ret = libtocksync_text_screen_display_on(); if (ret == RETURNCODE_SUCCESS) { - ret = text_screen_set_cursor(0, 0); + ret = libtocksync_text_screen_set_cursor(0, 0); memcpy(buffer, "Hello!", 6); - ret = text_screen_write(6); + ret = libtocksync_text_screen_write(buffer, 15, 6); - delay_ms(5000); + libtocksync_alarm_delay_ms(5000); - ret = text_screen_set_cursor(0, 1); + ret = libtocksync_text_screen_set_cursor(0, 1); memcpy(buffer, "Goodbyee!", 9); - ret = text_screen_write(9); + ret = libtocksync_text_screen_write(buffer, 15, 9); - delay_ms(2000); - ret = text_screen_clear(); + libtocksync_alarm_delay_ms(2000); + ret = libtocksync_text_screen_clear(); } return 0; } diff --git a/examples/tests/touch/main.c b/examples/tests/touch/main.c index 5dc06acaf..566ad02fa 100644 --- a/examples/tests/touch/main.c +++ b/examples/tests/touch/main.c @@ -1,77 +1,77 @@ #include #include -#include -#include -#include +#include +#include +#include -static void tocuh_event (int status, int x, int y, void *ud __attribute__ ((unused))) { +libtock_touch_event_t* multi_touch_buffer; + +static void touch_event (int status, uint16_t x, uint16_t y) { switch (status) { - case TOUCH_STATUS_PRESSED: { + case LIBTOCK_TOUCH_STATUS_PRESSED: { printf("pressed "); break; } - case TOUCH_STATUS_RELEASED: { + case LIBTOCK_TOUCH_STATUS_RELEASED: { printf("released "); break; } - case TOUCH_STATUS_MOVED: { + case LIBTOCK_TOUCH_STATUS_MOVED: { printf("moved "); break; } default: printf("error "); } - printf("%d x %d y %d\n", status, x, y); + printf("(%d): %d y %d\n", status, x, y); } -static void multi_tocuh_event (int num_touches, int data2 __attribute__ ((unused)), int data3 __attribute__ ( - (unused)), void *ud __attribute__ ((unused))) { +static void multi_touch_event ( + returncode_t ret __attribute__ ((unused)), + int num_touches, + int num_dropped __attribute__ ((unused)), + int num_nofit __attribute__ ((unused))) { for (int i = 0; i < num_touches; i++) { - unsigned char id, status; - unsigned short x, y; - read_touch(i, &id, &status, &x, &y); + uint8_t id, status, x, y, size, pressure; + libtock_touch_read_touch_from_buffer(multi_touch_buffer, i, &id, &status, &x, &y, &size, &pressure); printf("%d: ", id); switch (status) { - case TOUCH_STATUS_PRESSED: { + case LIBTOCK_TOUCH_STATUS_PRESSED: { printf("pressed "); break; } - case TOUCH_STATUS_RELEASED: { + case LIBTOCK_TOUCH_STATUS_RELEASED: { printf("released "); break; } - case TOUCH_STATUS_MOVED: { + case LIBTOCK_TOUCH_STATUS_MOVED: { printf("moved "); break; } default: printf("error "); } - printf("%d x %d y %d, ", status, x, y); + printf("(%d): %d y %d, ", status, x, y); } printf("\n"); // ack the multi touch event and enable the next event - multi_touch_next(); + libtock_touch_multi_touch_next(); } int main(void) { - int err; - int num_touches; - err = get_number_of_touches(&num_touches); - if (err < 0) { - return -1; - } + int num_touches = 0; + libtock_touch_get_number_of_touches(&num_touches); printf("Number of touches: %d\n", num_touches); - if (num_touches == 0) { printf("No touch found\n"); } else if (num_touches == 1) { // single touch - single_touch_set_callback(tocuh_event, NULL); + libtock_touch_enable_single_touch(touch_event); } else { // multi touch - multi_touch_set_callback(multi_tocuh_event, NULL, num_touches); + libtock_touch_allocate_multi_touch_buffer(num_touches, &multi_touch_buffer); + libtock_touch_enable_multi_touch(multi_touch_buffer, num_touches, multi_touch_event); } while (1) { diff --git a/examples/tests/tsl2561/Makefile b/examples/tests/tsl2561/Makefile deleted file mode 100644 index 54d6a7969..000000000 --- a/examples/tests/tsl2561/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# 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/tsl2561/main.c b/examples/tests/tsl2561/main.c deleted file mode 100644 index e7b27dd53..000000000 --- a/examples/tests/tsl2561/main.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include -#include -#include - -int main (void) { - printf("[TSL2561] Test\n"); - - // Start a light measurement - int lux; - tsl2561_get_lux_sync(&lux); - if (lux == RETURNCODE_ENODEVICE) { - printf("ERROR: No TSL2561 on this board.\n"); - } else if (lux < 0) { - printf("ERROR: unable to read the sensor (error code: %i)\n", lux); - } else { - // Print the lux value - printf("\tValue(%d lux) [0x%X]\n\n", lux, lux); - } -} diff --git a/examples/tests/u8g2-demos/circle/main.c b/examples/tests/u8g2-demos/circle/main.c index f216365b5..046b787a5 100644 --- a/examples/tests/u8g2-demos/circle/main.c +++ b/examples/tests/u8g2-demos/circle/main.c @@ -1,9 +1,7 @@ -#include #include #include -#include -#include +#include #include #include @@ -32,14 +30,14 @@ int main(void) { u8g2_DrawCircle(&u8g2, center_x, center_y, r, U8G2_DRAW_ALL); u8g2_SendBuffer(&u8g2); - delay_ms(100); + libtocksync_alarm_delay_ms(100); } for (int r = radius - 1; r > 0; r--) { u8g2_ClearBuffer(&u8g2); u8g2_DrawCircle(&u8g2, center_x, center_y, r, U8G2_DRAW_ALL); u8g2_SendBuffer(&u8g2); - delay_ms(100); + libtocksync_alarm_delay_ms(100); } } } diff --git a/examples/tests/u8g2-demos/count/main.c b/examples/tests/u8g2-demos/count/main.c index 4f3d6733f..6a356efaf 100644 --- a/examples/tests/u8g2-demos/count/main.c +++ b/examples/tests/u8g2-demos/count/main.c @@ -1,9 +1,8 @@ -#include #include #include #include -#include +#include #include #include @@ -40,6 +39,6 @@ int main(void) { u8g2_SendBuffer(&u8g2); count += 1; - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/u8g2-demos/graph/main.c b/examples/tests/u8g2-demos/graph/main.c index 83cc2566c..f9edeb823 100644 --- a/examples/tests/u8g2-demos/graph/main.c +++ b/examples/tests/u8g2-demos/graph/main.c @@ -1,9 +1,7 @@ #include #include -#include -#include -#include +#include #include #include @@ -37,6 +35,6 @@ int main(void) { append(samples, SAMPLES, count); graph_draw(&u8g2, &graph, samples, SAMPLES); count = (count + 2) % 20; - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); } } diff --git a/examples/tests/u8g2-demos/led-menu/main.c b/examples/tests/u8g2-demos/led-menu/main.c index 823430b7c..7d143604a 100644 --- a/examples/tests/u8g2-demos/led-menu/main.c +++ b/examples/tests/u8g2-demos/led-menu/main.c @@ -1,11 +1,9 @@ -#include #include #include -#include -#include -#include -#include +#include +#include +#include // These have to be included before mui.h #include @@ -17,10 +15,9 @@ u8g2_t u8g2; mui_t ui; -tock_timer_t debounce_timer; +libtock_alarm_t debounce_alarm; -bool action = false; -bool debouncing = false; +bool action = false; uint8_t my_value = 2; uint8_t my_value2 = 2; @@ -123,26 +120,31 @@ fds_t *fds = MUI_GOTO(64, 59, 1, " Ok ") ; -static void debounce_timer_callback(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - debouncing = false; +struct alarm_cb_data { + bool debouncing; +}; + +static struct alarm_cb_data data = { .debouncing = true }; + +static void debounce_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { + data.debouncing = false; } static void start_debounce(void) { - debouncing = true; - timer_in(300, debounce_timer_callback, NULL, &debounce_timer); + data.debouncing = true; + libtock_alarm_in_ms(300, debounce_cb, NULL, &debounce_alarm); } -static void button_callback(int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - if (debouncing) return; +static void button_callback( + __attribute__ ((unused)) returncode_t ret, + int btn_num, + bool val) { + if (data.debouncing) return; start_debounce(); - if (val == 1) { + if (val) { printf("b\n"); if (btn_num == 0) { @@ -162,16 +164,13 @@ static void button_callback(int btn_num, int main(void) { returncode_t ret; - ret = button_subscribe(button_callback, NULL); - if (ret < 0) return ret; - // Enable interrupts on each button. int count; - ret = button_count(&count); + ret = libtock_button_count(&count); if (ret < 0) return ret; for (int i = 0; i < count; i++) { - button_enable_interrupt(i); + libtock_button_notify_on_press(i, button_callback); } ret = u8g2_tock_init(&u8g2); @@ -197,24 +196,24 @@ int main(void) { printf("fruit %i\n", fruit_input); if (checkbox_led0) { - led_on(0); + libtock_led_on(0); } else { - led_off(0); + libtock_led_off(0); } if (checkbox_led1) { - led_on(1); + libtock_led_on(1); } else { - led_off(1); + libtock_led_off(1); } if (checkbox_led2) { - led_on(2); + libtock_led_on(2); } else { - led_off(2); + libtock_led_off(2); } if (checkbox_led3) { - led_on(3); + libtock_led_on(3); } else { - led_off(3); + libtock_led_off(3); } } diff --git a/examples/tests/u8g2-demos/spin/main.c b/examples/tests/u8g2-demos/spin/main.c index 49809aa3a..2e2a6e57e 100644 --- a/examples/tests/u8g2-demos/spin/main.c +++ b/examples/tests/u8g2-demos/spin/main.c @@ -1,10 +1,8 @@ #include -#include #include #include -#include -#include +#include #include #include @@ -43,7 +41,7 @@ int main(void) { u8g2_DrawLine(&u8g2, center_x, center_y, x, y); u8g2_SendBuffer(&u8g2); - delay_ms(200); + libtocksync_alarm_delay_ms(200); rot = (rot + 1) % 100; } diff --git a/examples/tests/u8g2-demos/tock-logo/main.c b/examples/tests/u8g2-demos/tock-logo/main.c index 526e81fdd..bd912ca75 100644 --- a/examples/tests/u8g2-demos/tock-logo/main.c +++ b/examples/tests/u8g2-demos/tock-logo/main.c @@ -1,7 +1,7 @@ -#include #include #include -#include + +#include #include #include diff --git a/examples/tests/u8g2-demos/tock-scroll/main.c b/examples/tests/u8g2-demos/tock-scroll/main.c index 0ea2ffd8a..c748f7d48 100644 --- a/examples/tests/u8g2-demos/tock-scroll/main.c +++ b/examples/tests/u8g2-demos/tock-scroll/main.c @@ -1,9 +1,8 @@ -#include #include #include #include -#include +#include #include #include @@ -47,7 +46,7 @@ int main(void) { u8g2_DrawBox(&u8g2, 0, 0, cwidth, height); u8g2_SendBuffer(&u8g2); - delay_ms(100); + libtocksync_alarm_delay_ms(100); } buf[1] = '\0'; diff --git a/examples/tests/u8g2-demos/triangle/main.c b/examples/tests/u8g2-demos/triangle/main.c index 7d40aa7c5..d3bba073b 100644 --- a/examples/tests/u8g2-demos/triangle/main.c +++ b/examples/tests/u8g2-demos/triangle/main.c @@ -1,9 +1,7 @@ -#include #include #include -#include -#include +#include #include #include diff --git a/examples/tests/udp/udp_rx/main.c b/examples/tests/udp/udp_rx/main.c index 9facceccd..b7113ad6c 100644 --- a/examples/tests/udp/udp_rx/main.c +++ b/examples/tests/udp/udp_rx/main.c @@ -2,12 +2,13 @@ #include #include -#include "led.h" -#include "timer.h" -#include "tock.h" +#include +#include +#include -#include -#include +#include +#include +#include /* * UDP sample packet reception app. @@ -31,11 +32,16 @@ void print_ipv6(ipv6_addr_t *ipv6_addr) { printf("%02x%02x", ipv6_addr->addr[14], ipv6_addr->addr[15]); } -static void callback(int payload_len, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - __attribute__ ((unused)) void* ud) { - led_toggle(0); +static void callback(statuscode_t status, + int payload_len) { + + returncode_t ret = tock_status_to_returncode(status); + if (ret != RETURNCODE_SUCCESS) { + printf("Error in receiving packet: %d\n", ret); + return; + } + + libtock_led_toggle(0); #define PRINT_STRING 1 #if PRINT_STRING @@ -54,7 +60,7 @@ static void callback(int payload_len, int main(void) { ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_addr_t addr = { ifaces[1], @@ -66,23 +72,23 @@ int main(void) { printf(" : %d, and binding to that socket.\n", addr.port); sock_handle_t h; handle = &h; - int ret = udp_bind(handle, &addr, BUF_BIND_CFG); + int ret = libtock_udp_bind(handle, &addr, BUF_BIND_CFG); if (ret < 0) { printf("Error in bind: %d\n", ret); } ; - if (ieee802154_driver_exists()) { - ieee802154_set_address(49138); // Corresponds to the dst mac addr set in kernel - ieee802154_set_pan(0xABCD); - ieee802154_config_commit(); - ieee802154_up(); + if (libtock_ieee802154_driver_exists()) { + libtock_ieee802154_set_address_short(49138); // Corresponds to the dst mac addr set in kernel + libtock_ieee802154_set_pan(0xABCD); + libtock_ieee802154_config_commit(); + libtocksync_ieee802154_up(); } else { printf("No 15.4 driver present, set mac address manually in kernel.\n"); } memset(packet_rx, 0, MAX_RX_PACKET_LEN); - ssize_t result = udp_recv(callback, packet_rx, MAX_RX_PACKET_LEN); + returncode_t result = libtock_udp_recv(packet_rx, (size_t) MAX_RX_PACKET_LEN, callback); switch (result) { case RETURNCODE_SUCCESS: @@ -104,8 +110,8 @@ int main(void) { /* This app tests receiving for 10 seconds * then closing the connection, so we include a busy wait for that * reason. */ - delay_ms(30000); - ssize_t err = udp_close(handle); + libtocksync_alarm_delay_ms(30000); + returncode_t err = libtock_udp_close(handle); if (err < 0) { printf("Error closing socket\n"); } else { diff --git a/examples/tests/udp/udp_send/main.c b/examples/tests/udp/udp_send/main.c index a437e8742..7c804e88d 100644 --- a/examples/tests/udp/udp_send/main.c +++ b/examples/tests/udp/udp_send/main.c @@ -2,14 +2,18 @@ #include #include -#include -#include -#include -#include -#include -#include - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #define DEBUG 1 @@ -25,7 +29,7 @@ int main(void) { static char packet[70]; ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_handle_t handle; sock_addr_t addr = { @@ -36,7 +40,7 @@ int main(void) { printf("Opening socket on "); print_ipv6(&ifaces[0]); printf(" : %d\n", addr.port); - int bind_return = udp_bind(&handle, &addr, BUF_BIND_CFG); + int bind_return = libtock_udp_bind(&handle, &addr, BUF_BIND_CFG); if (bind_return < 0) { printf("Bind failed. Error code: %d\n", bind_return); @@ -65,7 +69,7 @@ int main(void) { print_ipv6(&(destination.addr)); printf(" : %d\n", destination.port); } - ssize_t result = udp_send_to(packet, len, &destination); + returncode_t result = libtocksync_udp_send(packet, len, &destination); switch (result) { case RETURNCODE_SUCCESS: @@ -77,7 +81,7 @@ int main(void) { printf("Error sending packet %d\n\n", result); } count++; - delay_ms(5000); + libtocksync_alarm_delay_ms(5000); } } diff --git a/examples/tests/udp/udp_virt_app_kernel/main.c b/examples/tests/udp/udp_virt_app_kernel/main.c index 87da4aa74..5a7edae03 100644 --- a/examples/tests/udp/udp_virt_app_kernel/main.c +++ b/examples/tests/udp/udp_virt_app_kernel/main.c @@ -2,10 +2,10 @@ #include #include -#include -#include - -#include +#include +#include +#include +#include #define DEBUG 0 @@ -28,7 +28,7 @@ int main(void) { }; ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_handle_t handle; sock_addr_t addr = { @@ -36,41 +36,41 @@ int main(void) { 1000 // kernel tries to bind this after me }; - int len = snprintf(packet, sizeof(packet), "Hello World - App/Kernel virt\n"); - ssize_t result = udp_send_to(packet, len, &destination); - assert(result < 0); // should fail because we have not bound + int len = snprintf(packet, sizeof(packet), "Hello World - App/Kernel virt\n"); + returncode_t result = libtocksync_udp_send(packet, len, &destination); + assert(result != RETURNCODE_SUCCESS); // should fail because we have not bound if (DEBUG) { printf("Opening socket on "); print_ipv6(&ifaces[0]); printf(" : %d\n", addr.port); } - int bind_return = udp_bind(&handle, &addr, BUF_BIND_CFG); + int bind_return = libtock_udp_bind(&handle, &addr, BUF_BIND_CFG); assert(bind_return >= 0); // bind should succeed - delay_ms(3000); // resync with kernel + libtocksync_alarm_delay_ms(3000); // resync with kernel sock_addr_t addr2 = { ifaces[0], 1001 // same as what kernel has successfuly bound to }; - bind_return = udp_bind(&handle, &addr2, BUF_BIND_CFG); + bind_return = libtock_udp_bind(&handle, &addr2, BUF_BIND_CFG); assert(bind_return < 0); // bind should fail bc kernel has bound this sock_addr_t addr3 = { ifaces[0], 1002 // new port }; - bind_return = udp_bind(&handle, &addr3, BUF_BIND_CFG); + bind_return = libtock_udp_bind(&handle, &addr3, BUF_BIND_CFG); assert(bind_return >= 0); - delay_ms(1000); // should be synced with kernel test 2 starting now. + libtocksync_alarm_delay_ms(1000); // should be synced with kernel test 2 starting now. if (DEBUG) { printf("Sending packet (length %d) --> ", len); print_ipv6(&(destination.addr)); printf(" : %d\n", destination.port); } - result = udp_send_to(packet, len, &destination); + result = libtocksync_udp_send(packet, len, &destination); assert(result == RETURNCODE_SUCCESS); // send should succeed printf("App part of app/kernel test successful!\n"); diff --git a/examples/tests/udp/udp_virt_app_tests/app1/main.c b/examples/tests/udp/udp_virt_app_tests/app1/main.c index 65364eea1..111b859c3 100644 --- a/examples/tests/udp/udp_virt_app_tests/app1/main.c +++ b/examples/tests/udp/udp_virt_app_tests/app1/main.c @@ -2,10 +2,10 @@ #include #include -#include -#include - -#include +#include +#include +#include +#include #define DEBUG 0 @@ -20,7 +20,7 @@ int main(void) { static char packet[70]; ipv6_addr_t dest_addr = { {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f} + 0x1c, 0x1d, 0x1e, 0x1f} }; sock_addr_t destination = { dest_addr, @@ -28,7 +28,7 @@ int main(void) { }; ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_handle_t handle; sock_addr_t addr = { @@ -36,48 +36,48 @@ int main(void) { 11111 }; - int len = snprintf(packet, sizeof(packet), "Hello World - App1\n"); - ssize_t result = udp_send_to(packet, len, &destination); - assert(result < 0); // should fail because we have not bound + int len = snprintf(packet, sizeof(packet), "Hello World - App1\n"); + returncode_t result = libtocksync_udp_send(packet, len, &destination); + assert(result != RETURNCODE_SUCCESS); // should fail because we have not bound if (DEBUG) { printf("Opening socket on "); print_ipv6(&ifaces[0]); printf(" : %d\n", addr.port); } - int bind_return = udp_bind(&handle, &addr, BUF_BIND_CFG); - assert(bind_return >= 0); //bind should succeed + int bind_return = libtock_udp_bind(&handle, &addr, BUF_BIND_CFG); + assert(bind_return >= 0); // bind should succeed if (bind_return < 0) { printf("Bind failed. Error code: %d\n", bind_return); return -1; } - //bound, now try sending a too-long packet + // bound, now try sending a too-long packet int max_len = 0; - udp_get_max_tx_len(&max_len); - result = udp_send_to(packet, max_len + 1, &destination); - assert(result < 0); //should fail bc too long + libtock_udp_get_max_tx_len(&max_len); + result = libtocksync_udp_send(packet, max_len + 1, &destination); + assert(result != RETURNCODE_SUCCESS); // should fail bc too long if (DEBUG) { printf("Sending packet (length %d) --> ", len); print_ipv6(&(destination.addr)); printf(" : %d\n", destination.port); } - result = udp_send_to(packet, len, &destination); - assert(result == RETURNCODE_SUCCESS); //finally, a valid send attempt + result = libtocksync_udp_send(packet, len, &destination); + assert(result == RETURNCODE_SUCCESS); // finally, a valid send attempt - //of the two apps, app1 binds to port 80 first and should succeed + // of the two apps, app1 binds to port 80 first and should succeed sock_addr_t addr2 = { ifaces[0], 80 }; - bind_return = udp_bind(&handle, &addr2, BUF_BIND_CFG); - assert(bind_return >= 0); //bind succeeds bc this app binds first + bind_return = libtock_udp_bind(&handle, &addr2, BUF_BIND_CFG); + assert(bind_return >= 0); // bind succeeds bc this app binds first - delay_ms(100); //to re-sync with other app + libtocksync_alarm_delay_ms(100); // to re-sync with other app - result = udp_send_to(packet, len, &destination); + result = libtocksync_udp_send(packet, len, &destination); assert(result == RETURNCODE_SUCCESS); // should succeed, both apps should be bound to different ports printf("App1 test success!\n"); diff --git a/examples/tests/udp/udp_virt_app_tests/app2/main.c b/examples/tests/udp/udp_virt_app_tests/app2/main.c index 76f5d9df2..d2c25c301 100644 --- a/examples/tests/udp/udp_virt_app_tests/app2/main.c +++ b/examples/tests/udp/udp_virt_app_tests/app2/main.c @@ -2,10 +2,10 @@ #include #include -#include -#include - -#include +#include +#include +#include +#include #define DEBUG 0 @@ -20,7 +20,7 @@ int main(void) { static char packet[70]; ipv6_addr_t dest_addr = { {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f} + 0x1c, 0x1d, 0x1e, 0x1f} }; sock_addr_t destination = { dest_addr, @@ -28,7 +28,7 @@ int main(void) { }; ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_handle_t handle; sock_addr_t addr = { @@ -36,28 +36,28 @@ int main(void) { 22222 }; - int len = snprintf(packet, sizeof(packet), "Hello World - App2\n"); - ssize_t result = udp_send_to(packet, len, &destination); - assert(result < 0); // should fail because we have not bound + int len = snprintf(packet, sizeof(packet), "Hello World - App2\n"); + returncode_t result = libtocksync_udp_send(packet, len, &destination); + assert(result != RETURNCODE_SUCCESS); // should fail because we have not bound if (DEBUG) { printf("Opening socket on "); print_ipv6(&ifaces[0]); printf(" : %d\n", addr.port); } - int bind_return = udp_bind(&handle, &addr, BUF_BIND_CFG); - assert(bind_return >= 0); //bind should succeed + int bind_return = libtock_udp_bind(&handle, &addr, BUF_BIND_CFG); + assert(bind_return >= 0); // bind should succeed if (bind_return < 0) { printf("Bind failed. Error code: %d\n", bind_return); return -1; } - //bound, now try sending a too-long packet + // bound, now try sending a too-long packet int max_len = 0; - udp_get_max_tx_len(&max_len); - result = udp_send_to(packet, max_len + 1, &destination); - assert(result < 0); //should fail bc too long + libtock_udp_get_max_tx_len(&max_len); + result = libtocksync_udp_send(packet, max_len + 1, &destination); + assert(result < 0); // should fail bc too long if (DEBUG) { printf("Sending packet (length %d) --> ", len); @@ -69,28 +69,27 @@ int main(void) { // attempt. However, udp_send can take more than 10ms for a multi-fragment packet, // so putting the delay after the send still makes it possible for this app to // bind first. Accordingly, put the delay before the send to ensure it sends second. - delay_ms(10); - result = udp_send_to(packet, len, &destination); - assert(result == RETURNCODE_SUCCESS); //finally, a valid send attempt + libtocksync_alarm_delay_ms(10); + result = libtocksync_udp_send(packet, len, &destination); + assert(result == RETURNCODE_SUCCESS); // finally, a valid send attempt - //of the two apps, app2 binds to port 80 second and should fail + // of the two apps, app2 binds to port 80 second and should fail sock_addr_t addr2 = { ifaces[0], 80 }; - bind_return = udp_bind(&handle, &addr2, BUF_BIND_CFG); - assert(bind_return < 0); //bind should fail bc this app binds second to port 80 + bind_return = libtock_udp_bind(&handle, &addr2, BUF_BIND_CFG); + assert(bind_return < 0); // bind should fail bc this app binds second to port 80 - delay_ms(90); //to re-sync with other app + libtocksync_alarm_delay_ms(90); // to re-sync with other app sock_addr_t addr3 = { ifaces[0], 81 }; - bind_return = udp_bind(&handle, &addr3, BUF_BIND_CFG); - assert(bind_return >= 0); //bind should succeed now - + bind_return = libtock_udp_bind(&handle, &addr3, BUF_BIND_CFG); + assert(bind_return >= 0); // bind should succeed now - result = udp_send_to(packet, len, &destination); + result = libtocksync_udp_send(packet, len, &destination); assert(result == RETURNCODE_SUCCESS); // should succeed, both apps should be bound to different ports printf("App2 test success!\n"); } diff --git a/examples/tests/udp/udp_virt_rx_tests/app1/main.c b/examples/tests/udp/udp_virt_rx_tests/app1/main.c index aa7a200ad..bdc6da2cc 100644 --- a/examples/tests/udp/udp_virt_rx_tests/app1/main.c +++ b/examples/tests/udp/udp_virt_rx_tests/app1/main.c @@ -2,11 +2,10 @@ #include #include -#include "led.h" -#include "timer.h" -#include "tock.h" - -#include +#include +#include +#include +#include /* * UDP sample packet reception app. @@ -30,11 +29,16 @@ void print_ipv6(ipv6_addr_t *ipv6_addr) { printf("%02x%02x", ipv6_addr->addr[14], ipv6_addr->addr[15]); } -static void callback(int payload_len, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - __attribute__ ((unused)) void* ud) { - led_toggle(0); +static void callback(statuscode_t status, + int payload_len) { + + returncode_t ret = tock_status_to_returncode(status); + if (ret != RETURNCODE_SUCCESS) { + printf("Error in receiving packet: %d\n", ret); + return; + } + + libtock_led_toggle(0); #define PRINT_STRING 1 #if PRINT_STRING @@ -53,7 +57,7 @@ static void callback(int payload_len, int main(void) { ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_addr_t addr = { ifaces[1], @@ -65,10 +69,10 @@ int main(void) { printf(" : %d, and binding to that socket.\n", addr.port); sock_handle_t h; handle = &h; - udp_bind(handle, &addr, BUF_BIND_CFG); + libtock_udp_bind(handle, &addr, BUF_BIND_CFG); memset(packet_rx, 0, MAX_RX_PACKET_LEN); - ssize_t result = udp_recv(callback, packet_rx, MAX_RX_PACKET_LEN); + returncode_t result = libtock_udp_recv(packet_rx, MAX_RX_PACKET_LEN, callback); switch (result) { case RETURNCODE_SUCCESS: @@ -87,13 +91,12 @@ int main(void) { printf("Failed to bind to socket %d\n", result); break; } - /* This app tests receiving for 10 seconds * then closing the connection, so we include a delay for that * reason. */ - delay_ms(30000); - ssize_t err = udp_close(handle); - if (err < 0) { + libtocksync_alarm_delay_ms(30000); + result = libtock_udp_close(handle); + if (result != RETURNCODE_SUCCESS) { printf("Error closing socket\n"); } else { printf("Socket closed.\n"); diff --git a/examples/tests/udp/udp_virt_rx_tests/app2/main.c b/examples/tests/udp/udp_virt_rx_tests/app2/main.c index 69eea5b10..69e83a264 100644 --- a/examples/tests/udp/udp_virt_rx_tests/app2/main.c +++ b/examples/tests/udp/udp_virt_rx_tests/app2/main.c @@ -2,11 +2,10 @@ #include #include -#include "led.h" -#include "timer.h" -#include "tock.h" - -#include +#include +#include +#include +#include /* * UDP sample packet reception app. @@ -30,11 +29,16 @@ void print_ipv6(ipv6_addr_t *ipv6_addr) { printf("%02x%02x", ipv6_addr->addr[14], ipv6_addr->addr[15]); } -static void callback(int payload_len, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - __attribute__ ((unused)) void* ud) { - led_toggle(0); +static void callback(statuscode_t status, + int payload_len) { + + returncode_t ret = tock_status_to_returncode(status); + if (ret != RETURNCODE_SUCCESS) { + printf("Error in receiving packet: %d\n", ret); + return; + } + + libtock_led_toggle(0); #define PRINT_STRING 1 #if PRINT_STRING @@ -53,7 +57,7 @@ static void callback(int payload_len, int main(void) { ipv6_addr_t ifaces[10]; - udp_list_ifaces(ifaces, 10); + libtock_udp_list_ifaces(ifaces, 10); sock_addr_t addr = { ifaces[1], @@ -65,10 +69,10 @@ int main(void) { printf(" : %d, and binding to that socket.\n", addr.port); sock_handle_t h; handle = &h; - udp_bind(handle, &addr, BUF_BIND_CFG); + libtock_udp_bind(handle, &addr, BUF_BIND_CFG); memset(packet_rx, 0, MAX_RX_PACKET_LEN); - ssize_t result = udp_recv(callback, packet_rx, MAX_RX_PACKET_LEN); + returncode_t result = libtock_udp_recv(packet_rx, MAX_RX_PACKET_LEN, callback); switch (result) { case RETURNCODE_SUCCESS: @@ -87,13 +91,12 @@ int main(void) { printf("Failed to bind to socket %d\n", result); break; } - /* This app tests receiving for 10 seconds * then closing the connection, so we include a delay for that * reason. */ - delay_ms(30000); - ssize_t err = udp_close(handle); - if (err < 0) { + libtocksync_alarm_delay_ms(30000); + result = libtock_udp_close(handle); + if (result != RETURNCODE_SUCCESS) { printf("Error closing socket\n"); } else { printf("Socket closed.\n"); diff --git a/examples/tests/usb/main.c b/examples/tests/usb/main.c index 9cf998b75..9a2d5c636 100644 --- a/examples/tests/usb/main.c +++ b/examples/tests/usb/main.c @@ -1,23 +1,22 @@ #include -#include -#include -#include -#include +#include int main(void) { - int r; + returncode_t ret; + printf("[TEST] UDP\n"); - if (!usb_exists()) { + if (!libtock_usb_exists()) { printf("USB test: driver is not present\n"); - exit(1); + return -1; } - r = usb_enable_and_attach(); - - if (r == RETURNCODE_SUCCESS) { + ret = libtocksync_usb_enable_and_attach(); + if (ret == RETURNCODE_SUCCESS) { printf("USB test: Enabled and attached\n"); } else { - printf("USB test: Attach failed with status %d\n", r); + printf("USB test: Attach failed with status %d\n", ret); } + + return 0; } diff --git a/examples/tests/writeable_flash_regions/main.c b/examples/tests/writeable_flash_regions/main.c index 2def7b273..a61397906 100644 --- a/examples/tests/writeable_flash_regions/main.c +++ b/examples/tests/writeable_flash_regions/main.c @@ -1,6 +1,6 @@ #include -#include +#include int main (void) { int num_regions = tock_app_number_writeable_flash_regions(); diff --git a/examples/tests/yield/README.md b/examples/tests/yield/README.md index 8bae0f3cd..214779bff 100644 --- a/examples/tests/yield/README.md +++ b/examples/tests/yield/README.md @@ -8,7 +8,7 @@ This tests that yield-wait and yield-no-wait work correctly. A correct test should see "spinning", followed by "waiting", followed by "spinning." The "spinning" message indicates the application is spinning on `yield_no_wait` until it returns true -(the timer callback fires). The "waiting" message indicates the +(the alarm callback fires). The "waiting" message indicates the application is waiting on `yield` until the kernel wakes it up -with a timer callback. +with a alarm callback. diff --git a/examples/tests/yield/main.c b/examples/tests/yield/main.c index f7dfd059c..3f5686dd4 100644 --- a/examples/tests/yield/main.c +++ b/examples/tests/yield/main.c @@ -1,25 +1,31 @@ #include -#include -#include +#include +#include -static void timer_cb(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, void* ud) { - *((bool*)ud) = true; +struct alarm_cb_data { + bool fired; +}; + +static struct alarm_cb_data data = { .fired = false }; + +static void alarm_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { + data.fired = true; } int main(void) { - tock_timer_t timer; + libtock_alarm_t alarm; while (1) { - bool done = false; - timer_in(1500, timer_cb, &done, &timer); + data.fired = false; + libtock_alarm_in_ms(1500, alarm_cb, NULL, &alarm); printf("spinning\n"); while (yield_no_wait() == 0) {} printf("waiting\n"); - done = false; - timer_in(1500, timer_cb, &done, &timer); + data.fired = false; + libtock_alarm_in_ms(1500, alarm_cb, NULL, &alarm); yield(); } } diff --git a/examples/tests/yield_for_with_timeout_test/main.c b/examples/tests/yield_for_with_timeout_test/main.c index 1e70c610c..7556b901a 100644 --- a/examples/tests/yield_for_with_timeout_test/main.c +++ b/examples/tests/yield_for_with_timeout_test/main.c @@ -1,31 +1,37 @@ -#include -#include +#include +#include -static void timer_cb(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, void* ud) { - *((bool*)ud) = true; +struct alarm_cb_data { + bool fired; +}; + +static struct alarm_cb_data data = { .fired = false }; + +static void alarm_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opaque) { + data.fired = true; } int main(void) { while (1) { - bool done = false; - tock_timer_t timer; - timer_in(1500, timer_cb, &done, &timer); + data.fired = false; + libtock_alarm_t alarm; + libtock_alarm_in_ms(1500, alarm_cb, NULL, &alarm); - int ret = yield_for_with_timeout(&done, 1000); + int ret = libtocksync_alarm_yield_for_with_timeout(&data.fired, 1000); if (ret == RETURNCODE_SUCCESS) { - led_on(0); + libtock_led_on(0); } else { - led_off(0); + libtock_led_off(0); } - ret = yield_for_with_timeout(&done, 1000); + ret = libtocksync_alarm_yield_for_with_timeout(&data.fired, 1000); if (ret == RETURNCODE_SUCCESS) { - led_on(0); + libtock_led_on(0); } else { - led_off(0); + libtock_led_off(0); } } } diff --git a/examples/touch/Makefile b/examples/touch/Makefile deleted file mode 100644 index c9229d3e2..000000000 --- a/examples/touch/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Makefile for user application - -# Specify this directory relative to the current application. -TOCK_USERLAND_BASE_DIR = ../.. - -# Which files to compile. -C_SRCS := $(wildcard *.c) - -APP_HEAP_SIZE := 20000 - -# Include userland master makefile. Contains rules and flags for actually -# building the application. -include $(TOCK_USERLAND_BASE_DIR)/AppMakefile.mk diff --git a/examples/touch/main.c b/examples/touch/main.c deleted file mode 100644 index 90d7a7765..000000000 --- a/examples/touch/main.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include - -static void touch_event (int status, int x, int y, void *ud __attribute__ ((unused))) { - switch (status) { - case TOUCH_STATUS_PRESSED: { - printf("pressed "); - break; - } - case TOUCH_STATUS_RELEASED: { - printf("released "); - break; - } - case TOUCH_STATUS_MOVED: { - printf("moved "); - break; - } - default: - printf("error "); - } - printf("(%d): %d y %d\n", status, x, y); -} - -static void multi_touch_event (int num_touches, int data2 __attribute__ ((unused)), int data3 __attribute__ ( - (unused)), void *ud __attribute__ ((unused))) { - for (int i = 0; i < num_touches; i++) { - unsigned char id, status; - unsigned short x, y; - read_touch(i, &id, &status, &x, &y); - printf("%d: ", id); - switch (status) { - case TOUCH_STATUS_PRESSED: { - printf("pressed "); - break; - } - case TOUCH_STATUS_RELEASED: { - printf("released "); - break; - } - case TOUCH_STATUS_MOVED: { - printf("moved "); - break; - } - default: - printf("error "); - } - printf("(%d): %d y %d, ", status, x, y); - } - printf("\n"); - // ack the multi touch event and enable the next event - multi_touch_next(); -} - -int main(void) { - int num_touches = 0; - get_number_of_touches(&num_touches); - printf("Number of touches: %d\n", num_touches); - if (num_touches == 0) { - printf("No touch found\n"); - } else if (num_touches == 1) { - // single touch - enable_single_touch(); - single_touch_set_callback(touch_event, NULL); - } else { - // multi touch - enable_multi_touch(); - multi_touch_set_callback(multi_touch_event, NULL, num_touches); - } - - while (1) { - yield(); - } -} diff --git a/examples/tutorials/02_button_print/main.c b/examples/tutorials/02_button_print/main.c index 65fa487c9..bed999040 100644 --- a/examples/tutorials/02_button_print/main.c +++ b/examples/tutorials/02_button_print/main.c @@ -1,32 +1,30 @@ #include -#include +#include // Callback for button presses. // btn_num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_callback(__attribute__ ((unused)) int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { +// val: true if pressed, false if depressed +static void button_callback( + __attribute__ ((unused)) returncode_t ret, + __attribute__ ((unused)) int btn_num, + bool val) { // Only print on the down press. - if (val == 1) { + if (val) { printf("Hello!\n"); } } int main(void) { - button_subscribe(button_callback, NULL); - // Ensure there is a button to use. int count; - button_count(&count); + libtock_button_count(&count); if (count < 1) { // There are no buttons on this platform. printf("Error! No buttons on this platform.\n"); } else { // Enable an interrupt on the first button. - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); } // Loop forever waiting on button presses. diff --git a/examples/tutorials/03_ble_scan/main.c b/examples/tutorials/03_ble_scan/main.c index 470264b50..0b6fec5b1 100644 --- a/examples/tutorials/03_ble_scan/main.c +++ b/examples/tutorials/03_ble_scan/main.c @@ -8,7 +8,7 @@ // Included in the libnrfserialization.a library. #include -#include +#include /******************************************************************************* * BLE @@ -51,7 +51,7 @@ void ble_evt_adv_report (ble_evt_t* p_ble_evt) { adv->rssi, adv->dlen); // Also toggle the first LED. - led_toggle(0); + libtock_led_toggle(0); } /******************************************************************************* diff --git a/examples/tutorials/05_ipc/led/main.c b/examples/tutorials/05_ipc/led/main.c index 619da26b0..735d83afc 100644 --- a/examples/tutorials/05_ipc/led/main.c +++ b/examples/tutorials/05_ipc/led/main.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include // This service can control the LEDs on a board. // @@ -43,9 +43,9 @@ static void ipc_callback(int pid, int len, int buf, __attribute__ ((unused)) voi uint8_t led_state = buffer[2] > 0; if (led_state == 0) { - led_off(led_id); + libtock_led_off(led_id); } else { - led_on(led_id); + libtock_led_on(led_id); } ipc_notify_client(pid); break; @@ -54,7 +54,7 @@ static void ipc_callback(int pid, int len, int buf, __attribute__ ((unused)) voi int main(void) { // First get the number of LEDs setup on this board. - led_count((int*) &_number_of_leds); + libtock_led_count((int*) &_number_of_leds); ipc_register_service_callback("org.tockos.tutorials.ipc.led", ipc_callback, NULL); diff --git a/examples/tutorials/05_ipc/logic/main.c b/examples/tutorials/05_ipc/logic/main.c index 2cb74b182..8a9351cb6 100644 --- a/examples/tutorials/05_ipc/logic/main.c +++ b/examples/tutorials/05_ipc/logic/main.c @@ -1,7 +1,8 @@ -#include #include #include -#include + +#include +#include // Every 500 ms use the RNG service to randomly select an LED to turn on or // off and then use the LED service to control that LED. @@ -91,7 +92,7 @@ int main(void) { uint8_t led_state = (random >> 8) > 0x7F; set_led(led_index, led_state); - delay_ms(500); + libtocksync_alarm_delay_ms(500); } return 0; diff --git a/examples/tutorials/05_ipc/rng/main.c b/examples/tutorials/05_ipc/rng/main.c index df621686c..aa38c76ca 100644 --- a/examples/tutorials/05_ipc/rng/main.c +++ b/examples/tutorials/05_ipc/rng/main.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include // Random Number Generator Service // @@ -41,7 +41,7 @@ static void ipc_callback(int pid, int len, int buf, __attribute__ ((unused)) voi // Fill the buffer with random bytes. int number_of_bytes_received; - rng_sync(rng, len, number_of_bytes, &number_of_bytes_received); + libtocksync_rng_get_random_bytes(rng, len, number_of_bytes, &number_of_bytes_received); memcpy(buffer, rng, number_of_bytes_received); free(rng); diff --git a/examples/tutorials/hotp/hotp_milestone_one/main.c b/examples/tutorials/hotp/hotp_milestone_one/main.c index cf7667b6d..3245f4474 100644 --- a/examples/tutorials/hotp/hotp_milestone_one/main.c +++ b/examples/tutorials/hotp/hotp_milestone_one/main.c @@ -18,16 +18,14 @@ #include // Libtock includes -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include // Local includes #include "base32.h" +#include "step0.h" // --- Definitions for HOTP App --- @@ -35,157 +33,14 @@ // Select how many digits for a key #define KEY_DIGITS 6 -typedef uint64_t counter_t; - -typedef struct { - uint8_t len; - uint8_t key[64]; - counter_t counter; -} hotp_key_t; - -hotp_key_t hotp_key = {0}; - - -// --- Button Handling --- - -// Global to keep track of most recently pressed button -int pressed_btn_num; - -// Callback for button presses. -// num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_upcall(int num, - int val, - __attribute__ ((unused)) int arg2, - void * ud) { - if (val == 1) { - pressed_btn_num = num; - *((bool*)ud) = true; - } -} - -// Initializes interrupts on a button -static int initialize_buttons(bool* flag_pointer) { - // Enable button interrupts - int err = button_subscribe(button_upcall, (void*)flag_pointer); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Determine the number of supported buttons - int count = 0; - err = button_count(&count); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Enable interrupts if a button exists - if (count > 0) { - button_enable_interrupt(0); - } - - return RETURNCODE_SUCCESS; -} - - -// --- HMAC Handling --- - -static void hmac_upcall(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - void* done_flag) { - *((bool *) done_flag) = true; -} - -static int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, - int output_buffer_len) { - int ret; - bool hmac_done = false; - - ret = hmac_set_callback(hmac_upcall, &hmac_done); - if (ret < 0) { - goto done; - } - - ret = hmac_set_key_buffer(key, key_len); - if (ret < 0) { - goto deregister_upcall; - } - - ret = hmac_set_dest_buffer(output_buffer, output_buffer_len); - if (ret < 0) { - goto unallow_key_buffer; - } - - ret = hmac_set_data_buffer(data, data_len); - if (ret < 0) { - goto unallow_dest_buffer; - } - - ret = hmac_set_algorithm(TOCK_HMAC_ALG_SHA256); - if (ret < 0) { - goto unallow_data_buffer; - } - - ret = hmac_run(); - if (ret < 0) { - printf("HMAC failure: %d\r\n", ret); - goto unallow_data_buffer; - } - - yield_for(&hmac_done); - -unallow_data_buffer: - hmac_set_data_buffer(NULL, 0); - -unallow_dest_buffer: - hmac_set_dest_buffer(NULL, 0); - -unallow_key_buffer: - hmac_set_key_buffer(NULL, 0); - -deregister_upcall: - hmac_set_callback(NULL, NULL); - -done: - return ret; -} - -static int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int plaintext_capacity) { - int copylen = cipherlen; - if (plaintext_capacity < cipherlen) { - copylen = plaintext_capacity; - } - memcpy(plaintext, cipher, copylen); - return copylen; -} +hotp_key_t stored_key = {0}; // --- HOTP Actions --- -static void program_default_secret(void) { - led_on(0); - const char* default_secret = "test"; - - // Decode base32 to get HOTP key value - int ret = base32_decode((const uint8_t*)default_secret, hotp_key.key, 64); - if (ret < 0 ) { - printf("ERROR cannot base32 decode secret\r\n"); - hotp_key.len = 0; - return; - } - - // Initialize remainder of HOTP key - hotp_key.len = ret; - hotp_key.counter = 0; - - printf("Programmed \"%s\" as key \r\n", default_secret); - led_off(0); -} - -static void program_new_secret(void) { +static void program_new_secret(hotp_key_t* hotp_key) { // Request user input - led_on(0); + libtock_led_on(0); printf("Program a new key\r\n"); printf("(hit enter without typing to cancel)\r\n"); @@ -195,7 +50,9 @@ static void program_new_secret(void) { int i = 0; while (i < 127) { // read next character - char c = getch(); + char c; + int number_read, number_written; + libtocksync_console_read((uint8_t*) &c, 1, &number_read); // break on enter if (c == '\n') { @@ -208,83 +65,28 @@ static void program_new_secret(void) { i++; // echo input to user - putnstr(&c, 1); + libtocksync_console_write((uint8_t*) &c, 1, &number_written); } } // Finished. Append null terminator and echo newline newkey[i] = '\0'; - putnstr("\r\n", 2); + printf("\r\n"); // Handle early exits if (newkey[0] == '\0') { printf("Aborted\r\n"); - led_off(0); + libtock_led_off(0); return; } - // Decode base32 secret to get HOTP key value - hotp_key.len = base32_decode(newkey, hotp_key.key, 64); - hotp_key.counter = 0; + // Decode and save secret to flash + hotp_key->len = base32_decode(newkey, hotp_key->key, 64); + hotp_key->counter = 0; // Completed! printf("Programmed \"%s\" as key\r\n", newkey); - led_off(0); -} - -static void get_next_code(void) { - led_on(0); - - // Decrypt the key - uint8_t key[64]; - int keylen = decrypt(hotp_key.key, hotp_key.len, key, 64); - - // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, - // counter in HOTP), shuffled in a specific way: - uint8_t moving_factor[sizeof(counter_t)]; - for (size_t i = 0; i < sizeof(counter_t); i++) { - moving_factor[i] = (hotp_key.counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; - } - - // Perform the HMAC operation - const uint8_t HMAC_OUTPUT_BUF_LEN = 32; - uint8_t hmac_output_buf[HMAC_OUTPUT_BUF_LEN]; - hmac(key, keylen, moving_factor, sizeof(counter_t), hmac_output_buf, HMAC_OUTPUT_BUF_LEN); - - // Increment the counter - hotp_key.counter++; - - // Get output value - uint8_t offset = hmac_output_buf[HMAC_OUTPUT_BUF_LEN - 1] & 0x0f; - uint32_t S = (((hmac_output_buf[offset] & 0x7f) << 24) - | ((hmac_output_buf[offset + 1] & 0xff) << 16) - | ((hmac_output_buf[offset + 2] & 0xff) << 8) - | ((hmac_output_buf[offset + 3] & 0xff))); - - // Limit output to correct number of digits. Modulus by 10^digits - double digit_count = pow(10, KEY_DIGITS); - S %= (uint32_t)digit_count; - - // Record value as a string - char hotp_format_buffer[16]; - int len = snprintf(hotp_format_buffer, 16, "%.*ld", KEY_DIGITS, S); - if (len < 0) { - len = 0; - } else if (len > 16) { - len = 16; - } - - // Write the value to the USB keyboard. - int ret = usb_keyboard_hid_send_string_sync(hotp_format_buffer, len); - if (ret < 0) { - printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); - } else { - printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)hotp_key.counter - 1, - hotp_format_buffer); - } - - // Complete - led_off(0); + libtock_led_off(0); } @@ -292,43 +94,41 @@ static void get_next_code(void) { // Performs initialization and interactivity. int main(void) { - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Tock HOTP App Started. Usage:\r\n" "* Press Button 1 to get the next HOTP code for that slot.\r\n" "* Hold Button 1 to enter a new HOTP secret for that slot.\r\n"); // Initialize buttons - bool button_pressed = false; - if (initialize_buttons(&button_pressed) != RETURNCODE_SUCCESS) { + if (initialize_buttons() != RETURNCODE_SUCCESS) { printf("ERROR initializing buttons\r\n"); return 1; } // Configure a default HOTP secret - program_default_secret(); + program_default_secret(&stored_key); // Main loop. Waits for button presses while (true) { // Yield until a button is pressed - button_pressed = false; yield_for(&button_pressed); int btn_num = pressed_btn_num; // Delay and check if button is still pressed, signalling a "hold" - delay_ms(500); + libtocksync_alarm_delay_ms(500); int new_val = 0; - button_read(btn_num, &new_val); + libtock_button_read(btn_num, &new_val); // Handle long presses (program new secret) if (new_val) { - program_new_secret(); + program_new_secret(&stored_key); // Handle short presses on already configured keys (output next code) - } else if (hotp_key.len > 0) { - get_next_code(); + } else if (stored_key.len > 0) { + get_next_code(&stored_key, KEY_DIGITS); // Error for short press on a non-configured key - } else if (hotp_key.len == 0) { + } else if (stored_key.len == 0) { printf("HOTP / TOTP key not yet configured.\r\n"); } } diff --git a/examples/tutorials/hotp/hotp_milestone_one/step0.c b/examples/tutorials/hotp/hotp_milestone_one/step0.c new file mode 100644 index 000000000..2a23bb938 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_one/step0.c @@ -0,0 +1,167 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include "base32.h" +#include "step0.h" + +// --- Button Handling --- + +// Global to keep track of most recently pressed button +int pressed_btn_num; +bool button_pressed = false; + +// Callback for button presses. +// num: The index of the button associated with the callback +// val: 1 if pressed, 0 if depressed +static void button_callback(__attribute__ ((unused)) returncode_t ret, + int num, + bool val) { + if (val) { + pressed_btn_num = num; + button_pressed = true; + } +} + +// Initializes interrupts on a button +int initialize_buttons(void) { + returncode_t err; + + // Determine the number of supported buttons + int count = 0; + err = libtock_button_count(&count); + if (err != RETURNCODE_SUCCESS) { + return err; + } + + // Enable interrupts if a button exists + if (count > 0) { + libtock_button_notify_on_press(0, button_callback); + } + + return RETURNCODE_SUCCESS; +} + + +// --- HMAC Handling --- + +static bool hmac_done = false; +static void hmac_callback(__attribute__ ((unused)) returncode_t ret) { + hmac_done = true; +} + +int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, + int output_buffer_len) { + returncode_t ret; + hmac_done = false; + + ret = libtock_hmac_simple(LIBTOCK_HMAC_SHA256, + (uint8_t*) key, key_len, + (uint8_t*) data, data_len, + output_buffer, output_buffer_len, + hmac_callback); + if (ret != RETURNCODE_SUCCESS) { + printf("HMAC failure: %d\r\n", ret); + goto done; + } + + yield_for(&hmac_done); + +done: + libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); + libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); + libtock_hmac_set_upcall(NULL, NULL); + return ret; +} + +int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int plaintext_capacity) { + int copylen = cipherlen; + if (plaintext_capacity < cipherlen) { + copylen = plaintext_capacity; + } + memcpy(plaintext, cipher, copylen); + return copylen; +} + +// --- HOTP --- + +void program_default_secret(hotp_key_t* hotp_key) { + libtock_led_on(0); + const char* default_secret = "test"; + + // Decode base32 to get HOTP key value + int ret = base32_decode((const uint8_t*)default_secret, hotp_key->key, 64); + if (ret < 0 ) { + printf("ERROR cannot base32 decode secret\r\n"); + hotp_key->len = 0; + return; + } + + // Initialize remainder of HOTP key + hotp_key->len = ret; + hotp_key->counter = 0; + + printf("Programmed \"%s\" as key \r\n", default_secret); + libtock_led_off(0); +} + +void get_next_code(hotp_key_t* hotp_key, int key_digits) { + libtock_led_on(0); + + // Decrypt the key + uint8_t key[64]; + int keylen = decrypt(hotp_key->key, hotp_key->len, key, 64); + + // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, + // counter in HOTP), shuffled in a specific way: + uint8_t moving_factor[sizeof(counter_t)]; + for (size_t i = 0; i < sizeof(counter_t); i++) { + moving_factor[i] = (hotp_key->counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; + } + + // Perform the HMAC operation + const uint8_t HMAC_OUTPUT_BUF_LEN = 32; + uint8_t hmac_output_buf[HMAC_OUTPUT_BUF_LEN]; + hmac(key, keylen, moving_factor, sizeof(counter_t), hmac_output_buf, HMAC_OUTPUT_BUF_LEN); + + // Increment the counter + hotp_key->counter++; + + // Get output value + uint8_t offset = hmac_output_buf[HMAC_OUTPUT_BUF_LEN - 1] & 0x0f; + uint32_t S = (((hmac_output_buf[offset] & 0x7f) << 24) + | ((hmac_output_buf[offset + 1] & 0xff) << 16) + | ((hmac_output_buf[offset + 2] & 0xff) << 8) + | ((hmac_output_buf[offset + 3] & 0xff))); + + // Limit output to correct number of digits. Modulus by 10^digits + double digit_count = pow(10, key_digits); + S %= (uint32_t)digit_count; + + // Record value as a string + char hotp_format_buffer[16]; + int len = snprintf(hotp_format_buffer, 16, "%.*ld", key_digits, S); + if (len < 0) { + len = 0; + } else if (len > 16) { + len = 16; + } + + // Write the value to the USB keyboard. + int ret = libtocksync_usb_keyboard_hid_send_string(hotp_format_buffer, len); + if (ret < 0) { + printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); + } else { + printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)hotp_key->counter - 1, + hotp_format_buffer); + } + + // Complete + libtock_led_off(0); +} diff --git a/examples/tutorials/hotp/hotp_milestone_one/step0.h b/examples/tutorials/hotp/hotp_milestone_one/step0.h new file mode 100644 index 000000000..0b1d2ec90 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_one/step0.h @@ -0,0 +1,32 @@ +#pragma once + +//////////////////////////////////////////////////////////////////////////////// +// +// All functions included in step 0 that are reused. +// +//////////////////////////////////////////////////////////////////////////////// + +#include + + +// Select how many digits for a key +#define KEY_DIGITS 6 + +typedef uint64_t counter_t; + +typedef struct { + uint8_t len; + uint8_t key[64]; + counter_t counter; +} hotp_key_t; + +extern bool button_pressed; +extern int pressed_btn_num; + +int initialize_buttons(void); +int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, + int output_buffer_len); +int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int plaintext_capacity); + +void program_default_secret(hotp_key_t* hotp_key); +void get_next_code(hotp_key_t* hotp_key, int key_digits); \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/main.c b/examples/tutorials/hotp/hotp_milestone_three/main.c index e59d2d5e7..59e37d4dd 100644 --- a/examples/tutorials/hotp/hotp_milestone_three/main.c +++ b/examples/tutorials/hotp/hotp_milestone_three/main.c @@ -9,25 +9,17 @@ // Digits should be "6" unless you later change that // C standard library includes -#include -#include -#include -#include #include -#include -#include // Libtock includes -#include -#include -#include -#include -#include -#include -#include +#include +#include // Local includes #include "base32.h" +#include "step0.h" +#include "step1.h" +#include "step2.h" // --- Definitions for HOTP App --- @@ -41,351 +33,59 @@ // Slot 3: 8 digits int key_digits[NUM_KEYS] = {6, 6, 7, 8}; -typedef uint64_t counter_t; - -typedef struct { - uint8_t len; - uint8_t key[64]; - counter_t counter; -} hotp_key_t; - -// hotp_key_t hotp_key = {0}; - - -// --- Button Handling --- - -// Global to keep track of most recently pressed button -int pressed_btn_num; - -// Callback for button presses. -// num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_upcall(int num, - int val, - __attribute__ ((unused)) int arg2, - void * ud) { - if (val == 1) { - pressed_btn_num = num; - *((bool*)ud) = true; - } -} - -// Initializes interrupts for all buttons on the board -static int initialize_buttons(bool* flag_pointer) { - // Enable button interrupts - int err = button_subscribe(button_upcall, (void*)flag_pointer); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Enable interrupts on each button. - int count = 0; - err = button_count(&count); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - for (int i = 0; i < count; i++) { - button_enable_interrupt(i); - } - - return RETURNCODE_SUCCESS; -} - - -// --- App State Handling --- - -typedef struct { - uint32_t magic; - hotp_key_t keys[NUM_KEYS]; -} key_storage_t; - -APP_STATE_DECLARE(key_storage_t, keystore); - -static int initialize_app_state(void) { - // Recover state from flash if it exists - int ret = app_state_load_sync(); - if (ret != 0) { - printf("ERROR(%i): Could not read the flash region.\r\n", ret); - return ret; - } else { - printf("Flash read\r\n"); - } - - // Initialize default values if nothing previously existed - if (keystore.magic != 0xdeadbeef) { - keystore.magic = 0xdeadbeef; - for (int i = 0; i < NUM_KEYS; i++) { - keystore.keys[i].len = 0; - } - ret = app_state_save_sync(); - if (ret != 0) { - printf("ERROR(%i): Could not write back to flash.\r\n", ret); - return ret; - } else { - printf("Initialized state\r\n"); - } - } - - return RETURNCODE_SUCCESS; -} - - -// --- HMAC Handling --- - -static void hmac_upcall(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - void* done_flag) { - *((bool *) done_flag) = true; -} - -static int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, - int output_buffer_len) { - int ret; - bool hmac_done = false; - - ret = hmac_set_callback(hmac_upcall, &hmac_done); - if (ret < 0) { - goto done; - } - - ret = hmac_set_key_buffer(key, key_len); - if (ret < 0) { - goto deregister_upcall; - } - - ret = hmac_set_dest_buffer(output_buffer, output_buffer_len); - if (ret < 0) { - goto unallow_key_buffer; - } - - ret = hmac_set_data_buffer(data, data_len); - if (ret < 0) { - goto unallow_dest_buffer; - } - - ret = hmac_set_algorithm(TOCK_HMAC_ALG_SHA256); - if (ret < 0) { - goto unallow_data_buffer; - } - - ret = hmac_run(); - if (ret < 0) { - printf("HMAC failure: %d\r\n", ret); - goto unallow_data_buffer; - } - - yield_for(&hmac_done); - -unallow_data_buffer: - hmac_set_data_buffer(NULL, 0); - -unallow_dest_buffer: - hmac_set_dest_buffer(NULL, 0); - -unallow_key_buffer: - hmac_set_key_buffer(NULL, 0); - -deregister_upcall: - hmac_set_callback(NULL, NULL); - -done: - return ret; -} - -static int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int plaintext_capacity) { - int copylen = cipherlen; - if (plaintext_capacity < cipherlen) { - copylen = plaintext_capacity; - } - memcpy(plaintext, cipher, copylen); - return copylen; -} - - -// --- HOTP Actions --- - -static void program_default_secret(void) { - led_on(0); - const char* default_secret = "test"; - - // Decode base32 to get HOTP key value - int ret = base32_decode((const uint8_t*)default_secret, keystore.keys[0].key, 64); - if (ret < 0 ) { - printf("ERROR cannot base32 decode secret\r\n"); - keystore.keys[0].len = 0; - return; - } - - // Initialize remainder of HOTP key - keystore.keys[0].len = ret; - keystore.keys[0].counter = 0; - - printf("Programmed \"%s\" as key \r\n", default_secret); - led_off(0); -} - -static void program_new_secret(int slot_num) { - // Request user input - led_on(slot_num); - printf("Program a new key in slot %d\r\n", slot_num); - printf("(hit enter without typing to cancel)\r\n"); - - // Read key values from user - // TODO: sure would be nice to clear all previous input before starting this - uint8_t newkey[128]; - int i = 0; - while (i < 127) { - // read next character - char c = getch(); - - // break on enter - if (c == '\n') { - break; - } - - // only record alphanumeric characters - if (isalnum((int) c)) { - newkey[i] = c; - i++; - - // echo input to user - putnstr(&c, 1); - } - } - - // Finished. Append null terminator and echo newline - newkey[i] = '\0'; - putnstr("\r\n", 2); - - // Handle early exits - if (newkey[0] == '\0') { - printf("Aborted\r\n"); - led_off(slot_num); - return; - } - - // Decode and save secret to flash - keystore.keys[slot_num].len = base32_decode(newkey, keystore.keys[slot_num].key, 64); - keystore.keys[slot_num].counter = 0; - int ret = app_state_save_sync(); - if (ret != 0) { - printf("ERROR(%i): Could not write back to flash.\r\n", ret); - } - - // Completed! - printf("Programmed \"%s\" to slot %d\r\n", newkey, slot_num); - led_off(slot_num); -} - -static void get_next_code(int slot_num) { - led_on(slot_num); - - // Decrypt the key - uint8_t key[64]; - int keylen = decrypt(keystore.keys[slot_num].key, keystore.keys[slot_num].len, key, 64); - - // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, - // counter in HOTP), shuffled in a specific way: - uint8_t moving_factor[sizeof(counter_t)]; - for (size_t i = 0; i < sizeof(counter_t); i++) { - moving_factor[i] = (keystore.keys[slot_num].counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; - } - - // Perform the HMAC operation - const uint8_t HMAC_OUTPUT_BUF_LEN = 32; - uint8_t hmac_output_buf[HMAC_OUTPUT_BUF_LEN]; - hmac(key, keylen, moving_factor, sizeof(counter_t), hmac_output_buf, HMAC_OUTPUT_BUF_LEN); - - // Increment the counter and save to flash - keystore.keys[slot_num].counter++; - int ret = app_state_save_sync(); - if (ret != 0) { - printf("ERROR(%i): Could not write back to flash.\r\n", ret); - } - - // Get output value - uint8_t offset = hmac_output_buf[HMAC_OUTPUT_BUF_LEN - 1] & 0x0f; - uint32_t S = (((hmac_output_buf[offset] & 0x7f) << 24) - | ((hmac_output_buf[offset + 1] & 0xff) << 16) - | ((hmac_output_buf[offset + 2] & 0xff) << 8) - | ((hmac_output_buf[offset + 3] & 0xff))); - - // Limit output to correct number of digits. Modulus by 10^digits - double digit_count = pow(10, key_digits[slot_num]); - S %= (uint32_t)digit_count; - - // Record value as a string - char hotp_format_buffer[16]; - int len = snprintf(hotp_format_buffer, 16, "%.*ld", key_digits[slot_num], S); - if (len < 0) { - len = 0; - } else if (len > 16) { - len = 16; - } - - // Write the value to the USB keyboard. - ret = usb_keyboard_hid_send_string_sync(hotp_format_buffer, len); - if (ret < 0) { - printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); - } else { - printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)keystore.keys[slot_num].counter - 1, - hotp_format_buffer); - } - - // Complete - led_off(slot_num); -} +// List of HOTP keys. +hotp_key_t stored_keys[NUM_KEYS]; // --- Main Loop --- // Performs initialization and interactivity. int main(void) { - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Tock HOTP App Started. Usage:\r\n" "* Press a button to get the next HOTP code for that slot.\r\n" "* Hold a button to enter a new HOTP secret for that slot.\r\n"); - // Initialize app state - if (initialize_app_state() != RETURNCODE_SUCCESS) { - printf("ERROR initializing app store\r\n"); - return 1; + // Initialize keys from KV store. + for (int i = 0; i < NUM_KEYS; i++) { + if (initialize_key(&stored_keys[i], i) != RETURNCODE_SUCCESS) { + printf("ERROR initializing key from KV\r\n"); + return 1; + } } // Initialize buttons - bool button_pressed = false; - if (initialize_buttons(&button_pressed) != RETURNCODE_SUCCESS) { + if (initialize_buttons() != RETURNCODE_SUCCESS) { printf("ERROR initializing buttons\r\n"); return 1; } // Configure a default HOTP secret - program_default_secret(); + program_default_secret(&stored_keys[0]); // Main loop. Waits for button presses while (true) { // Yield until a button is pressed - button_pressed = false; yield_for(&button_pressed); int btn_num = pressed_btn_num; // Delay and check if button is still pressed, signalling a "hold" - delay_ms(500); + libtocksync_alarm_delay_ms(500); int new_val = 0; - button_read(btn_num, &new_val); + libtock_button_read(btn_num, &new_val); // Handle long presses (program new secret) if (new_val) { - program_new_secret(btn_num); + program_new_secret(&stored_keys[btn_num]); + save_key(&stored_keys[btn_num], btn_num); - // Handle short presses on already configured keys (output next code) - } else if (btn_num < NUM_KEYS && keystore.keys[btn_num].len > 0) { - get_next_code(btn_num); + } else if (btn_num < NUM_KEYS && stored_keys[btn_num].len > 0) { + // Handle short presses on already configured keys (output next code). + get_next_code(&stored_keys[btn_num], key_digits[btn_num]); + save_key(&stored_keys[btn_num], btn_num); - // Error for short press on a non-configured key - } else if (keystore.keys[btn_num].len == 0) { + } else if (stored_keys[btn_num].len == 0) { + // Error for short press on a non-configured key. printf("HOTP / TOTP slot %d not yet configured.\r\n", btn_num); } } diff --git a/examples/tutorials/hotp/hotp_milestone_three/step0.c b/examples/tutorials/hotp/hotp_milestone_three/step0.c new file mode 120000 index 000000000..9877a9411 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step0.c @@ -0,0 +1 @@ +../hotp_milestone_one/step0.c \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/step0.h b/examples/tutorials/hotp/hotp_milestone_three/step0.h new file mode 120000 index 000000000..a3f30f7e5 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step0.h @@ -0,0 +1 @@ +../hotp_milestone_one/step0.h \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/step1.c b/examples/tutorials/hotp/hotp_milestone_three/step1.c new file mode 120000 index 000000000..2c43bc623 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step1.c @@ -0,0 +1 @@ +../hotp_milestone_two/step1.c \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/step1.h b/examples/tutorials/hotp/hotp_milestone_three/step1.h new file mode 120000 index 000000000..44216e724 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step1.h @@ -0,0 +1 @@ +../hotp_milestone_two/step1.h \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/step2.c b/examples/tutorials/hotp/hotp_milestone_three/step2.c new file mode 100644 index 000000000..e9c132a7e --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step2.c @@ -0,0 +1,52 @@ +#include +#include + +#include +#include + +#include "step0.h" +#include "step1.h" +#include "step2.h" + + + +int initialize_key(hotp_key_t* hotp_key, int index) { + int ret; + + uint8_t key[64]; + int key_len = 0; + uint8_t value[sizeof(hotp_key_t)]; + uint32_t value_len = 0; + + key_len = snprintf((char*) key, 64, "hotp-key-%i", index); + + ret = libtocksync_kv_get(key, key_len, value, sizeof(hotp_key_t), &value_len); + + // Check if we read what looks like a valid key. + if (ret == RETURNCODE_SUCCESS && value_len == sizeof(hotp_key_t)) { + // Looks valid + memcpy(hotp_key, value, sizeof(hotp_key_t)); + } + + return RETURNCODE_SUCCESS; +} + +void save_key(hotp_key_t* hotp_key, int index) { + int ret; + + // Key is "hotp-key-[index]". Value is the `hotp_key_t` data. + uint8_t key[64]; + int key_len = 0; + uint8_t value[sizeof(hotp_key_t)]; + + key_len = snprintf((char*) key, 64, "hotp-key-%i", index); + + // Save the key value. + memcpy(value, hotp_key, sizeof(hotp_key_t)); + ret = libtocksync_kv_set(key, key_len, value, sizeof(hotp_key_t)); + + if (ret != 0) { + printf("ERROR(%i): %s.\r\n", ret, tock_strrcode(ret)); + printf(" Could not store key.\r\n"); + } +} \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_three/step2.h b/examples/tutorials/hotp/hotp_milestone_three/step2.h new file mode 100644 index 000000000..3903549ac --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_three/step2.h @@ -0,0 +1,13 @@ +#pragma once + +//////////////////////////////////////////////////////////////////////////////// +// +// All functions included in step 2 that are reused. +// +//////////////////////////////////////////////////////////////////////////////// + +#include + +int initialize_key(hotp_key_t* hotp_key, int index); + +void save_key(hotp_key_t* hotp_key, int index); diff --git a/examples/tutorials/hotp/hotp_milestone_two/main.c b/examples/tutorials/hotp/hotp_milestone_two/main.c index 8c6ecef4e..830af09a0 100644 --- a/examples/tutorials/hotp/hotp_milestone_two/main.c +++ b/examples/tutorials/hotp/hotp_milestone_two/main.c @@ -18,17 +18,15 @@ #include // Libtock includes -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include // Local includes #include "base32.h" +#include "step0.h" +#include "step1.h" // --- Definitions for HOTP App --- @@ -36,320 +34,77 @@ // Select how many digits for a key #define KEY_DIGITS 6 -typedef uint64_t counter_t; - -typedef struct { - uint8_t len; - uint8_t key[64]; - counter_t counter; -} hotp_key_t; - -hotp_key_t hotp_key = {0}; - - -// --- Button Handling --- - -// Global to keep track of most recently pressed button -int pressed_btn_num; - -// Callback for button presses. -// num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_upcall(int num, - int val, - __attribute__ ((unused)) int arg2, - void * ud) { - if (val == 1) { - pressed_btn_num = num; - *((bool*)ud) = true; - } -} - -// Initializes interrupts on a button -static int initialize_buttons(bool* flag_pointer) { - // Enable button interrupts - int err = button_subscribe(button_upcall, (void*)flag_pointer); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Determine the number of supported buttons - int count = 0; - err = button_count(&count); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Enable interrupts if a button exists - if (count > 0) { - button_enable_interrupt(0); - } - - return RETURNCODE_SUCCESS; -} +hotp_key_t stored_key = {0}; // --- Persistent Key Handling --- -static void save_key(void) { - int ret; - uint8_t value[sizeof(hotp_key_t)]; - - // Key is "hotp". Value is the `key_storage_t` data. - memcpy(value, &hotp_key, sizeof(hotp_key_t)); - ret = kv_set_sync((const uint8_t *) "hotp", 4, value, sizeof(hotp_key_t)); - - if (ret != 0) { - printf("ERROR(%i): %s.\r\n", ret, tock_strrcode(ret)); - printf(" Could not store key.\r\n"); - } -} - -static int initialize_key(void) { +static int initialize_key(hotp_key_t* hotp_key, int index) { int ret; + uint8_t key[64]; + int key_len = 0; uint8_t value[sizeof(hotp_key_t)]; uint32_t value_len = 0; - ret = kv_get_sync((const uint8_t *) "hotp", 4, value, sizeof(hotp_key_t), &value_len); + + key_len = snprintf((char*) key, 64, "hotp-key-%i", index); + + ret = libtocksync_kv_get(key, key_len, value, sizeof(hotp_key_t), &value_len); // Check if we read what looks like a valid key. if (ret == RETURNCODE_SUCCESS && value_len == sizeof(hotp_key_t)) { // Looks valid - memcpy(&hotp_key, value, sizeof(hotp_key_t)); + memcpy(hotp_key, value, sizeof(hotp_key_t)); } return RETURNCODE_SUCCESS; } - -// --- HMAC Handling --- - -static void hmac_upcall(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - void* done_flag) { - *((bool *) done_flag) = true; -} - -static int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, - int output_buffer_len) { - int ret; - bool hmac_done = false; - - ret = hmac_set_callback(hmac_upcall, &hmac_done); - if (ret < 0) { - goto done; - } - - ret = hmac_set_key_buffer(key, key_len); - if (ret < 0) { - goto deregister_upcall; - } - - ret = hmac_set_dest_buffer(output_buffer, output_buffer_len); - if (ret < 0) { - goto unallow_key_buffer; - } - - ret = hmac_set_data_buffer(data, data_len); - if (ret < 0) { - goto unallow_dest_buffer; - } - - ret = hmac_set_algorithm(TOCK_HMAC_ALG_SHA256); - if (ret < 0) { - goto unallow_data_buffer; - } - - ret = hmac_run(); - if (ret < 0) { - printf("HMAC failure: %d\r\n", ret); - goto unallow_data_buffer; - } - - yield_for(&hmac_done); - -unallow_data_buffer: - hmac_set_data_buffer(NULL, 0); - -unallow_dest_buffer: - hmac_set_dest_buffer(NULL, 0); - -unallow_key_buffer: - hmac_set_key_buffer(NULL, 0); - -deregister_upcall: - hmac_set_callback(NULL, NULL); - -done: - return ret; -} - -static int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int plaintext_capacity) { - int copylen = cipherlen; - if (plaintext_capacity < cipherlen) { - copylen = plaintext_capacity; - } - memcpy(plaintext, cipher, copylen); - return copylen; -} - - -// --- HOTP Actions --- - -static void program_default_secret(void) { - led_on(0); - const char* default_secret = "test"; - - // Decode base32 to get HOTP key value - int ret = base32_decode((const uint8_t*)default_secret, hotp_key.key, 64); - if (ret < 0 ) { - printf("ERROR cannot base32 decode secret\r\n"); - hotp_key.len = 0; - return; - } - - // Initialize remainder of HOTP key - hotp_key.len = ret; - hotp_key.counter = 0; - - printf("Programmed \"%s\" as key \r\n", default_secret); - led_off(0); -} - -static void program_new_secret(void) { - // Request user input - led_on(0); - printf("Program a new key\r\n"); - printf("(hit enter without typing to cancel)\r\n"); - - // Read key values from user - // TODO: sure would be nice to clear all previous input before starting this - uint8_t newkey[128]; - int i = 0; - while (i < 127) { - // read next character - char c = getch(); - - // break on enter - if (c == '\n') { - break; - } - - // only record alphanumeric characters - if (isalnum((int) c)) { - newkey[i] = c; - i++; - - // echo input to user - putnstr(&c, 1); - } - } - - // Finished. Append null terminator and echo newline - newkey[i] = '\0'; - putnstr("\r\n", 2); - - // Handle early exits - if (newkey[0] == '\0') { - printf("Aborted\r\n"); - led_off(0); - return; - } - - // Decode and save secret to flash - hotp_key.len = base32_decode(newkey, hotp_key.key, 64); - hotp_key.counter = 0; - save_key(); - - // Completed! - printf("Programmed \"%s\" as key\r\n", newkey); - led_off(0); -} - -static void get_next_code(void) { +static void save_key(hotp_key_t* hotp_key, int index) { int ret; - led_on(0); - - // Decrypt the key + // Key is "hotp-key-[index]". Value is the `hotp_key_t` data. uint8_t key[64]; - int keylen = decrypt(hotp_key.key, hotp_key.len, key, 64); + int key_len = 0; + uint8_t value[sizeof(hotp_key_t)]; - // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, - // counter in HOTP), shuffled in a specific way: - uint8_t moving_factor[sizeof(counter_t)]; - for (size_t i = 0; i < sizeof(counter_t); i++) { - moving_factor[i] = (hotp_key.counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; - } + key_len = snprintf((char*) key, 64, "hotp-key-%i", index); - // Perform the HMAC operation - const uint8_t HMAC_OUTPUT_BUF_LEN = 32; - uint8_t hmac_output_buf[HMAC_OUTPUT_BUF_LEN]; - hmac(key, keylen, moving_factor, sizeof(counter_t), hmac_output_buf, HMAC_OUTPUT_BUF_LEN); - - // Increment the counter and save to flash - hotp_key.counter++; - save_key(); - - // Get output value - uint8_t offset = hmac_output_buf[HMAC_OUTPUT_BUF_LEN - 1] & 0x0f; - uint32_t S = (((hmac_output_buf[offset] & 0x7f) << 24) - | ((hmac_output_buf[offset + 1] & 0xff) << 16) - | ((hmac_output_buf[offset + 2] & 0xff) << 8) - | ((hmac_output_buf[offset + 3] & 0xff))); - - // Limit output to correct number of digits. Modulus by 10^digits - double digit_count = pow(10, KEY_DIGITS); - S %= (uint32_t)digit_count; - - // Record value as a string - char hotp_format_buffer[16]; - int len = snprintf(hotp_format_buffer, 16, "%.*ld", KEY_DIGITS, S); - if (len < 0) { - len = 0; - } else if (len > 16) { - len = 16; - } + // Save the key value. + memcpy(value, hotp_key, sizeof(hotp_key_t)); + ret = libtocksync_kv_set(key, key_len, value, sizeof(hotp_key_t)); - // Write the value to the USB keyboard. - ret = usb_keyboard_hid_send_string_sync(hotp_format_buffer, len); - if (ret < 0) { - printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); - } else { - printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)hotp_key.counter - 1, - hotp_format_buffer); + if (ret != 0) { + printf("ERROR(%i): %s.\r\n", ret, tock_strrcode(ret)); + printf(" Could not store key.\r\n"); } - - // Complete - led_off(0); } + // --- Main Loop --- // Performs initialization and interactivity. int main(void) { - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Tock HOTP App Started. Usage:\r\n" "* Press Button 1 to get the next HOTP code for that slot.\r\n" "* Hold Button 1 to enter a new HOTP secret for that slot.\r\n"); // Initialize key from KV store. - if (initialize_key() != RETURNCODE_SUCCESS) { + if (initialize_key(&stored_key, 0) != RETURNCODE_SUCCESS) { printf("ERROR initializing key from KV\r\n"); return 1; } // Initialize buttons - bool button_pressed = false; - if (initialize_buttons(&button_pressed) != RETURNCODE_SUCCESS) { + if (initialize_buttons() != RETURNCODE_SUCCESS) { printf("ERROR initializing buttons\r\n"); return 1; } // Configure a default HOTP secret - program_default_secret(); + program_default_secret(&stored_key); // Main loop. Waits for button presses while (true) { @@ -359,20 +114,22 @@ int main(void) { int btn_num = pressed_btn_num; // Delay and check if button is still pressed, signalling a "hold" - delay_ms(500); + libtocksync_alarm_delay_ms(500); int new_val = 0; - button_read(btn_num, &new_val); + libtock_button_read(btn_num, &new_val); // Handle long presses (program new secret) if (new_val) { - program_new_secret(); + program_new_secret(&stored_key); + save_key(&stored_key, 0); // Handle short presses on already configured keys (output next code) - } else if (hotp_key.len > 0) { - get_next_code(); + } else if (stored_key.len > 0) { + get_next_code(&stored_key, KEY_DIGITS); + save_key(&stored_key, 0); // Error for short press on a non-configured key - } else if (hotp_key.len == 0) { + } else if (stored_key.len == 0) { printf("HOTP / TOTP key not yet configured.\r\n"); } } diff --git a/examples/tutorials/hotp/hotp_milestone_two/step0.c b/examples/tutorials/hotp/hotp_milestone_two/step0.c new file mode 120000 index 000000000..9877a9411 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_two/step0.c @@ -0,0 +1 @@ +../hotp_milestone_one/step0.c \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_two/step0.h b/examples/tutorials/hotp/hotp_milestone_two/step0.h new file mode 120000 index 000000000..a3f30f7e5 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_two/step0.h @@ -0,0 +1 @@ +../hotp_milestone_one/step0.h \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_milestone_two/step1.c b/examples/tutorials/hotp/hotp_milestone_two/step1.c new file mode 100644 index 000000000..6baff639f --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_two/step1.c @@ -0,0 +1,60 @@ +#include +#include + +#include +#include + +#include "base32.h" +#include "step0.h" +#include "step1.h" + +void program_new_secret(hotp_key_t* hotp_key) { + // Request user input + libtock_led_on(0); + printf("Program a new key\r\n"); + printf("(hit enter without typing to cancel)\r\n"); + + // Read key values from user + // TODO: sure would be nice to clear all previous input before starting this + uint8_t newkey[128]; + int i = 0; + while (i < 127) { + // read next character + char c; + int number_read, number_written; + libtocksync_console_read((uint8_t*) &c, 1, &number_read); + + // break on enter + if (c == '\n') { + break; + } + + // only record alphanumeric characters + if (isalnum((int) c)) { + newkey[i] = c; + i++; + + // echo input to user + libtocksync_console_write((uint8_t*) &c, 1, &number_written); + } + } + + // Finished. Append null terminator and echo newline + newkey[i] = '\0'; + printf("\r\n"); + + // Handle early exits + if (newkey[0] == '\0') { + printf("Aborted\r\n"); + libtock_led_off(0); + return; + } + + // Decode and save secret to flash + hotp_key->len = base32_decode(newkey, hotp_key->key, 64); + hotp_key->counter = 0; + + // Completed! + printf("Programmed \"%s\" as key\r\n", newkey); + libtock_led_off(0); +} diff --git a/examples/tutorials/hotp/hotp_milestone_two/step1.h b/examples/tutorials/hotp/hotp_milestone_two/step1.h new file mode 100644 index 000000000..d316e8be0 --- /dev/null +++ b/examples/tutorials/hotp/hotp_milestone_two/step1.h @@ -0,0 +1,11 @@ +#pragma once + +//////////////////////////////////////////////////////////////////////////////// +// +// All functions included in step 1 that are reused. +// +//////////////////////////////////////////////////////////////////////////////// + +#include + +void program_new_secret(hotp_key_t* hotp_key); diff --git a/examples/tutorials/hotp/hotp_oracle_complete/main.c b/examples/tutorials/hotp/hotp_oracle_complete/main.c index 57656ddef..66d5b720b 100644 --- a/examples/tutorials/hotp/hotp_oracle_complete/main.c +++ b/examples/tutorials/hotp/hotp_oracle_complete/main.c @@ -14,21 +14,20 @@ #include #include #include -#include #include // Libtock includes -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include // Local includes #include "base32.h" #include "oracle.h" +#include "step0.h" // --- Definitions for HOTP App --- @@ -42,64 +41,21 @@ // Slot 3: 8 digits int key_digits[NUM_KEYS] = {6, 6, 7, 8}; -typedef uint64_t counter_t; - typedef struct __attribute__((__packed__)) { uint8_t len; uint8_t iv[16]; uint8_t key[64]; counter_t counter; -} hotp_key_t; +} hotp_encrypted_key_t; // List of HOTP keys. -hotp_key_t keys[NUM_KEYS]; - - +hotp_encrypted_key_t keys[NUM_KEYS]; -// --- Button Handling --- - -// Global to keep track of most recently pressed button -int pressed_btn_num; - -// Callback for button presses. -// num: The index of the button associated with the callback -// val: 1 if pressed, 0 if depressed -static void button_upcall(int num, - int val, - __attribute__ ((unused)) int arg2, - void * ud) { - if (val == 1) { - pressed_btn_num = num; - *((bool*)ud) = true; - } -} - -// Initializes interrupts for all buttons on the board -static int initialize_buttons(bool* flag_pointer) { - // Enable button interrupts - int err = button_subscribe(button_upcall, (void*)flag_pointer); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - // Enable interrupts on each button. - int count = 0; - err = button_count(&count); - if (err != RETURNCODE_SUCCESS) { - return err; - } - - for (int i = 0; i < count; i++) { - button_enable_interrupt(i); - } - - return RETURNCODE_SUCCESS; -} // --- Persistent Key Handling --- -static void program_default_secret(void); +static void program_default_encrypted_secret(void); static void save_key(int slot_num) { int ret; @@ -109,7 +65,7 @@ static void save_key(int slot_num) { // Key is "hotp-key-". Value is the `hotp_key_t` data. int key_len = snprintf((char*) key, 64, "hotp-key-%i", slot_num); memcpy(value, &keys[slot_num], sizeof(hotp_key_t)); - ret = kv_set_sync(key, key_len, value, sizeof(hotp_key_t)); + ret = libtocksync_kv_set(key, key_len, value, sizeof(hotp_key_t)); if (ret != 0) { printf("ERROR(%i): %s.\r\n", ret, tock_strrcode(ret)); @@ -129,7 +85,7 @@ static int initialize_keys(void) { int key_len = snprintf((char*) key, 64, "hotp-key-%i", i); uint32_t value_len = 0; - ret = kv_get_sync(key, key_len, value, sizeof(hotp_key_t), &value_len); + ret = libtocksync_kv_get(key, key_len, value, sizeof(hotp_key_t), &value_len); // Check if we read what looks like a valid key. if (ret != RETURNCODE_SUCCESS || value_len != sizeof(hotp_key_t)) { @@ -137,7 +93,7 @@ static int initialize_keys(void) { save_key(i); if (i == 0) { - program_default_secret(); + program_default_encrypted_secret(); } } else { // Looks valid, copy into our local array of keys. @@ -149,73 +105,9 @@ static int initialize_keys(void) { return RETURNCODE_SUCCESS; } - -// --- HMAC Handling --- - -static void hmac_upcall(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - void* done_flag) { - *((bool *) done_flag) = true; -} - -static int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, - int output_buffer_len) { - int ret; - bool hmac_done = false; - - ret = hmac_set_callback(hmac_upcall, &hmac_done); - if (ret < 0) { - goto done; - } - - ret = hmac_set_key_buffer(key, key_len); - if (ret < 0) { - goto deregister_upcall; - } - - ret = hmac_set_dest_buffer(output_buffer, output_buffer_len); - if (ret < 0) { - goto unallow_key_buffer; - } - - ret = hmac_set_data_buffer(data, data_len); - if (ret < 0) { - goto unallow_dest_buffer; - } - - ret = hmac_set_algorithm(TOCK_HMAC_ALG_SHA256); - if (ret < 0) { - goto unallow_data_buffer; - } - - ret = hmac_run(); - if (ret < 0) { - printf("HMAC failure: %d\r\n", ret); - goto unallow_data_buffer; - } - - yield_for(&hmac_done); - -unallow_data_buffer: - hmac_set_data_buffer(NULL, 0); - -unallow_dest_buffer: - hmac_set_dest_buffer(NULL, 0); - -unallow_key_buffer: - hmac_set_key_buffer(NULL, 0); - -deregister_upcall: - hmac_set_callback(NULL, NULL); - -done: - return ret; -} - // --- HOTP Actions --- -static void program_secret(int slot_num, const char* secret) { +static void program_secret(int slot_num, uint8_t* secret) { uint8_t plaintext_key[64]; // Decode base32 to get HOTP key value int ret = base32_decode((const uint8_t*)secret, plaintext_key, 64); @@ -225,7 +117,7 @@ static void program_secret(int slot_num, const char* secret) { return; } - ret = encrypt(plaintext_key, ret, keys[slot_num].key, 64, keys[slot_num].iv); + ret = oracle_encrypt(plaintext_key, ret, keys[slot_num].key, 64, keys[slot_num].iv); if (ret < 0 ) { printf("ERROR(%i): %s.\r\n", ret, tock_strrcode(ret)); printf("ERROR cannot encrypt key\r\n"); @@ -242,29 +134,31 @@ static void program_secret(int slot_num, const char* secret) { printf("Programmed \"%s\" to slot %d\r\n", secret, slot_num); } -static void program_default_secret(void) { - led_on(0); +static void program_default_encrypted_secret(void) { + libtock_led_on(0); const char* default_secret = "test"; - program_secret(0, default_secret); - led_off(0); + program_secret(0, (uint8_t*) default_secret); + libtock_led_off(0); } static void program_new_secret(int slot_num) { // Request user input - led_on(slot_num); + libtock_led_on(slot_num); printf("Program a new key in slot %d\r\n", slot_num); printf("(hit enter without typing to cancel)\r\n"); // Read key values from user // TODO: sure would be nice to clear all previous input before starting this - char newkey[128]; + uint8_t newkey[128]; int i = 0; while (i < 127) { // read next character - char c = getch(); + char c; + int number_read, number_written; + libtocksync_console_read((uint8_t*) &c, 1, &number_read); // break on enter - if (c == '\n' || c == '\r') { + if (c == '\n') { break; } @@ -274,31 +168,31 @@ static void program_new_secret(int slot_num) { i++; // echo input to user - putnstr(&c, 1); + libtocksync_console_write((uint8_t*) &c, 1, &number_written); } } // Finished. Append null terminator and echo newline newkey[i] = '\0'; - putnstr("\r\n", 2); + printf("\r\n"); // Handle early exits if (newkey[0] == '\0') { printf("Aborted\r\n"); - led_off(slot_num); + libtock_led_off(0); return; } program_secret(slot_num, newkey); - led_off(slot_num); + libtock_led_off(slot_num); } -static void get_next_code(int slot_num) { - led_on(slot_num); +static void get_next_code_encrypted(int slot_num) { + libtock_led_on(slot_num); // Decrypt the key uint8_t key[64]; - int keylen = decrypt(keys[slot_num].iv, keys[slot_num].key, keys[slot_num].len, key, 64); + int keylen = oracle_decrypt(keys[slot_num].iv, keys[slot_num].key, keys[slot_num].len, key, 64); // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, // counter in HOTP), shuffled in a specific way: @@ -336,9 +230,9 @@ static void get_next_code(int slot_num) { len = 16; } - if (driver_exists(DRIVER_NUM_USBKEYBOARDHID)) { + if (libtock_usb_keyboard_hid_exists()) { // Write the value to the USB keyboard. - int ret = usb_keyboard_hid_send_string_sync(hotp_format_buffer, len); + int ret = libtocksync_usb_keyboard_hid_send_string(hotp_format_buffer, len); if (ret < 0) { printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); } else { @@ -352,7 +246,7 @@ static void get_next_code(int slot_num) { } // Complete - led_off(slot_num); + libtock_led_off(slot_num); } @@ -371,8 +265,7 @@ int main(void) { } // Initialize buttons - bool button_pressed = false; - if (initialize_buttons(&button_pressed) != RETURNCODE_SUCCESS) { + if (initialize_buttons() != RETURNCODE_SUCCESS) { printf("ERROR initializing buttons\r\n"); return 1; } @@ -385,9 +278,9 @@ int main(void) { int btn_num = pressed_btn_num; // Delay and check if button is still pressed, signalling a "hold" - delay_ms(500); + libtocksync_alarm_delay_ms(500); int new_val = 0; - button_read(btn_num, &new_val); + libtock_button_read(btn_num, &new_val); // Handle long presses (program new secret) if (new_val) { @@ -395,7 +288,7 @@ int main(void) { // Handle short presses on already configured keys (output next code) } else if (btn_num < NUM_KEYS && keys[btn_num].len > 0) { - get_next_code(btn_num); + get_next_code_encrypted(btn_num); // Error for short press on a non-configured key } else if (keys[btn_num].len == 0) { diff --git a/examples/tutorials/hotp/hotp_oracle_complete/oracle.c b/examples/tutorials/hotp/hotp_oracle_complete/oracle.c index cc6a457ec..2440005cd 100644 --- a/examples/tutorials/hotp/hotp_oracle_complete/oracle.c +++ b/examples/tutorials/hotp/hotp_oracle_complete/oracle.c @@ -1,8 +1,9 @@ -#include "oracle.h" - -#include #include +#include + +#include "oracle.h" + struct crypt_upcall_ud { bool done; int len; @@ -16,7 +17,7 @@ static void crypt_upcall(__attribute__((unused)) int num, ((struct crypt_upcall_ud*)ud)->len = len; } -int decrypt(const uint8_t* iv, const uint8_t* cipher, int cipher_len, uint8_t* output, int outputlen) { +int oracle_decrypt(const uint8_t* iv, const uint8_t* cipher, int cipher_len, uint8_t* output, int outputlen) { // set IV allow_ro_return_t ror = allow_readonly(0x99999, 0, iv, 16); if (!ror.success) { @@ -52,13 +53,13 @@ int decrypt(const uint8_t* iv, const uint8_t* cipher, int cipher_len, uint8_t* o return ud.len; } -int encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* output, int output_len, uint8_t iv[16]) { +int oracle_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* output, int output_len, uint8_t iv[16]) { // get randomness for iv int rng_out = 0; - int suc = rng_sync(iv, 16, 16, &rng_out); + int suc = libtocksync_rng_get_random_bytes(iv, 16, 16, &rng_out); if (suc != 0) { return suc; } - return decrypt(iv, plaintext, plaintext_len, output, output_len); + return oracle_decrypt(iv, plaintext, plaintext_len, output, output_len); } diff --git a/examples/tutorials/hotp/hotp_oracle_complete/oracle.h b/examples/tutorials/hotp/hotp_oracle_complete/oracle.h index a341be9c3..1d1f067d2 100644 --- a/examples/tutorials/hotp/hotp_oracle_complete/oracle.h +++ b/examples/tutorials/hotp/hotp_oracle_complete/oracle.h @@ -4,7 +4,7 @@ #include -int decrypt(const uint8_t* iv, const uint8_t* cipher, int cipher_len, uint8_t* output, int outputlen); +int oracle_decrypt(const uint8_t* iv, const uint8_t* cipher, int cipher_len, uint8_t* output, int outputlen); -int encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* output, int output_len, uint8_t iv[16]); +int oracle_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* output, int output_len, uint8_t iv[16]); diff --git a/examples/tutorials/hotp/hotp_oracle_complete/step0.c b/examples/tutorials/hotp/hotp_oracle_complete/step0.c new file mode 120000 index 000000000..9877a9411 --- /dev/null +++ b/examples/tutorials/hotp/hotp_oracle_complete/step0.c @@ -0,0 +1 @@ +../hotp_milestone_one/step0.c \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_oracle_complete/step0.h b/examples/tutorials/hotp/hotp_oracle_complete/step0.h new file mode 120000 index 000000000..a3f30f7e5 --- /dev/null +++ b/examples/tutorials/hotp/hotp_oracle_complete/step0.h @@ -0,0 +1 @@ +../hotp_milestone_one/step0.h \ No newline at end of file diff --git a/examples/tutorials/hotp/hotp_starter/main.c b/examples/tutorials/hotp/hotp_starter/main.c index 734722bf2..866362574 100644 --- a/examples/tutorials/hotp/hotp_starter/main.c +++ b/examples/tutorials/hotp/hotp_starter/main.c @@ -18,13 +18,12 @@ #include // Libtock includes -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include // Local includes #include "base32.h" @@ -43,45 +42,41 @@ typedef struct { counter_t counter; } hotp_key_t; -hotp_key_t hotp_key = {0}; +hotp_key_t stored_key = {0}; // --- Button Handling --- // Global to keep track of most recently pressed button int pressed_btn_num; +bool button_pressed = false; // Callback for button presses. // num: The index of the button associated with the callback // val: 1 if pressed, 0 if depressed -static void button_upcall(int num, - int val, - __attribute__ ((unused)) int arg2, - void * ud) { - if (val == 1) { +static void button_callback(__attribute__ ((unused)) returncode_t ret, + int num, + bool val) { + if (val) { pressed_btn_num = num; - *((bool*)ud) = true; + button_pressed = true; } } // Initializes interrupts on a button -static int initialize_buttons(bool* flag_pointer) { - // Enable button interrupts - int err = button_subscribe(button_upcall, (void*)flag_pointer); - if (err != RETURNCODE_SUCCESS) { - return err; - } +static int initialize_buttons(void) { + returncode_t err; // Determine the number of supported buttons int count = 0; - err = button_count(&count); + err = libtock_button_count(&count); if (err != RETURNCODE_SUCCESS) { return err; } // Enable interrupts if a button exists if (count > 0) { - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); } return RETURNCODE_SUCCESS; @@ -90,64 +85,33 @@ static int initialize_buttons(bool* flag_pointer) { // --- HMAC Handling --- -static void hmac_upcall(__attribute__ ((unused)) int arg0, - __attribute__ ((unused)) int arg1, - __attribute__ ((unused)) int arg2, - void* done_flag) { - *((bool *) done_flag) = true; +static bool hmac_done = false; +static void hmac_callback(__attribute__ ((unused)) returncode_t ret) { + hmac_done = true; } static int hmac(const uint8_t* key, int key_len, const uint8_t* data, int data_len, uint8_t* output_buffer, int output_buffer_len) { - int ret; - bool hmac_done = false; - - ret = hmac_set_callback(hmac_upcall, &hmac_done); - if (ret < 0) { - goto done; - } - - ret = hmac_set_key_buffer(key, key_len); - if (ret < 0) { - goto deregister_upcall; - } - - ret = hmac_set_dest_buffer(output_buffer, output_buffer_len); - if (ret < 0) { - goto unallow_key_buffer; - } - - ret = hmac_set_data_buffer(data, data_len); - if (ret < 0) { - goto unallow_dest_buffer; - } - - ret = hmac_set_algorithm(TOCK_HMAC_ALG_SHA256); - if (ret < 0) { - goto unallow_data_buffer; - } - - ret = hmac_run(); - if (ret < 0) { + returncode_t ret; + hmac_done = false; + + ret = libtock_hmac_simple(LIBTOCK_HMAC_SHA256, + (uint8_t*) key, key_len, + (uint8_t*) data, data_len, + output_buffer, output_buffer_len, + hmac_callback); + if (ret != RETURNCODE_SUCCESS) { printf("HMAC failure: %d\r\n", ret); - goto unallow_data_buffer; + goto done; } yield_for(&hmac_done); -unallow_data_buffer: - hmac_set_data_buffer(NULL, 0); - -unallow_dest_buffer: - hmac_set_dest_buffer(NULL, 0); - -unallow_key_buffer: - hmac_set_key_buffer(NULL, 0); - -deregister_upcall: - hmac_set_callback(NULL, NULL); - done: + libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); + libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); + libtock_hmac_set_upcall(NULL, NULL); return ret; } @@ -160,41 +124,40 @@ static int decrypt(const uint8_t* cipher, int cipherlen, uint8_t* plaintext, int return copylen; } - // --- HOTP Actions --- -static void program_default_secret(void) { - led_on(0); +static void program_default_secret(hotp_key_t* hotp_key) { + libtock_led_on(0); const char* default_secret = "test"; // Decode base32 to get HOTP key value - int ret = base32_decode((const uint8_t*)default_secret, hotp_key.key, 64); + int ret = base32_decode((const uint8_t*)default_secret, hotp_key->key, 64); if (ret < 0 ) { printf("ERROR cannot base32 decode secret\r\n"); - hotp_key.len = 0; + hotp_key->len = 0; return; } // Initialize remainder of HOTP key - hotp_key.len = ret; - hotp_key.counter = 0; + hotp_key->len = ret; + hotp_key->counter = 0; printf("Programmed \"%s\" as key \r\n", default_secret); - led_off(0); + libtock_led_off(0); } -static void get_next_code(void) { - led_on(0); +static void get_next_code(hotp_key_t* hotp_key) { + libtock_led_on(0); // Decrypt the key uint8_t key[64]; - int keylen = decrypt(hotp_key.key, hotp_key.len, key, 64); + int keylen = decrypt(hotp_key->key, hotp_key->len, key, 64); // Generate the HMAC'ed data from the "moving factor" (timestamp in TOTP, // counter in HOTP), shuffled in a specific way: uint8_t moving_factor[sizeof(counter_t)]; for (size_t i = 0; i < sizeof(counter_t); i++) { - moving_factor[i] = (hotp_key.counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; + moving_factor[i] = (hotp_key->counter >> ((sizeof(counter_t) - i - 1) * 8)) & 0xFF; } // Perform the HMAC operation @@ -203,7 +166,7 @@ static void get_next_code(void) { hmac(key, keylen, moving_factor, sizeof(counter_t), hmac_output_buf, HMAC_OUTPUT_BUF_LEN); // Increment the counter - hotp_key.counter++; + hotp_key->counter++; // Get output value uint8_t offset = hmac_output_buf[HMAC_OUTPUT_BUF_LEN - 1] & 0x0f; @@ -226,37 +189,37 @@ static void get_next_code(void) { } // Write the value to the USB keyboard. - int ret = usb_keyboard_hid_send_string_sync(hotp_format_buffer, len); + int ret = libtocksync_usb_keyboard_hid_send_string(hotp_format_buffer, len); if (ret < 0) { printf("ERROR sending string with USB keyboard HID: %i\r\n", ret); } else { - printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)hotp_key.counter - 1, + printf("Counter: %u. Typed \"%s\" on the USB HID the keyboard\r\n", (size_t)hotp_key->counter - 1, hotp_format_buffer); } // Complete - led_off(0); + libtock_led_off(0); } + // --- Main Loop --- // Performs initialization and interactivity. int main(void) { - delay_ms(1000); + libtocksync_alarm_delay_ms(1000); printf("Tock HOTP App Started. Usage:\r\n" "* Press Button 1 to get the next HOTP code for that slot.\r\n" "* Hold Button 1 to enter a new HOTP secret for that slot.\r\n"); // Initialize buttons - bool button_pressed = false; - if (initialize_buttons(&button_pressed) != RETURNCODE_SUCCESS) { + if (initialize_buttons() != RETURNCODE_SUCCESS) { printf("ERROR initializing buttons\r\n"); return 1; } // Configure a default HOTP secret - program_default_secret(); + program_default_secret(&stored_key); // Main loop. Waits for button presses while (true) { @@ -265,11 +228,11 @@ int main(void) { yield_for(&button_pressed); // Handle short presses on already configured keys (output next code) - if (hotp_key.len > 0) { - get_next_code(); + if (stored_key.len > 0) { + get_next_code(&stored_key); // Error for short press on a non-configured key - } else if (hotp_key.len == 0) { + } else if (stored_key.len == 0) { printf("HOTP / TOTP key not yet configured.\r\n"); } } diff --git a/examples/unit_tests/nrf52840dk-test/main.c b/examples/unit_tests/nrf52840dk-test/main.c index 5e463f672..ede7dc7c4 100644 --- a/examples/unit_tests/nrf52840dk-test/main.c +++ b/examples/unit_tests/nrf52840dk-test/main.c @@ -1,12 +1,13 @@ -#include -#include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include + + #define GPIO1_IN 0 #define GPIO1_OUT 1 @@ -25,575 +26,546 @@ static int int_nr; static int int_ctr; -static void *int_data; bool test_setup(void) { - if (gpio_enable_input(GPIO0_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(GPIO0_IN, libtock_pull_none) != 0) { return false; } - if (gpio_clear(GPIO0_OUT) != 0) { + if (libtock_gpio_clear(GPIO0_OUT) != 0) { return false; } - if (gpio_enable_output(GPIO0_OUT) != 0) { + if (libtock_gpio_enable_output(GPIO0_OUT) != 0) { return false; } - if (gpio_enable_input(GPIO1_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(GPIO1_IN, libtock_pull_none) != 0) { return false; } - if (gpio_clear(GPIO1_OUT) != 0) { + if (libtock_gpio_clear(GPIO1_OUT) != 0) { return false; } - if (gpio_enable_output(GPIO1_OUT) != 0) { + if (libtock_gpio_enable_output(GPIO1_OUT) != 0) { return false; } - if (gpio_enable_input(LED1_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(LED1_IN, libtock_pull_none) != 0) { return false; } - if (gpio_enable_input(LED2_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(LED2_IN, libtock_pull_none) != 0) { return false; } - if (gpio_enable_input(LED3_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(LED3_IN, libtock_pull_none) != 0) { return false; } - if (gpio_enable_input(LED4_IN, PullNone) != 0) { + if (libtock_gpio_enable_input(LED4_IN, libtock_pull_none) != 0) { return false; } - if (gpio_enable_output(BUTTON1_OUT) != 0) { + if (libtock_gpio_enable_output(BUTTON1_OUT) != 0) { return false; } - if (gpio_enable_output(BUTTON2_OUT) != 0) { + if (libtock_gpio_enable_output(BUTTON2_OUT) != 0) { return false; } - if (gpio_enable_output(BUTTON3_OUT) != 0) { + if (libtock_gpio_enable_output(BUTTON3_OUT) != 0) { return false; } - if (gpio_enable_output(BUTTON4_OUT) != 0) { + if (libtock_gpio_enable_output(BUTTON4_OUT) != 0) { return false; } /* Buttons are low active */ - gpio_set(BUTTON1_OUT); - gpio_set(BUTTON2_OUT); - gpio_set(BUTTON3_OUT); - gpio_set(BUTTON4_OUT); - int_nr = -1; - int_data = NULL; - int_ctr = 0; + libtock_gpio_set(BUTTON1_OUT); + libtock_gpio_set(BUTTON2_OUT); + libtock_gpio_set(BUTTON3_OUT); + libtock_gpio_set(BUTTON4_OUT); + int_nr = -1; + int_ctr = 0; return true; } void test_teardown(void) { - gpio_disable_interrupt(GPIO0_IN); - gpio_disable(GPIO0_IN); - gpio_disable(GPIO0_OUT); - gpio_disable_interrupt(GPIO1_IN); - gpio_disable(GPIO1_IN); - gpio_disable(GPIO1_OUT); - gpio_disable(LED1_IN); - gpio_disable(LED2_IN); - gpio_disable(LED3_IN); - gpio_disable(LED4_IN); - led_off(0); - led_off(1); - led_off(2); - led_off(3); - gpio_set(BUTTON1_OUT); - gpio_set(BUTTON2_OUT); - gpio_set(BUTTON3_OUT); - gpio_set(BUTTON4_OUT); - button_disable_interrupt(0); - button_disable_interrupt(1); - button_disable_interrupt(2); - button_disable_interrupt(3); + libtock_gpio_disable_interrupt(GPIO0_IN); + libtock_gpio_disable(GPIO0_IN); + libtock_gpio_disable(GPIO0_OUT); + libtock_gpio_disable_interrupt(GPIO1_IN); + libtock_gpio_disable(GPIO1_IN); + libtock_gpio_disable(GPIO1_OUT); + libtock_gpio_disable(LED1_IN); + libtock_gpio_disable(LED2_IN); + libtock_gpio_disable(LED3_IN); + libtock_gpio_disable(LED4_IN); + libtock_led_off(0); + libtock_led_off(1); + libtock_led_off(2); + libtock_led_off(3); + libtock_gpio_set(BUTTON1_OUT); + libtock_gpio_set(BUTTON2_OUT); + libtock_gpio_set(BUTTON3_OUT); + libtock_gpio_set(BUTTON4_OUT); + libtock_button_command_disable_interrupt(0); + libtock_button_command_disable_interrupt(1); + libtock_button_command_disable_interrupt(2); + libtock_button_command_disable_interrupt(3); } static bool test_basic_gpio0(void) { int val; - CHECK(gpio_read(GPIO0_IN, &val) == 0); + CHECK(libtock_gpio_read(GPIO0_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_set(GPIO0_OUT) == 0); - CHECK(gpio_read(GPIO0_IN, &val) == 0); + CHECK(libtock_gpio_set(GPIO0_OUT) == 0); + CHECK(libtock_gpio_read(GPIO0_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_clear(GPIO0_OUT) == 0); - CHECK(gpio_read(GPIO0_IN, &val) == 0); + CHECK(libtock_gpio_clear(GPIO0_OUT) == 0); + CHECK(libtock_gpio_read(GPIO0_IN, &val) == 0); CHECK(val == 0); return true; } static bool test_basic_gpio1(void) { int val; - CHECK(gpio_read(GPIO1_IN, &val) == 0); + CHECK(libtock_gpio_read(GPIO1_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_set(GPIO1_OUT) == 0); - CHECK(gpio_read(GPIO1_IN, &val) == 0); + CHECK(libtock_gpio_set(GPIO1_OUT) == 0); + CHECK(libtock_gpio_read(GPIO1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_clear(GPIO1_OUT) == 0); - CHECK(gpio_read(GPIO1_IN, &val) == 0); + CHECK(libtock_gpio_clear(GPIO1_OUT) == 0); + CHECK(libtock_gpio_read(GPIO1_IN, &val) == 0); CHECK(val == 0); return true; } -static void test_callback (int pin_num, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void* userdata) { +static void test_button_callback ( + __attribute__ ((unused)) returncode_t ret, + int pin_num, + __attribute__ ((unused)) bool val) { + int_nr = pin_num; + int_ctr += 1; +} + +static void test_gpio_callback ( + uint32_t pin_num, + __attribute__ ((unused)) bool val) { int_nr = pin_num; - int_data = userdata; int_ctr += 1; } static bool test_gpio0_int_raising(void) { int val; - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO0_IN, RisingEdge) == 0); - CHECK(gpio_set(GPIO0_OUT) == 0); - CHECK(gpio_read(GPIO0_IN, &val) == 0); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO0_IN, libtock_rising_edge) == 0); + CHECK(libtock_gpio_set(GPIO0_OUT) == 0); + CHECK(libtock_gpio_read(GPIO0_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_clear(GPIO0_OUT) == 0); - CHECK(gpio_read(GPIO0_IN, &val) == 0); + CHECK(libtock_gpio_clear(GPIO0_OUT) == 0); + CHECK(libtock_gpio_read(GPIO0_IN, &val) == 0); CHECK(val == 0); - delay_ms(2); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == GPIO0_IN); - CHECK(int_data == data); return true; } static bool test_gpio0_int_falling(void) { - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO0_IN, FallingEdge) == 0); - CHECK(gpio_set(GPIO0_OUT) == 0); - CHECK(gpio_clear(GPIO0_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO0_IN, libtock_falling_edge) == 0); + CHECK(libtock_gpio_set(GPIO0_OUT) == 0); + CHECK(libtock_gpio_clear(GPIO0_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == GPIO0_IN); - CHECK(int_data == data); return true; } static bool test_gpio0_int_both(void) { - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO0_IN, Change) == 0); - CHECK(gpio_set(GPIO0_OUT) == 0); - CHECK(gpio_clear(GPIO0_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO0_IN, libtock_change) == 0); + CHECK(libtock_gpio_set(GPIO0_OUT) == 0); + CHECK(libtock_gpio_clear(GPIO0_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); CHECK(int_nr == GPIO0_IN); - CHECK(int_data == data); return true; } static bool test_gpio1_int_raising(void) { int val; - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO1_IN, RisingEdge) == 0); - CHECK(gpio_set(GPIO1_OUT) == 0); - CHECK(gpio_read(GPIO1_IN, &val) == 0); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO1_IN, libtock_rising_edge) == 0); + CHECK(libtock_gpio_set(GPIO1_OUT) == 0); + CHECK(libtock_gpio_read(GPIO1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_clear(GPIO1_OUT) == 0); - CHECK(gpio_read(GPIO1_IN, &val) == 0); + CHECK(libtock_gpio_clear(GPIO1_OUT) == 0); + CHECK(libtock_gpio_read(GPIO1_IN, &val) == 0); CHECK(val == 0); - delay_ms(2); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == GPIO1_IN); - CHECK(int_data == data); return true; } static bool test_gpio1_int_falling(void) { - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO1_IN, FallingEdge) == 0); - CHECK(gpio_set(GPIO1_OUT) == 0); - CHECK(gpio_clear(GPIO1_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO1_IN, libtock_falling_edge) == 0); + CHECK(libtock_gpio_set(GPIO1_OUT) == 0); + CHECK(libtock_gpio_clear(GPIO1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == GPIO1_IN); - CHECK(int_data == data); return true; } static bool test_gpio1_int_both(void) { - void *data = (void *) 12345678; - CHECK(gpio_interrupt_callback(test_callback, data) == 0); - CHECK(gpio_enable_interrupt(GPIO1_IN, Change) == 0); - CHECK(gpio_set(GPIO1_OUT) == 0); - CHECK(gpio_clear(GPIO1_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set_interrupt_callback(test_gpio_callback) == 0); + CHECK(libtock_gpio_enable_interrupt(GPIO1_IN, libtock_change) == 0); + CHECK(libtock_gpio_set(GPIO1_OUT) == 0); + CHECK(libtock_gpio_clear(GPIO1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); CHECK(int_nr == GPIO1_IN); - CHECK(int_data == data); return true; } static bool test_leds_start_off(void) { int count, val; /* LED outputs are low active */ - CHECK(led_count(&count) == 0); + CHECK(libtock_led_count(&count) == 0); CHECK(count == 4); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_switch_led1(void) { int val; - CHECK(led_on(0) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_on(0) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_off(0) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_off(0) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_switch_led2(void) { int val; - CHECK(led_on(1) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_on(1) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_off(1) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_off(1) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_switch_led3(void) { int val; - CHECK(led_on(2) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_on(2) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_off(2) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_off(2) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_switch_led4(void) { int val; - CHECK(led_on(3) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_on(3) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 0); - CHECK(led_off(3) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_off(3) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_toggle_led1(void) { int val; - CHECK(led_toggle(0) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(0) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_toggle(0) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(0) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_toggle_led2(void) { int val; - CHECK(led_toggle(1) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(1) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_toggle(1) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(1) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_toggle_led3(void) { int val; - CHECK(led_toggle(2) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(2) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 0); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); - CHECK(led_toggle(2) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(2) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_toggle_led4(void) { int val; - CHECK(led_toggle(3) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(3) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 0); - CHECK(led_toggle(3) == 0); - CHECK(gpio_read(LED1_IN, &val) == 0); + CHECK(libtock_led_toggle(3) == 0); + CHECK(libtock_gpio_read(LED1_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED2_IN, &val) == 0); + CHECK(libtock_gpio_read(LED2_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED3_IN, &val) == 0); + CHECK(libtock_gpio_read(LED3_IN, &val) == 0); CHECK(val == 1); - CHECK(gpio_read(LED4_IN, &val) == 0); + CHECK(libtock_gpio_read(LED4_IN, &val) == 0); CHECK(val == 1); return true; } static bool test_buttons_start_off(void) { int count, val; - CHECK(button_count(&count) == 0); + CHECK(libtock_button_count(&count) == 0); CHECK(count == 4); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); return true; } static bool test_push_button1(void) { int val; - CHECK(gpio_clear(BUTTON1_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_clear(BUTTON1_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 1); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); - CHECK(gpio_set(BUTTON1_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_set(BUTTON1_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); return true; } static bool test_push_button2(void) { int val; - CHECK(gpio_clear(BUTTON2_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_clear(BUTTON2_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 1); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); - CHECK(gpio_set(BUTTON2_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_set(BUTTON2_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); return true; } static bool test_push_button3(void) { int val; - CHECK(gpio_clear(BUTTON3_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_clear(BUTTON3_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 1); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); - CHECK(gpio_set(BUTTON3_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_set(BUTTON3_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); return true; } static bool test_push_button4(void) { int val; - CHECK(gpio_clear(BUTTON4_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_clear(BUTTON4_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 1); - CHECK(gpio_set(BUTTON4_OUT) == 0); - CHECK(button_read(0, &val) == 0); + CHECK(libtock_gpio_set(BUTTON4_OUT) == 0); + CHECK(libtock_button_read(0, &val) == 0); CHECK(val == 0); - CHECK(button_read(1, &val) == 0); + CHECK(libtock_button_read(1, &val) == 0); CHECK(val == 0); - CHECK(button_read(2, &val) == 0); + CHECK(libtock_button_read(2, &val) == 0); CHECK(val == 0); - CHECK(button_read(3, &val) == 0); + CHECK(libtock_button_read(3, &val) == 0); CHECK(val == 0); return true; } static bool test_button1_int(void) { - void *data = (void *) 12345678; - CHECK(button_subscribe(test_callback, data) == 0); - CHECK(button_enable_interrupt(0) == 0); - CHECK(gpio_clear(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_button_notify_on_press(0, test_button_callback) == 0); + CHECK(libtock_gpio_clear(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == 0); - CHECK(int_data == data); - int_data = NULL; - CHECK(gpio_set(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); CHECK(int_nr == 0); - CHECK(int_data == data); return true; } static bool test_two_buttons_int(void) { - void *data = (void *) 12345678; - CHECK(button_subscribe(test_callback, data) == 0); - CHECK(button_enable_interrupt(0) == 0); - CHECK(button_enable_interrupt(1) == 0); - CHECK(gpio_clear(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_button_notify_on_press(0, test_button_callback) == 0); + CHECK(libtock_button_notify_on_press(1, test_button_callback) == 0); + CHECK(libtock_gpio_clear(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == 0); - CHECK(int_data == data); - int_data = NULL; - CHECK(gpio_clear(BUTTON2_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_clear(BUTTON2_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); CHECK(int_nr == 1); - CHECK(int_data == data); - int_data = NULL; - CHECK(gpio_set(BUTTON2_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set(BUTTON2_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 3); CHECK(int_nr == 1); - CHECK(int_data == data); - int_data = NULL; - CHECK(gpio_set(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 4); CHECK(int_nr == 0); - CHECK(int_data == data); return true; } static bool test_disable_button_int(void) { - void *data = (void *) 12345678; - CHECK(button_subscribe(test_callback, data) == 0); - CHECK(button_enable_interrupt(0) == 0); - CHECK(button_enable_interrupt(1) == 0); - CHECK(gpio_clear(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_button_notify_on_press(0, test_button_callback) == 0); + CHECK(libtock_button_notify_on_press(1, test_button_callback) == 0); + CHECK(libtock_gpio_clear(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 1); CHECK(int_nr == 0); - CHECK(int_data == data); - int_data = NULL; - CHECK(gpio_clear(BUTTON2_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_clear(BUTTON2_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); CHECK(int_nr == 1); - CHECK(int_data == data); - int_data = NULL; - CHECK(button_disable_interrupt(1) == 0); - CHECK(gpio_set(BUTTON2_OUT) == 0); - delay_ms(2); + CHECK(libtock_button_command_disable_interrupt(1) == 0); + CHECK(libtock_gpio_set(BUTTON2_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 2); - CHECK(gpio_set(BUTTON1_OUT) == 0); - delay_ms(2); + CHECK(libtock_gpio_set(BUTTON1_OUT) == 0); + libtocksync_alarm_delay_ms(2); CHECK(int_ctr == 3); CHECK(int_nr == 0); - CHECK(int_data == data); return true; } diff --git a/examples/unit_tests/passfail/main.c b/examples/unit_tests/passfail/main.c index ec6683205..b648e5069 100644 --- a/examples/unit_tests/passfail/main.c +++ b/examples/unit_tests/passfail/main.c @@ -1,9 +1,10 @@ +#include #include -#include -#include -#include -#include +#include +#include + + static bool test_pass(void) { return true; diff --git a/examples/unit_tests/timeout/main.c b/examples/unit_tests/timeout/main.c index ad2390f79..99a9f036c 100644 --- a/examples/unit_tests/timeout/main.c +++ b/examples/unit_tests/timeout/main.c @@ -1,22 +1,22 @@ -#include -#include -#include - #include +#include +#include +#include + + static bool test_pass(void) { - delay_ms(100); + libtocksync_alarm_delay_ms(100); return true; } static bool test_fail(void) { - delay_ms(100); + libtocksync_alarm_delay_ms(100); return false; } - static bool test_timeout(void) { - delay_ms(500); + libtocksync_alarm_delay_ms(500); return true; } diff --git a/examples/witenergy/main.c b/examples/witenergy/main.c index 985a4704a..4e5fbb3f0 100644 --- a/examples/witenergy/main.c +++ b/examples/witenergy/main.c @@ -15,13 +15,12 @@ #include -#include - -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include /******************************************************************************* @@ -496,7 +495,7 @@ static void __on_ble_evt (ble_evt_t* p_ble_evt) { _next_state = OORT_STATE_NONE; printf("Disconnected! Attempting to reconnect in 2s\n"); - delay_ms(2000); + libtocksync_alarm_delay_ms(2000); setup_oort(); break; } @@ -577,11 +576,11 @@ void toggle_relay (void) { } } -static void button_callback(__attribute__ ((unused)) int btn_num, - int val, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) void *ud) { - if (val == 1 && _state == OORT_STATE_NONE) { +static void button_callback( + __attribute__ ((unused)) returncode_t ret, + __attribute__ ((unused)) int btn_num, + bool val) { + if (val && _state == OORT_STATE_NONE) { printf("Button press! Toggle the relay!\n"); toggle_relay(); } @@ -594,8 +593,7 @@ int main (void) { printf("Press the user button to toggle the relay.\n"); // Button press toggles meter relay. - button_subscribe(button_callback, NULL); - button_enable_interrupt(0); + libtock_button_notify_on_press(0, button_callback); // Setup simple BLE. This does most of the nordic setup. simple_ble_init(&_ble_config); diff --git a/libnrfserialization/Makefile b/libnrfserialization/Makefile index 1ff083d58..7a5f60a48 100644 --- a/libnrfserialization/Makefile +++ b/libnrfserialization/Makefile @@ -87,6 +87,7 @@ CPPFLAGS_$(LIBNAME) += -DBLEADDR_FLASH_LOCATION=$(BLEADDR_FLASH_LOCATION) # Need libtock headers override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR) +override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/libtock # Avoid failing in CI due to warnings in the library. CPPFLAGS_$(LIBNAME) += -Wno-error diff --git a/libnrfserialization/serialization_tock.c b/libnrfserialization/serialization_tock.c index 62b8c2818..62b861cd2 100644 --- a/libnrfserialization/serialization_tock.c +++ b/libnrfserialization/serialization_tock.c @@ -2,10 +2,11 @@ #include #include #include +#include -#include -#include -#include +#include +#include +#include #include "nrf.h" #include "ser_phy.h" @@ -57,7 +58,7 @@ static bool _need_wakeup = false; static bool _queued_packets = false; // Timer to detect when we fail to get a response message after sending a // command. -static tock_timer_t* _timeout_timer = NULL; +static libtock_alarm_t* _timeout_timer = NULL; // yield() variable. static bool nrf_serialization_done = false; @@ -65,11 +66,11 @@ static bool nrf_serialization_done = false; * Prototypes ******************************************************************************/ -void timeout_timer_cb (int a, int b, int c, void* ud); +void timeout_timer_cb (uint32_t a, uint32_t b, void* opaque); void ble_serialization_callback (int callback_type, int rx_len, int c, void* other); - +static void serialization_timer_cb (uint32_t a, uint32_t b, void* opaque); uint32_t sd_app_evt_wait (void); -void serialization_timer_cb (int a, int b, int c, void* timer_id); + uint32_t ser_app_hal_hw_init (void); void ser_app_hal_delay (uint32_t ms); @@ -88,11 +89,10 @@ void critical_region_exit (void); * Callback from the UART layer in the kernel ******************************************************************************/ -void timeout_timer_cb (int a, int b, int c, void* ud) { +void timeout_timer_cb (uint32_t a, uint32_t b, void* opaque) { UNUSED_PARAMETER(a); UNUSED_PARAMETER(b); - UNUSED_PARAMETER(c); - UNUSED_PARAMETER(ud); + UNUSED_PARAMETER(opaque); // Uh oh did not get a response to a command packet. // Send up an error. @@ -148,7 +148,7 @@ void ble_serialization_callback (int callback_type, int rx_len, int c, void* oth // Got a response, cancel any pending timer if (_timeout_timer != NULL) { - timer_cancel(_timeout_timer); + libtock_alarm_cancel(_timeout_timer); free(_timeout_timer); _timeout_timer = NULL; } @@ -286,7 +286,7 @@ uint32_t ser_app_hal_hw_init (void) { } void ser_app_hal_delay (uint32_t ms) { - delay_ms(ms); + libtocksync_alarm_delay_ms(ms); } void ser_app_hal_nrf_reset_pin_clear (void) {} @@ -310,6 +310,7 @@ void ser_app_hal_nrf_evt_pending (void) { uint32_t ser_phy_open (ser_phy_events_handler_t events_handler) { int ret; + int bytes_read; if (events_handler == NULL) { return NRF_ERROR_NULL; @@ -321,17 +322,17 @@ uint32_t ser_phy_open (ser_phy_events_handler_t events_handler) { } // Start by doing a reset. - ret = nrf51_serialization_reset(); + ret = libtock_nrf51_serialization_reset(); if (ret < 0) return NRF_ERROR_INTERNAL; // Configure the serialization layer in the kernel - ret = nrf51_serialization_subscribe(ble_serialization_callback); + ret = libtock_nrf51_serialization_set_upcall(ble_serialization_callback, NULL); if (ret < 0) return NRF_ERROR_INTERNAL; - ret = nrf51_serialization_setup_receive_buffer((char*) rx, SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE); + ret = libtock_nrf51_serialization_set_readwrite_allow_receive_buffer(rx, SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE); if (ret < 0) return NRF_ERROR_INTERNAL; - ret = nrf51_serialization_read(SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE); + ret = libtock_nrf51_serialization_read(SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE, &bytes_read); if (ret < 0) return NRF_ERROR_INTERNAL; // Save the callback handler @@ -352,8 +353,8 @@ uint32_t ser_phy_tx_pkt_send (const uint8_t* p_buffer, uint16_t num_of_bytes) { if (tx_len == 0) { // We need to set a timer in case we never get the response packet. if (ser_sd_transport_is_busy()) { - _timeout_timer = (tock_timer_t*)malloc(sizeof(tock_timer_t)); - timer_in(100, timeout_timer_cb, NULL, _timeout_timer); + _timeout_timer = (libtock_alarm_t*)malloc(sizeof(libtock_alarm_t)); + libtock_alarm_in_ms(100, timeout_timer_cb, NULL, _timeout_timer); } // Encode the number of bytes as the first two bytes of the outgoing @@ -368,7 +369,7 @@ uint32_t ser_phy_tx_pkt_send (const uint8_t* p_buffer, uint16_t num_of_bytes) { tx_len = num_of_bytes + SER_PHY_HEADER_SIZE; // Call tx procedure to start transmission of a packet - int ret = nrf51_serialization_write((char*) tx, tx_len); + int ret = libtock_nrf51_serialization_write(tx, tx_len); if (ret < 0) { return NRF_ERROR_INTERNAL; } @@ -486,12 +487,11 @@ uint32_t app_timer_create (app_timer_id_t const * p_timer_id, -void serialization_timer_cb (int a, int b, int c, void* timer_id) { +static void serialization_timer_cb (uint32_t a, uint32_t b, void* opaque) { UNUSED_PARAMETER(a); UNUSED_PARAMETER(b); - UNUSED_PARAMETER(c); - timer_node_t* p_node = (timer_node_t*) timer_id; + timer_node_t* p_node = (timer_node_t*) opaque; p_node->p_timeout_handler(p_node->p_context); } @@ -529,8 +529,8 @@ uint32_t app_timer_start (app_timer_id_t timer_id, p_node->p_context = p_context; // timer_repeating_subscribe(p_node->p_timeout_handler, &timer_id); // Use 0 for the prescaler - tock_timer_t* timer = (tock_timer_t*)malloc(sizeof(tock_timer_t)); - timer_every(APP_TIMER_MS(timeout_ticks, 0), serialization_timer_cb, timer_id, timer); + libtock_alarm_repeating_t* timer = (libtock_alarm_repeating_t*)malloc(sizeof(libtock_alarm_repeating_t)); + libtock_alarm_repeating_every(APP_TIMER_MS(timeout_ticks, 0), serialization_timer_cb, timer_id, timer); } else { // timer_oneshot_subscribe(p_node->p_timeout_handler, &timer_id); } diff --git a/libtock-sync/Makefile b/libtock-sync/Makefile new file mode 100644 index 000000000..4513ed261 --- /dev/null +++ b/libtock-sync/Makefile @@ -0,0 +1,22 @@ +# Libtock-sync makefile. Can build Libtock standalone. Also included by application +# makefiles to ensure their libtock dependency is built + +# Base folder definitions +TOCK_USERLAND_BASE_DIR ?= .. +LIBNAME := libtocksync +$(LIBNAME)_DIR := $(TOCK_USERLAND_BASE_DIR)/libtock-sync +$(LIBNAME)_SRC_ROOT := $(TOCK_USERLAND_BASE_DIR) + +# List all C and Assembly files +$(LIBNAME)_SRCS := $(wildcard $($(LIBNAME)_DIR)/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/crypto/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/display/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/interface/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/kernel/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/net/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/peripherals/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/sensors/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/services/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/storage/*.c) + +include $(TOCK_USERLAND_BASE_DIR)/TockLibrary.mk diff --git a/libtock-sync/README.md b/libtock-sync/README.md new file mode 100644 index 000000000..4fe579728 --- /dev/null +++ b/libtock-sync/README.md @@ -0,0 +1,15 @@ +`libtock-sync` Synchronous Library +================================== + +This libtock-c library provides synchronous APIs to Tock system call drivers. + +Using This Library +------------------ + +All headers are in the `libtock-sync/` directory. For example: + +```c +#include +``` + +All functions start with `libtocksync_`. diff --git a/libtock-sync/crypto/hmac.c b/libtock-sync/crypto/hmac.c new file mode 100644 index 000000000..e38f188c9 --- /dev/null +++ b/libtock-sync/crypto/hmac.c @@ -0,0 +1,41 @@ +#include "hmac.h" + +struct hmac_data { + bool fired; + returncode_t ret; +}; + +static struct hmac_data result = {.fired = false}; + +static void hmac_cb_hmac(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, + uint8_t* key_buffer, uint32_t key_length, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hmac_buffer, uint32_t hmac_length) { + returncode_t ret; + + result.fired = false; + + ret = libtock_hmac_simple(hmac_type, key_buffer, key_length, input_buffer, input_length, hmac_buffer, hmac_length, + hmac_cb_hmac); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_hmac_set_readonly_allow_key_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_readonly_allow_data_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_readwrite_allow_destination_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/crypto/hmac.h b/libtock-sync/crypto/hmac.h new file mode 100644 index 000000000..c0d0dac13 --- /dev/null +++ b/libtock-sync/crypto/hmac.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Compute an HMAC on the given buffer. +returncode_t libtocksync_hmac_simple(libtock_hmac_algorithm_t hmac_type, + uint8_t* key_buffer, uint32_t key_length, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hmac_buffer, uint32_t hmac_length); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/crypto/sha.c b/libtock-sync/crypto/sha.c new file mode 100644 index 000000000..b3b237b84 --- /dev/null +++ b/libtock-sync/crypto/sha.c @@ -0,0 +1,36 @@ +#include "sha.h" + +struct sha_data { + bool fired; + returncode_t ret; +}; + +static struct sha_data result = {.fired = false}; + +static void sha_cb_hash(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_sha_simple_hash(libtock_sha_algorithm_t hash_type, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length) { + returncode_t ret; + + result.fired = false; + + ret = libtock_sha_simple_hash(hash_type, input_buffer, input_length, hash_buffer, hash_length, sha_cb_hash); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_sha_set_readonly_allow_data_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sha_set_readwrite_allow_destination_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/crypto/sha.h b/libtock-sync/crypto/sha.h new file mode 100644 index 000000000..6377e6d2b --- /dev/null +++ b/libtock-sync/crypto/sha.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a SHA hash on the given buffer. +returncode_t libtocksync_sha_simple_hash(libtock_sha_algorithm_t hash_type, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/display/screen.c b/libtock-sync/display/screen.c new file mode 100644 index 000000000..6536bd3fa --- /dev/null +++ b/libtock-sync/display/screen.c @@ -0,0 +1,165 @@ +#include "screen.h" + +struct screen_done { + returncode_t ret; + bool fired; +}; +struct screen_format { + libtock_screen_format_t format; + returncode_t ret; + bool fired; +}; +struct screen_rotation { + int rotation; + returncode_t ret; + bool fired; +}; + +struct screen_done result; +struct screen_format result_format; +struct screen_rotation result_rotation; + + +static void screen_cb_done(returncode_t ret) { + result.ret = ret; + result.fired = true; +} +static void screen_cb_format(returncode_t ret, libtock_screen_format_t format) { + result_format.ret = ret; + result_format.format = format; + result_format.fired = true; +} +static void screen_cb_rotation(returncode_t ret, libtock_screen_rotation_t rotation) { + result_rotation.ret = ret; + result_rotation.rotation = rotation; + result_rotation.fired = true; +} + +returncode_t libtocksync_screen_set_brightness(uint32_t brightness) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_set_brightness(brightness, screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_screen_invert_on(void) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_invert_on(screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_screen_invert_off(void) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_invert_on(screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_screen_get_pixel_format(libtock_screen_format_t* format) { + returncode_t ret; + + result_format.fired = false; + + ret = libtock_screen_get_pixel_format(screen_cb_format); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result_format.fired); + if (result_format.ret != RETURNCODE_SUCCESS) return result_format.ret; + + *format = result_format.format; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_screen_get_rotation(libtock_screen_rotation_t* rotation) { + returncode_t ret; + + result_rotation.fired = false; + + ret = libtock_screen_get_rotation(screen_cb_rotation); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result_rotation.fired); + if (result_rotation.ret != RETURNCODE_SUCCESS) return result_rotation.ret; + + *rotation = result_rotation.rotation; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_screen_set_rotation(libtock_screen_rotation_t rotation) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_set_rotation(rotation, screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_screen_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_set_frame(x, y, width, height, screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_screen_fill(uint8_t* buffer, int buffer_len, size_t color) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_fill(buffer, buffer_len, color, screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_screen_set_readonly_allow(NULL, 0); + return ret; +} + +returncode_t libtocksync_screen_write(uint8_t* buffer, int buffer_len, size_t length) { + returncode_t ret; + + result.fired = false; + + ret = libtock_screen_write(buffer, buffer_len, length, screen_cb_done); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_screen_set_readonly_allow(NULL, 0); + return ret; +} diff --git a/libtock-sync/display/screen.h b/libtock-sync/display/screen.h new file mode 100644 index 000000000..0ab0902fb --- /dev/null +++ b/libtock-sync/display/screen.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Set the screen brightness. +returncode_t libtocksync_screen_set_brightness(uint32_t brightness); + +// Invert the screen. +returncode_t libtocksync_screen_invert_on(void); + +// Disable the screen inversion. +returncode_t libtocksync_screen_invert_off(void); + +// Get the current pixel format used by the screen. +returncode_t libtocksync_screen_get_pixel_format(libtock_screen_format_t* format); + +// Get the current screen rotation. +returncode_t libtocksync_screen_get_rotation(libtock_screen_rotation_t* rotation); + +// Rotate the screen. +returncode_t libtocksync_screen_set_rotation(libtock_screen_rotation_t rotation); + +// Set the active screen frame. +returncode_t libtocksync_screen_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + +// Fill the screen. +returncode_t libtocksync_screen_fill(uint8_t* buffer, int buffer_len, size_t color); + +// Write the buffer to the screen. +returncode_t libtocksync_screen_write(uint8_t* buffer, int buffer_len, size_t length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/display/text_screen.c b/libtock-sync/display/text_screen.c new file mode 100644 index 000000000..9dbe0e349 --- /dev/null +++ b/libtock-sync/display/text_screen.c @@ -0,0 +1,114 @@ +#include "text_screen.h" + +struct text_screen_data { + bool fired; + returncode_t ret; +}; + +struct text_screen_size_data { + bool fired; + returncode_t ret; + uint32_t width; + uint32_t height; +}; + +struct text_screen_data result = {.fired = false}; +struct text_screen_size_data result_size = {.fired = false}; + +static void text_screen_cb(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +static void text_screen_size_cb(returncode_t ret, uint32_t width, uint32_t height) { + result_size.fired = true; + result_size.ret = ret; + result_size.width = width; + result_size.height = height; +} + + +static returncode_t text_screen_op(returncode_t (*op)()) { + returncode_t ret; + result.fired = false; + + ret = op(text_screen_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_text_screen_display_on(void) { + return text_screen_op(libtock_text_screen_display_on); +} + +returncode_t libtocksync_text_screen_display_off(void) { + return text_screen_op(libtock_text_screen_display_off); +} + +returncode_t libtocksync_text_screen_blink_on(void) { + return text_screen_op(libtock_text_screen_blink_on); +} + +returncode_t libtocksync_text_screen_blink_off(void) { + return text_screen_op(libtock_text_screen_blink_off); +} + +returncode_t libtocksync_text_screen_show_cursor(void) { + return text_screen_op(libtock_text_screen_show_cursor); +} + +returncode_t libtocksync_text_screen_hide_cursor(void) { + return text_screen_op(libtock_text_screen_hide_cursor); +} + +returncode_t libtocksync_text_screen_clear(void) { + return text_screen_op(libtock_text_screen_clear); +} + +returncode_t libtocksync_text_screen_home(void) { + return text_screen_op(libtock_text_screen_home); +} + +returncode_t libtocksync_text_screen_set_cursor(uint8_t col, uint8_t row) { + returncode_t ret; + result.fired = false; + + ret = libtock_text_screen_set_cursor(col, row, text_screen_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_text_screen_write(uint8_t* buffer, uint32_t buffer_len, uint32_t write_len) { + returncode_t ret; + result.fired = false; + + ret = libtock_text_screen_write(buffer, buffer_len, write_len, text_screen_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + + ret = libtock_text_screen_set_readonly_allow(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return result.ret; +} + +returncode_t libtocksync_text_screen_get_size(uint32_t* width, uint32_t* height) { + returncode_t ret; + result.fired = false; + + ret = libtock_text_screen_get_size(text_screen_size_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result_size.fired); + if (result_size.ret != RETURNCODE_SUCCESS) return result_size.ret; + + *width = result_size.width; + *height = result_size.height; + + return result_size.ret; +} diff --git a/libtock-sync/display/text_screen.h b/libtock-sync/display/text_screen.h new file mode 100644 index 000000000..88ae8d39d --- /dev/null +++ b/libtock-sync/display/text_screen.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtocksync_text_screen_display_on(void); + +returncode_t libtocksync_text_screen_display_off(void); + +returncode_t libtocksync_text_screen_blink_on(void); + +returncode_t libtocksync_text_screen_blink_off(void); + +returncode_t libtocksync_text_screen_show_cursor(void); + +returncode_t libtocksync_text_screen_hide_cursor(void); + +returncode_t libtocksync_text_screen_clear(void); + +returncode_t libtocksync_text_screen_home(void); + +returncode_t libtocksync_text_screen_set_cursor(uint8_t col, uint8_t row); + +returncode_t libtocksync_text_screen_write(uint8_t* buffer, uint32_t buffer_len, uint32_t write_len); + +returncode_t libtocksync_text_screen_get_size(uint32_t* width, uint32_t* height); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/interface/button.c b/libtock-sync/interface/button.c new file mode 100644 index 000000000..201701e0d --- /dev/null +++ b/libtock-sync/interface/button.c @@ -0,0 +1,39 @@ +#include "button.h" + +struct data { + bool fired; + bool pressed; + int button_num; + returncode_t result; +}; + +static struct data result = { .fired = false }; + + +static void button_cb(returncode_t ret, int button_num, bool pressed) { + result.fired = true; + result.pressed = pressed; + result.button_num = button_num; + result.result = ret; +} + + +returncode_t libtocksync_button_wait_for_press(int button_num) { + returncode_t err; + result.fired = false; + + err = libtock_button_notify_on_press(button_num, button_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback and for the button to be pressed. + while (true) { + yield_for(&result.fired); + if (result.result != RETURNCODE_SUCCESS) return result.result; + + if (result.pressed && result.button_num == button_num) { + break; + } + } + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/interface/button.h b/libtock-sync/interface/button.h new file mode 100644 index 000000000..cc8c0b0f6 --- /dev/null +++ b/libtock-sync/interface/button.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a specific button to be pressed. +// +// This blocks until the button has been pressed. Note, this will not return if +// the button is currently pressed and then released. It will wait until the +// button is pressed again. +// +// ## Arguments +// +// - `button_num`: Which button to wait for. +// +// ## Return Value +// +// A returncode indicating whether the button wait was completed successfully. +returncode_t libtocksync_button_wait_for_press(int button_num); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/interface/buzzer.c b/libtock-sync/interface/buzzer.c new file mode 100644 index 000000000..ae08e4a8e --- /dev/null +++ b/libtock-sync/interface/buzzer.c @@ -0,0 +1,24 @@ +#include "buzzer.h" + +struct data { + bool fired; +}; + +static struct data result = { .fired = false }; + + +static void buzzer_cb(void) { + result.fired = true; +} + +returncode_t libtocksync_buzzer_tone(uint32_t frequency_hz, uint32_t duration_ms) { + int err; + result.fired = false; + + err = libtock_buzzer_tone(frequency_hz, duration_ms, buzzer_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback meaning the tone is finished. + yield_for(&result.fired); + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/interface/buzzer.h b/libtock-sync/interface/buzzer.h new file mode 100644 index 000000000..69d25c7f6 --- /dev/null +++ b/libtock-sync/interface/buzzer.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Play a constant tone for a certain amount of time. +// +// This blocks until the tone has played. +// +// ## Arguments +// +// - `frequency_hz`: Frequency of the tone in hertz. +// - `duration_ms`: Length of the tone in milliseconds. +// +// ## Return Value +// +// A returncode indicating whether the tone was played successfully. +returncode_t libtocksync_buzzer_tone(uint32_t frequency_hz, uint32_t duration_ms); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/interface/console.c b/libtock-sync/interface/console.c new file mode 100644 index 000000000..ec4ef2e28 --- /dev/null +++ b/libtock-sync/interface/console.c @@ -0,0 +1,45 @@ +#include "console.h" + +struct console_result { + bool fired; + int length; + returncode_t result; +}; + +static struct console_result result = { .fired = false }; + +static void generic_cb(returncode_t ret, uint32_t length) { + result.length = length; + result.fired = true; + result.result = ret; +} + +returncode_t libtocksync_console_write(const uint8_t* buffer, uint32_t length, int* written) { + int err; + result.fired = false; + + err = libtock_console_write(buffer, length, &generic_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.result != RETURNCODE_SUCCESS) return result.result; + + *written = result.length; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_console_read(uint8_t* buffer, uint32_t length, int* read) { + int err; + result.fired = false; + + err = libtock_console_read(buffer, length, &generic_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.result != RETURNCODE_SUCCESS) return result.result; + + *read = result.length; + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/interface/console.h b/libtock-sync/interface/console.h new file mode 100644 index 000000000..5d0b78b59 --- /dev/null +++ b/libtock-sync/interface/console.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtocksync_console_write(const uint8_t* buffer, uint32_t length, int* written); + +returncode_t libtocksync_console_read(uint8_t* buffer, uint32_t length, int* read); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/usb_keyboard_hid.c b/libtock-sync/interface/usb_keyboard_hid.c similarity index 59% rename from libtock/usb_keyboard_hid.c rename to libtock-sync/interface/usb_keyboard_hid.c index 7df2d215d..d26e0a310 100644 --- a/libtock/usb_keyboard_hid.c +++ b/libtock-sync/interface/usb_keyboard_hid.c @@ -1,73 +1,36 @@ #include -#include -#include "tock.h" #include "usb_keyboard_hid.h" -struct usb_keyboard_hid_data { + +struct usb_keyboard_hid_result { bool fired; - int callback_type; + returncode_t ret; }; -static struct usb_keyboard_hid_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void usb_keyboard_hid_upcall(int callback_type, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - struct usb_keyboard_hid_data* data = (struct usb_keyboard_hid_data*) ud; - data->callback_type = callback_type; - data->fired = true; -} - - -int usb_keyboard_hid_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_USBKEYBOARDHID, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int usb_keyboard_hid_set_receive_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_USBKEYBOARDHID, 1, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -int usb_keyboard_hid_set_send_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_USBKEYBOARDHID, 1, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} +struct usb_keyboard_hid_result result = {.fired = false}; -int usb_keyboard_hid_send(void) { - syscall_return_t cval = command(DRIVER_NUM_USBKEYBOARDHID, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); +static void usb_keyboard_hil_cb(returncode_t ret) { + result.fired = true; + result.ret = ret; } -int usb_keyboard_hid_send_sync(uint8_t* buffer, uint32_t len) { +returncode_t libtocksync_usb_keyboard_hid_send(uint8_t* buffer, uint32_t len) { int err; result.fired = false; - err = usb_keyboard_hid_set_callback(usb_keyboard_hid_upcall, (void*) &result); - if (err < 0) return err; - - err = usb_keyboard_hid_set_send_buffer(buffer, len); - if (err < 0) return err; - - err = usb_keyboard_hid_send(); // Sometimes returns ERESERVE (but everything keeps working??) - if (err < 0) return err; + err = libtock_usb_keyboard_hid_send(buffer, len, usb_keyboard_hil_cb); + if (err != RETURNCODE_SUCCESS) return err; // Wait for the callback. yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; - err = usb_keyboard_hid_set_send_buffer(NULL, 0); - if (err < 0) return err; - - return RETURNCODE_SUCCESS; + err = libtock_usb_keyboard_hid_set_readwrite_allow_send_buffer(NULL, 0); + return err; } - - -static int to_hid_keycode(char c, uint8_t* modifier, uint8_t* key) -{ +static int to_hid_keycode(char c, uint8_t* modifier, uint8_t* key) { uint8_t shift = 2; // KB_MODIFIER_LEFT_SHIFT = 2 // Clear modifier. @@ -187,10 +150,7 @@ static int to_hid_keycode(char c, uint8_t* modifier, uint8_t* key) return -1; } - - -int usb_keyboard_hid_send_letter_sync(char letter) { - +returncode_t libtocksync_usb_keyboard_hid_send_letter(char letter) { uint8_t modifier; uint8_t key = 0; to_hid_keycode(letter, &modifier, &key); @@ -206,23 +166,23 @@ int usb_keyboard_hid_send_letter_sync(char letter) { buffer[7] = 0; // Send key press. - int err = usb_keyboard_hid_send_sync(buffer, 64); - if (err < 0) return err; + int err = libtocksync_usb_keyboard_hid_send(buffer, 64); + if (err != RETURNCODE_SUCCESS) return err; buffer[0] = 0; buffer[2] = 0; // Clear key press. - err = usb_keyboard_hid_send_sync(buffer, 64); - if (err < 0) return err; + err = libtocksync_usb_keyboard_hid_send(buffer, 64); + if (err != RETURNCODE_SUCCESS) return err; return RETURNCODE_SUCCESS; } -int usb_keyboard_hid_send_string_sync(char* str, int length) { +returncode_t libtocksync_usb_keyboard_hid_send_string(char* str, int length) { for (int i = 0; i < length; i++) { - int err = usb_keyboard_hid_send_letter_sync(str[i]); - if (err < 0) return err; + int err = libtocksync_usb_keyboard_hid_send_letter(str[i]); + if (err != RETURNCODE_SUCCESS) return err; } return RETURNCODE_SUCCESS; diff --git a/libtock-sync/interface/usb_keyboard_hid.h b/libtock-sync/interface/usb_keyboard_hid.h new file mode 100644 index 000000000..8ced3e2d6 --- /dev/null +++ b/libtock-sync/interface/usb_keyboard_hid.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Send a buffer to the USB HID keyboard. +returncode_t libtocksync_usb_keyboard_hid_send(uint8_t* buffer, uint32_t len); + +// Send a letter to emulate a keyboard keypress. +returncode_t libtocksync_usb_keyboard_hid_send_letter(char letter); + +// Send a string of letters as keypresses to emulate typing on a keyboard. +returncode_t libtocksync_usb_keyboard_hid_send_string(char* str, int length); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/kernel/read_only_state.c b/libtock-sync/kernel/read_only_state.c new file mode 100644 index 000000000..83f601cc9 --- /dev/null +++ b/libtock-sync/kernel/read_only_state.c @@ -0,0 +1,18 @@ +#include "read_only_state.h" + +returncode_t libtocksync_read_only_state_quick_yield(void* base, int* pending_tasks) { + if (yield_check_tasks()) { + *pending_tasks = 1; + return RETURNCODE_SUCCESS; + } else { + uint32_t tasks = libtock_read_only_state_get_pending_tasks(base); + + if (tasks > 0) { + // Waiting tasks, call yield + yield(); + } + + *pending_tasks = tasks; + return RETURNCODE_SUCCESS; + } +} diff --git a/libtock-sync/kernel/read_only_state.h b/libtock-sync/kernel/read_only_state.h new file mode 100644 index 000000000..75d2d4309 --- /dev/null +++ b/libtock-sync/kernel/read_only_state.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Use ROS to check if there are any pending tasks. If there are we yield, if +// not then we return immediately without any syscalls. +// +// `pending_tasks` is set to the number of pending tasks before yield was +// called. If there are no pending tasks, `pending_tasks` is set to 0. +// +// Returns `RETURNCODE_SUCCESS` on success, and error otherwise. +returncode_t libtocksync_read_only_state_quick_yield(void* base, int* pending_tasks); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/net/ieee802154.c b/libtock-sync/net/ieee802154.c new file mode 100644 index 000000000..8162c2ac8 --- /dev/null +++ b/libtock-sync/net/ieee802154.c @@ -0,0 +1,93 @@ +#include + +#include "ieee802154.h" + +struct ieee802154_receive_data { + bool fired; + int pan; + int src_addr; + int dest_addr; +}; + +static struct ieee802154_receive_data receive_result = { .fired = false }; + + +struct ieee802154_send_data { + bool fired; + bool acked; + statuscode_t status; +}; + +static struct ieee802154_send_data send_result = { .fired = false }; + +static void ieee802154_receive_done_cb(int pan, int src_addr, int dest_addr) { + receive_result.fired = true; + receive_result.pan = pan; + receive_result.src_addr = src_addr; + receive_result.dest_addr = dest_addr; +} + +static void ieee802154_send_done_cb(statuscode_t status, bool acked) { + send_result.fired = true; + send_result.acked = acked; + send_result.status = status; +} + + +returncode_t libtocksync_ieee802154_send(uint16_t addr, + security_level_t level, + key_id_mode_t key_id_mode, + uint8_t* key_id, + const uint8_t* payload, + uint8_t len) { + send_result.fired = false; + + returncode_t ret = libtock_ieee802154_send(addr, level, key_id_mode, key_id, payload, len, ieee802154_send_done_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the frame to be sent + yield_for(&send_result.fired); + + return tock_status_to_returncode(send_result.status); +} + + +returncode_t libtocksync_ieee802154_send_raw( + const uint8_t *payload, + uint8_t len) { + send_result.fired = false; + + returncode_t ret = libtock_ieee802154_send_raw(payload, len, ieee802154_send_done_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for the frame to be sent + yield_for(&send_result.fired); + + return tock_status_to_returncode(send_result.status); +} + +returncode_t libtocksync_ieee802154_receive(const libtock_ieee802154_rxbuf *frame) { + receive_result.fired = false; + + returncode_t ret = libtock_ieee802154_receive(frame, ieee802154_receive_done_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Wait for a frame + yield_for(&receive_result.fired); + + // receive upcall is only scheduled by the kernel if a frame is successfully received + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_ieee802154_up(void) { + // Spin until radio is on. + bool status; + libtock_ieee802154_is_up(&status); + + while (!status) { + libtocksync_alarm_delay_ms(10); + libtock_ieee802154_is_up(&status); + } + libtocksync_alarm_delay_ms(10); // without this delay, immediate calls to send can still fail. + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/net/ieee802154.h b/libtock-sync/net/ieee802154.h new file mode 100644 index 000000000..bd223524a --- /dev/null +++ b/libtock-sync/net/ieee802154.h @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Sends an IEEE 802.15.4 frame synchronously. The desired key must first be +// added to the key list. It is then looked up with the security level and key +// ID provided. Returns TOCK_SUCCESS or TOCK_ENOACK on successful transmission, +// depending on whether or not an ACK was received. +// `addr` (in): Destination short MAC address. +// `level` (in): Security level desired. Can be SEC_LEVEL_NONE, in which case +// `key_id_mode` is meaningless and can be set to 0. +// `key_id_mode` (in): The key ID mode, if `level` is not SEC_LEVEL_NONE. +// `key_id` (in): Optional data depending on the value of `key_id_mode` if +// `level` is not SEC_LEVEL_NONE. See `libtock_ieee802154_add_key`. +// `payload` (in): Buffer containing the desired frame payload. Must point to +// `len` bytes of valid memory. +// `len` (in): Length of frame payload. +returncode_t libtocksync_ieee802154_send(uint16_t addr, + security_level_t level, + key_id_mode_t key_id_mode, + uint8_t* key_id, + const uint8_t* payload, + uint8_t len); + +// Sends an IEEE 802.15.4 frame synchronously. This is an alternative and contemporary +// to the `libtock_ieee802154_send` function. This provides an interface for userprocesses to +// form a frame (including headers, security, CRC etc) entirely in the userprocess. +// `libtock_ieee802154_send_raw` then takes this formed frame buffer and passes the frame +// to the 15.4 capsule which sends the buffer (without altering the frame). +// `payload` (in): Buffer containing the desired frame payload. +// `len` (in): Length of frame payload. +returncode_t libtocksync_ieee802154_send_raw(const uint8_t *payload, + uint8_t len); + +// Waits synchronously for an IEEE 802.15.4 frame. +// `frame` (in): Buffer in which to put the full IEEE 802.15.4 frame data. Note +// that the data written might include more than just the IEEE 802.15.4 frame itself. +// Use `libtock_ieee802154_frame_get_*` to interact with the resulting frame. +returncode_t libtocksync_ieee802154_receive(const libtock_ieee802154_rxbuf *frame); + +// Synchronously enable the 802.15.4 radio. Returns once the radio is fully +// initialized. +returncode_t libtocksync_ieee802154_up(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/net/lora_phy.c b/libtock-sync/net/lora_phy.c new file mode 100644 index 000000000..30288045e --- /dev/null +++ b/libtock-sync/net/lora_phy.c @@ -0,0 +1,38 @@ +#include "lora_phy.h" + +struct lora_phy_spi_data { + bool fired; + returncode_t ret; +}; + +static struct lora_phy_spi_data result = {.fired = false}; + +static void lora_phy_spi_cb(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_lora_phy_write(const uint8_t* write, + uint32_t len) { + result.fired = false; + returncode_t ret; + + ret = libtock_lora_phy_write(write, len, lora_phy_spi_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_lora_phy_read_write(const uint8_t* write, + uint8_t* read, + uint32_t len) { + result.fired = false; + returncode_t ret; + + ret = libtock_lora_phy_read_write(write, read, len, lora_phy_spi_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + return result.ret; +} diff --git a/libtock-sync/net/lora_phy.h b/libtock-sync/net/lora_phy.h new file mode 100644 index 000000000..7d1f33a92 --- /dev/null +++ b/libtock-sync/net/lora_phy.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtocksync_lora_phy_write(const uint8_t* write, + uint32_t len); + +returncode_t libtocksync_lora_phy_read_write(const uint8_t* write, + uint8_t* read, + uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/net/udp.c b/libtock-sync/net/udp.c new file mode 100644 index 000000000..473dffc04 --- /dev/null +++ b/libtock-sync/net/udp.c @@ -0,0 +1,53 @@ +#include + +#include "udp.h" + +struct recv_data { + bool fired; + int val; + statuscode_t status; +}; + +struct send_data { + bool fired; + statuscode_t status; +}; + +static struct send_data send_sync_result = { .fired = false }; +static struct recv_data recv_sync_result = { .fired = false }; + +static void send_callback(statuscode_t ret) { + send_sync_result.fired = true; + send_sync_result.status = ret; +} + +static void recv_callback(statuscode_t ret, int len) { + recv_sync_result.val = len; + recv_sync_result.fired = true; + recv_sync_result.status = ret; +} + +returncode_t libtocksync_udp_send(void *buf, size_t len, + sock_addr_t *dst_addr) { + returncode_t ret; + send_sync_result.fired = false; + + ret = libtock_udp_send(buf, len, dst_addr, send_callback); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&send_sync_result.fired); + return tock_status_to_returncode(send_sync_result.status); +} + +returncode_t libtocksync_udp_recv(void *buf, size_t len, size_t* received_len) { + returncode_t ret; + recv_sync_result.fired = false; + + ret = libtock_udp_recv(buf, len, recv_callback); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&recv_sync_result.fired); + + *received_len = recv_sync_result.val; + return tock_status_to_returncode(recv_sync_result.status); +} diff --git a/libtock-sync/net/udp.h b/libtock-sync/net/udp.h new file mode 100644 index 000000000..1ee523e65 --- /dev/null +++ b/libtock-sync/net/udp.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: fix these names + +returncode_t libtocksync_udp_send(void *buf, size_t len, + sock_addr_t *dst_addr); + +returncode_t libtocksync_udp_recv(void *buf, size_t len, size_t* received_len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/adc.c b/libtock-sync/peripherals/adc.c new file mode 100644 index 000000000..90595792f --- /dev/null +++ b/libtock-sync/peripherals/adc.c @@ -0,0 +1,85 @@ +#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; +}; + +static struct adc_data result; + + +static void sample(uint8_t channel, uint16_t sample) { + result.fired = true; + result.channel = channel; + result.sample = sample; +} + +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; +} + + +static libtock_adc_callbacks callbacks = { + .single_sample_callback = sample, + .continuous_sample_callback = sample, + .buffered_sample_callback = buffered_sample, + .continuous_buffered_sample_callback = buffered_sample, +}; + + + +returncode_t libtocksync_adc_sample(uint8_t channel, uint16_t* sample) { + int err; + result.fired = false; + result.error = RETURNCODE_SUCCESS; + + err = libtock_adc_single_sample(channel, &callbacks); + if (err != RETURNCODE_SUCCESS) return err; + + // wait for callback + yield_for(&result.fired); + + // copy over result + *sample = result.sample; + + return result.error; +} + +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; + + err = libtock_adc_buffered_sample(channel, frequency, &callbacks); + if (err != RETURNCODE_SUCCESS) return err; + + // wait for callback + yield_for(&result.fired); + + // copy over result + if (result.buffer != buffer) { + return RETURNCODE_FAIL; + } + + return result.error; +} diff --git a/libtock-sync/peripherals/adc.h b/libtock-sync/peripherals/adc.h new file mode 100644 index 000000000..155ca26b8 --- /dev/null +++ b/libtock-sync/peripherals/adc.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +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); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/crc.c b/libtock-sync/peripherals/crc.c new file mode 100644 index 000000000..d10931290 --- /dev/null +++ b/libtock-sync/peripherals/crc.c @@ -0,0 +1,33 @@ +#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; +} + +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); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + if (result.status != RETURNCODE_SUCCESS) return result.status; + + ret = libtock_crc_set_readonly_allow(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + *crc = result.crc; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/crc.h b/libtock-sync/peripherals/crc.h new file mode 100644 index 000000000..c766b80d8 --- /dev/null +++ b/libtock-sync/peripherals/crc.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a CRC. +// +// Returns `SUCCESS` and sets `result` on success. +// Returns `EBUSY` if a computation is already in progress. +// Returns `ESIZE` if the buffer is too big for the unit. +returncode_t libtocksync_crc_compute(const uint8_t* buf, size_t buflen, libtock_crc_alg_t algorithm, uint32_t* result); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/gpio.c b/libtock-sync/peripherals/gpio.c new file mode 100644 index 000000000..e456a43dd --- /dev/null +++ b/libtock-sync/peripherals/gpio.c @@ -0,0 +1,53 @@ +#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; +} + +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; + + ret = libtock_gpio_enable_input(pin, pin_config); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_gpio_enable_interrupt(pin, mode); + if (ret != RETURNCODE_SUCCESS) return ret; + + while (1) { + yield_for(&result.fired); + + if (result.pin == pin) { + if (mode == libtock_rising_edge && result.value == true) break; + if (mode == libtock_falling_edge && result.value == false) break; + if (mode == libtock_change) break; + } + result.fired = false; + } + return RETURNCODE_SUCCESS; +} + +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); +} + +returncode_t libtocksync_gpio_wait_until_low(uint32_t pin, libtock_gpio_input_mode_t pin_config) { + return wait_until(pin, pin_config, libtock_falling_edge); +} + +returncode_t libtocksync_gpio_wait_until_changed(uint32_t pin, libtock_gpio_input_mode_t pin_config) { + return wait_until(pin, pin_config, libtock_change); +} diff --git a/libtock-sync/peripherals/gpio.h b/libtock-sync/peripherals/gpio.h new file mode 100644 index 000000000..6af0b2242 --- /dev/null +++ b/libtock-sync/peripherals/gpio.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// 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); + +// Configure a GPIO pin as an input and then wait until a falling interrupt +// occurs. +returncode_t libtocksync_gpio_wait_until_low(uint32_t pin, libtock_gpio_input_mode_t pin_config); + +// Configure a GPIO pin as an input and then wait until the pin level changes. +returncode_t libtocksync_gpio_wait_until_changed(uint32_t pin, libtock_gpio_input_mode_t pin_config); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/gpio_async.c b/libtock-sync/peripherals/gpio_async.c new file mode 100644 index 000000000..b51f7eed3 --- /dev/null +++ b/libtock-sync/peripherals/gpio_async.c @@ -0,0 +1,92 @@ +#include "gpio_async.h" + +struct gpio_async_data { + bool fired; + bool value; + returncode_t ret; +}; + +static struct gpio_async_data result = { .fired = false }; + +static void gpio_async_callback_command(returncode_t ret, bool value) { + result.fired = true; + result.value = value; + result.ret = ret; +} + +static returncode_t gpio_async_op(uint32_t port, uint8_t pin, returncode_t (*op)(uint32_t, uint8_t, + libtock_gpio_async_callback_command)) { + returncode_t err; + result.fired = false; + + err = op(port, pin, gpio_async_callback_command); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_gpio_async_make_output(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_make_output); +} + +returncode_t libtocksync_gpio_async_set(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_set); +} + +returncode_t libtocksync_gpio_async_clear(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_clear); +} + +returncode_t libtocksync_gpio_async_toggle(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_toggle); +} + +returncode_t libtocksync_gpio_async_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config) { + returncode_t err; + result.fired = false; + + err = libtock_gpio_async_make_input(port, pin, pin_config, gpio_async_callback_command); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_gpio_async_read(uint32_t port, uint8_t pin, bool* value) { + returncode_t err; + result.fired = false; + + err = libtock_gpio_async_read(port, pin, gpio_async_callback_command); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *value = result.value; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_gpio_async_enable_interrupt(uint32_t port, uint8_t pin, + libtock_gpio_interrupt_mode_t irq_config) { + returncode_t err; + result.fired = false; + + err = libtock_gpio_async_enable_interrupt(port, pin, irq_config, gpio_async_callback_command); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_gpio_async_disable_interrupt(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_disable_interrupt); +} + +returncode_t libtocksync_gpio_async_disable_sync(uint32_t port, uint8_t pin) { + return gpio_async_op(port, pin, libtock_gpio_async_disable); +} diff --git a/libtock-sync/peripherals/gpio_async.h b/libtock-sync/peripherals/gpio_async.h new file mode 100644 index 000000000..051b99702 --- /dev/null +++ b/libtock-sync/peripherals/gpio_async.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtocksync_gpio_async_make_output(uint32_t port, uint8_t pin); + +returncode_t libtocksync_gpio_async_set(uint32_t port, uint8_t pin); + +returncode_t libtocksync_gpio_async_clear(uint32_t port, uint8_t pin); + +returncode_t libtocksync_gpio_async_toggle(uint32_t port, uint8_t pin); + +returncode_t libtocksync_gpio_async_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config); + +returncode_t libtocksync_gpio_async_read(uint32_t port, uint8_t pin, bool* value); + +returncode_t libtocksync_gpio_async_enable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_interrupt_mode_t irq_config); + +returncode_t libtocksync_gpio_async_disable_interrupt(uint32_t port, uint8_t pin); + +returncode_t libtocksync_gpio_async_disable_sync(uint32_t port, uint8_t pin); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/rng.c b/libtock-sync/peripherals/rng.c new file mode 100644 index 000000000..dc7341a60 --- /dev/null +++ b/libtock-sync/peripherals/rng.c @@ -0,0 +1,36 @@ +#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; +} + +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); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + + ret = libtock_rng_set_allow_readwrite(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *num_received = result.received; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/peripherals/rng.h b/libtock-sync/peripherals/rng.h new file mode 100644 index 000000000..c50b3384e --- /dev/null +++ b/libtock-sync/peripherals/rng.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Synchronous RNG request. +// +// Request `num` random bytes. +// +// - buf: buffer to store random bytes in. +// - len: length of buffer. +// - num: number of random bytes requested. +// - num_received: pointer which will be set with number of bytes received. +returncode_t libtocksync_rng_get_random_bytes(uint8_t* buf, uint32_t len, uint32_t num, int* num_received); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/rtc.c b/libtock-sync/peripherals/rtc.c new file mode 100644 index 000000000..a9407e8cb --- /dev/null +++ b/libtock-sync/peripherals/rtc.c @@ -0,0 +1,54 @@ +#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; +} + +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); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *date = result.date; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_rtc_set_date(libtock_rtc_date_t* set_date) { + returncode_t ret; + + result_done.fired = false; + + ret = libtock_rtc_set_date(set_date, rtc_done_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result_done.fired); + + return result_done.ret; +} diff --git a/libtock-sync/peripherals/rtc.h b/libtock-sync/peripherals/rtc.h new file mode 100644 index 000000000..380a17f70 --- /dev/null +++ b/libtock-sync/peripherals/rtc.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Get the current date. +returncode_t libtocksync_rtc_get_date(libtock_rtc_date_t* date); + +// Set the date. +returncode_t libtocksync_rtc_set_date(libtock_rtc_date_t* set_date); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/peripherals/spi_controller.c b/libtock-sync/peripherals/spi_controller.c new file mode 100644 index 000000000..bd52009b9 --- /dev/null +++ b/libtock-sync/peripherals/spi_controller.c @@ -0,0 +1,49 @@ +#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; +} + +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); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + err = libtock_spi_controller_allow_readonly_write(NULL, 0); + return err; +} + +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); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + err = libtock_spi_controller_allow_readonly_write(NULL, 0); + if (err != RETURNCODE_SUCCESS) return err; + err = libtock_spi_controller_allow_readwrite_read(NULL, 0); + if (err != RETURNCODE_SUCCESS) return err; + + return err; +} diff --git a/libtock-sync/peripherals/spi_controller.h b/libtock-sync/peripherals/spi_controller.h new file mode 100644 index 000000000..449c72b68 --- /dev/null +++ b/libtock-sync/peripherals/spi_controller.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// As the SPI, write a buffer of data. +returncode_t libtocksync_spi_controller_write(const uint8_t* write, + size_t len); + +// As the SPI, write and read buffers of data. +returncode_t libtocksync_spi_controller_read_write(const uint8_t* write, + uint8_t* read, + size_t len); + +#ifdef __cplusplus +} +#endif + + + diff --git a/libtock-sync/peripherals/spi_peripheral.c b/libtock-sync/peripherals/spi_peripheral.c new file mode 100644 index 000000000..38ea5f15b --- /dev/null +++ b/libtock-sync/peripherals/spi_peripheral.c @@ -0,0 +1,49 @@ +#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; +} + +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); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + err = libtock_spi_peripheral_allow_readonly_write(NULL, 0); + return err; +} + +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); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + err = libtock_spi_peripheral_allow_readonly_write(NULL, 0); + if (err != RETURNCODE_SUCCESS) return err; + err = libtock_spi_peripheral_allow_readwrite_read(NULL, 0); + if (err != RETURNCODE_SUCCESS) return err; + + return err; +} diff --git a/libtock-sync/peripherals/spi_peripheral.h b/libtock-sync/peripherals/spi_peripheral.h new file mode 100644 index 000000000..0544b9f81 --- /dev/null +++ b/libtock-sync/peripherals/spi_peripheral.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// As the SPI peripheral, write a buffer of data. +returncode_t libtocksync_spi_peripheral_write(const uint8_t* write, + size_t len); + +// As the SPI peripheral, write and read buffers of data. +returncode_t libtocksync_spi_peripheral_read_write(const uint8_t* write, + uint8_t* read, + size_t len); + +#ifdef __cplusplus +} +#endif + + + diff --git a/libtock-sync/peripherals/usb.c b/libtock-sync/peripherals/usb.c new file mode 100644 index 000000000..e03d31bc3 --- /dev/null +++ b/libtock-sync/peripherals/usb.c @@ -0,0 +1,25 @@ +#include "usb.h" + +struct usb_data { + bool fired; + returncode_t ret; +}; + +struct usb_data result = { .fired = false }; + +static void usb_callback(returncode_t ret){ + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_usb_enable_and_attach(void) { + int err; + + result.fired = false; + + err = libtock_usb_enable_and_attach(usb_callback); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + return result.ret; +} diff --git a/libtock-sync/peripherals/usb.h b/libtock-sync/peripherals/usb.h new file mode 100644 index 000000000..0b2215530 --- /dev/null +++ b/libtock-sync/peripherals/usb.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Enable and attach the USB and wait until the USB attaches. +returncode_t libtocksync_usb_enable_and_attach(void); + +#ifdef __cplusplus +} +#endif + + + diff --git a/libtock-sync/sensors/ambient_light.c b/libtock-sync/sensors/ambient_light.c new file mode 100644 index 000000000..06481dd30 --- /dev/null +++ b/libtock-sync/sensors/ambient_light.c @@ -0,0 +1,32 @@ +#include "ambient_light.h" + +typedef struct { + int intensity; + returncode_t ret; + bool fired; +} ambient_light_data_t; + +static ambient_light_data_t result = {.fired = false}; + +// callback for synchronous reads +static void ambient_light_callback(returncode_t ret, int intensity) { + result.intensity = intensity; + result.ret = ret; + result.fired = true; +} + +returncode_t libtocksync_ambient_light_read_intensity(int* lux_value) { + returncode_t err; + + result.fired = false; + + err = libtock_ambient_light_read_intensity(ambient_light_callback); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *lux_value = result.intensity; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/ambient_light.h b/libtock-sync/sensors/ambient_light.h new file mode 100644 index 000000000..e0ad71f72 --- /dev/null +++ b/libtock-sync/sensors/ambient_light.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the ambient light sensor synchronously. +// +// ## Arguments +// +// - `lux_value`: Set to the light level in lux. +// +// ## Return Value +// +// A returncode indicating whether the sensor read was completed successfully. +returncode_t libtocksync_ambient_light_read_intensity(int* lux_value); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/sensors/humidity.c b/libtock-sync/sensors/humidity.c new file mode 100644 index 000000000..25cc85d60 --- /dev/null +++ b/libtock-sync/sensors/humidity.c @@ -0,0 +1,32 @@ +#include "humidity.h" + +typedef struct { + int humidity; + returncode_t ret; + bool fired; +} humidity_result_t; + +static humidity_result_t result = {.fired = false}; + +// callback for synchronous reads +static void humidity_callback(returncode_t ret, int humidity) { + result.humidity = humidity; + result.ret = ret; + result.fired = true; +} + +returncode_t libtocksync_humidity_read(int* humidity) { + returncode_t err; + + result.fired = false; + + err = libtock_humidity_read(humidity_callback); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *humidity = result.humidity; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/humidity.h b/libtock-sync/sensors/humidity.h new file mode 100644 index 000000000..c93440898 --- /dev/null +++ b/libtock-sync/sensors/humidity.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the humidity sensor synchronously. +// +// ## Arguments +// +// - `humidity`: Set to the humidity in hundredths of a percent. +// +// ## Return Value +// +// A returncode indicating whether the sensor read was completed successfully. +returncode_t libtocksync_humidity_read(int* humidity); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/sensors/ninedof.c b/libtock-sync/sensors/ninedof.c new file mode 100644 index 000000000..7e1dbeb83 --- /dev/null +++ b/libtock-sync/sensors/ninedof.c @@ -0,0 +1,95 @@ +#include +#include + +#include "ninedof.h" + +struct ninedof_data { + int x; + int y; + int z; + bool fired; + returncode_t ret; +}; + +static struct ninedof_data result = { .fired = false }; + + + +static void ninedof_cb(returncode_t ret, int x, int y, int z) { + result.x = x; + result.y = y; + result.z = z; + result.fired = true; + result.ret = ret; +} + + + +returncode_t libtocksync_ninedof_read_accelerometer(int* x, int* y, int* z) { + returncode_t err; + + result.fired = false; + + err = libtock_ninedof_read_accelerometer(ninedof_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *x = result.x; + *y = result.y; + *z = result.z; + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_ninedof_read_accelerometer_magnitude(double* magnitude) { + returncode_t err; + int x, y, z; + + err = libtocksync_ninedof_read_accelerometer(&x, &y, &z); + if (err != RETURNCODE_SUCCESS) return err; + + *magnitude = sqrt(result.x * result.x + result.y * result.y + result.z * result.z); + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_ninedof_read_magnetometer(int* x, int* y, int* z) { + returncode_t err; + + result.fired = false; + + err = libtock_ninedof_read_magnetometer(ninedof_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *x = result.x; + *y = result.y; + *z = result.z; + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_ninedof_read_gyroscope(int* x, int* y, int* z) { + returncode_t err; + + result.fired = false; + + err = libtock_ninedof_read_gyroscope(ninedof_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *x = result.x; + *y = result.y; + *z = result.z; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/ninedof.h b/libtock-sync/sensors/ninedof.h new file mode 100644 index 000000000..d8877c7e3 --- /dev/null +++ b/libtock-sync/sensors/ninedof.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the accelerometer synchronously. +// +// ## Arguments +// +// - `x`: Set to the X acceleration component. +// - `y`: Set to the Y acceleration component. +// - `z`: Set to the Z acceleration component. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_ninedof_read_accelerometer(int* x, int* y, int* z); + +// Read the accelerometer and calculate the accelerometer magnitude. +// +// ## Arguments +// +// - `magnetometer`: Set to the magnitude of the acceleration. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_ninedof_read_accelerometer_magnitude(double* magnitude); + +// Read the magnetometer synchronously. +// +// ## Arguments +// +// - `x`: Set to the X magnetometer component. +// - `y`: Set to the Y magnetometer component. +// - `z`: Set to the Z magnetometer component. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_ninedof_read_magnetometer(int* x, int* y, int* z); + +// Read the gyroscope synchronously. +// +// ## Arguments +// +// - `x`: Set to the X component. +// - `y`: Set to the Y component. +// - `z`: Set to the Z component. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_ninedof_read_gyroscope(int* x, int* y, int* z); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/sensors/pressure.c b/libtock-sync/sensors/pressure.c new file mode 100644 index 000000000..45f482a10 --- /dev/null +++ b/libtock-sync/sensors/pressure.c @@ -0,0 +1,32 @@ +#include "pressure.h" + +struct pressure_data { + bool fired; + int pressure; + returncode_t ret; +}; + +static struct pressure_data result = { .fired = false }; + +static void pressure_cb(returncode_t ret, int pressure) { + result.pressure = pressure; + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_pressure_read(int* pressure) { + returncode_t err; + + result.fired = false; + + err = libtock_pressure_read(pressure_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *pressure = result.pressure; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/pressure.h b/libtock-sync/sensors/pressure.h new file mode 100644 index 000000000..7009148f7 --- /dev/null +++ b/libtock-sync/sensors/pressure.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the pressure synchronously. +// +// ## Arguments +// +// - `pressure`: The pressure reading in hPa. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_pressure_read(int* pressure); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/sensors/proximity.c b/libtock-sync/sensors/proximity.c new file mode 100644 index 000000000..f2fb085e4 --- /dev/null +++ b/libtock-sync/sensors/proximity.c @@ -0,0 +1,46 @@ +#include "proximity.h" + +struct data { + bool fired; + uint8_t proximity; + returncode_t ret; +}; + +static struct data result = {.fired = false}; + +static void proximity_cb(returncode_t ret, uint8_t proximity) { + result.proximity = proximity; + result.ret = ret; + result.fired = true; +} + +returncode_t libtocksync_proximity_read(uint8_t *proximity) { + returncode_t err; + result.fired = false; + + err = libtock_proximity_read(proximity_cb); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *proximity = result.proximity; + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_proximity_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold, + uint8_t *proximity) { + returncode_t err; + result.fired = false; + + err = libtock_proximity_read_on_interrupt(lower_threshold, higher_threshold, proximity_cb); + if (err != RETURNCODE_SUCCESS) return err; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *proximity = result.proximity; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/proximity.h b/libtock-sync/sensors/proximity.h new file mode 100644 index 000000000..b96671b7b --- /dev/null +++ b/libtock-sync/sensors/proximity.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read proximity synchronously. +// +// This function queries the sensor for a proximity reading which is then +// returned via the callback. A proximity value is in the range [0,255] where +// '255' indicates the closest measurable distance and '0' that no object is +// detected. +returncode_t libtocksync_proximity_read(uint8_t *proximity); + +// Return proximity value on interrupt synchronously. +// +// This function can be used to wait for the sensor to detect a proximity +// reading in the user-specified range. This range is determined by the +// `proximity_set_interrupt_thresholds` arguments. A proximity value is in the +// range [0,255] where '255' indicates the closest measurable distance and '0' +// that no object is detected. +returncode_t libtocksync_proximity_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold, uint8_t *proximity); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/sensors/sound_pressure.c b/libtock-sync/sensors/sound_pressure.c new file mode 100644 index 000000000..6d9661687 --- /dev/null +++ b/libtock-sync/sensors/sound_pressure.c @@ -0,0 +1,33 @@ +#include "sound_pressure.h" + +struct sound_pressure_data { + bool fired; + int sound_pressure; + returncode_t ret; +}; + +static struct sound_pressure_data result = { .fired = false }; + +// Internal callback for faking synchronous reads +static void cb(returncode_t ret, uint8_t sound_pressure) { + result.sound_pressure = sound_pressure; + result.fired = true; + result.ret = ret; +} + + +returncode_t libtocksync_sound_pressure_read(uint8_t* sound_pressure) { + returncode_t err; + result.fired = false; + + err = libtock_sound_pressure_read(cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *sound_pressure = result.sound_pressure; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/sound_pressure.h b/libtock-sync/sensors/sound_pressure.h new file mode 100644 index 000000000..5538f1121 --- /dev/null +++ b/libtock-sync/sensors/sound_pressure.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the ambient sound pressure level synchronously. +// +// ## Arguments +// +// - `sound_pressure`: The pressure reading in dB. +// +// ## Return Value +// +// A returncode indicating whether the read was completed successfully. +returncode_t libtocksync_sound_pressure_read(uint8_t* sound_pressure); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/sensors/temperature.c b/libtock-sync/sensors/temperature.c new file mode 100644 index 000000000..a51e86769 --- /dev/null +++ b/libtock-sync/sensors/temperature.c @@ -0,0 +1,31 @@ +#include "temperature.h" + +struct data { + bool fired; + int temp; + returncode_t result; +}; + +static struct data result = { .fired = false }; + +static void temp_cb(returncode_t ret, int temperature) { + result.temp = temperature; + result.fired = true; + result.result = ret; +} + +returncode_t libtocksync_temperature_read(int* temperature) { + returncode_t err; + result.fired = false; + + err = libtock_temperature_read(temp_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.result != RETURNCODE_SUCCESS) return result.result; + + *temperature = result.temp; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/sensors/temperature.h b/libtock-sync/sensors/temperature.h new file mode 100644 index 000000000..4750d3afc --- /dev/null +++ b/libtock-sync/sensors/temperature.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Read the temperature sensor synchronously. +// +// ## Arguments +// +// - `temperature`: Set to the temperature value in hundredths of degrees +// centigrade. +// +// ## Return Value +// +// A returncode indicating whether the temperature read was completed +// successfully. +returncode_t libtocksync_temperature_read(int* temperature); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/services/README.md b/libtock-sync/services/README.md new file mode 100644 index 000000000..cff75fba2 --- /dev/null +++ b/libtock-sync/services/README.md @@ -0,0 +1,7 @@ +Libtock Services +================ + +This folder contains resources that help with writing Tock apps by providing +higher-level services using libtock APIs. + +Services that use `yield()` are stored in libtock-sync. diff --git a/libtock-sync/services/alarm.c b/libtock-sync/services/alarm.c new file mode 100644 index 000000000..4b1a2de63 --- /dev/null +++ b/libtock-sync/services/alarm.c @@ -0,0 +1,51 @@ +#include "alarm.h" + +struct alarm_cb_data { + bool fired; +}; + +static struct alarm_cb_data delay_data = { .fired = false }; + +static void delay_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opqaue) { + delay_data.fired = true; +} + +int libtocksync_alarm_delay_ms(uint32_t ms) { + delay_data.fired = false; + libtock_alarm_t alarm; + int rc; + + if ((rc = libtock_alarm_in_ms(ms, delay_cb, NULL, &alarm)) != RETURNCODE_SUCCESS) { + return rc; + } + + yield_for(&delay_data.fired); + return rc; +} + +static struct alarm_cb_data yf_timeout_data = { .fired = false }; + +static void yf_timeout_cb(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opqaue) { + yf_timeout_data.fired = true; +} + +int libtocksync_alarm_yield_for_with_timeout(bool* cond, uint32_t ms) { + yf_timeout_data.fired = false; + libtock_alarm_t alarm; + libtock_alarm_in_ms(ms, yf_timeout_cb, NULL, &alarm); + + while (!*cond) { + if (yf_timeout_data.fired) { + return RETURNCODE_FAIL; + } + + yield(); + } + + libtock_alarm_cancel(&alarm); + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/services/alarm.h b/libtock-sync/services/alarm.h new file mode 100644 index 000000000..1c5f6402a --- /dev/null +++ b/libtock-sync/services/alarm.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Blocks for the given amount of time in millisecond. + * + * This is a blocking version of `libtock_alarm_in_ms`. Instead of calling a user + * specified callback, it blocks the current call-stack. + * + * \param ms the number of milliseconds to delay for. + * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. + */ +int libtocksync_alarm_delay_ms(uint32_t ms); + +/** \brief Functions as yield_for with a timeout. + * + * This yields on a condition variable, but will return early + * if that condition is not met before the timeout in milliseconds. + * + * \param cond the condition to yield_for. + * \param ms the amount of time before returning without the condition. + * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL for timeout. + */ +int libtocksync_alarm_yield_for_with_timeout(bool* cond, uint32_t ms); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/unit_test.c b/libtock-sync/services/unit_test.c similarity index 93% rename from libtock/unit_test.c rename to libtock-sync/services/unit_test.c index d810487a2..b4fbe195f 100644 --- a/libtock/unit_test.c +++ b/libtock-sync/services/unit_test.c @@ -11,9 +11,10 @@ #include #include -#include -#include -#include +#include "alarm.h" +#include + +#include "unit_test.h" /******************************************************************************* * STRUCT DEFINITIONS AND HELPER FUNCTIONS @@ -82,8 +83,8 @@ struct unit_test_t { // Process ID of this test runner. int pid; - // Timer structure used for triggering test timeout conditions. - tock_timer_t timer; + // alarm structure used for triggering test timeout conditions. + libtock_alarm_t alarm; // Result of the most recently completed test. unit_test_result_t result; @@ -230,7 +231,7 @@ void unit_test_runner(unit_test_fun *tests, uint32_t test_count, // Establish communication with the test supervisor service. First delay 10 ms // to ensure the supervisor service has time to register. - delay_ms(10); + libtocksync_alarm_delay_ms(10); size_t test_svc; int err = ipc_discover(svc_name, &test_svc); if (err < 0) return; @@ -320,19 +321,23 @@ static void print_test_summary(unit_test_t *test) { incomplete, total); } +struct alarm_cb_data { + unit_test_t *test; +}; + +static struct alarm_cb_data data = { .test = NULL }; + /** \brief Timer callback for handling a test timeout. * * When a test times out, there's no guarantee about the test runner's state, so * we just stop the tests here and print the results. */ -static void timeout_callback(__attribute__ ((unused)) int now, - __attribute__ ((unused)) int expiration, - __attribute__ ((unused)) int unused, void* ud) { - - unit_test_t *test = (unit_test_t *)ud; - test->result = Timeout; - print_test_result(test); - print_test_summary(test); +static void timeout_callback(__attribute__ ((unused)) uint32_t now, + __attribute__ ((unused)) uint32_t scheduled, + __attribute__ ((unused)) void* opqaue) { + data.test->result = Timeout; + print_test_result(data.test); + print_test_summary(data.test); } /** \brief IPC service callback for coordinating test runners. @@ -372,15 +377,16 @@ static void unit_test_service_callback(int pid, break; case TestStart: - // Start the timer and start the test. - timer_in(test->timeout_ms, timeout_callback, test, &test->timer); + // Start the alarm and start the test. + data.test = test; + libtock_alarm_in_ms(test->timeout_ms, timeout_callback, NULL, &test->alarm); ipc_notify_client(test->pid); break; case TestEnd: - // Cancel the timeout timer since the test is now complete. + // Cancel the timeout alarm since the test is now complete. // Record the test result for the test summary statistics. - timer_cancel(&test->timer); + libtock_alarm_cancel(&test->alarm); // If the test timed out, the summary results will already have been // printed. In this case, we no longer want the tests to continue, diff --git a/libtock/unit_test.h b/libtock-sync/services/unit_test.h similarity index 100% rename from libtock/unit_test.h rename to libtock-sync/services/unit_test.h diff --git a/libtock-sync/storage/app_state.c b/libtock-sync/storage/app_state.c new file mode 100644 index 000000000..33d25d72d --- /dev/null +++ b/libtock-sync/storage/app_state.c @@ -0,0 +1,27 @@ +#include "app_state.h" + +struct app_state_data { + bool fired; + returncode_t ret; +}; + +static struct app_state_data result = {.fired = false}; + +static void app_state_cb(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_app_state_save(void) { + returncode_t err; + + result.fired = false; + + err = libtock_app_state_save(app_state_cb); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + + return result.ret; +} diff --git a/libtock-sync/storage/app_state.h b/libtock-sync/storage/app_state.h new file mode 100644 index 000000000..5cfec924d --- /dev/null +++ b/libtock-sync/storage/app_state.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Save the application state. +returncode_t libtocksync_app_state_save(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock-sync/storage/kv.c b/libtock-sync/storage/kv.c new file mode 100644 index 000000000..0600d9e81 --- /dev/null +++ b/libtock-sync/storage/kv.c @@ -0,0 +1,80 @@ +#include "kv.h" + +struct kv_data { + bool fired; + int length; + returncode_t ret; +}; + +static struct kv_data result = {.fired = false}; + +static void kv_cb_get(returncode_t ret, int length) { + result.fired = true; + result.length = length; + result.ret = ret; +} + +static void kv_cb_done(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + +returncode_t libtocksync_kv_get(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, + uint32_t* value_len) { + returncode_t err; + result.fired = false; + + err = libtock_kv_get(key_buffer, key_len, ret_buffer, ret_len, kv_cb_get); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + // Return the length of the retrieved value. + *value_len = result.length; + + return RETURNCODE_SUCCESS; +} + +static returncode_t kv_insert(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, + uint32_t val_len, returncode_t (*op_fn)(const uint8_t*, uint32_t, const uint8_t*, + uint32_t, libtock_kv_callback_done)){ + returncode_t err; + result.fired = false; + + // Do the requested set/add/update operation. + err = op_fn(key_buffer, key_len, val_buffer, val_len, kv_cb_done); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} + +returncode_t libtocksync_kv_set(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, + uint32_t val_len) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_set); +} + +returncode_t libtocksync_kv_add(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, + uint32_t val_len) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_add); +} + +returncode_t libtocksync_kv_update(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, + uint32_t val_len) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_update); +} + +returncode_t libtocksync_kv_delete(const uint8_t* key_buffer, uint32_t key_len) { + returncode_t err; + result.fired = false; + + err = libtock_kv_delete(key_buffer, key_len, kv_cb_done); + if (err != RETURNCODE_SUCCESS) return err; + + // Wait for the callback. + yield_for(&result.fired); + return result.ret; +} diff --git a/libtock-sync/storage/kv.h b/libtock-sync/storage/kv.h new file mode 100644 index 000000000..d659ca0b9 --- /dev/null +++ b/libtock-sync/storage/kv.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtocksync_kv_get(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, + uint32_t* value_len); + +returncode_t libtocksync_kv_set(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); + +returncode_t libtocksync_kv_add(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); + +returncode_t libtocksync_kv_update(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); + +returncode_t libtocksync_kv_delete(const uint8_t* key_buffer, uint32_t key_len); + +#ifdef __cplusplus +} +#endif + + + + + + + diff --git a/libtock-sync/storage/nonvolatile_storage.c b/libtock-sync/storage/nonvolatile_storage.c new file mode 100644 index 000000000..bef40a51b --- /dev/null +++ b/libtock-sync/storage/nonvolatile_storage.c @@ -0,0 +1,57 @@ +#include "nonvolatile_storage.h" + +struct nv_data { + bool fired; + returncode_t ret; + int length; +}; + +struct nv_data result = {.fired = false}; + +static void write_cb(returncode_t ret, int length) { + result.fired = true; + result.ret = ret; + result.length = length; +} + +static void read_cb(returncode_t ret, int length) { + result.fired = true; + result.ret = ret; + result.length = length; +} + +returncode_t libtocksync_nonvolatile_storage_write(uint32_t offset, uint32_t length, uint8_t* buffer, + uint32_t buffer_length, int* length_written) { + returncode_t ret; + result.fired = false; + + ret = libtock_nonvolatile_storage_write(offset, length, buffer, buffer_length, write_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_nonvolatile_storage_set_allow_readonly_write_buffer(NULL, 0); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *length_written = result.length; + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_nonvolatile_storage_read(uint32_t offset, uint32_t length, uint8_t* buffer, + uint32_t buffer_length, int* length_read) { + returncode_t ret; + result.fired = false; + + ret = libtock_nonvolatile_storage_read(offset, length, buffer, buffer_length, read_cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_nonvolatile_storage_set_allow_readwrite_read_buffer(NULL, 0); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + *length_read = result.length; + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/storage/nonvolatile_storage.h b/libtock-sync/storage/nonvolatile_storage.h new file mode 100644 index 000000000..acf281e17 --- /dev/null +++ b/libtock-sync/storage/nonvolatile_storage.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Write `length` bytes from `buffer` to the nonvolatile storage starting at +// `offset`. +returncode_t libtocksync_nonvolatile_storage_write(uint32_t offset, uint32_t length, uint8_t* buffer, uint32_t buffer_length, int* length_written); + +// Read `length` bytes into `buffer` from the nonvolatile storage starting at +// `offset`. +returncode_t libtocksync_nonvolatile_storage_read(uint32_t offset, uint32_t length, uint8_t* buffer, uint32_t buffer_length, int* length_read); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/storage/sdcard.c b/libtock-sync/storage/sdcard.c new file mode 100644 index 000000000..cf2f7a240 --- /dev/null +++ b/libtock-sync/storage/sdcard.c @@ -0,0 +1,85 @@ +#include "sdcard.h" + +// used for creating synchronous versions of functions +// +// - `fired` - set when callback has been called +// - `block_size` - block size of SD card, set upon initialization complete +// - `size_in_kB` - size in kilobytes of SD card, set upon initialization complete +// - `error` - error code signaled in callback, 0 if successful +struct sdcard_data { + bool fired; + uint32_t block_size; + uint32_t size_in_kB; + returncode_t ret; +}; + +struct sdcard_data result = {.fired = false}; + +static void sdcard_cb_init(returncode_t ret, uint32_t block_size, uint32_t size_in_kB) { + result.fired = true; + result.block_size = block_size; + result.size_in_kB = size_in_kB; + result.ret = ret; +} + +static void sdcard_cb_general(returncode_t ret) { + result.fired = true; + result.ret = ret; +} + + +returncode_t libtocksync_sdcard_initialize(uint32_t* block_size, uint32_t* size_in_kB) { + returncode_t ret; + result.fired = false; + + ret = libtock_sdcard_initialize(sdcard_cb_init); + if (ret != RETURNCODE_SUCCESS) return ret; + + // wait for callback + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + // copy args + if (block_size != NULL) { + *block_size = result.block_size; + } + if (size_in_kB != NULL) { + *size_in_kB = result.size_in_kB; + } + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_sdcard_read_block(uint32_t sector, uint8_t* buffer, uint32_t len) { + returncode_t ret; + result.fired = false; + + ret = libtock_sdcard_read_block(sector, buffer, len, sdcard_cb_general); + if (ret != RETURNCODE_SUCCESS) return ret; + + // wait for callback + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_sdcard_set_readwrite_allow_read_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return RETURNCODE_SUCCESS; +} + +returncode_t libtocksync_sdcard_write_block(uint32_t sector, uint8_t* buffer, uint32_t len) { + returncode_t ret; + result.fired = false; + + ret = libtock_sdcard_write_block(sector, buffer, len, sdcard_cb_general); + if (ret != RETURNCODE_SUCCESS) return ret; + + // wait for callback + yield_for(&result.fired); + if (result.ret != RETURNCODE_SUCCESS) return result.ret; + + ret = libtock_sdcard_set_readonly_allow_write_buffer(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return RETURNCODE_SUCCESS; +} diff --git a/libtock-sync/storage/sdcard.h b/libtock-sync/storage/sdcard.h new file mode 100644 index 000000000..5ceaa10ce --- /dev/null +++ b/libtock-sync/storage/sdcard.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize the SD card. +returncode_t libtocksync_sdcard_initialize(uint32_t* block_size, uint32_t* size_in_kB); + +// Read a block from the SD card. +returncode_t libtocksync_sdcard_read_block(uint32_t sector, uint8_t* buffer, uint32_t len); + +// Write a block to the SD card. +returncode_t libtocksync_sdcard_write_block(uint32_t sector, uint8_t* buffer, uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock-sync/sys.c b/libtock-sync/sys.c new file mode 100644 index 000000000..9ad288306 --- /dev/null +++ b/libtock-sync/sys.c @@ -0,0 +1,18 @@ +#include "interface/console.h" + +// XXX Suppress missing prototype warnings for this file as the headers should +// be in newlib internals, but first stab at including things didn't quite work +// and the warnings are just noise +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + +// ------------------------------ +// SYNCHRONOUS LIBC SUPPORT STUBS +// ------------------------------ + +int _write(__attribute__ ((unused)) int fd, const void *buf, uint32_t count) { + int written; + libtocksync_console_write((const uint8_t*) buf, count, &written); + return written; +} diff --git a/libtock/Makefile b/libtock/Makefile index 83e6f1825..59957f14a 100644 --- a/libtock/Makefile +++ b/libtock/Makefile @@ -7,10 +7,26 @@ LIBNAME := libtock $(LIBNAME)_DIR := $(TOCK_USERLAND_BASE_DIR)/$(LIBNAME) # List all C and Assembly files -$(LIBNAME)_SRCS := $(wildcard $($(LIBNAME)_DIR)/internal/*.c) $(wildcard $($(LIBNAME)_DIR)/*.c) $(wildcard $($(LIBNAME)_DIR)/*.s) +$(LIBNAME)_SRCS := $(wildcard $($(LIBNAME)_DIR)/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/crypto/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/crypto/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/display/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/display/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/interface/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/interface/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/kernel/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/kernel/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/net/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/net/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/peripherals/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/peripherals/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/services/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/sensors/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/sensors/syscalls/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/storage/*.c) +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/storage/syscalls/*.c) -# Include the libtock folder for includes to find header files. This is -# temporary until the libtock-c rewrite is merged. -override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/libtock +# Temporary hack for alarm +$(LIBNAME)_SRCS += $(wildcard $($(LIBNAME)_DIR)/internal/*.c) include $(TOCK_USERLAND_BASE_DIR)/TockLibrary.mk diff --git a/libtock/README.md b/libtock/README.md new file mode 100644 index 000000000..988f3ad4b --- /dev/null +++ b/libtock/README.md @@ -0,0 +1,39 @@ +Core Libtock Library +==================== + +The libtock library provides core functionality for writing Tock apps in C. In +particular this library provides three main components: + +1. The `crt0.c` file which executes first when an app first starts. This + configures memory to initialize the C runtime. +2. Interfaces for libc to use common C functions (e.g., `printf()`). +3. Drivers for the system call APIs the Tock kernel provides (e.g., timers and + sensors). + +The libtock library is **complete asynchronous**, meaning it does not call +`yield()`. All exposed functionality can safely be used for asynchronous +operation. Using the libtock library exclusively allows an app to avoid mixing +asynchronous and synchronous operations. + +_Note_: Users who prefer synchronous functions can use the libtock-sync library. + +Library Usage +------------- + +The format of the libtock library is documented in the [style +guide](../doc/guide.md). + +To include an API in your app, you should include its header file: + +```c +#include +``` + +All library function names start with `libtock_{api}_`. General usage +functionality is provide via the `{api}.h` header file. All of the low level +syscall operations are found in `libtock/{category}/syscalls/{api}_syscalls.h` +if you need to call that driver's system calls directly. + +Functions that start an asynchronous operation take a callback function pointer +as their final argument. Each function pointer has a type signature which is +documented in the `{api}.h` header file. diff --git a/libtock/adc.c b/libtock/adc.c deleted file mode 100644 index 22e8dff59..000000000 --- a/libtock/adc.c +++ /dev/null @@ -1,301 +0,0 @@ -// ADC interface - -#include -#include - -#include "adc.h" -#include "tock.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 -typedef struct { - bool fired; - uint8_t channel; - uint16_t sample; - uint32_t length; - uint16_t* buffer; - int error; -} adc_data_t; - -// Internal callback for creating synchronous functions -// -// callback_type - number indicating which type of callback occurred -// arg1, arg2 - meaning varies based on callback_type -// callback_args - user data passed into the set_callback function -// -// Possible callbacks -// SingleSample: single sample operation is complete -// arg1 - channel number that collected sample corresponds to -// arg2 - sample value -// MultipleSample: sampling a buffer worth of data is complete -// arg1 - channel in lower 8 bits, -// number of samples collected in upper 24 bits -// arg2 - pointer to buffer filled with samples -// ContinuousSample: a buffer of sample data is ready -// arg1 - channel in lower 8 bits, -// number of samples collected in upper 24 bits -// arg2 - pointer to buffer filled with samples -static void adc_upcall(int callback_type, - int arg1, - int arg2, - void* callback_args) { - - adc_data_t* result = (adc_data_t*)callback_args; - - switch (callback_type) { - case SingleSample: - result->error = RETURNCODE_SUCCESS; - result->channel = arg1; - result->sample = arg2; - break; - - case ContinuousSample: - result->error = RETURNCODE_SUCCESS; - result->channel = arg1; - result->sample = arg2; - break; - - case SingleBuffer: - result->error = RETURNCODE_SUCCESS; - result->channel = (arg1 & 0xFF); - result->length = ((arg1 >> 8) & 0xFFFFFF); - result->buffer = (uint16_t*)arg2; - break; - - case ContinuousBuffer: - result->error = RETURNCODE_SUCCESS; - result->channel = (arg1 & 0xFF); - result->length = ((arg1 >> 8) & 0xFFFFFF); - result->buffer = (uint16_t*)arg2; - break; - - default: - result->error = RETURNCODE_FAIL; - break; - } - result->fired = true; -} - -// function pointers used for wrapping adc callbacks with the `adc_routing_upcall` -// below -static void (*single_sample_callback)(uint8_t, uint16_t, void*) = NULL; -static void (*continuous_sample_callback)(uint8_t, uint16_t, void*) = NULL; -static void (*buffered_sample_callback)(uint8_t, uint32_t, uint16_t*, void*) = NULL; -static void (*continuous_buffered_sample_callback)(uint8_t, uint32_t, uint16_t*, void*) = NULL; - -// Internal callback for routing to operation-specific callbacks -// -// callback_type - number indicating which type of callback occurred -// arg1, arg2 - meaning varies based on callback_type -// callback_args - user data passed into the set_callback function -// -// Possible callbacks -// SingleSample: single sample operation is complete -// arg1 - channel number that collected sample corresponds to -// arg2 - sample value -// MultipleSample: sampling a buffer worth of data is complete -// arg1 - channel in lower 8 bits, -// number of samples collected in upper 24 bits -// arg2 - pointer to buffer filled with samples -// ContinuousSample: a buffer of sample data is ready -// arg1 - channel in lower 8 bits, -// number of samples collected in upper 24 bits -// arg2 - pointer to buffer filled with samples -static void adc_routing_upcall(int callback_type, - int arg1, - int arg2, - void* callback_args) { - - switch (callback_type) { - case SingleSample: - if (single_sample_callback) { - uint8_t channel = (uint8_t)arg1; - uint16_t sample = (uint16_t)arg2; - single_sample_callback(channel, sample, callback_args); - } - break; - - case ContinuousSample: - if (continuous_sample_callback) { - uint8_t channel = (uint8_t)arg1; - uint16_t sample = (uint16_t)arg2; - continuous_sample_callback(channel, sample, callback_args); - } - break; - - case SingleBuffer: - if (buffered_sample_callback) { - uint8_t channel = (uint8_t)(arg1 & 0xFF); - uint32_t length = ((arg1 >> 8) & 0xFFFFFF); - uint16_t* buffer = (uint16_t*)arg2; - buffered_sample_callback(channel, length, buffer, callback_args); - } - break; - - case ContinuousBuffer: - if (continuous_buffered_sample_callback) { - uint8_t channel = (uint8_t)(arg1 & 0xFF); - uint32_t length = ((arg1 >> 8) & 0xFFFFFF); - uint16_t* buffer = (uint16_t*)arg2; - continuous_buffered_sample_callback(channel, length, buffer, callback_args); - } - break; - } -} - - -// ***** System Call Interface ***** - -int adc_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t subval = subscribe(DRIVER_NUM_ADC, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(subval); -} - -int adc_set_buffer(uint16_t* buffer, uint32_t len) { - // we "allow" byte arrays, so this is actually twice as long - allow_rw_return_t rw = allow_readwrite(DRIVER_NUM_ADC, 0, (void*)buffer, len * 2); - return tock_allow_rw_return_to_returncode(rw); -} - -int adc_set_double_buffer(uint16_t* buffer, uint32_t len) { - // we "allow" byte arrays, so this is actually twice as long - allow_rw_return_t rw = allow_readwrite(DRIVER_NUM_ADC, 1, (void*)buffer, len * 2); - return tock_allow_rw_return_to_returncode(rw); -} - -bool adc_exists(void) { - return driver_exists(DRIVER_NUM_ADC); -} - -int adc_channel_count(int* count) { - syscall_return_t res = command(DRIVER_NUM_ADC, 0, 0, 0); - return tock_command_return_u32_to_returncode(res, (uint32_t*) count); -} - -int adc_single_sample(uint8_t channel) { - syscall_return_t res = command(DRIVER_NUM_ADC, 1, channel, 0); - return tock_command_return_novalue_to_returncode(res); -} - -int adc_continuous_sample(uint8_t channel, uint32_t frequency) { - syscall_return_t res = command(DRIVER_NUM_ADC, 2, channel, frequency); - return tock_command_return_novalue_to_returncode(res); -} - -int adc_buffered_sample(uint8_t channel, uint32_t frequency) { - syscall_return_t res = command(DRIVER_NUM_ADC, 3, channel, frequency); - return tock_command_return_novalue_to_returncode(res); -} - -int adc_continuous_buffered_sample(uint8_t channel, uint32_t frequency) { - syscall_return_t res = command(DRIVER_NUM_ADC, 4, channel, frequency); - return tock_command_return_novalue_to_returncode(res); -} - -int adc_stop_sampling(void) { - syscall_return_t res = command(DRIVER_NUM_ADC, 5, 0, 0); - return tock_command_return_novalue_to_returncode(res); -} - - -// ***** Callback Wrappers ***** - -int adc_set_single_sample_callback(void (*callback)(uint8_t, uint16_t, void*), - void* callback_args) { - single_sample_callback = callback; - return adc_set_callback(adc_routing_upcall, callback_args); -} - -int adc_set_continuous_sample_callback(void (*callback)(uint8_t, uint16_t, void*), - void* callback_args) { - continuous_sample_callback = callback; - return adc_set_callback(adc_routing_upcall, callback_args); -} - -int adc_set_buffered_sample_callback(void (*callback)(uint8_t, uint32_t, uint16_t*, void*), - void* callback_args) { - buffered_sample_callback = callback; - return adc_set_callback(adc_routing_upcall, callback_args); -} - -int adc_set_continuous_buffered_sample_callback(void (*callback)(uint8_t, uint32_t, uint16_t*, void*), - void* callback_args){ - continuous_buffered_sample_callback = callback; - return adc_set_callback(adc_routing_upcall, callback_args); -} - - -// ***** Synchronous Calls ***** - -int adc_sample_sync(uint8_t channel, uint16_t* sample) { - int err; - adc_data_t result = {0}; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = adc_set_callback(adc_upcall, (void*) &result); - if (err < RETURNCODE_SUCCESS) return err; - - err = adc_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; -} - -int adc_sample_buffer_sync(uint8_t channel, uint32_t frequency, uint16_t* buffer, uint32_t length) { - int err; - adc_data_t result = {0}; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = adc_set_callback(adc_upcall, (void*) &result); - if (err < RETURNCODE_SUCCESS) return err; - - err = adc_set_buffer(buffer, length); - if (err < RETURNCODE_SUCCESS) return err; - - err = adc_buffered_sample(channel, frequency); - if (err < RETURNCODE_SUCCESS) return err; - - // wait for callback - yield_for(&result.fired); - - // copy over result - if (result.buffer != buffer) { - return RETURNCODE_FAIL; - } - - return result.error; -} - -int adc_get_reference_voltage (void) { - syscall_return_t res = command(DRIVER_NUM_ADC, 102, 0, 0); - if (res.type == TOCK_SYSCALL_SUCCESS_U32) { - return res.data[0]; - } else { - return tock_command_return_novalue_to_returncode(res); - } -} - -int adc_get_resolution_bits (void) { - syscall_return_t res = command(DRIVER_NUM_ADC, 101, 0, 0); - if (res.type == TOCK_SYSCALL_SUCCESS_U32) { - return res.data[0]; - } else { - return tock_command_return_novalue_to_returncode(res); - } -} diff --git a/libtock/adc.h b/libtock/adc.h deleted file mode 100644 index bd7a46cf0..000000000 --- a/libtock/adc.h +++ /dev/null @@ -1,157 +0,0 @@ -// driver for collecting analog samples -#pragma once - -#include - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_ADC 0x5 - -// mode of the ADC -// Used to tell which operation a callback corresponds to -typedef enum { - SingleSample = 0, - ContinuousSample = 1, - SingleBuffer = 2, - ContinuousBuffer = 3 -} ADCMode_t; - -// ***** System Call Interface ***** - -// set the function called by the ADC when operations are complete -// See `adc_cb` in adc.c for callback documentation -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int adc_set_callback(subscribe_upcall callback, void* callback_args); - -// provides an application buffer to the ADC driver to fill with samples -// -// buffer - pointer to buffer to fill with samples -// length - number of samples requested, must be less than or equal to buffer -// length -int adc_set_buffer(uint16_t* buffer, uint32_t length); - -// provide an application buffer to fill with samples when continuously -// sampling -// -// buffer - pointer to buffer to fill with samples -// length - number of samples requested, must be less than or equal to buffer -// length -int adc_set_double_buffer(uint16_t* buffer, uint32_t length); - -// query whether the ADC driver is present -bool adc_exists(void); - -// query how many channels are available in the ADC driver -int adc_channel_count(int* count); - -// request a single analog sample -// -// channel - number of the channel to be sampled -int adc_single_sample(uint8_t channel); - -// request an repeated analog samples at a given frequency -// -// channel - number of the channel to be sampled -// frequency - rate in samples per second to collect data at -int adc_continuous_sample(uint8_t channel, uint32_t frequency); - -// request a buffer full of samples from the ADC -// -// channel - number of the channel to be sampled -// frequency - rate in samples per second to collect data at -int adc_buffered_sample(uint8_t channel, uint32_t frequency); - -// request continuous ADC sampling -// Alternates between the two provided application buffers -// -// channel - number of the channel to be sampled -// frequency - rate in samples per second to collect data at -int adc_continuous_buffered_sample(uint8_t channel, uint32_t frequency); - -// cancel an outstanding ADC operation -// No callback will occur from the prior ADC operation. The ADC may not be -// immediately ready to use again if a single sample was canceled. Usually used -// to stop a continuous sampling operation -int adc_stop_sampling(void); - - -// ***** Callback Wrappers ***** - -// set the function called by the ADC when a single_sample operation -// completes. -// -// callback - pointer to function to be called -// uint8_t - channel the sample was taken on -// uint16_t - sample value -// void* - user pointer to pass to callback -int adc_set_single_sample_callback(void(*callback)(uint8_t, uint16_t, void*), - void* callback_args); - -// set the function called by the ADC when a continuous_sample operation -// completes. -// -// callback - pointer to function to be called -// uint8_t - channel the sample was taken on -// uint16_t - sample value -// void* - user pointer to pass to callback -int adc_set_continuous_sample_callback(void(*callback)(uint8_t, uint16_t, void*), - void* callback_args); - -// set the function called by the ADC when a buffered_sample operation -// completes. -// -// callback - pointer to function to be called -// uint8_t - channel the sample was taken on -// uint32_t - number of samples -// uint16_t* - pointer to buffer containing samples -// void* - user pointer to pass to callback -int adc_set_buffered_sample_callback(void(*callback)(uint8_t, uint32_t, uint16_t*, void*), - void* callback_args); - -// set the function called by the ADC when a continuous_buffered_sample operation -// completes. -// -// callback - pointer to function to be called -// uint8_t - channel the sample was taken on -// uint32_t - number of samples -// uint16_t* - pointer to buffer containing samples -// void* - user pointer to pass to callback -int adc_set_continuous_buffered_sample_callback(void(*callback)(uint8_t, uint32_t, uint16_t*, void*), - void* callback_args); - - -// ***** Synchronous Calls ***** - -// request a single analog sample -// Wrapper providing a synchronous interface around the raw ADC system calls -// -// channel - number of the channel to be sampled -// sample - pointer to a uint16_t in which the sample will be stored -int adc_sample_sync(uint8_t channel, uint16_t* sample); - -// request a buffer full of analog samples -// Wrapper providing a synchronous interface around the raw ADC system calls -// -// channel - number of the channel to be sampled -// frequency - rate in samples per second to collect data at -// buffer - pointer to buffer to be filled with samples -// length - number of samples requested, must be less than or equal to buffer -// length -int adc_sample_buffer_sync(uint8_t channel, uint32_t frequency, uint16_t* buffer, uint32_t length); - -// returns the reference voltage in mV or an error ( < 0) -// it this is not available -int adc_get_reference_voltage (void); - -// returns the adc resolution bits -int adc_get_resolution_bits (void); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/aes.h b/libtock/aes.h deleted file mode 100644 index 237dbb976..000000000 --- a/libtock/aes.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int aes_set_callback(subscribe_upcall callback, void* callback_args); - -int aes_set_key_buffer(const uint8_t* buffer, uint32_t len); -/* - * Contains the IV buffer, if applicable. - */ -int aes_set_iv_buffer(const uint8_t* buffer, uint32_t len); - -/* - * Contains the nonce for CCM buffer. - */ -int aes_set_nonce_buffer(const uint8_t* buffer, uint32_t len); - -/* - * Contains the source buffer. - * If doing a AES CCM operation this sets the mlen value to `len`. - */ -int aes_set_source_buffer(const uint8_t* buffer, uint32_t len); -int aes_set_dest_buffer(uint8_t* buffer, uint32_t len); - -/* - * Check that the AES system exists - */ -int aes_check_status(void); - -/* - * Set the AES algorithm - * operation: - * * 0 -> AES128Ctr - * * 1 -> AES128CBC - * * 2 -> AES128ECB - * * 3 -> AES128CCM - * encrypting: - * * true -> Encrypt the source data - * * false -> Decrypt the source data - */ -int aes_set_algorithm(uint8_t operation, bool encrypting); - -/* - * Setup the platform and run the first encryption. - * This must be called before `aes_crypt()` and `aes_finish()` - * but must be called after `aes_set_algorithm()` and all relevent - * buffers are set up. - * - * This will load in the specified key, IV and then run the - * encryption/decryption operation on the data in the source - * buffer and save the output in the destination buffer. - * - * This will trigger a callback. - * - */ -int aes_setup(void); - -/* - * This must be called after aes_setup(). It will run the - * encryption/decryption operation on the source data and store - * it in the destination buffer, based on thte key and IV that was - * loaded by `aes_setup()`. - * - * Between a call of `aes_setup()` and `aes_finish()` this can be called - * any number of times (from 0 to infinite). - * - * Each call to this will trigger a callback - */ -int aes_crypt(void); - -/* - * This must be called when the operation is complete. This indicates that the - * app has finished the operation. Any future operations need to call - * `aes_set_algorithm()` and `aes_setup()` as the key and IV will be cleared. - */ -int aes_finish(void); - -/* - * This sets the A offset for AES CCM. - */ -int aes_ccm_set_a_off(uint32_t value); - -/* - * This sets the M offset for AES CCM. - */ -int aes_ccm_set_m_off(uint32_t value); - -/* - * This sets the mic length for AES CCM. - */ -int aes_ccm_set_mic_len(uint32_t value); - -/* - * This sets the confidential bool for AES CCM. - */ -int aes_ccm_set_confidential(bool value); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/alarm.h b/libtock/alarm.h deleted file mode 100644 index 9e82a884f..000000000 --- a/libtock/alarm.h +++ /dev/null @@ -1,89 +0,0 @@ -/** @file alarm.h - * @brief Alarm function prototypes - * - * The alarm module allows the client to initiate alarms and receive - * callbacks when those alarms have expired. Clients can set one-shot alarms to - * fire at particular clock values (`alarm_at`) - * - * The client should not assume anything about the underlying clock used by an - * implementation other than that it is running at sufficient frequency to - * deliver at least millisecond granularity and that it is a 32-bit clock (i.e. - * it will wrap at 2^32 clock ticks). - * - * ## Example - * - * static void callback(int now, int interval, int arg2, char* str) { - * printf("%s\n", str); - * } - * - * uint32_t frequency = alarm_frequency(); - * uint32_t now = alarm_now(); - * static alarm_t alarm; - * alarm_at(now + frequency, callback, (void*)"1 second elapsed", &alarm); - * - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tock.h" - -#include - -/** \brief Opaque handle to a single-shot alarm. - * - * An opaque handle to an alarm created by `alarm_at` or `alarm_in`. Memory - * management is handled by the underlying implementation. - */ -typedef struct alarm { - uint32_t reference; - uint32_t dt; - subscribe_upcall *callback; - void* ud; - struct alarm* next; - struct alarm* prev; -} alarm_t; - - -/** \brief Create a new alarm to fire at a particular clock value. - * - * The `alarm` parameter is allocated by the caller and must live as long as - * the alarm is outstanding. - * - * \param reference: the reference time from which the alarm is being set - * \param dt: the time after reference that the alarm should fire - * \param callback a callback to be invoked when the alarm expires. - * \param userdata passed to the callback. - * \param a pointer to a new alarm_t to be used by the implementation to keep - * track of the alarm. - * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. - */ -int alarm_at(uint32_t reference, uint32_t dt, subscribe_upcall, void*, alarm_t *alarm); - -/** \brief Cancels an existing alarm. - * - * The caller is responsible for freeing the `alarm_t`. - * - * \param alarm - */ -void alarm_cancel(alarm_t*); - -// Use this to implement _gettimeofday yourself as libtock-c doesn't provide -// an implementation. -// -// See https://github.com/tock/libtock-c/pull/355#issuecomment-1841351091 for -// more details -// -// ```c -// int _gettimeofday(struct timeval *tv, void *tzvp) { -// return gettimeasticks(tv, tzvp); -// } -// ``` -int gettimeasticks(struct timeval *tv, void *tzvp); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/ambient_light.c b/libtock/ambient_light.c deleted file mode 100644 index 0b2b75e79..000000000 --- a/libtock/ambient_light.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "ambient_light.h" -#include "tock.h" - -typedef struct { - int intensity; - bool fired; -} ambient_light_data_t; - -// callback for synchronous reads -static void ambient_light_upcall(int intensity, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, void* ud) { - ambient_light_data_t* result = (ambient_light_data_t*)ud; - result->intensity = intensity; - result->fired = true; -} - -bool ambient_light_exists(void) { - return driver_exists(DRIVER_NUM_AMBIENT_LIGHT); -} - -int ambient_light_read_intensity_sync(int* lux_value) { - int err; - ambient_light_data_t result = {0}; - result.fired = false; - - err = ambient_light_subscribe(ambient_light_upcall, (void*)(&result)); - if (err < RETURNCODE_SUCCESS) { - return err; - } - - err = ambient_light_start_intensity_reading(); - if (err < RETURNCODE_SUCCESS) { - return err; - } - - yield_for(&result.fired); - - *lux_value = result.intensity; - - return RETURNCODE_SUCCESS; -} - -int ambient_light_subscribe(subscribe_upcall callback, void* userdata) { - subscribe_return_t ret = subscribe(DRIVER_NUM_AMBIENT_LIGHT, 0, callback, userdata); - return tock_subscribe_return_to_returncode(ret); -} - -int ambient_light_start_intensity_reading(void) { - syscall_return_t ret = command(DRIVER_NUM_AMBIENT_LIGHT, 1, 0, 0); - return tock_command_return_novalue_to_returncode(ret); -} diff --git a/libtock/ambient_light.h b/libtock/ambient_light.h deleted file mode 100644 index 0eb8bc7fd..000000000 --- a/libtock/ambient_light.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_AMBIENT_LIGHT 0x60002 - -bool ambient_light_exists(void); - -// units: ambient light reading in lux (lx). - -int ambient_light_subscribe(subscribe_upcall callback, void* userdata); -int ambient_light_start_intensity_reading(void); - -int ambient_light_read_intensity_sync(int* lux_value); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/analog_comparator.c b/libtock/analog_comparator.c deleted file mode 100644 index 128d74739..000000000 --- a/libtock/analog_comparator.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "analog_comparator.h" -#include "tock.h" - -bool analog_comparator_exists(void) { - return driver_exists(DRIVER_NUM_ANALOG_COMPARATOR); -} - -int analog_comparator_comparison(uint8_t channel, bool* comparison) { - syscall_return_t com = command(DRIVER_NUM_ANALOG_COMPARATOR, 1, channel, 0); - return tock_command_return_u32_to_returncode(com, (uint32_t*) comparison); -} - -int analog_comparator_start_comparing(uint8_t channel) { - syscall_return_t com = command(DRIVER_NUM_ANALOG_COMPARATOR, 2, channel, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int analog_comparator_stop_comparing(uint8_t channel) { - syscall_return_t com = command(DRIVER_NUM_ANALOG_COMPARATOR, 3, channel, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int analog_comparator_count(int* count) { - syscall_return_t com = command(DRIVER_NUM_ANALOG_COMPARATOR, 4, 0, 0); - return tock_command_return_u32_to_returncode(com, (uint32_t*) count); -} - -int analog_comparator_interrupt_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sub = subscribe(DRIVER_NUM_ANALOG_COMPARATOR, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sub); -} diff --git a/libtock/analog_comparator.h b/libtock/analog_comparator.h deleted file mode 100644 index ac9edea1b..000000000 --- a/libtock/analog_comparator.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_ANALOG_COMPARATOR 0x7 - -// Does the driver exist? -bool analog_comparator_exists(void); - -// Request the number of available ACs -int analog_comparator_count(int* count); - -// Compare the voltages of two pins (if one is higher than the other) on the -// corresponding AC by doing a single comparison. -// -// channel - index of the analog comparator channel, starting at 0. -int analog_comparator_comparison(uint8_t channel, bool* comparison); - -// Enable interrupt-based comparisons. This will make the AC listen and send an -// interrupt as soon as Vp > Vn. -// -// channel - index of the analog comparator channel, starting at 0. -int analog_comparator_start_comparing(uint8_t channel); - -// Disable interrupt-based comparisons. This will make the AC stop listening, -// and thereby stop sending interrupts. -// -// channel - index of the analog comparator channel, starting at 0. -int analog_comparator_stop_comparing(uint8_t channel); - -// Function called by the AC when an interrupt is received. -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int analog_comparator_interrupt_callback(subscribe_upcall callback, void* callback_args); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/app_state.c b/libtock/app_state.c deleted file mode 100644 index 68fd62528..000000000 --- a/libtock/app_state.c +++ /dev/null @@ -1,76 +0,0 @@ -#include - -#include "app_state.h" -#include "tock.h" - -// Internal callback for synchronous interfaces -static void app_state_sync_upcall(__attribute__ ((unused)) int callback_type, - __attribute__ ((unused)) int value, - __attribute__ ((unused)) int unused, - void* ud) { - *((bool*) ud) = true; -} - - -static bool _app_state_inited = false; -static int app_state_init(void) { - allow_ro_return_t aret = - allow_readonly(DRIVER_NUM_APP_FLASH, 0, _app_state_ram_pointer, _app_state_size); - if (!aret.success) { - return tock_status_to_returncode(aret.status); - } - - // Check that we have a region to use for this. - int number_regions = tock_app_number_writeable_flash_regions(); - if (number_regions == 0) return RETURNCODE_ENOMEM; - - // Get the pointer to flash which we need to ask the kernel where it is. - _app_state_flash_pointer = tock_app_writeable_flash_region_begins_at(0); - - _app_state_inited = true; - return 0; -} - - -int app_state_load_sync(void) { - if (!_app_state_inited) { - int err; - err = app_state_init(); - if (err < 0) return err; - } - - memcpy(_app_state_ram_pointer, _app_state_flash_pointer, _app_state_size); - return 0; -} - -int app_state_save(subscribe_upcall callback, void* callback_args) { - if (!_app_state_inited) { - int err = app_state_init(); - if (err < 0) return err; - } - - subscribe_return_t sret = - subscribe(DRIVER_NUM_APP_FLASH, 0, callback, callback_args); - if (!sret.success) { - return tock_status_to_returncode(sret.status); - } - - syscall_return_t cret = - command(DRIVER_NUM_APP_FLASH, 1, (uint32_t) _app_state_flash_pointer, 0); - return tock_command_return_novalue_to_returncode(cret); -} - - -static bool save_sync_flag; -int app_state_save_sync(void) { - int err; - save_sync_flag = false; - - err = app_state_save(app_state_sync_upcall, (void*) &save_sync_flag); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&save_sync_flag); - - return 0; -} diff --git a/libtock/button.c b/libtock/button.c deleted file mode 100644 index 05ffdc8e2..000000000 --- a/libtock/button.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "button.h" - -int button_subscribe(subscribe_upcall callback, void *ud) { - subscribe_return_t res = subscribe(DRIVER_NUM_BUTTON, 0, callback, ud); - return tock_subscribe_return_to_returncode(res); -} - -int button_count(int* count) { - syscall_return_t res = command(DRIVER_NUM_BUTTON, 0, 0, 0); - return tock_command_return_u32_to_returncode(res, (uint32_t*) count); -} - -int button_enable_interrupt(int button_num) { - syscall_return_t res = command(DRIVER_NUM_BUTTON, 1, button_num, 0); - return tock_command_return_novalue_to_returncode(res); -} - -int button_disable_interrupt(int button_num) { - syscall_return_t res = command(DRIVER_NUM_BUTTON, 2, button_num, 0); - return tock_command_return_novalue_to_returncode(res); -} - -int button_read(int button_num, int* button_value) { - syscall_return_t res = command(DRIVER_NUM_BUTTON, 3, button_num, 0); - return tock_command_return_u32_to_returncode(res, (uint32_t*) button_value); -} diff --git a/libtock/button.h b/libtock/button.h deleted file mode 100644 index 544aa4d10..000000000 --- a/libtock/button.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_BUTTON 0x3 - -int button_subscribe(subscribe_upcall callback, void *ud); -int button_enable_interrupt(int button_num); -int button_disable_interrupt(int button_num); -int button_read(int button_num, int* button_value); -int button_count(int* count); - - -#ifdef __cplusplus -} -#endif - diff --git a/libtock/buzzer.c b/libtock/buzzer.c deleted file mode 100644 index 324900a3e..000000000 --- a/libtock/buzzer.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "buzzer.h" -#include "tock.h" - -// Internal callback for faking synchronous reads -static void callback_sync (__attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - *(bool*)ud = true; -} - -static void callback(__attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - ((void (*)(void)) ud)(); -} - -int buzzer_exists (void) { - return driver_exists(BUZZER_DRIVER); -} - -int tone_sync (size_t frequency_hz, size_t duration_ms) { - bool done = false; - subscribe_return_t sval = subscribe(BUZZER_DRIVER, 0, callback_sync, &done); - if (!sval.success) { - return tock_status_to_returncode(sval.status); - } - - syscall_return_t cval = command(BUZZER_DRIVER, 1, frequency_hz, duration_ms); - if (cval.type != TOCK_SYSCALL_SUCCESS) { - return tock_command_return_novalue_to_returncode(cval); - } - - // Wait for tone to finish. - yield_for(&done); - return RETURNCODE_SUCCESS; -} - -int tone (size_t frequency_hz, size_t duration_ms, void (*tone_done)(void)) { - subscribe_return_t sval = subscribe(BUZZER_DRIVER, 0, callback, tone_done); - if (!sval.success) { - return tock_status_to_returncode(sval.status); - } - - syscall_return_t cval = command(BUZZER_DRIVER, 1, frequency_hz, duration_ms); - return tock_command_return_novalue_to_returncode(cval); -} diff --git a/libtock/console.c b/libtock/console.c deleted file mode 100644 index 7d69f21ec..000000000 --- a/libtock/console.c +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include -#include - -#include "console.h" - -typedef struct putstr_data { - char* buf; - int len; - bool called; - struct putstr_data* next; -} putstr_data_t; - -static putstr_data_t *putstr_head = NULL; -static putstr_data_t *putstr_tail = NULL; - -static void putstr_upcall(int _x __attribute__ ((unused)), - int _y __attribute__ ((unused)), - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - putstr_data_t* data = putstr_head; - data->called = true; - putstr_head = data->next; - - if (putstr_head == NULL) { - putstr_tail = NULL; - } else { - int ret; - ret = putnstr_async(putstr_head->buf, putstr_head->len, putstr_upcall, NULL); - if (ret < 0) { - // XXX There's no path to report errors currently, so just drop it - putstr_upcall(0, 0, 0, NULL); - } - } -} - -int putnstr(const char *str, size_t len) { - int ret = RETURNCODE_SUCCESS; - - putstr_data_t* data = (putstr_data_t*)malloc(sizeof(putstr_data_t)); - if (data == NULL) return RETURNCODE_ENOMEM; - - data->len = len; - data->called = false; - data->buf = (char*)malloc(len * sizeof(char)); - if (data->buf == NULL) { - ret = RETURNCODE_ENOMEM; - goto putnstr_fail_buf_alloc; - } - strncpy(data->buf, str, len); - data->next = NULL; - - if (putstr_tail == NULL) { - // Invariant, if tail is NULL, head is also NULL - ret = putnstr_async(data->buf, data->len, putstr_upcall, NULL); - if (ret < 0) goto putnstr_fail_async; - putstr_head = data; - putstr_tail = data; - } else { - putstr_tail->next = data; - putstr_tail = data; - } - - yield_for(&data->called); - -putnstr_fail_async: - free(data->buf); -putnstr_fail_buf_alloc: - free(data); - - return ret; -} - -int putnstr_async(const char *str, size_t len, subscribe_upcall cb, void* userdata) { -#pragma GCC diagnostic push -#pragma GCC diagnostic pop - - allow_ro_return_t ro = allow_readonly(DRIVER_NUM_CONSOLE, 1, str, len); - if (!ro.success) { - return tock_status_to_returncode(ro.status); - } - - subscribe_return_t sub = subscribe(DRIVER_NUM_CONSOLE, 1, cb, userdata); - if (!sub.success) { - return tock_status_to_returncode(sub.status); - } - - syscall_return_t com = command(DRIVER_NUM_CONSOLE, 1, len, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int getnstr_async(char *buf, size_t len, subscribe_upcall cb, void* userdata) { - allow_rw_return_t rw = allow_readwrite(DRIVER_NUM_CONSOLE, 1, buf, len); - if (!rw.success) { - return tock_status_to_returncode(rw.status); - } - - subscribe_return_t sub = subscribe(DRIVER_NUM_CONSOLE, 2, cb, userdata); - if (!sub.success) { - return tock_status_to_returncode(sub.status); - } - - syscall_return_t com = command(DRIVER_NUM_CONSOLE, 2, len, 0); - return tock_command_return_novalue_to_returncode(com); -} - -typedef struct getnstr_data { - bool called; - int result; -} getnstr_data_t; - -static getnstr_data_t getnstr_data = { true, 0 }; - -static void getnstr_upcall(int result, - int _y __attribute__ ((unused)), - int _z __attribute__ ((unused)), - void* ud __attribute__ ((unused))) { - getnstr_data.result = result; - getnstr_data.called = true; -} - -int getnstr(char *str, size_t len) { - int ret; - - if (!getnstr_data.called) { - // A call is already in progress - return RETURNCODE_EALREADY; - } - getnstr_data.called = false; - - ret = getnstr_async(str, len, getnstr_upcall, NULL); - if (ret < 0) { - return ret; - } - - yield_for(&getnstr_data.called); - - return getnstr_data.result; -} - -int getch(void) { - int r; - char buf[1]; - - r = getnstr(buf, 1); - return (r == RETURNCODE_SUCCESS) ? buf[0] : RETURNCODE_FAIL; -} - -int getnstr_abort(void) { - syscall_return_t com = command(DRIVER_NUM_CONSOLE, 3, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} diff --git a/libtock/console.h b/libtock/console.h deleted file mode 100644 index 2f10866cf..000000000 --- a/libtock/console.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_CONSOLE 0x1 - -int putnstr(const char* str, size_t len); -int putnstr_async(const char* str, size_t len, subscribe_upcall cb, void* userdata); - -int getnstr(char *str, size_t len); -int getnstr_async(char *str, size_t len, subscribe_upcall cb, void* userdata); - -/* Returns TOCK_FAIL on failure, or else the character received */ -int getch(void); - -// Abort an ongoing receive call. -int getnstr_abort(void); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/crc.c b/libtock/crc.c deleted file mode 100644 index f7c255081..000000000 --- a/libtock/crc.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "crc.h" -#include "tock.h" - -int crc_exists(void) { - return driver_exists(DRIVER_NUM_CRC); -} - -int crc_request(enum crc_alg alg, size_t len) { - syscall_return_t ret = command(DRIVER_NUM_CRC, 1, alg, (uint32_t)len); - if (ret.type == TOCK_SYSCALL_SUCCESS) { - return RETURNCODE_SUCCESS; - } else { - // printf("Failure on crc_request: %s\n", tock_strerr(ret.data[0])); - return tock_status_to_returncode(ret.data[0]); - } -} - -int crc_subscribe(subscribe_upcall callback, void *ud) { - subscribe_return_t ret = subscribe(DRIVER_NUM_CRC, 0, callback, ud); - return tock_subscribe_return_to_returncode(ret); -} - -int crc_set_buffer(const void* buf, size_t len) { - allow_ro_return_t ret = allow_readonly(DRIVER_NUM_CRC, 0, (void*) buf, len); - return tock_allow_ro_return_to_returncode(ret); -} - -struct data { - bool fired; - int status; - uint32_t result; -}; - -static void callback(int status, int v1, __attribute__((unused)) int v2, void *data) { - struct data *d = data; - d->fired = true; - d->status = status; - d->result = v1; -} - -int crc_compute(const void *buf, size_t buflen, enum crc_alg alg, uint32_t *result) { - struct data d = { .fired = false }; - int ret; - ret = crc_set_buffer(buf, buflen); - if (ret < 0) return ret; - ret = crc_subscribe(callback, (void *) &d); - if (ret < 0) return ret; - ret = crc_request(alg, buflen); - if (ret < 0) return ret; - yield_for(&d.fired); - - if (d.status == TOCK_STATUSCODE_SUCCESS) { - *result = d.result; - } - - return tock_status_to_returncode(d.status); -} diff --git a/libtock/crc.h b/libtock/crc.h deleted file mode 100644 index 39cca4dde..000000000 --- a/libtock/crc.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_CRC 0x40002 - -// 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. -// -enum crc_alg { - // Polynomial 0x04C11DB7, output reversed then inverted ("CRC-32") - CRC_32, - // Polynomial 0x1EDC6F41, output reversed then inverted ("CRC-32C" / "Castagnoli") - CRC_32C, - - /// Polynomial 0x1021, no output post-processing - CRC_16CCITT, -}; - -// Does the driver exist? -int crc_exists(void); - -// Compute a CRC value over the given buffer using the given algorithm -// -// Returns SUCCESS and sets `result` on success. -// Returns EBUSY if a computation is already in progress. -// Returns ESIZE if the buffer is too big for the unit. -int crc_compute(const void *buf, size_t buflen, enum crc_alg, uint32_t *result); - -// Register a callback to receive CRC results -// -// The callback will receive these parameters, in order: -// status: SUCCESS if all inputs are valid, else EINVAL -// result: When status == SUCCESS, the CRC result -int crc_subscribe(subscribe_upcall, void *); - -// Provide the buffer over which to compute a CRC -int crc_set_buffer(const void*, size_t); - -// Request a CRC computation asynchronously -// -// The callback and buffer must be provided first. -// -// If SUCCESS is returned, the result will be provided to -// the registered callback. -// -// Returns EBUSY if a computation is already in progress. -// Returns ESIZE if the buffer is too big for the unit. -int crc_request(enum crc_alg, size_t len); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/crypto/aes.c b/libtock/crypto/aes.c new file mode 100644 index 000000000..d31265adb --- /dev/null +++ b/libtock/crypto/aes.c @@ -0,0 +1,33 @@ +#include "aes.h" + +returncode_t libtock_aes_set_algorithm(libtock_aes_algorithm_t operation, bool encrypting) { + return libtock_aes_command_set_algorithm((uint8_t) operation, encrypting); +} + +returncode_t libtock_aes_setup(void) { + return libtock_aes_command_setup(); +} + +returncode_t libtock_aes_crypt(void) { + return libtock_aes_command_crypt(); +} + +returncode_t libtock_aes_finish(void) { + return libtock_aes_command_finish(); +} + +returncode_t libtock_aes_ccm_set_a_off(uint32_t value) { + return libtock_aes_command_ccm_set_a_off(value); +} + +returncode_t libtock_aes_ccm_set_m_off(uint32_t value) { + return libtock_aes_command_ccm_set_m_off(value); +} + +returncode_t libtock_aes_ccm_set_mic_len(uint32_t value) { + return libtock_aes_command_ccm_set_mic_len(value); +} + +returncode_t libtock_aes_ccm_set_confidential(bool value) { + return libtock_aes_command_ccm_set_confidential(value); +} diff --git a/libtock/crypto/aes.h b/libtock/crypto/aes.h new file mode 100644 index 000000000..f3ced28b0 --- /dev/null +++ b/libtock/crypto/aes.h @@ -0,0 +1,68 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/aes_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + LIBTOCK_AES128Ctr = 0, + LIBTOCK_AES128CBC = 1, + LIBTOCK_AES128ECB = 2, + LIBTOCK_AES128CCM = 3 +} libtock_aes_algorithm_t; + +// Set the AES algorithm +// operation: +// * 0 -> AES128Ctr +// * 1 -> AES128CBC +// * 2 -> AES128ECB +// * 3 -> AES128CCM +// encrypting: +// * true -> Encrypt the source data +// * false -> Decrypt the source data +returncode_t libtock_aes_set_algorithm(libtock_aes_algorithm_t operation, bool encrypting); + +// Setup the platform and run the first encryption. This must be called before +// `aes_crypt()` and `aes_finish()` but must be called after +// `aes_set_algorithm()` and all relevant buffers are set up. +// +// This will load in the specified key, IV and then run the +// encryption/decryption operation on the data in the source buffer and save the +// output in the destination buffer. +// +// This will trigger a callback. +returncode_t libtock_aes_setup(void); + +// This must be called after aes_setup(). It will run the encryption/decryption +// operation on the source data and store it in the destination buffer, based on +// the key and IV that was loaded by `aes_setup()`. +// +// Between a call of `aes_setup()` and `aes_finish()` this can be called any +// number of times (from 0 to infinite). +// +// Each call to this will trigger a callback. +returncode_t libtock_aes_crypt(void); + +// This must be called when the operation is complete. This indicates that the +// app has finished the operation. Any future operations need to call +// `aes_set_algorithm()` and `aes_setup()` as the key and IV will be cleared. +returncode_t libtock_aes_finish(void); + +// This sets the A offset for AES CCM. +returncode_t libtock_aes_ccm_set_a_off(uint32_t value); + +// This sets the M offset for AES CCM. +returncode_t libtock_aes_ccm_set_m_off(uint32_t value); + +// This sets the mic length for AES CCM. +returncode_t libtock_aes_ccm_set_mic_len(uint32_t value); + +// This sets the confidential bool for AES CCM. +returncode_t libtock_aes_ccm_set_confidential(bool value); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/crypto/hmac.c b/libtock/crypto/hmac.c new file mode 100644 index 000000000..9d25235f1 --- /dev/null +++ b/libtock/crypto/hmac.c @@ -0,0 +1,37 @@ +#include "hmac.h" + +static void hmac_upcall(int ret, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, void* opaque) { + libtock_hmac_callback_hmac cb = (libtock_hmac_callback_hmac) opaque; + cb((returncode_t) ret); +} + + +returncode_t libtock_hmac_simple(libtock_hmac_algorithm_t hmac_type, + uint8_t* key_buffer, uint32_t key_length, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length, + libtock_hmac_callback_hmac cb) { + + returncode_t ret; + + ret = libtock_hmac_command_set_algorithm((uint32_t) hmac_type); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_readonly_allow_key_buffer(key_buffer, key_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_readonly_allow_data_buffer(input_buffer, input_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_readwrite_allow_destination_buffer(hash_buffer, hash_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_set_upcall(hmac_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_hmac_command_run(); + return ret; + +} diff --git a/libtock/crypto/hmac.h b/libtock/crypto/hmac.h new file mode 100644 index 000000000..99ba8ac2d --- /dev/null +++ b/libtock/crypto/hmac.h @@ -0,0 +1,40 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/hmac_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for HMAC callback. +// +// - `arg1` (`returncode_t`): Status from computing the HMAC. +typedef void (*libtock_hmac_callback_hmac)(returncode_t); + +typedef enum { + LIBTOCK_HMAC_SHA256 = 0, + LIBTOCK_HMAC_SHA384 = 1, + LIBTOCK_HMAC_SHA512 = 2, +} libtock_hmac_algorithm_t; + + + +// Compute an HMAC using `keyb_buffer` over `input_buffer` and store the result +// in `hash_buffer`. +// +// The callback will be called when the HMAC is available. +returncode_t libtock_hmac_simple(libtock_hmac_algorithm_t hmac_type, + uint8_t* key_buffer, uint32_t key_length, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length, + libtock_hmac_callback_hmac cb); + +#ifdef __cplusplus +} +#endif + + + + + diff --git a/libtock/crypto/sha.c b/libtock/crypto/sha.c new file mode 100644 index 000000000..623f075f6 --- /dev/null +++ b/libtock/crypto/sha.c @@ -0,0 +1,31 @@ +#include "sha.h" + +static void sha_upcall(int ret, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, void* opaque) { + libtock_sha_callback_hash cb = (libtock_sha_callback_hash) opaque; + cb((returncode_t) ret); +} + +returncode_t libtock_sha_simple_hash(libtock_sha_algorithm_t hash_type, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length, + libtock_sha_callback_hash cb) { + + returncode_t ret; + + ret = libtock_sha_command_set_algorithm((uint8_t) hash_type); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sha_set_readonly_allow_data_buffer(input_buffer, input_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sha_set_readwrite_allow_destination_buffer(hash_buffer, hash_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sha_set_upcall(sha_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sha_command_run(); + return ret; +} diff --git a/libtock/crypto/sha.h b/libtock/crypto/sha.h new file mode 100644 index 000000000..d1bc34ead --- /dev/null +++ b/libtock/crypto/sha.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/sha_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for SHA hash callback. +// +// - `arg1` (`returncode_t`): Status from computing the hash. +typedef void (*libtock_sha_callback_hash)(returncode_t); + +typedef enum { + LIBTOCK_SHA256 = 0, + LIBTOCK_SHA384 = 1, + LIBTOCK_SHA512 = 2, +} libtock_sha_algorithm_t; + + + +// Compute a SHA hash over `input_buffer` and store the hash in `hash_buffer`. +// +// The callback will be called when the hash is available. +returncode_t libtock_sha_simple_hash(libtock_sha_algorithm_t hash_type, + uint8_t* input_buffer, uint32_t input_length, + uint8_t* hash_buffer, uint32_t hash_length, + libtock_sha_callback_hash cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/aes.c b/libtock/crypto/syscalls/aes_syscalls.c similarity index 65% rename from libtock/aes.c rename to libtock/crypto/syscalls/aes_syscalls.c index 0bac10937..5f3913bf9 100644 --- a/libtock/aes.c +++ b/libtock/crypto/syscalls/aes_syscalls.c @@ -1,6 +1,4 @@ -#include "aes.h" - -#define DRIVER_NUM_AES 0x40006 +#include "aes_syscalls.h" #define TOCK_AES_CB 0 @@ -9,7 +7,6 @@ #define TOCK_AES_SOURCE_BUF 2 #define TOCK_AES_DEST_BUF 0 -#define TOCK_AES_CHECK_PRESENT 0 #define TOCK_AES_SET_ALG 1 #define TOCK_AES_SETUP 2 #define TOCK_AES_CRYPT 3 @@ -20,80 +17,75 @@ #define TOCK_AES_CCM_MIC_LEN 7 #define TOCK_AES_CCM_CONF 8 -int aes_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_AES, TOCK_AES_CB, callback, callback_args); +bool libtock_aes_exists(void) { + return driver_exists(DRIVER_NUM_AES); +} + +returncode_t libtock_aes_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_AES, TOCK_AES_CB, callback, opaque); return tock_subscribe_return_to_returncode(sval); } -int aes_set_key_buffer(const uint8_t* buffer, uint32_t len) { +returncode_t libtock_aes_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_AES, TOCK_AES_KEY_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -/* - * Contains the IV buffer, if applicable. - * If doing a AES CCM operation this contains the nonce instead. - */ -int aes_set_iv_buffer(const uint8_t* buffer, uint32_t len) { +returncode_t libtock_aes_set_readonly_allow_iv_buffer(const uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_AES, TOCK_AES_IV_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -int aes_set_nonce_buffer(const uint8_t* buffer, uint32_t len) { - return aes_set_iv_buffer(buffer, len); +returncode_t libtock_aes_set_readonly_allow_nonce_buffer(const uint8_t* buffer, uint32_t len) { + return libtock_aes_set_readonly_allow_iv_buffer(buffer, len); } -int aes_set_source_buffer(const uint8_t* buffer, uint32_t len) { +returncode_t libtock_aes_set_readonly_allow_source_buffer(const uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_AES, TOCK_AES_SOURCE_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -int aes_set_dest_buffer(uint8_t* buffer, uint32_t len) { +returncode_t libtock_aes_set_readwrite_allow_dest_buffer(uint8_t* buffer, uint32_t len) { allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_AES, TOCK_AES_DEST_BUF, (void*) buffer, len); return tock_allow_rw_return_to_returncode(aval); } -int aes_check_status(void) { - syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CHECK_PRESENT, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int aes_set_algorithm(uint8_t operation, bool encrypting) { +returncode_t libtock_aes_command_set_algorithm(uint8_t operation, bool encrypting) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_SET_ALG, operation, encrypting); return tock_command_return_novalue_to_returncode(cval); } -int aes_setup(void) { +returncode_t libtock_aes_command_setup(void) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_SETUP, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_crypt(void) { +returncode_t libtock_aes_command_crypt(void) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CRYPT, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_finish(void) { +returncode_t libtock_aes_command_finish(void) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_FINISH, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_ccm_set_a_off(uint32_t value) { +returncode_t libtock_aes_command_ccm_set_a_off(uint32_t value) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CCM_AOFF, value, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_ccm_set_m_off(uint32_t value) { +returncode_t libtock_aes_command_ccm_set_m_off(uint32_t value) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CCM_MOFF, value, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_ccm_set_mic_len(uint32_t value) { +returncode_t libtock_aes_command_ccm_set_mic_len(uint32_t value) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CCM_MIC_LEN, value, 0); return tock_command_return_novalue_to_returncode(cval); } -int aes_ccm_set_confidential(bool value) { +returncode_t libtock_aes_command_ccm_set_confidential(bool value) { syscall_return_t cval = command(DRIVER_NUM_AES, TOCK_AES_CCM_CONF, value, 0); return tock_command_return_novalue_to_returncode(cval); } diff --git a/libtock/crypto/syscalls/aes_syscalls.h b/libtock/crypto/syscalls/aes_syscalls.h new file mode 100644 index 000000000..7ac955d13 --- /dev/null +++ b/libtock/crypto/syscalls/aes_syscalls.h @@ -0,0 +1,48 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_AES 0x40006 + +bool libtock_aes_exists(void); + +returncode_t libtock_aes_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_aes_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len); + +// Contains the IV buffer, if applicable. +// If doing a AES CCM operation this contains the nonce instead. +returncode_t libtock_aes_set_readonly_allow_iv_buffer(const uint8_t* buffer, uint32_t len); + +// Contains the nonce for CCM buffer. +returncode_t libtock_aes_set_readonly_allow_nonce_buffer(const uint8_t* buffer, uint32_t len); + +// Contains the source buffer. +// If doing a AES CCM operation this sets the mlen value to `len`. +returncode_t libtock_aes_set_readonly_allow_source_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_aes_set_readwrite_allow_dest_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_aes_command_set_algorithm(uint8_t operation, bool encrypting); + +returncode_t libtock_aes_command_setup(void); + +returncode_t libtock_aes_command_crypt(void); + +returncode_t libtock_aes_command_finish(void); + +returncode_t libtock_aes_command_ccm_set_a_off(uint32_t value); + +returncode_t libtock_aes_command_ccm_set_m_off(uint32_t value); + +returncode_t libtock_aes_command_ccm_set_mic_len(uint32_t value); + +returncode_t libtock_aes_command_ccm_set_confidential(bool value); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/hmac.c b/libtock/crypto/syscalls/hmac_syscalls.c similarity index 66% rename from libtock/hmac.c rename to libtock/crypto/syscalls/hmac_syscalls.c index f9f331789..e57ba94a7 100644 --- a/libtock/hmac.c +++ b/libtock/crypto/syscalls/hmac_syscalls.c @@ -1,6 +1,4 @@ -#include "hmac.h" - -#define DRIVER_NUM_HMAC 0x40003 +#include "hmac_syscalls.h" #define TOCK_HMAC_CB 0 @@ -13,42 +11,46 @@ #define TOCK_HMAC_UPDATE 2 #define TOCK_HMAC_FINISH 3 -int hmac_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_HMAC, TOCK_HMAC_CB, callback, callback_args); +bool libtock_hmac_exists(void) { + return driver_exists(DRIVER_NUM_HMAC); +} + +returncode_t libtock_hmac_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_HMAC, TOCK_HMAC_CB, callback, opaque); return tock_subscribe_return_to_returncode(sval); } -int hmac_set_key_buffer(const uint8_t* buffer, uint32_t len) { +returncode_t libtock_hmac_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_HMAC, TOCK_HMAC_KEY_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -int hmac_set_data_buffer(const uint8_t* buffer, uint32_t len) { +returncode_t libtock_hmac_set_readonly_allow_data_buffer(const uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_HMAC, TOCK_HMAC_DATA_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -int hmac_set_dest_buffer(uint8_t* buffer, uint32_t len) { +returncode_t libtock_hmac_set_readwrite_allow_destination_buffer(uint8_t* buffer, uint32_t len) { allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_HMAC, TOCK_HMAC_DEST_BUF, (void*) buffer, len); return tock_allow_rw_return_to_returncode(aval); } -int hmac_set_algorithm(uint8_t hash) { +returncode_t libtock_hmac_command_set_algorithm(uint32_t hash) { syscall_return_t cval = command(DRIVER_NUM_HMAC, TOCK_HMAC_SET_ALGORITHM, hash, 0); return tock_command_return_novalue_to_returncode(cval); } -int hmac_run(void) { +returncode_t libtock_hmac_command_run(void) { syscall_return_t cval = command(DRIVER_NUM_HMAC, TOCK_HMAC_RUN, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int hmac_update(void) { +returncode_t libtock_hmac_command_update(void) { syscall_return_t cval = command(DRIVER_NUM_HMAC, TOCK_HMAC_UPDATE, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int hmac_finish(void) { +returncode_t libtock_hmac_command_finish(void) { syscall_return_t cval = command(DRIVER_NUM_HMAC, TOCK_HMAC_FINISH, 0, 0); return tock_command_return_novalue_to_returncode(cval); } diff --git a/libtock/crypto/syscalls/hmac_syscalls.h b/libtock/crypto/syscalls/hmac_syscalls.h new file mode 100644 index 000000000..a4c707bb6 --- /dev/null +++ b/libtock/crypto/syscalls/hmac_syscalls.h @@ -0,0 +1,31 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_HMAC 0x40003 + +bool libtock_hmac_exists(void); + +returncode_t libtock_hmac_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_hmac_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_hmac_set_readonly_allow_data_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_hmac_set_readwrite_allow_destination_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_hmac_command_set_algorithm(uint32_t hash); + +returncode_t libtock_hmac_command_run(void); + +returncode_t libtock_hmac_command_update(void); + +returncode_t libtock_hmac_command_finish(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sha.c b/libtock/crypto/syscalls/sha_syscalls.c similarity index 67% rename from libtock/sha.c rename to libtock/crypto/syscalls/sha_syscalls.c index eeb1b3e5b..cb2e8a0b1 100644 --- a/libtock/sha.c +++ b/libtock/crypto/syscalls/sha_syscalls.c @@ -1,6 +1,4 @@ -#include "sha.h" - -#define DRIVER_NUM_SHA 0x40005 +#include "sha_syscalls.h" #define TOCK_SHA_CB 0 @@ -12,37 +10,41 @@ #define TOCK_SHA_UPDATE 2 #define TOCK_SHA_FINISH 3 -int sha_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_SHA, TOCK_SHA_CB, callback, callback_args); +bool libtock_sha_exists(void) { + return driver_exists(DRIVER_NUM_SHA); +} + +returncode_t libtock_sha_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SHA, TOCK_SHA_CB, callback, opaque); return tock_subscribe_return_to_returncode(sval); } -int sha_set_data_buffer(uint8_t* buffer, uint32_t len) { +returncode_t libtock_sha_set_readonly_allow_data_buffer(uint8_t* buffer, uint32_t len) { allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SHA, TOCK_SHA_DATA_BUF, (void*) buffer, len); return tock_allow_ro_return_to_returncode(aval); } -int sha_set_dest_buffer(uint8_t* buffer, uint32_t len) { +returncode_t libtock_sha_set_readwrite_allow_destination_buffer(uint8_t* buffer, uint32_t len) { allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SHA, TOCK_SHA_DEST_BUF, (void*) buffer, len); return tock_allow_rw_return_to_returncode(aval); } -int sha_set_algorithm(uint8_t hash) { +returncode_t libtock_sha_command_set_algorithm(uint8_t hash) { syscall_return_t cval = command(DRIVER_NUM_SHA, TOCK_SHA_SET_ALGORITHM, hash, 0); return tock_command_return_novalue_to_returncode(cval); } -int sha_run(void) { +returncode_t libtock_sha_command_run(void) { syscall_return_t cval = command(DRIVER_NUM_SHA, TOCK_SHA_RUN, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int sha_update(void) { +returncode_t libtock_sha_command_update(void) { syscall_return_t cval = command(DRIVER_NUM_SHA, TOCK_SHA_UPDATE, 0, 0); return tock_command_return_novalue_to_returncode(cval); } -int sha_finish(void) { +returncode_t libtock_sha_command_finish(void) { syscall_return_t cval = command(DRIVER_NUM_SHA, TOCK_SHA_FINISH, 0, 0); return tock_command_return_novalue_to_returncode(cval); } diff --git a/libtock/crypto/syscalls/sha_syscalls.h b/libtock/crypto/syscalls/sha_syscalls.h new file mode 100644 index 000000000..02e0e6acb --- /dev/null +++ b/libtock/crypto/syscalls/sha_syscalls.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SHA 0x40005 + +bool libtock_sha_exists(void); + +returncode_t libtock_sha_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_sha_set_readonly_allow_data_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_sha_set_readwrite_allow_destination_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_sha_command_set_algorithm(uint8_t hash); + +returncode_t libtock_sha_command_run(void); + +returncode_t libtock_sha_command_update(void); + +returncode_t libtock_sha_command_finish(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/dac.c b/libtock/dac.c deleted file mode 100644 index 9a3cab06a..000000000 --- a/libtock/dac.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "dac.h" -#include "tock.h" - -int dac_initialize(void) { - syscall_return_t res = command(DRIVER_NUM_DAC, 1, 0, 0); - return tock_command_return_novalue_to_returncode(res); -} - -int dac_set_value(uint32_t value) { - syscall_return_t res = command(DRIVER_NUM_DAC, 2, value, 0); - return tock_command_return_novalue_to_returncode(res); -} diff --git a/libtock/dac.h b/libtock/dac.h deleted file mode 100644 index 812514c42..000000000 --- a/libtock/dac.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_DAC 0x6 - -// Initialize and enable the DAC. -int dac_initialize(void); - -// Set the DAC to a value. -int dac_set_value(uint32_t value); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/display/screen.c b/libtock/display/screen.c new file mode 100644 index 000000000..fba3b29f6 --- /dev/null +++ b/libtock/display/screen.c @@ -0,0 +1,231 @@ +#include + +#include "screen.h" + +static void screen_callback_done(int status, + __attribute__ ((unused)) int data1, + __attribute__ ((unused)) int data2, + void* opaque) { + libtock_screen_callback_done cb = (libtock_screen_callback_done) opaque; + cb(tock_status_to_returncode(status)); +} + +static void screen_callback_format(int status, + __attribute__ ((unused)) int data1, + __attribute__ ((unused)) int data2, + void* opaque) { + libtock_screen_callback_format cb = (libtock_screen_callback_format) opaque; + cb(tock_status_to_returncode(status), (libtock_screen_format_t) data1); +} + +static void screen_callback_rotation(int status, + __attribute__ ((unused)) int data1, + __attribute__ ((unused)) int data2, + void* opaque) { + libtock_screen_callback_rotation cb = (libtock_screen_callback_rotation) opaque; + cb(tock_status_to_returncode(status), (libtock_screen_rotation_t) data1); +} + + +statuscode_t libtock_screen_buffer_init(size_t len, uint8_t** buffer) { + if (*buffer != NULL) return TOCK_STATUSCODE_ALREADY; + + *buffer = (uint8_t*) calloc(1, len); + if (*buffer == NULL) return TOCK_STATUSCODE_FAIL; + + return TOCK_STATUSCODE_SUCCESS; +} + +int libtock_screen_get_bits_per_pixel(libtock_screen_format_t format) { + switch (format) { + case MONO: + return 1; + + case RGB_233: + return 8; + + case RGB_565: + return 16; + + case RGB_888: + return 24; + + case ARGB_8888: + return 32; + + default: + return 0; + } +} + + + +returncode_t libtock_screen_get_supported_resolutions(uint32_t* resolutions) { + return libtock_screen_command_get_supported_resolutions(resolutions); +} + +returncode_t libtock_screen_get_supported_resolution(size_t index, uint32_t* width, uint32_t* height) { + return libtock_screen_command_get_supported_resolution(index, width, height); +} + +returncode_t libtock_screen_get_supported_pixel_formats(uint32_t* formats) { + return libtock_screen_command_get_supported_pixel_formats(formats); +} + +returncode_t libtock_screen_get_supported_pixel_format(size_t index, libtock_screen_format_t* format) { + returncode_t ret; + uint32_t f; + ret = libtock_screen_command_get_supported_pixel_format(index, &f); + *format = f; + return ret; +} + +bool libtock_screen_setup_enabled(void) { + returncode_t err; + uint32_t enabled; + err = libtock_screen_command_enabled(&enabled); + if (err != RETURNCODE_SUCCESS) return false; + return enabled > 0; +} + +returncode_t libtock_screen_set_brightness(uint32_t brightness, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_set_brightness(brightness); + return ret; +} + +returncode_t libtock_screen_invert_on(libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_invert_on(); + return ret; +} + +returncode_t libtock_screen_invert_off(libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_invert_off(); + return ret; +} + + + +returncode_t libtock_screen_get_resolution(uint32_t* width, uint32_t* height) { + return libtock_screen_command_get_resolution(width, height); +} + +returncode_t libtock_screen_set_resolution(uint32_t width, uint32_t height, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_set_resolution(width, height); + return ret; +} + + + +returncode_t libtock_screen_get_pixel_format(libtock_screen_callback_format cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_format, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_get_pixel_format(); + return ret; +} + +returncode_t libtock_screen_set_pixel_format(libtock_screen_format_t format, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_set_pixel_format((uint32_t) format); + return ret; +} + + +returncode_t libtock_screen_get_rotation(libtock_screen_callback_rotation cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_rotation, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_get_rotation(); + return ret; +} + +returncode_t libtock_screen_set_rotation(libtock_screen_rotation_t rotation, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_set_rotation((uint32_t) rotation); + return ret; +} + + + +returncode_t libtock_screen_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height, + libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_set_frame(x, y, width, height); + return ret; +} + +static returncode_t screen_set_color(uint8_t* buffer, int buffer_len, int position, size_t color) { + // TODO color mode + if (position < buffer_len - 2) { + buffer[position * 2] = (color >> 8) & 0xFF; + buffer[position * 2 + 1] = color & 0xFF; + return RETURNCODE_SUCCESS; + } else { + return RETURNCODE_ESIZE; + } +} + +returncode_t libtock_screen_fill(uint8_t* buffer, int buffer_len, size_t color, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = screen_set_color(buffer, buffer_len, 0, color); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_set_readonly_allow(buffer, buffer_len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_fill(); + return ret; +} + +returncode_t libtock_screen_write(uint8_t* buffer, int buffer_len, size_t length, libtock_screen_callback_done cb) { + returncode_t ret; + + ret = libtock_screen_set_readonly_allow(buffer, buffer_len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_set_upcall(screen_callback_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_screen_command_write(length); + return ret; +} diff --git a/libtock/display/screen.h b/libtock/display/screen.h new file mode 100644 index 000000000..20b30bb86 --- /dev/null +++ b/libtock/display/screen.h @@ -0,0 +1,137 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/screen_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SCREEN 0x90001 + +// Supported pixel formats. +typedef enum { + MONO=0, + RGB_233=1, + RGB_565=2, + RGB_888=3, + ARGB_8888=4, +} libtock_screen_format_t; + +// Supported screen rotations. +typedef enum { + ROTATION_NORMAL=0, + ROTATION_90=1, + ROTATION_180=2, + ROTATION_270=3, +} libtock_screen_rotation_t; + +// Callback when an operation has completed. +// +// This callback is used for several operations, but is generic as it only +// returns the returncode for the operation as provided in the upcall. +typedef void (*libtock_screen_callback_done)(returncode_t); + +// Callback when retrieving the screen pixel format. +// +// The callback is provided the screen format when called. +typedef void (*libtock_screen_callback_format)(returncode_t, libtock_screen_format_t); + +// Callback when retrieving the screen rotation. +// +// The callback includes the rotation angle as an int. +typedef void (*libtock_screen_callback_rotation)(returncode_t, libtock_screen_rotation_t); + + +// INIT + +// Allocate and setup `buffer` with size `len`. +// +// This will allocate len bytes and assign buffer to the array. This buffer can +// be used for drawing the screen. +statuscode_t libtock_screen_buffer_init(size_t len, uint8_t** buffer); + +// QUERY + +// Check if the screen is setup. Returns `true` if the screen is enabled, or +// `false` otherwise. +bool libtock_screen_setup_enabled(void); + +// Get the number of supported resolutions for the screen. +returncode_t libtock_screen_get_supported_resolutions(uint32_t* resolutions); + +// Get a particular resolution based on `index`. `width` and `height` will be +// set with the resolution corresponding to that index. +returncode_t libtock_screen_get_supported_resolution(size_t index, uint32_t* width, uint32_t* height); + +// Get the number or supported pixel formats. +returncode_t libtock_screen_get_supported_pixel_formats(uint32_t* formats); + +// Get the particular format based on `index`. `format` will be set with the +// correct pixel format for that index. +returncode_t libtock_screen_get_supported_pixel_format(size_t index, libtock_screen_format_t* format); + +// POWER + +// Set the brightness. The callback will be called when the brightness is set. +returncode_t libtock_screen_set_brightness(uint32_t brightness, libtock_screen_callback_done cb); + +// Turn on color inversion. The callback will be called when the operation is +// complete. +returncode_t libtock_screen_invert_on(libtock_screen_callback_done cb); + +// Turn off color inversion. The callback will be called when the operation is +// complete. +returncode_t libtock_screen_invert_off(libtock_screen_callback_done cb); + +// PIXEL FORMAT + +// Calculate and return the number of bits per pixel for the given pixel format. +int libtock_screen_get_bits_per_pixel(libtock_screen_format_t format); + +// Get the pixel format. The format will be returned in the callback. +returncode_t libtock_screen_get_pixel_format(libtock_screen_callback_format cb); + +// Set the pixel format. The callback will be called when the format is set. +returncode_t libtock_screen_set_pixel_format(libtock_screen_format_t format, libtock_screen_callback_done cb); + +// RESOLUTION AND ROTATION + +// Get the current resolution of the screen. +returncode_t libtock_screen_get_resolution(uint32_t* width, uint32_t* height); + +// Set the resolution of the screen to the specified width and height. The +// callback will be called when the resolution is set. +returncode_t libtock_screen_set_resolution(uint32_t width, uint32_t height, libtock_screen_callback_done cb); + +// Get the current screen rotation. The rotation will be specified in the +// callback function. +returncode_t libtock_screen_get_rotation(libtock_screen_callback_rotation cb); + +// Set the screen rotation. The callback will be called when the operation +// completes. +returncode_t libtock_screen_set_rotation(libtock_screen_rotation_t rotation, libtock_screen_callback_done cb); + +// DRAWING + +// Set the current drawing frame on the screen. +// +// The frame is specified by the X,Y coordinates as the upper left, and the +// width and height of the frame box. The callback will be called when setting +// the frame is complete. +returncode_t libtock_screen_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height, libtock_screen_callback_done cb); + +// Fill the screen to a given color. +// +// The screen data is in buffer. The callback will be called when the screen is +// finished being filled. +returncode_t libtock_screen_fill(uint8_t* buffer, int buffer_len, size_t color, libtock_screen_callback_done cb); + +// Write the data in buffer to the screen. +// +// The callback will be called when the screen is finished being updated. +returncode_t libtock_screen_write(uint8_t* buffer, int buffer_len, size_t length, libtock_screen_callback_done cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/display/syscalls/screen_syscalls.c b/libtock/display/syscalls/screen_syscalls.c new file mode 100644 index 000000000..229668d1e --- /dev/null +++ b/libtock/display/syscalls/screen_syscalls.c @@ -0,0 +1,102 @@ +#include "screen_syscalls.h" + +bool libtock_screen_exists(void) { + return driver_exists(DRIVER_NUM_SCREEN); +} + +returncode_t libtock_screen_set_upcall(subscribe_upcall cb, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SCREEN, 0, cb, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_screen_set_readonly_allow(const void* ptr, size_t size) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SCREEN, 0, ptr, size); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_screen_command_get_supported_resolutions(uint32_t* resolutions) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 11, 0, 0); + return tock_command_return_u32_to_returncode(cval, resolutions); +} + +returncode_t libtock_screen_command_get_supported_resolution(uint32_t index, uint32_t* width, uint32_t* height) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 12, index, 0); + return tock_command_return_u32_u32_to_returncode(cval, width, height); +} + +returncode_t libtock_screen_command_get_resolution(uint32_t* width, uint32_t* height) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 23, 0, 0); + return tock_command_return_u32_u32_to_returncode(cval, width, height); +} + +returncode_t libtock_screen_command_set_resolution(uint32_t width, uint32_t height) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 24, width, height); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_get_supported_pixel_formats(uint32_t* formats) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 13, 0, 0); + return tock_command_return_u32_to_returncode(cval, formats); +} + +returncode_t libtock_screen_command_get_supported_pixel_format(uint32_t index, uint32_t* format) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 14, index, 0); + return tock_command_return_u32_to_returncode(cval, format); +} + +returncode_t libtock_screen_command_enabled(uint32_t* enabled) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 1, 0, 0); + return tock_command_return_u32_to_returncode(cval, enabled); +} + +returncode_t libtock_screen_command_set_brightness(uint32_t brightness) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 3, brightness, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_invert_on(void) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 4, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_invert_off(void) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 5, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_get_pixel_format(void) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 25, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_set_pixel_format(uint32_t format) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 26, format, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_get_rotation(void) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 21, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_set_rotation(uint32_t rotation) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 22, rotation, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { + uint32_t arg1 = ((x & 0xFFFF) << 16) | (y & 0xFFFF); + uint32_t arg2 = ((width & 0xFFFF) << 16) | (height & 0xFFFF); + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 100, arg1, arg2); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_write(uint32_t length) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 200, length, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_screen_command_fill(void) { + syscall_return_t cval = command(DRIVER_NUM_SCREEN, 300, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/display/syscalls/screen_syscalls.h b/libtock/display/syscalls/screen_syscalls.h new file mode 100644 index 000000000..682eadd97 --- /dev/null +++ b/libtock/display/syscalls/screen_syscalls.h @@ -0,0 +1,74 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SCREEN 0x90001 + +// Check if the screen driver exists. +bool libtock_screen_exists(void); + +// Set the upcall for screen upcalls. +returncode_t libtock_screen_set_upcall(subscribe_upcall cb, void* opaque); + +// Allow a buffer used to write the screen. +returncode_t libtock_screen_set_readonly_allow(const void* ptr, size_t size); + +// Get the number of supported resolutions. +returncode_t libtock_screen_command_get_supported_resolutions(uint32_t* resolutions); + +// Get the supported resolution at the given index. +returncode_t libtock_screen_command_get_supported_resolution(uint32_t index, uint32_t* width, uint32_t* height); + +// Get the current screen resolution. +returncode_t libtock_screen_command_get_resolution(uint32_t* width, uint32_t* height); + +// Set the screen resolution. +returncode_t libtock_screen_command_set_resolution(uint32_t width, uint32_t height); + +// Get the number of supported pixel formats. +returncode_t libtock_screen_command_get_supported_pixel_formats(uint32_t* formats); + +// Get the specific supported pixel format. +returncode_t libtock_screen_command_get_supported_pixel_format(uint32_t index, uint32_t* format); + +// Check if screen is enabled. +returncode_t libtock_screen_command_enabled(uint32_t* enabled); + +// Set the brightness. +returncode_t libtock_screen_command_set_brightness(uint32_t brightness); + +// Invert the screen. +returncode_t libtock_screen_command_invert_on(void); + +// Disable the screen inversion. +returncode_t libtock_screen_command_invert_off(void); + +// Get the current pixel format. +returncode_t libtock_screen_command_get_pixel_format(void); + +// Set the pixel format. +returncode_t libtock_screen_command_set_pixel_format(uint32_t format); + +// Get the current screen rotation. +returncode_t libtock_screen_command_get_rotation(void); + +// Set the screen rotation. +returncode_t libtock_screen_command_set_rotation(uint32_t rotation); + +// Set the current active screen frame. +returncode_t libtock_screen_command_set_frame(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + +// Write the allowed buffer to the screen. +returncode_t libtock_screen_command_write(uint32_t length); + +// Fill the screen from the allowed buffer. +returncode_t libtock_screen_command_fill(void); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/display/syscalls/text_screen_syscalls.c b/libtock/display/syscalls/text_screen_syscalls.c new file mode 100644 index 000000000..b142d5ddf --- /dev/null +++ b/libtock/display/syscalls/text_screen_syscalls.c @@ -0,0 +1,66 @@ +#include "text_screen_syscalls.h" + +returncode_t libtock_text_screen_set_upcall(subscribe_upcall callback, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_TEXT_SCREEN, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_text_screen_set_readonly_allow(const uint8_t* ptr, uint32_t size) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_TEXT_SCREEN, 0, ptr, size); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_text_screen_command_get_size(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_on(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 2, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_off(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 3, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_blink_on(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 4, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_blink_off(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 5, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_show_cursor(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 6, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_hide_cursor(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 7, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_write(uint32_t len) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 8, len, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_clear(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 9, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_home(void) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 10, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_text_screen_command_set_cursor(uint32_t col, uint32_t row) { + syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, 11, col, row); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/display/syscalls/text_screen_syscalls.h b/libtock/display/syscalls/text_screen_syscalls.h new file mode 100644 index 000000000..116ab1b03 --- /dev/null +++ b/libtock/display/syscalls/text_screen_syscalls.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_TEXT_SCREEN 0x90003 + +returncode_t libtock_text_screen_set_upcall(subscribe_upcall callback, void *opaque); + +returncode_t libtock_text_screen_set_readonly_allow(const uint8_t* ptr, uint32_t size); + +returncode_t libtock_text_screen_command_get_size(void); + +returncode_t libtock_text_screen_command_on(void); + +returncode_t libtock_text_screen_command_off(void); + +returncode_t libtock_text_screen_command_blink_on(void); + +returncode_t libtock_text_screen_command_blink_off(void); + +returncode_t libtock_text_screen_command_show_cursor(void); + +returncode_t libtock_text_screen_command_hide_cursor(void); + +returncode_t libtock_text_screen_command_write(uint32_t len); + +returncode_t libtock_text_screen_command_clear(void); + +returncode_t libtock_text_screen_command_home(void); + +returncode_t libtock_text_screen_command_set_cursor(uint32_t col, uint32_t row); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/display/text_screen.c b/libtock/display/text_screen.c new file mode 100644 index 000000000..c0c53ef5e --- /dev/null +++ b/libtock/display/text_screen.c @@ -0,0 +1,131 @@ +#include "text_screen.h" + +static void text_screen_callback(int status, + __attribute__ ((unused)) int data1, + __attribute__ ((unused)) int data2, + void* opaque) { + libtock_text_screen_callback_done cb = (libtock_text_screen_callback_done) opaque; + cb(tock_status_to_returncode(status)); +} + +static void text_screen_callback_size(int status, + int data1, + int data2, + void* opaque) { + libtock_text_screen_callback_size cb = (libtock_text_screen_callback_size) opaque; + cb(tock_status_to_returncode(status), (uint32_t) data1, (uint32_t) data2); +} + +returncode_t libtock_text_screen_display_on (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_on(); + return err; +} + +returncode_t libtock_text_screen_display_off (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_off(); + return err; +} + +returncode_t libtock_text_screen_blink_on (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_blink_on(); + return err; +} + +returncode_t libtock_text_screen_blink_off (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_blink_off(); + return err; +} + +returncode_t libtock_text_screen_show_cursor (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_show_cursor(); + return err; +} + +returncode_t libtock_text_screen_hide_cursor (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_hide_cursor(); + return err; +} + +returncode_t libtock_text_screen_clear (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_clear(); + return err; +} + +returncode_t libtock_text_screen_home (libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_home(); + return err; +} + +returncode_t libtock_text_screen_set_cursor (uint8_t col, uint8_t row, libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_set_cursor((uint8_t) col, (uint8_t) row); + return err; +} + +returncode_t libtock_text_screen_write (uint8_t* buffer, uint32_t buffer_len, uint32_t write_len, + libtock_text_screen_callback_done cb) { + returncode_t err; + + err = libtock_text_screen_set_readonly_allow(buffer, buffer_len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_set_upcall(text_screen_callback, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_write(write_len); + return err; +} + +returncode_t libtock_text_screen_get_size (libtock_text_screen_callback_size cb) { + returncode_t err; + + err = libtock_text_screen_set_upcall(text_screen_callback_size, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_text_screen_command_get_size(); + return err; +} diff --git a/libtock/display/text_screen.h b/libtock/display/text_screen.h new file mode 100644 index 000000000..6026a87f6 --- /dev/null +++ b/libtock/display/text_screen.h @@ -0,0 +1,49 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/text_screen_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_TEXT_SCREEN 0x90003 + +// Callback when an operation has completed. +// +// This callback is used for several operations, but is generic as it only +// returns the returncode for the operation as provided in the upcall. +typedef void (*libtock_text_screen_callback_done)(returncode_t); + +// Callback with size. +// +// - `arg1` (`returncode_t`): Status of getting the size. +// - `arg2` (`uint32_t`): Width of display. +// - `arg3` (`uint32_t`): Height of display. +typedef void (*libtock_text_screen_callback_size)(returncode_t, uint32_t, uint32_t); + +returncode_t libtock_text_screen_display_on (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_display_off (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_blink_on (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_blink_off (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_show_cursor (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_hide_cursor (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_clear (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_home (libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_set_cursor (uint8_t col, uint8_t row, libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_write (uint8_t* buffer, uint32_t buffer_len, uint32_t write_len, libtock_text_screen_callback_done cb); + +returncode_t libtock_text_screen_get_size (libtock_text_screen_callback_size cb); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock/eui64.h b/libtock/eui64.h deleted file mode 100644 index 2579e28c2..000000000 --- a/libtock/eui64.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_EUI64 0x30006 -#define EUI64_CMD_GETTER 1 - -bool libtock_eui64_exists(void); -returncode_t libtock_eui64_command_get(uint64_t *eui64); - -// Obtain eui64 as `uint64_t` if supported. -returncode_t libtock_eui64_get(uint64_t *eui64); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/gpio.c b/libtock/gpio.c deleted file mode 100644 index 9da78b22e..000000000 --- a/libtock/gpio.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "gpio.h" - -bool gpio_exists(void) { - return driver_exists(GPIO_DRIVER_NUM); -} - -int gpio_enable_output(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 1, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_set(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 2, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_clear(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 3, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_toggle(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 4, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_enable_input(GPIO_Pin_t pin, GPIO_InputMode_t pin_config) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 5, pin, pin_config); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_read(GPIO_Pin_t pin, int* pin_value) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 6, pin, 0); - return tock_command_return_u32_to_returncode(rval, (uint32_t*) pin_value); -} - -int gpio_enable_interrupt(GPIO_Pin_t pin, GPIO_InterruptMode_t irq_config) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 7, pin, irq_config); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_disable_interrupt(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 8, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_disable(GPIO_Pin_t pin) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 9, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int gpio_count(int* count) { - syscall_return_t rval = command(GPIO_DRIVER_NUM, 10, 0, 0); - return tock_command_return_u32_to_returncode(rval, (uint32_t*) count); -} - -int gpio_interrupt_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(GPIO_DRIVER_NUM, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} diff --git a/libtock/gpio.h b/libtock/gpio.h deleted file mode 100644 index 23be7a34e..000000000 --- a/libtock/gpio.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define GPIO_DRIVER_NUM 0x4 - -// GPIO pins exposed to userspace are defined in platform definitions. The index -// of each pin in the array corresponds to the value of GPIO_Pin_t in userspace. -// For example, on imix board, pin8's GPIO_Pin_t value is 6. -typedef uint32_t GPIO_Pin_t; - -typedef enum { - PullNone=0, - PullUp, - PullDown, -} GPIO_InputMode_t; - -typedef enum { - Change=0, - RisingEdge, - FallingEdge, -} GPIO_InterruptMode_t; - -// Returns the number of GPIO pins configured on the board. -int gpio_count(int* count); - -bool gpio_exists(void); -int gpio_enable_output(GPIO_Pin_t pin); -int gpio_set(GPIO_Pin_t pin); -int gpio_clear(GPIO_Pin_t pin); -int gpio_toggle(GPIO_Pin_t pin); -int gpio_enable_input(GPIO_Pin_t pin, GPIO_InputMode_t pin_config); -int gpio_read(GPIO_Pin_t pin, int* pin_value); -int gpio_enable_interrupt(GPIO_Pin_t pin, GPIO_InterruptMode_t irq_config); -int gpio_disable_interrupt(GPIO_Pin_t pin); -int gpio_disable(GPIO_Pin_t pin); -int gpio_interrupt_callback(subscribe_upcall callback, void* callback_args); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/gpio_async.c b/libtock/gpio_async.c deleted file mode 100644 index 19fab8744..000000000 --- a/libtock/gpio_async.c +++ /dev/null @@ -1,226 +0,0 @@ -#include "gpio_async.h" -#include "tock.h" - -#define CONCAT_PORT_DATA(port, data) (((data & 0xFFFF) << 16) | (port & 0xFFFF)) - - -struct gpio_async_data { - bool fired; - int value; - int callback_type; -}; - -static struct gpio_async_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void gpio_async_upcall(__attribute__ ((unused)) int callback_type, - __attribute__ ((unused)) int value, - __attribute__ ((unused)) int unused, - void* ud) { - struct gpio_async_data* myresult = (struct gpio_async_data*) ud; - myresult->callback_type = callback_type; - myresult->value = value; - myresult->fired = true; -} - - -int gpio_async_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sub = subscribe(DRIVER_NUM_GPIO_ASYNC, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sub); -} - -int gpio_async_make_output(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 1, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_set(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 2, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_clear(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 3, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_toggle(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 4, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_make_input(uint32_t port, uint8_t pin, GPIO_InputMode_t pin_config) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 5, pin, CONCAT_PORT_DATA(port, pin_config)); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_read(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 6, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_enable_interrupt(uint32_t port, uint8_t pin, GPIO_InterruptMode_t irq_config) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 7, pin, CONCAT_PORT_DATA(port, irq_config)); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_disable_interrupt(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 8, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_disable(uint32_t port, uint8_t pin) { - syscall_return_t com = command(DRIVER_NUM_GPIO_ASYNC, 9, pin, port); - return tock_command_return_novalue_to_returncode(com); -} - -int gpio_async_interrupt_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sub = subscribe(DRIVER_NUM_GPIO_ASYNC, 1, callback, callback_args); - return tock_subscribe_return_to_returncode(sub); -} - - - -int gpio_async_make_output_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_make_output(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_set_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_set(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_clear_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_clear(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_toggle_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_toggle(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_make_input_sync(uint32_t port, uint8_t pin, GPIO_InputMode_t pin_config) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_make_input(port, pin, pin_config); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_read_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_read(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_enable_interrupt_sync(uint32_t port, uint8_t pin, GPIO_InterruptMode_t irq_config) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_enable_interrupt(port, pin, irq_config); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_disable_interrupt_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_disable_interrupt(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} - -int gpio_async_disable_sync(uint32_t port, uint8_t pin) { - int err; - result.fired = false; - - err = gpio_async_set_callback(gpio_async_upcall, (void*) &result); - if (err < 0) return err; - - err = gpio_async_disable(port, pin); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return result.value; -} diff --git a/libtock/gpio_async.h b/libtock/gpio_async.h deleted file mode 100644 index 084830be2..000000000 --- a/libtock/gpio_async.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "gpio.h" -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_GPIO_ASYNC 0x80003 - -// Callback for operation done events. -// int arg1: callback type -// int arg2: optional value -// int arg3: unused -int gpio_async_set_callback (subscribe_upcall callback, void* callback_args); - -// Callback for when GPIO interrupts occur. -// int arg1: port number -// int arg2: pin number -// int arg3: unused -int gpio_async_interrupt_callback(subscribe_upcall callback, void* callback_args); - -int gpio_async_make_output(uint32_t port, uint8_t pin); -int gpio_async_set(uint32_t port, uint8_t pin); -int gpio_async_clear(uint32_t port, uint8_t pin); -int gpio_async_toggle(uint32_t port, uint8_t pin); -int gpio_async_make_input(uint32_t port, uint8_t pin, GPIO_InputMode_t pin_config); -int gpio_async_read(uint32_t port, uint8_t pin); -int gpio_async_enable_interrupt(uint32_t port, uint8_t pin, GPIO_InterruptMode_t irq_config); -int gpio_async_disable_interrupt(uint32_t port, uint8_t pin); -int gpio_async_disable(uint32_t port, uint8_t pin); - -// Synchronous Versions -int gpio_async_make_output_sync(uint32_t port, uint8_t pin); -int gpio_async_set_sync(uint32_t port, uint8_t pin); -int gpio_async_clear_sync(uint32_t port, uint8_t pin); -int gpio_async_toggle_sync(uint32_t port, uint8_t pin); -int gpio_async_make_input_sync(uint32_t port, uint8_t pin, GPIO_InputMode_t pin_config); -int gpio_async_read_sync(uint32_t port, uint8_t pin); -int gpio_async_enable_interrupt_sync(uint32_t port, uint8_t pin, GPIO_InterruptMode_t irq_config); -int gpio_async_disable_interrupt_sync(uint32_t port, uint8_t pin); -int gpio_async_disable_sync(uint32_t port, uint8_t pin); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/hmac.h b/libtock/hmac.h deleted file mode 100644 index cfff660e4..000000000 --- a/libtock/hmac.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define TOCK_HMAC_ALG_SHA256 0 -#define TOCK_HMAC_ALG_SHA384 1 -#define TOCK_HMAC_ALG_SHA512 2 - -int hmac_set_callback (subscribe_upcall callback, void* callback_args); - -int hmac_set_key_buffer(const uint8_t* buffer, uint32_t len); -int hmac_set_data_buffer(const uint8_t* buffer, uint32_t len); -int hmac_set_dest_buffer(uint8_t* buffer, uint32_t len); - -int hmac_set_algorithm(uint8_t hash); -int hmac_run(void); -int hmac_update(void); -int hmac_finish(void); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/humidity.c b/libtock/humidity.c deleted file mode 100644 index 35797b7b8..000000000 --- a/libtock/humidity.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "humidity.h" -#include "tock.h" - -struct data { - bool fired; - int humidity; -}; - -static struct data result = { .fired = false }; - -// Internal upcall for faking synchronous reads -static void humidity_upcall(int humidity, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - void* ud) { - struct data* data = (struct data*) ud; - data->humidity = humidity; - data->fired = true; -} - -bool humidity_exists(void) { - return driver_exists(DRIVER_NUM_HUMIDITY); -} - -int humidity_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_HUMIDITY, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int humidity_read(void) { - syscall_return_t rval = command(DRIVER_NUM_HUMIDITY, 1, 0, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int humidity_read_sync(unsigned* humidity) { - int err; - result.fired = false; - - err = humidity_set_callback(humidity_upcall, (void*) &result); - if (err < 0) return err; - - err = humidity_read(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *humidity = result.humidity; - - return 0; -} diff --git a/libtock/humidity.h b/libtock/humidity.h deleted file mode 100644 index 3854d82d8..000000000 --- a/libtock/humidity.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_HUMIDITY 0x60001 - -// check if humidity sensor exists -bool humidity_exists(void); - -// units: humidity in hundredths of percent. - -// function to be called when the humidity measurement is finished -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int humidity_set_callback (subscribe_upcall callback, void* callback_args); - -// initiate an humidity measurement used both for synchronous and asynchronous readings -int humidity_read(void); - -// initiate a synchronous humidity measurement -// -// humi - pointer/address where the result of the humidity reading should be stored -int humidity_read_sync (unsigned* humi); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/ieee802154.c b/libtock/ieee802154.c deleted file mode 100644 index a239bd2f4..000000000 --- a/libtock/ieee802154.c +++ /dev/null @@ -1,758 +0,0 @@ -#include - -#include "ieee802154.h" -#include "timer.h" - -const int RADIO_DRIVER = 0x30001; - -const int ALLOW_RX = 0; -const int ALLOW_CFG = 1; - -const int ALLOW_RO_TX = 0; - -const int SUBSCRIBE_RX = 0; -const int SUBSCRIBE_TX = 1; - -const int COMMAND_STATUS = 1; -const int COMMAND_SET_ADDR = 2; -const int COMMAND_SET_ADDR_LONG = 3; -const int COMMAND_SET_PAN = 4; -const int COMMAND_SET_CHANNEL = 5; -const int COMMAND_SET_POWER = 6; -const int COMMAND_CONFIG_COMMIT = 7; - -const int COMMAND_GET_ADDR = 8; -const int COMMAND_GET_ADDR_LONG = 9; -const int COMMAND_GET_PAN = 10; -const int COMMAND_GET_CHANNEL = 11; -const int COMMAND_GET_POWER = 12; - -const int COMMAND_MAX_NEIGHBORS = 13; -const int COMMAND_NUM_NEIGHBORS = 14; -const int COMMAND_GET_NEIGHBOR_ADDR = 15; -const int COMMAND_GET_NEIGHBOR_ADDR_LONG = 16; -const int COMMAND_ADD_NEIGHBOR = 17; -const int COMMAND_REMOVE_NEIGHBOR = 18; - -const int COMMAND_MAX_KEYS = 19; -const int COMMAND_NUM_KEYS = 20; -const int COMMAND_GET_KEY_LEVEL = 21; -const int COMMAND_GET_KEY_ID = 22; -const int COMMAND_GET_KEY = 23; -const int COMMAND_ADD_KEY = 24; -const int COMMAND_REMOVE_KEY = 25; - -const int COMMAND_SEND = 26; -const int COMMAND_SEND_RAW = 27; - - -// Temporary buffer used for some commands where the system call interface -// parameters / return codes are not enough te contain the required data. -unsigned char BUF_CFG[27]; - -bool ieee802154_driver_exists(void) { - return driver_exists(RADIO_DRIVER); -} - -int ieee802154_up(void) { - // Spin until radio is on. Maybe this can be done with a callback? - while (!ieee802154_is_up()) { - delay_ms(10); - } - delay_ms(10); // without this delay, immediate calls to send can still fail. - return RETURNCODE_SUCCESS; -} - -int ieee802154_down(void) { - // Currently unsupported: there is no way to implement this with the existing - // radio interface. - return RETURNCODE_ENOSUPPORT; -} - -bool ieee802154_is_up(void) { - return command(RADIO_DRIVER, COMMAND_STATUS, 0, 0).type == TOCK_SYSCALL_SUCCESS; -} - -int ieee802154_set_address(unsigned short addr) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SET_ADDR, (unsigned int) addr, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_set_address_long(unsigned char *addr_long) { - if (!addr_long) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) addr_long, 8); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SET_ADDR_LONG, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_set_pan(unsigned short pan) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SET_PAN, (unsigned int) pan, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_set_channel(unsigned char channel) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SET_CHANNEL, (unsigned int) channel, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_set_power(char power) { - // Cast the signed char to an unsigned char before zero-padding it. - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SET_POWER, (unsigned int) (unsigned char) power, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_config_commit(void) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_CONFIG_COMMIT, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_get_address(unsigned short *addr) { - if (!addr) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_ADDR, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) addr); - - // Driver adds 1 to make the value positive. - *addr -= 1; - - return ret; -} - -int ieee802154_get_address_long(unsigned char *addr_long) { - if (!addr_long) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) addr_long, 8); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_ADDR_LONG, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_get_pan(unsigned short *pan) { - if (!pan) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_PAN, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) pan); - - // Driver adds 1 to make the value positive. - *pan -= 1; - - return ret; -} - -int ieee802154_get_channel(unsigned char *channel) { - if (!channel) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_PAN, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) channel); - - // Driver adds 1 to make the value positive. - *channel -= 1; - - return ret; -} - -int ieee802154_get_power(char *power) { - if (!power) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_POWER, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) power); - - // Driver adds 1 to the power after casting it to unsigned, so this works - *power -= 1; - - return ret; -} - -int ieee802154_max_neighbors(int* neighbors) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_MAX_NEIGHBORS, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) neighbors); - - // Driver adds 1 to the power after casting it to unsigned, so this works - *neighbors -= 1; - - return ret; -} - -int ieee802154_num_neighbors(int* neighbors) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_NUM_NEIGHBORS, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) neighbors); - - // Driver adds 1 to the power after casting it to unsigned, so this works - *neighbors -= 1; - - return ret; -} - -int ieee802154_get_neighbor_address(unsigned index, unsigned short *addr) { - if (!addr) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_NEIGHBOR_ADDR, (unsigned int) index, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) addr); - - // Driver adds 1 to ensure it is positive. - *addr -= 1; - - return ret; -} - -int ieee802154_get_neighbor_address_long(unsigned index, unsigned char *addr_long) { - if (!addr_long) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) addr_long, 8); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_NEIGHBOR_ADDR_LONG, (unsigned int) index, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_get_neighbor(unsigned index, - unsigned short *addr, - unsigned char * addr_long) { - int err = ieee802154_get_neighbor_address(index, addr); - if (err < 0) return err; - return ieee802154_get_neighbor_address_long(index, addr_long); -} - -int ieee802154_add_neighbor(unsigned short addr, unsigned char *addr_long, unsigned *index) { - if (!addr_long) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) addr_long, 8); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_ADD_NEIGHBOR, (unsigned int) addr, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) index); - - // Driver adds 1 to ensure it is positive. - *index -= 1; - - return ret; -} - -int ieee802154_remove_neighbor(unsigned index) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_REMOVE_NEIGHBOR, (unsigned int) index, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_max_keys(int* keys) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_MAX_KEYS, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) keys); - - // Driver adds 1 to ensure it is positive. - *keys -= 1; - - return ret; -} - -int ieee802154_num_keys(int* keys) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_NUM_KEYS, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) keys); - - // Driver adds 1 to ensure it is positive. - *keys -= 1; - - return ret; -} - -int ieee802154_get_key_security_level(unsigned index, security_level_t *level) { - if (!level) return RETURNCODE_EINVAL; - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_KEY_LEVEL, (unsigned int) index, 0); - int store_u32 = 0; - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) store_u32); - - if (ret == RETURNCODE_SUCCESS) { - // Driver adds 1 to ensure it is positive. - store_u32 -= 1; - *level = store_u32; - } - - return ret; -} - -int ieee802154_key_id_bytes(key_id_mode_t key_id_mode) { - switch (key_id_mode) { - default: - case KEY_ID_IMPLICIT: - return 0; - case KEY_ID_INDEX: - return 1; - case KEY_ID_SRC_4_INDEX: - return 5; - case KEY_ID_SRC_8_INDEX: - return 9; - } -} - -int ieee802154_get_key_id(unsigned index, - key_id_mode_t *key_id_mode, - unsigned char *key_id) { - if (!key_id_mode || !key_id) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) BUF_CFG, 10); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_KEY_ID, (unsigned int) index, 0); - int ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - *key_id_mode = (key_id_mode_t) (BUF_CFG[0]); - memcpy(key_id, BUF_CFG + 1, ieee802154_key_id_bytes(*key_id_mode)); - } - - return ret; -} - -int ieee802154_get_key(unsigned index, unsigned char *key) { - if (!key) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) key, 16); - if (!rw.success) return tock_status_to_returncode(rw.status); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_GET_KEY, (unsigned int) index, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ieee802154_get_key_desc(unsigned index, - security_level_t *level, - key_id_mode_t * key_id_mode, - unsigned char * key_id, - unsigned char * key) { - int err = ieee802154_get_key_security_level(index, level); - if (err < 0) return err; - err = ieee802154_get_key_id(index, key_id_mode, key_id); - if (err < 0) return err; - return ieee802154_get_key(index, key); -} - -int ieee802154_add_key(security_level_t level, - key_id_mode_t key_id_mode, - unsigned char * key_id, - unsigned char * key, - unsigned * index) { - if (!key) return RETURNCODE_EINVAL; - - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) BUF_CFG, 27); - if (!rw.success) return tock_status_to_returncode(rw.status); - - BUF_CFG[0] = level; - BUF_CFG[1] = key_id_mode; - int bytes = ieee802154_key_id_bytes(key_id_mode); - if (bytes > 0) { - memcpy(BUF_CFG + 2, key_id, bytes); - } - memcpy(BUF_CFG + 2 + 9, key, 16); - - syscall_return_t com = command(RADIO_DRIVER, COMMAND_ADD_KEY, 0, 0); - int ret = tock_command_return_u32_to_returncode(com, (uint32_t*) index); - - // Driver adds 1 to ensure it is positive. - *index -= 1; - - return ret; -} - -int ieee802154_remove_key(unsigned index) { - syscall_return_t com = command(RADIO_DRIVER, COMMAND_REMOVE_KEY, (unsigned int) index, 0); - return tock_command_return_novalue_to_returncode(com); -} - -// Internal callback for transmission -static int tx_result; -static int tx_acked; -static void tx_done_callback(int status, - int acked, - __attribute__ ((unused)) int arg3, - void* ud) { - tx_result = tock_status_to_returncode(status); - tx_acked = acked; - *((bool*) ud) = true; -} - -int ieee802154_send(unsigned short addr, - security_level_t level, - key_id_mode_t key_id_mode, - unsigned char * key_id, - const char * payload, - unsigned char len) { - // Setup parameters in ALLOW_CFG and ALLOW_RO_TX - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_CFG, (void *) BUF_CFG, 11); - if (!rw.success) return tock_status_to_returncode(rw.status); - - BUF_CFG[0] = level; - BUF_CFG[1] = key_id_mode; - int bytes = ieee802154_key_id_bytes(key_id_mode); - if (bytes > 0) { - memcpy(BUF_CFG + 2, key_id, bytes); - } - allow_ro_return_t ro = allow_readonly(RADIO_DRIVER, ALLOW_RO_TX, (void *) payload, len); - if (!ro.success) return tock_status_to_returncode(ro.status); - - // Subscribe to the transmit callback - bool tx_done = false; - subscribe_return_t sub = subscribe(RADIO_DRIVER, SUBSCRIBE_TX, - tx_done_callback, (void *) &tx_done); - if (!sub.success) return tock_status_to_returncode(sub.status); - - // Issue the send command and wait for the transmission to be done. - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SEND, (unsigned int) addr, 0); - int ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&tx_done); - if (tx_result != RETURNCODE_SUCCESS) { - return tx_result; - } else if (tx_acked == 0) { - return RETURNCODE_ENOACK; - } - - return RETURNCODE_SUCCESS; -} - -int ieee802154_send_raw( - const char * payload, - unsigned char len) { - // Setup parameters in ALLOW_RO_TX - allow_ro_return_t ro = allow_readonly(RADIO_DRIVER, ALLOW_RO_TX, (void *) payload, len); - if (!ro.success) return tock_status_to_returncode(ro.status); - - // Subscribe to the transmit callback - bool tx_done = false; - subscribe_return_t sub = subscribe(RADIO_DRIVER, SUBSCRIBE_TX, - tx_done_callback, (void *) &tx_done); - if (!sub.success) return tock_status_to_returncode(sub.status); - - // Issue the send command and wait for the transmission to be done. - syscall_return_t com = command(RADIO_DRIVER, COMMAND_SEND_RAW, 0, 0); - int ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&tx_done); - if (tx_result != RETURNCODE_SUCCESS) { - return tx_result; - } else if (tx_acked == 0) { - return RETURNCODE_ENOACK; - } - - return RETURNCODE_SUCCESS; -} - - - -// Internal callback for receive -static void rx_done_callback(__attribute__ ((unused)) int pans, - __attribute__ ((unused)) int dst_addr, - __attribute__ ((unused)) int src_addr, - void* ud) { - reset_ring_buf(NULL, NULL, NULL); - *((bool*) ud) = true; -} - -int ieee802154_receive_sync(const ieee802154_rxbuf *frame) { - // Provide the buffer to the kernel - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_RX, (void *) frame, IEEE802154_RING_BUFFER_LEN); - if (!rw.success) return tock_status_to_returncode(rw.status); - - // Subscribe to the received callback - bool rx_done = false; - subscribe_return_t sub = subscribe(RADIO_DRIVER, SUBSCRIBE_RX, rx_done_callback, (void *) &rx_done); - if (!sub.success) return tock_status_to_returncode(sub.status); - - // Wait for a frame - yield_for(&rx_done); - return RETURNCODE_SUCCESS; -} - -// must be called before accessing the contents of the "allowed" receive buffer -bool ieee802154_unallow_rx_buf(void) { - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_RX, NULL, 0); - return rw.success; -} - -bool reset_ring_buf(const ieee802154_rxbuf* frame, subscribe_upcall callback, void* ud) { - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_RX, (void *) frame, - (frame) ? IEEE802154_RING_BUFFER_LEN : 0); - subscribe_return_t sub = subscribe(RADIO_DRIVER, SUBSCRIBE_RX, callback, ud); - return rw.success && sub.success; -} - -char* ieee802154_read_next_frame(const ieee802154_rxbuf* frame) { - if (!frame) return NULL; - - char *rx_buf = (char *) frame; - int read_index = rx_buf[0]; - int write_index = rx_buf[1]; - if (read_index == write_index) { - return NULL; - } - rx_buf[0]++; - if (rx_buf[0] >= IEEE802154_MAX_RING_BUF_FRAMES) { - rx_buf[0] = 0; - } - return &rx_buf[IEEE802154_RING_BUF_META_LEN + (read_index * IEEE802154_FRAME_LEN)]; -} - -int ieee802154_receive(subscribe_upcall callback, - const ieee802154_rxbuf* frame, - void* ud) { - - // Provide the buffer to the kernel - allow_rw_return_t rw = allow_readwrite(RADIO_DRIVER, ALLOW_RX, (void *) frame, IEEE802154_RING_BUFFER_LEN); - if (!rw.success) return tock_status_to_returncode(rw.status); - - subscribe_return_t sub = subscribe(RADIO_DRIVER, SUBSCRIBE_RX, callback, ud); - return tock_subscribe_return_to_returncode(sub); -} - -int ieee802154_frame_get_length(const char *frame) { - if (!frame) return 0; - // data_offset + data_len - 2 header bytes - return frame[0] + frame[1] - 2; -} - -int ieee802154_frame_get_payload_offset(const char *frame) { - if (!frame) return 0; - return frame[0]; -} - -int ieee802154_frame_get_payload_length(const char *frame) { - if (!frame) return 0; - return frame[1]; -} - -// Utility function to determine if the source and destination PAN and -// addresses are present depending on the frame control field. This is used -// only internally as a header parsing subroutine. Supports only 2003, 2006 or -// 2015 frame versions. Returns false if the addressing mode combination is -// invalid or the frame version is not supported. All out-parameters must be -// provided. -// -// If the source pan is dropped, that means that it is the same as the -// destination pan, which must be present. -static bool ieee802154_get_addressing(uint16_t frame_control, - bool * dst_pan_present, - addr_mode_t *dst_mode, - bool * src_pan_present, - bool * src_pan_dropped, - addr_mode_t *src_mode) { - if (!dst_pan_present || !dst_mode || !src_pan_present || !src_pan_dropped || - !src_mode) { - return false; - } - - typedef enum { - VERSION_2003 = 0x0, - VERSION_2006 = 0x1, - VERSION_2015 = 0x2, - } version_t; - - // Fields that determine if the PANs are present - version_t version = (version_t) ((frame_control >> 12) & 0x3); - *dst_mode = (addr_mode_t) ((frame_control >> 10) & 0x3); - *src_mode = (addr_mode_t) ((frame_control >> 14) & 0x3); - bool pan_id_compression = (frame_control >> 6) & 0x1; - bool dst_present = dst_mode != ADDR_NONE; - bool src_present = src_mode != ADDR_NONE; - - // The flags that we are trying to determine - *src_pan_dropped = false; - - // IEEE 802.15.4: Section 7.2.1.5 determines whether the PANs are present - // depending on the pan ID compression field and the addressing modes. - if (version == VERSION_2015) { - if (dst_present) { - if (src_present) { - *src_pan_dropped = pan_id_compression; - *dst_pan_present = true; - *src_pan_present = !pan_id_compression; - } else { - *dst_pan_present = !pan_id_compression; - *src_pan_present = false; - } - } else { - if (src_present) { - *dst_pan_present = false; - *src_pan_present = !pan_id_compression; - } else { - *dst_pan_present = pan_id_compression; - *src_pan_present = false; - } - } - } else if (version == VERSION_2003 || version == VERSION_2006) { - *src_pan_dropped = pan_id_compression; - *dst_pan_present = dst_present; - *src_pan_present = src_present && !src_pan_dropped; - } else { - return false; - } - - // Check validity of addressing modes - if (*src_pan_dropped && !*dst_pan_present) { - return 0xff; - } - - return true; -} - -// Utility function to obtain the frame control field from a frame -static void ieee802154_get_frame_control(const char *frame, uint16_t *frame_control) { - if (!frame || !frame_control) return; - *frame_control = ((uint16_t) frame[IEEE802154_FRAME_META_LEN]) | - (((uint16_t) frame[IEEE802154_FRAME_META_LEN + 1]) << 8); -} - -// Utility function to obtain the address offset from a frame -static void ieee802154_get_addr_offset(const char *frame, uint16_t *addr_offset, uint16_t *frame_control, - const uint16_t *SEQ_SUPPRESSED) { - if (!frame || !addr_offset || !frame_control || !SEQ_SUPPRESSED) return; - *addr_offset = ((*frame_control & *SEQ_SUPPRESSED) ? 2 : 3) + IEEE802154_FRAME_META_LEN; -} - -addr_mode_t ieee802154_frame_get_dst_addr(__attribute__ ((unused)) const char * frame, - __attribute__ ((unused)) unsigned short *short_addr, - __attribute__ ((unused)) unsigned char * long_addr) { - if (!frame) return ADDR_NONE; - - uint16_t frame_control; - ieee802154_get_frame_control(frame, &frame_control); - - bool dst_pan_present, src_pan_present, src_pan_dropped; - addr_mode_t dst_mode, src_mode; - if (!ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, - &src_pan_present, &src_pan_dropped, &src_mode)) { - return ADDR_NONE; - } - - // The addressing fields are after the sequence number, which can be ommitted - const uint16_t SEQ_SUPPRESSED = 0x0100; - uint16_t addr_offset; - ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); - - if (dst_pan_present) addr_offset += 2; - - if (dst_mode == ADDR_SHORT && short_addr) { - *short_addr = ((unsigned short) frame[addr_offset]) | - (((unsigned short) frame[addr_offset + 1]) << 8); - } - if (dst_mode == ADDR_LONG && long_addr) { - int i; - for (i = 0; i < 8; i++) { - long_addr[i] = frame[addr_offset + 7 - i]; - } - } - - return dst_mode; -} - -addr_mode_t ieee802154_frame_get_src_addr(__attribute__ ((unused)) const char * frame, - __attribute__ ((unused)) unsigned short *short_addr, - __attribute__ ((unused)) unsigned char * long_addr) { - if (!frame) return ADDR_NONE; - - uint16_t frame_control; - ieee802154_get_frame_control(frame, &frame_control); - - bool dst_pan_present, src_pan_present, src_pan_dropped; - addr_mode_t dst_mode, src_mode; - if (!ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, - &src_pan_present, &src_pan_dropped, &src_mode)) { - return ADDR_NONE; - } - - // The addressing fields are after the sequence number, which can be ommitted - const uint16_t SEQ_SUPPRESSED = 0x0100; - uint16_t addr_offset; - ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); - - if (dst_pan_present) addr_offset += 2; - if (dst_mode == ADDR_SHORT) { - addr_offset += 2; - } else if (dst_mode == ADDR_LONG) { - addr_offset += 8; - } - if (src_pan_present) addr_offset += 2; - - if (src_mode == ADDR_SHORT && short_addr) { - *short_addr = ((unsigned short) frame[addr_offset]) | - (((unsigned short) frame[addr_offset + 1]) << 8); - } - if (src_mode == ADDR_LONG && long_addr) { - int i; - for (i = 0; i < 8; i++) { - long_addr[i] = frame[addr_offset + 7 - i]; - } - } - - return src_mode; -} - -bool ieee802154_frame_get_dst_pan(__attribute__ ((unused)) const char * frame, - __attribute__ ((unused)) unsigned short *pan) { - if (!frame) return false; - - uint16_t frame_control; - ieee802154_get_frame_control(frame, &frame_control); - - bool dst_pan_present, src_pan_present, src_pan_dropped; - addr_mode_t dst_mode, src_mode; - if (!ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, - &src_pan_present, &src_pan_dropped, &src_mode)) { - return false; - } - - // The addressing fields are after the sequence number, which can be ommitted - const uint16_t SEQ_SUPPRESSED = 0x0100; - uint16_t addr_offset; - ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); - - if (dst_pan_present && pan) { - *pan = ((unsigned short) frame[addr_offset]) | - (((unsigned short) frame[addr_offset + 1]) << 8); - } - - return dst_pan_present; -} - -bool ieee802154_frame_get_src_pan(__attribute__ ((unused)) const char * frame, - __attribute__ ((unused)) unsigned short *pan) { - if (!frame) return false; - - uint16_t frame_control; - ieee802154_get_frame_control(frame, &frame_control); - - bool dst_pan_present, src_pan_present, src_pan_dropped; - addr_mode_t dst_mode, src_mode; - if (!ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, - &src_pan_present, &src_pan_dropped, &src_mode)) { - return false; - } - - // The addressing fields are after the sequence number, which can be ommitted - const uint16_t SEQ_SUPPRESSED = 0x0100; - uint16_t addr_offset; - ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); - - if (src_pan_dropped) { - // We can assume that the destination pan is present. - if (pan) { - *pan = ((unsigned short) frame[addr_offset]) | - (((unsigned short) frame[addr_offset + 1]) << 8); - } - } else { - if (dst_pan_present) addr_offset += 2; - if (dst_mode == ADDR_SHORT) { - addr_offset += 2; - } else if (dst_mode == ADDR_LONG) { - addr_offset += 8; - } - - if (src_pan_present && pan) { - *pan = ((unsigned short) frame[addr_offset]) | - (((unsigned short) frame[addr_offset + 1]) << 8); - } - } - - return src_pan_present || src_pan_dropped; -} \ No newline at end of file diff --git a/libtock/interface/button.c b/libtock/interface/button.c new file mode 100644 index 000000000..de8062137 --- /dev/null +++ b/libtock/interface/button.c @@ -0,0 +1,27 @@ +#include "button.h" + +returncode_t libtock_button_count(int* count) { + return libtock_button_command_count(count); +} + +returncode_t libtock_button_read(int button_num, int* button_value) { + return libtock_button_command_read(button_num, button_value); +} + +static void button_upcall(int btn_num, + int val, + __attribute__ ((unused)) int arg2, + void * opaque) { + libtock_button_callback cb = (libtock_button_callback) opaque; + cb(RETURNCODE_SUCCESS, btn_num, val == 1); +} + +returncode_t libtock_button_notify_on_press(int button_num, libtock_button_callback cb) { + returncode_t ret; + + ret = libtock_button_set_upcall(button_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_button_command_enable_interrupt(button_num); + return ret; +} diff --git a/libtock/interface/button.h b/libtock/interface/button.h new file mode 100644 index 000000000..5b1ea81ab --- /dev/null +++ b/libtock/interface/button.h @@ -0,0 +1,41 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/button_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for button press callbacks. +// +// - `arg1` (`returncode_t`): Returncode indicating status of button press. +// - `arg2` (`int`): Button index. +// - `arg3` (`bool`): True if pressed, false otherwise. +typedef void (*libtock_button_callback)(returncode_t, int, bool); + +// Read the current button state into `button_value`. +// +// ## Arguments +// +// - `button_num`: The index of the button. +// - `button_value`: Will be set to 1 if button is pressed, 0 otherwise. +returncode_t libtock_button_read(int button_num, int* button_value); + +// Set `count` to the number of buttons. +returncode_t libtock_button_count(int* count); + +// Setup a callback when a button is pressed. +// +// ## Arguments +// +// - `button_num`: The index of the button. +// - `cb`: The function to be called when the button is pressed. Will be called +// both when the button is pressed and when released. +returncode_t libtock_button_notify_on_press(int button_num, libtock_button_callback cb); + + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/interface/buzzer.c b/libtock/interface/buzzer.c new file mode 100644 index 000000000..9f7ef7e25 --- /dev/null +++ b/libtock/interface/buzzer.c @@ -0,0 +1,20 @@ +#include "buzzer.h" + +static void libtock_buzzer_temp_upcall(__attribute__ ((unused)) int arg0, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + void * opaque) { + libtock_buzzer_done_callback cb = (libtock_buzzer_done_callback) opaque; + cb(); +} + +returncode_t libtock_buzzer_tone(uint32_t frequency_hz, uint32_t duration_ms, libtock_buzzer_done_callback cb) { + + returncode_t ret; + + ret = libtock_buzzer_set_upcall(libtock_buzzer_temp_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_buzzer_command_tone(frequency_hz, duration_ms); + return ret; +} diff --git a/libtock/buzzer.h b/libtock/interface/buzzer.h similarity index 80% rename from libtock/buzzer.h rename to libtock/interface/buzzer.h index b554f2296..a96056747 100644 --- a/libtock/buzzer.h +++ b/libtock/interface/buzzer.h @@ -1,8 +1,11 @@ #pragma once -#include +#include "../tock.h" +#include "syscalls/buzzer_syscalls.h" -#define BUZZER_DRIVER 0x90000 +#ifdef __cplusplus +extern "C" { +#endif #define NOTE_B0 31 #define NOTE_C1 33 @@ -94,6 +97,14 @@ #define NOTE_D8 4699 #define NOTE_DS8 4978 -int buzzer_exists (void); -int tone_sync (size_t frequency_hz, size_t duration_ms); -int tone (size_t frequency_hz, size_t duration_ms, void (*tone_done)(void)); +// Function signature for buzzer done callbacks. +typedef void (*libtock_buzzer_done_callback)(void); + +// Play a tone and call a callback when the tone finishes. +// +// The tone will play at the frequency specified for the duration. +returncode_t libtock_buzzer_tone(uint32_t frequency_hz, uint32_t duration_ms, libtock_buzzer_done_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/console.c b/libtock/interface/console.c new file mode 100644 index 000000000..ca1b86d2f --- /dev/null +++ b/libtock/interface/console.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "console.h" + +static void generic_upcall(int ret, + int length, + int _z __attribute__ ((unused)), + void* ud) { + libtock_console_callback_write cb = (libtock_console_callback_write)ud; + cb(ret, length); +} + +returncode_t libtock_console_write(const uint8_t* buffer, uint32_t len, libtock_console_callback_write cb) { + returncode_t err; + + err = libtock_console_write_done_set_upcall(generic_upcall, (void*)cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_console_set_read_allow(buffer, len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_console_command_write(len); + return err; +} + +returncode_t libtock_console_read(uint8_t* buffer, uint32_t len, libtock_console_callback_read cb) { + returncode_t err; + + err = libtock_console_read_done_set_upcall(generic_upcall, (void*)cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_console_set_readwrite_allow(buffer, len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_console_command_read(len); + return err; +} + +returncode_t libtock_console_abort_read(void) { + return libtock_console_command_abort_read(); +} diff --git a/libtock/interface/console.h b/libtock/interface/console.h new file mode 100644 index 000000000..1a7084c2f --- /dev/null +++ b/libtock/interface/console.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/console_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for write done callbacks. +// +// - `length` (`int`): Number of bytes written +typedef void (*libtock_console_callback_write)(returncode_t, uint32_t); + +// Function signature for read done callbacks. +// +// - `length` (`int`): Number of bytes read +typedef void (*libtock_console_callback_read)(returncode_t, uint32_t); + +returncode_t libtock_console_write(const uint8_t* buffer, uint32_t len, libtock_console_callback_write cb); + +returncode_t libtock_console_read(uint8_t* buffer, uint32_t len, libtock_console_callback_read cb); + +returncode_t libtock_console_abort_read(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/led.c b/libtock/interface/led.c new file mode 100644 index 000000000..58da2d9d8 --- /dev/null +++ b/libtock/interface/led.c @@ -0,0 +1,17 @@ +#include "led.h" + +returncode_t libtock_led_count(int* count) { + return libtock_led_command_count(count); +} + +returncode_t libtock_led_on(int led_num) { + return libtock_led_command_on(led_num); +} + +returncode_t libtock_led_off(int led_num) { + return libtock_led_command_off(led_num); +} + +returncode_t libtock_led_toggle(int led_num) { + return libtock_led_command_toggle(led_num); +} diff --git a/libtock/interface/led.h b/libtock/interface/led.h new file mode 100644 index 000000000..041bc24e2 --- /dev/null +++ b/libtock/interface/led.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/led_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns the number of LEDs on the host platform. +returncode_t libtock_led_count(int* count); + +// Turn on the specified LED. +returncode_t libtock_led_on(int led_num); + +// Turn off the specified LED. +returncode_t libtock_led_off(int led_num); + +// Toggle the specified LED. +returncode_t libtock_led_toggle(int led_num); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/syscalls/button_syscalls.c b/libtock/interface/syscalls/button_syscalls.c new file mode 100644 index 000000000..390a4c019 --- /dev/null +++ b/libtock/interface/syscalls/button_syscalls.c @@ -0,0 +1,36 @@ +#include "button_syscalls.h" + +bool libtock_button_exists(void) { + int count; + int ret; + + ret = libtock_button_command_count(&count); + if (ret != RETURNCODE_SUCCESS) return false; + + return count > 0; +} + +returncode_t libtock_button_set_upcall(subscribe_upcall callback, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_BUTTON, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_button_command_count(int* count) { + syscall_return_t cval = command(DRIVER_NUM_BUTTON, 0, 0, 0); + return tock_command_return_u32_to_returncode(cval, (uint32_t*) count); +} + +returncode_t libtock_button_command_enable_interrupt(int button_num) { + syscall_return_t cval = command(DRIVER_NUM_BUTTON, 1, button_num, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_button_command_disable_interrupt(int button_num) { + syscall_return_t cval = command(DRIVER_NUM_BUTTON, 2, button_num, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_button_command_read(int button_num, int* button_value) { + syscall_return_t cval = command(DRIVER_NUM_BUTTON, 3, button_num, 0); + return tock_command_return_u32_to_returncode(cval, (uint32_t*) button_value); +} diff --git a/libtock/interface/syscalls/button_syscalls.h b/libtock/interface/syscalls/button_syscalls.h new file mode 100644 index 000000000..7024f55c7 --- /dev/null +++ b/libtock/interface/syscalls/button_syscalls.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_BUTTON 0x3 + +// Check if the button system call driver is available on this board. +bool libtock_button_exists(void); + +// Set the upcall for the button driver. +returncode_t libtock_button_set_upcall(subscribe_upcall callback, void *opaque); + +// Set `count` to the number of buttons. +returncode_t libtock_button_command_count(int* count); + +// Enable the interrupt for the button so that button presses trigger upcalls. +// +// ## Arguments +// +// - `button_num`: The index of the button. +returncode_t libtock_button_command_enable_interrupt(int button_num); + +// Disable the interrupt for the button so that button presses do not trigger +// upcalls. +// +// ## Arguments +// +// - `button_num`: The index of the button. +returncode_t libtock_button_command_disable_interrupt(int button_num); + +// Read the current button state into `button_value`. +// +// ## Arguments +// +// - `button_num`: The index of the button. +// - `button_value`: Will be set to 1 if button is pressed, 0 otherwise. +returncode_t libtock_button_command_read(int button_num, int* button_value); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/interface/syscalls/buzzer_syscalls.c b/libtock/interface/syscalls/buzzer_syscalls.c new file mode 100644 index 000000000..5400739b2 --- /dev/null +++ b/libtock/interface/syscalls/buzzer_syscalls.c @@ -0,0 +1,15 @@ +#include "buzzer_syscalls.h" + +bool libtock_buzzer_exists(void) { + return driver_exists(DRIVER_NUM_BUZZER); +} + +returncode_t libtock_buzzer_set_upcall(subscribe_upcall callback, void* opaque){ + subscribe_return_t sval = subscribe(DRIVER_NUM_BUZZER, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_buzzer_command_tone(uint32_t frequency_hz, uint32_t duration_ms) { + syscall_return_t cval = command(DRIVER_NUM_BUZZER, 1, frequency_hz, duration_ms); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/interface/syscalls/buzzer_syscalls.h b/libtock/interface/syscalls/buzzer_syscalls.h new file mode 100644 index 000000000..831054e7a --- /dev/null +++ b/libtock/interface/syscalls/buzzer_syscalls.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_BUZZER 0x90000 + +// Check if the buzzer system call driver is available on this board. +bool libtock_buzzer_exists(void); + +// Subscribe an upcall for the buzzer. +returncode_t libtock_buzzer_set_upcall(subscribe_upcall callback, void* opaque); + +// Start a tone at a given frequency for a given duration. +returncode_t libtock_buzzer_command_tone(uint32_t frequency_hz, uint32_t duration_ms); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/interface/syscalls/console_syscalls.c b/libtock/interface/syscalls/console_syscalls.c new file mode 100644 index 000000000..e24b628c1 --- /dev/null +++ b/libtock/interface/syscalls/console_syscalls.c @@ -0,0 +1,40 @@ +#include "console_syscalls.h" + +returncode_t libtock_console_write_done_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_CONSOLE, 1, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_console_read_done_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_CONSOLE, 2, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_console_set_read_allow(const uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_CONSOLE, 1, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_console_set_readwrite_allow(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_CONSOLE, 1, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +bool libtock_console_command_exists(void) { + return driver_exists(DRIVER_NUM_CONSOLE); +} + +returncode_t libtock_console_command_write(int length) { + syscall_return_t cval = command(DRIVER_NUM_CONSOLE, 1, length, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_console_command_read(int length) { + syscall_return_t cval = command(DRIVER_NUM_CONSOLE, 2, length, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_console_command_abort_read(void) { + syscall_return_t cval = command(DRIVER_NUM_CONSOLE, 3, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/interface/syscalls/console_syscalls.h b/libtock/interface/syscalls/console_syscalls.h new file mode 100644 index 000000000..111ef812b --- /dev/null +++ b/libtock/interface/syscalls/console_syscalls.h @@ -0,0 +1,38 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_CONSOLE 0x1 + +// Configure the upcall for write completion events. +returncode_t libtock_console_write_done_set_upcall(subscribe_upcall callback, void* opaque); + +// Configure the upcall for write completion events. +returncode_t libtock_console_read_done_set_upcall(subscribe_upcall callback, void* opaque); + +// Set the buffer for writing data to the console. +returncode_t libtock_console_set_read_allow(const uint8_t* buffer, uint32_t len); + +// Set the buffer for reading data from the console. +returncode_t libtock_console_set_readwrite_allow(uint8_t* buffer, uint32_t len); + +// Check if the console driver exists +bool libtock_console_command_exists(void); + +// Initiate a write operation of the allowed read-only buffer with the provided length +returncode_t libtock_console_command_write(int length); + +// Initiate a read operation into the allowed read-write buffer of the provided length +returncode_t libtock_console_command_read(int length); + +// Abort any oustanding read operations +returncode_t libtock_console_command_abort_read(void); + + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/syscalls/led_syscalls.c b/libtock/interface/syscalls/led_syscalls.c new file mode 100644 index 000000000..734dbec49 --- /dev/null +++ b/libtock/interface/syscalls/led_syscalls.c @@ -0,0 +1,31 @@ +#include "led_syscalls.h" + +bool libtock_led_exists(void) { + int count; + int ret; + + ret = libtock_led_command_count(&count); + if (ret != RETURNCODE_SUCCESS) return false; + + return count > 0; +} + +returncode_t libtock_led_command_count(int* count) { + syscall_return_t rval = command(DRIVER_NUM_LED, 0, 0, 0); + return tock_command_return_u32_to_returncode(rval, (uint32_t*) count); +} + +returncode_t libtock_led_command_on(int led_num) { + syscall_return_t rval = command(DRIVER_NUM_LED, 1, led_num, 0); + return tock_command_return_novalue_to_returncode(rval); +} + +returncode_t libtock_led_command_off(int led_num) { + syscall_return_t rval = command(DRIVER_NUM_LED, 2, led_num, 0); + return tock_command_return_novalue_to_returncode(rval); +} + +returncode_t libtock_led_command_toggle(int led_num) { + syscall_return_t rval = command(DRIVER_NUM_LED, 3, led_num, 0); + return tock_command_return_novalue_to_returncode(rval); +} diff --git a/libtock/interface/syscalls/led_syscalls.h b/libtock/interface/syscalls/led_syscalls.h new file mode 100644 index 000000000..45dc7c9c7 --- /dev/null +++ b/libtock/interface/syscalls/led_syscalls.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_LED 0x2 + +// Check if the button system call driver is available on this board. +bool libtock_led_exists(void); + +// Returns the number of LEDs on the host platform. +returncode_t libtock_led_command_count(int* count); + +// Turn on the LED specified by index. +returncode_t libtock_led_command_on(int led_num); + +// Turn off the LED specified by index. +returncode_t libtock_led_command_off(int led_num); + +// Toggle the LED specified by index. +returncode_t libtock_led_command_toggle(int led_num); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/syscalls/usb_keyboard_hid_syscalls.c b/libtock/interface/syscalls/usb_keyboard_hid_syscalls.c new file mode 100644 index 000000000..3e952994e --- /dev/null +++ b/libtock/interface/syscalls/usb_keyboard_hid_syscalls.c @@ -0,0 +1,20 @@ +#include "usb_keyboard_hid_syscalls.h" + +bool libtock_usb_keyboard_hid_exists(void) { + return driver_exists(DRIVER_NUM_USB_KEYBOARD_HID); +} + +returncode_t libtock_usb_keyboard_hid_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_USB_KEYBOARD_HID, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_usb_keyboard_hid_set_readwrite_allow_send_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_USB_KEYBOARD_HID, 1, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_usb_keyboard_hid_command_send(void) { + syscall_return_t cval = command(DRIVER_NUM_USB_KEYBOARD_HID, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/interface/syscalls/usb_keyboard_hid_syscalls.h b/libtock/interface/syscalls/usb_keyboard_hid_syscalls.h new file mode 100644 index 000000000..ba95bcc3e --- /dev/null +++ b/libtock/interface/syscalls/usb_keyboard_hid_syscalls.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_USB_KEYBOARD_HID 0x90005 + +// Check if this driver exists. +bool libtock_usb_keyboard_hid_exists(void); + +// Configure the upcall for send/receive events. +returncode_t libtock_usb_keyboard_hid_set_upcall(subscribe_upcall callback, void* opaque); + +// Set the buffer for sending data. +returncode_t libtock_usb_keyboard_hid_set_readwrite_allow_send_buffer(uint8_t* buffer, uint32_t len); + +// Command to send the keyboard press to the host. +returncode_t libtock_usb_keyboard_hid_command_send(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/interface/usb_keyboard_hid.c b/libtock/interface/usb_keyboard_hid.c new file mode 100644 index 000000000..2763ae585 --- /dev/null +++ b/libtock/interface/usb_keyboard_hid.c @@ -0,0 +1,22 @@ +#include "usb_keyboard_hid.h" + +static void usb_keyboard_hid_upcall(__attribute__ ((unused)) int callback_type, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_usb_keyboard_hid_callback cb = (libtock_usb_keyboard_hid_callback) opaque; + cb(RETURNCODE_SUCCESS); +} + +returncode_t libtock_usb_keyboard_hid_send(uint8_t* buffer, uint32_t len, libtock_usb_keyboard_hid_callback cb) { + returncode_t err; + + err = libtock_usb_keyboard_hid_set_upcall(usb_keyboard_hid_upcall, (void*) cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_usb_keyboard_hid_set_readwrite_allow_send_buffer(buffer, len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_usb_keyboard_hid_command_send(); // Sometimes returns ERESERVE (but everything keeps working??) + return err; +} diff --git a/libtock/interface/usb_keyboard_hid.h b/libtock/interface/usb_keyboard_hid.h new file mode 100644 index 000000000..fe31c57ea --- /dev/null +++ b/libtock/interface/usb_keyboard_hid.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/usb_keyboard_hid_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for send done callbacks. +// +// - `arg1` (`returncode_t`): Status of USB keyboard HID send operation. +typedef void (*libtock_usb_keyboard_hid_callback)(returncode_t); + +// Set the buffer to the over the USB keyboard HID interface. The callback will +// be triggered when the send has completed. +returncode_t libtock_usb_keyboard_hid_send(uint8_t* buffer, uint32_t len, libtock_usb_keyboard_hid_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/internal/alarm.h b/libtock/internal/alarm.h deleted file mode 100644 index a6ee93dd3..000000000 --- a/libtock/internal/alarm.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_ALARM 0x0 - -/* - * Sets the callback for timers - * - * When invoked, the callback's first argument will be the timer value at which - * the timer was fired. - * - * Side-effects: cancels any existing/outstanding timers - */ -int alarm_internal_subscribe(subscribe_upcall cb, void *userdata); - -/* - * Starts a oneshot alarm - * - * expiration - absolute expiration value = reference + dt. - * Using reference + dt allows library to distinguish expired timers from - * timers in the far future. - * - * Side-effects: cancels any existing/outstanding timers - */ -int alarm_internal_set(uint32_t reference, uint32_t dt); - - -/* - * Stops any outstanding hardware alarm. - * - * Side-effects: cancels any existing/outstanding timers - */ -int alarm_internal_stop(void); - -/* - * Get the the timer frequency in Hz. - */ -int alarm_internal_frequency(uint32_t* frequency); - -/* - * Get the current alarm counter. - */ -int alarm_internal_read(uint32_t* time); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/internal/alarm_internal.c b/libtock/internal/alarm_internal.c deleted file mode 100644 index bb4963063..000000000 --- a/libtock/internal/alarm_internal.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "internal/alarm.h" - -int alarm_internal_subscribe(subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_ALARM, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -int alarm_internal_set(uint32_t reference, uint32_t tics) { - syscall_return_t rval = command(DRIVER_NUM_ALARM, 6, reference, tics); - uint32_t rc; - return tock_command_return_u32_to_returncode(rval, &rc); -} - -int alarm_internal_stop(void) { - syscall_return_t rval = command(DRIVER_NUM_ALARM, 3, 0, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int alarm_internal_frequency(uint32_t* frequency) { - syscall_return_t rval = command(DRIVER_NUM_ALARM, 1, 0, 0); - return tock_command_return_u32_to_returncode(rval, frequency); -} - -int alarm_internal_read(uint32_t* time) { - syscall_return_t rval = command(DRIVER_NUM_ALARM, 2, 0, 0); - return tock_command_return_u32_to_returncode(rval, time); -} diff --git a/libtock/internal/nonvolatile_storage.h b/libtock/internal/nonvolatile_storage.h deleted file mode 100644 index 7902da9a0..000000000 --- a/libtock/internal/nonvolatile_storage.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "tock.h" - -#define DRIVER_NUM_NONVOLATILE_STORAGE 0x50001 - -#ifdef __cplusplus -extern "C" { -#endif - -int nonvolatile_storage_internal_read_done_subscribe(subscribe_upcall cb, void *userdata); -int nonvolatile_storage_internal_write_done_subscribe(subscribe_upcall cb, void *userdata); - -int nonvolatile_storage_internal_read_buffer(uint8_t* buffer, uint32_t len); -int nonvolatile_storage_internal_write_buffer(uint8_t* buffer, uint32_t len); - -int nonvolatile_storage_internal_get_number_bytes(int* number_bytes); -int nonvolatile_storage_internal_read(uint32_t offset, uint32_t length); -int nonvolatile_storage_internal_write(uint32_t offset, uint32_t length); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/internal/nonvolatile_storage_internal.c b/libtock/internal/nonvolatile_storage_internal.c deleted file mode 100644 index f087922f4..000000000 --- a/libtock/internal/nonvolatile_storage_internal.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "internal/nonvolatile_storage.h" - -int nonvolatile_storage_internal_read_done_subscribe(subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_NONVOLATILE_STORAGE, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -int nonvolatile_storage_internal_write_done_subscribe(subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_NONVOLATILE_STORAGE, 1, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -int nonvolatile_storage_internal_read_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_NONVOLATILE_STORAGE, 0, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -int nonvolatile_storage_internal_write_buffer(uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_NONVOLATILE_STORAGE, 0, (void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int nonvolatile_storage_internal_get_number_bytes(int* number_bytes) { - syscall_return_t res = command(DRIVER_NUM_NONVOLATILE_STORAGE, 1, 0, 0); - return tock_command_return_u32_to_returncode(res, (uint32_t*) number_bytes); -} - -int nonvolatile_storage_internal_read(uint32_t offset, uint32_t length) { - syscall_return_t res = command(DRIVER_NUM_NONVOLATILE_STORAGE, 2, (int) offset, (int) length); - return tock_command_return_novalue_to_returncode(res); -} - -int nonvolatile_storage_internal_write(uint32_t offset, uint32_t length) { - syscall_return_t res = command(DRIVER_NUM_NONVOLATILE_STORAGE, 3, (int) offset, (int) length); - return tock_command_return_novalue_to_returncode(res); -} diff --git a/libtock/ipc.c b/libtock/kernel/ipc.c similarity index 100% rename from libtock/ipc.c rename to libtock/kernel/ipc.c diff --git a/libtock/ipc.h b/libtock/kernel/ipc.h similarity index 98% rename from libtock/ipc.h rename to libtock/kernel/ipc.h index c086b3b5c..1c3db78c3 100644 --- a/libtock/ipc.h +++ b/libtock/kernel/ipc.h @@ -3,7 +3,7 @@ #include #include -#include "tock.h" +#include "../tock.h" #ifdef __cplusplus extern "C" { diff --git a/libtock/kernel/read_only_state.c b/libtock/kernel/read_only_state.c new file mode 100644 index 000000000..9978a798a --- /dev/null +++ b/libtock/kernel/read_only_state.c @@ -0,0 +1,34 @@ +#include "read_only_state.h" + + +returncode_t libtock_read_only_state_allocate_region(uint8_t* base, int len) { + if (len < LIBTOCK_READ_ONLY_STATE_BUFFER_LEN) { + // The buffer is not long enough + return RETURNCODE_ESIZE; + } + + return libtock_read_only_state_set_userspace_read_allow_allocate_region(base, len); +} + +uint32_t libtock_read_only_state_get_pending_tasks(void* base) { + uint32_t* ptr = base; + return ptr[1]; +} + +uint64_t libtock_read_only_state_get_ticks(void* base) { + uint32_t* ptr = base; + + // Start with the high bytes set to 0 + uint32_t high, low; + + do { + // Get the high bytes the value in memory + high = ptr[3]; + // Read the low bytes + low = ptr[2]; + // If the high bytes don't match what is still in memory re-try + // the load + } while (high != ptr[3]); + + return ((uint64_t)high << 32) | low; +} diff --git a/libtock/kernel/read_only_state.h b/libtock/kernel/read_only_state.h new file mode 100644 index 000000000..6344cdd6e --- /dev/null +++ b/libtock/kernel/read_only_state.h @@ -0,0 +1,38 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/read_only_state_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// We currently support ROS version 1 +// Version 1: +// |-------------------------| +// | Count (u32) | +// |-------------------------| +// | Pending Tasks (u32) | +// |-------------------------| +// | | +// | Time Ticks (u64) | +// |-------------------------| +#define LIBTOCK_READ_ONLY_STATE_BUFFER_LEN (4 * 4 + 4 * 4 + 8 * 4) + +// Share a buffer with the kernel to use for read only state +// +// - `base` the buffer to use. +// - `len` should be `LIBTOCK_READ_ONLY_STATE_BUFFER_LEN`. +returncode_t libtock_read_only_state_allocate_region(uint8_t* base, int len); + +// Use the read only state buffer provided by `base` +// to get the number of pending tasks. +uint32_t libtock_read_only_state_get_pending_tasks(void* base); + +// Use the read only state buffer provided by `base` +// to get the current time returned from the kernel. +uint64_t libtock_read_only_state_get_ticks(void* base); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/kernel/syscalls/read_only_state_syscalls.c b/libtock/kernel/syscalls/read_only_state_syscalls.c new file mode 100644 index 000000000..4e9fc3967 --- /dev/null +++ b/libtock/kernel/syscalls/read_only_state_syscalls.c @@ -0,0 +1,15 @@ +#include "read_only_state_syscalls.h" + +bool libtock_read_only_state_exists(void) { + return driver_exists(DRIVER_NUM_READ_ONLY_STATE); +} + +returncode_t libtock_read_only_state_set_userspace_read_allow_allocate_region(uint8_t* buffer, uint32_t length) { + allow_userspace_r_return_t aval = allow_userspace_read(DRIVER_NUM_READ_ONLY_STATE, 0, (void*) buffer, length); + return tock_allow_userspace_r_return_to_returncode(aval); +} + +returncode_t libtock_read_only_state_command_get_version(uint32_t* version) { + syscall_return_t cval = command(DRIVER_NUM_READ_ONLY_STATE, 1, 0, 0); + return tock_command_return_u32_to_returncode(cval, version); +} diff --git a/libtock/kernel/syscalls/read_only_state_syscalls.h b/libtock/kernel/syscalls/read_only_state_syscalls.h new file mode 100644 index 000000000..6dddbbb85 --- /dev/null +++ b/libtock/kernel/syscalls/read_only_state_syscalls.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_READ_ONLY_STATE 0x00009 + +// Check if this driver is available on the kernel. +bool libtock_read_only_state_exists(void); + +// Share a buffer with the kernel to use for read only state +// +// - `buffer` the buffer to use. +// - `len` should be `LIBTOCK_READ_ONLY_STATE_BUFFER_LEN`. +returncode_t libtock_read_only_state_set_userspace_read_allow_allocate_region(uint8_t* buffer, uint32_t length); + +// Get the latest version of the read only state supported by the kernel. +returncode_t libtock_read_only_state_command_get_version(uint32_t* version); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/kv.c b/libtock/kv.c deleted file mode 100644 index 6f7abf8c7..000000000 --- a/libtock/kv.c +++ /dev/null @@ -1,196 +0,0 @@ -#include "kv.h" - -#define DRIVER_NUM_KV_SYSTEM 0x50003 - -#define TOCK_KV_CB 0 - -#define TOCK_KV_KEY_BUF 0 -#define TOCK_KV_INPUT_BUF 1 -#define TOCK_KV_OUTPUT_BUF 0 - -#define TOCK_KV_CHECK_PRESENT 0 -#define TOCK_KV_GET 1 -#define TOCK_KV_SET 2 -#define TOCK_KV_DELETE 3 -#define TOCK_KV_ADD 4 -#define TOCK_KV_UPDATE 5 - -int kv_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_KV_SYSTEM, TOCK_KV_CB, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int kv_set_key_buffer(const uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_KV_SYSTEM, TOCK_KV_KEY_BUF, (void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int kv_set_input_buffer(const uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_KV_SYSTEM, TOCK_KV_INPUT_BUF, (void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int kv_set_output_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_KV_SYSTEM, TOCK_KV_OUTPUT_BUF, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -int kv_check_status(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_CHECK_PRESENT, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int kv_get(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_GET, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int kv_set(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_SET, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int kv_delete(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_DELETE, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int kv_add(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_ADD, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int kv_update(void) { - syscall_return_t cval = command(DRIVER_NUM_KV_SYSTEM, TOCK_KV_UPDATE, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -struct kv_data { - bool fired; - int err; - int length; -}; - -static struct kv_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void kv_upcall( int err, - int length, - __attribute__ ((unused)) int unused2, - void* ud) { - struct kv_data* data = (struct kv_data*) ud; - data->fired = true; - data->err = tock_status_to_returncode(err); - data->length = length; -} - -int kv_get_sync(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, - uint32_t* value_len) { - int err; - result.fired = false; - - err = kv_set_callback(kv_upcall, (void*) &result); - if (err < 0) return err; - - err = kv_set_key_buffer(key_buffer, key_len); - if (err < 0) return err; - - err = kv_set_output_buffer(ret_buffer, ret_len); - if (err < 0) return err; - - err = kv_get(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - // Retrieve the buffers. - err = kv_set_output_buffer(NULL, 0); - if (err < 0) return err; - - err = kv_set_key_buffer(NULL, 0); - if (err < 0) return err; - - if (result.err < 0) { - return result.err; - } - - // Return the length of the retrieved value. - *value_len = result.length; - - return RETURNCODE_SUCCESS; -} - -static int kv_insert_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, - uint32_t val_len, int (*op_fn)(void)){ - int err; - result.fired = false; - - err = kv_set_callback(kv_upcall, (void*) &result); - if (err < 0) return err; - - err = kv_set_key_buffer(key_buffer, key_len); - if (err < 0) return err; - - err = kv_set_input_buffer(val_buffer, val_len); - if (err < 0) return err; - - // Do the requested set/add/update operation. - err = op_fn(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - // Retrieve the buffers. - err = kv_set_output_buffer(NULL, 0); - if (err < 0) return err; - - err = kv_set_key_buffer(NULL, 0); - if (err < 0) return err; - - if (result.err < 0) { - return result.err; - } - - return RETURNCODE_SUCCESS; -} - -int kv_set_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len) { - return kv_insert_sync(key_buffer, key_len, val_buffer, val_len, kv_set); -} - -int kv_add_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len) { - return kv_insert_sync(key_buffer, key_len, val_buffer, val_len, kv_add); -} - -int kv_update_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len) { - return kv_insert_sync(key_buffer, key_len, val_buffer, val_len, kv_update); -} - -int kv_delete_sync(const uint8_t* key_buffer, uint32_t key_len) { - int err; - result.fired = false; - - err = kv_set_callback(kv_upcall, (void*) &result); - if (err < 0) return err; - - err = kv_set_key_buffer(key_buffer, key_len); - if (err < 0) return err; - - err = kv_delete(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - // Retrieve the buffers. - err = kv_set_key_buffer(NULL, 0); - if (err < 0) return err; - - if (result.err < 0) { - return result.err; - } - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/kv.h b/libtock/kv.h deleted file mode 100644 index 570119d46..000000000 --- a/libtock/kv.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int kv_set_callback(subscribe_upcall callback, void* callback_args); - -int kv_set_key_buffer(const uint8_t* buffer, uint32_t len); -int kv_set_input_buffer(const uint8_t* buffer, uint32_t len); -int kv_set_output_buffer(uint8_t* buffer, uint32_t len); - -/* - * Check that the KV system exists - */ -int kv_check_status(void); - -int kv_get(void); -int kv_set(void); -int kv_add(void); -int kv_update(void); -int kv_delete(void); - -int kv_get_sync(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, uint32_t* value_len); -int kv_set_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); -int kv_add_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); -int kv_update_sync(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len); -int kv_delete_sync(const uint8_t* key_buffer, uint32_t key_len); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/l3gd20.c b/libtock/l3gd20.c deleted file mode 100644 index 0a94ad4d4..000000000 --- a/libtock/l3gd20.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "l3gd20.h" - -// struct to hold values send with the callback -typedef struct l3gd20_response { - int data1; - int data2; - int data3; - bool done; // the callback has been called -} L3GD20Response; - -// see manual page 9 -const float SCALE_FACTOR[3] = {8.75, 17.5, 70.0}; - -unsigned char scale_factor = 0; - -static void command_callback_yield (int data1, int data2, int data3, void* ud) { - L3GD20Response *response = (L3GD20Response*)ud; - if (response) { - response->data1 = data1; - response->data2 = data2; - response->data3 = data3; - response->done = true; - } -} - -static int l3gd20_subscribe (subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_L3GD20, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -bool l3gd20_is_present (void) { - L3GD20Response response; - response.data1 = false; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - if (command(DRIVER_NUM_L3GD20, 1, 0, 0).type == TOCK_SYSCALL_SUCCESS) { - yield_for(&(response.done)); - } - return response.data1 ? true : false; -} - -int l3gd20_power_on (void) { - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 2, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - return RETURNCODE_SUCCESS; -} - -int l3gd20_set_scale (unsigned char scale) { - if (scale > 2) scale = 2; - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 3, scale, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - scale_factor = scale; - yield_for(&(response.done)); - return RETURNCODE_SUCCESS; -} - -int l3gd20_enable_hpf (bool enabled) { - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 4, enabled ? 1 : 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - return RETURNCODE_SUCCESS; -} - -int l3gd20_set_hpf_parameters (unsigned char mode, unsigned char divider) { - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 5, mode, divider); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - return RETURNCODE_SUCCESS; -} - -int l3gd20_read_xyz (L3GD20XYZ *xyz) { - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 6, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - if (xyz != NULL) { - xyz->x = (float)response.data1 * SCALE_FACTOR[scale_factor] * 0.001; - xyz->y = (float)response.data2 * SCALE_FACTOR[scale_factor] * 0.001; - xyz->z = (float)response.data3 * SCALE_FACTOR[scale_factor] * 0.001; - } - return RETURNCODE_SUCCESS; -} - -int l3gd20_read_temperature (int *temperature) { - L3GD20Response response; - response.done = false; - - int ret = l3gd20_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_L3GD20, 7, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - if (temperature != NULL) { - *temperature = response.data1; - } - return RETURNCODE_SUCCESS; -} diff --git a/libtock/l3gd20.h b/libtock/l3gd20.h deleted file mode 100644 index 67f5b37b2..000000000 --- a/libtock/l3gd20.h +++ /dev/null @@ -1,56 +0,0 @@ -/*L3GD20 3 axis gyroscope and temperature sensor -* -* -* -*/ - -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_L3GD20 0x70005 - -// HPF Senzitivity -#define L3GD20_SCALE_250 0 -#define L3GD20_SCALE_500 1 -#define L3GD20_SCALE_2000 2 - -// HPF Divider -#define L3GD20_HPF_DIV_1 0 -#define L3GD20_HPF_DIV_2 1 -#define L3GD20_HPF_DIV_4 2 -#define L3GD20_HPF_DIV_8 3 -#define L3GD20_HPF_DIV_16 4 -#define L3GD20_HPF_DIV_32 5 -#define L3GD20_HPF_DIV_64 6 -#define L3GD20_HPF_DIV_128 7 -#define L3GD20_HPF_DIV_256 8 -#define L3GD20_HPF_DIV_512 9 - -// HPF Mode -#define L3GD20_HPF_MODE_HP_RESET_FILTER 0 -#define L3GD20_HPF_MODE_REFERENCE 1 -#define L3GD20_HPF_MODE_NORMAL 2 -#define L3GD20_HPF_MODE_AUTO_RESET 3 - -typedef struct l3gd20xyz { - float x; - float y; - float z; -} L3GD20XYZ; - -bool l3gd20_is_present (void); -int l3gd20_power_on (void); -int l3gd20_set_scale (unsigned char scale); -int l3gd20_enable_hpf (bool enabled); -int l3gd20_set_hpf_parameters (unsigned char mode, unsigned char divider); -int l3gd20_read_xyz (L3GD20XYZ *xyz); -int l3gd20_read_temperature (int *temperature); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/led.c b/libtock/led.c deleted file mode 100644 index ed307b7d4..000000000 --- a/libtock/led.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "led.h" - -int led_count(int* count) { - syscall_return_t rval = command(DRIVER_NUM_LEDS, 0, 0, 0); - return tock_command_return_u32_to_returncode(rval, (uint32_t*) count); -} - -int led_on(int led_num) { - syscall_return_t rval = command(DRIVER_NUM_LEDS, 1, led_num, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int led_off(int led_num) { - syscall_return_t rval = command(DRIVER_NUM_LEDS, 2, led_num, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int led_toggle(int led_num) { - syscall_return_t rval = command(DRIVER_NUM_LEDS, 3, led_num, 0); - return tock_command_return_novalue_to_returncode(rval); -} diff --git a/libtock/led.h b/libtock/led.h deleted file mode 100644 index 50525899b..000000000 --- a/libtock/led.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_LEDS 0x00000002 - -int led_on(int led_num); -int led_off(int led_num); -int led_toggle(int led_num); - -// Returns the number of LEDs on the host platform. -int led_count(int* count); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/lora_phy.c b/libtock/lora_phy.c deleted file mode 100644 index e5d64598c..000000000 --- a/libtock/lora_phy.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "lora_phy.h" - -int lora_phy_set_rate(int rate) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 5, rate, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_get_rate(void) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 6, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_set_phase(bool phase) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 7, (unsigned char)phase, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_get_phase(void) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 8, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_set_polarity(bool pol) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 9, (unsigned char)pol, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_get_polarity(void) { - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 10, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_LORAPHY_SPI, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int lora_phy_set_master_write_buffer(const uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_LORAPHY_SPI, 0, (const void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int lora_phy_set_master_read_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_LORAPHY_SPI, 0, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -static void lora_phy_upcall(__attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - __attribute__ ((unused)) void* ud) { - *((bool*)ud) = true; -} - -int lora_phy_write(const char* buf, - size_t len, - subscribe_upcall cb, bool* cond) { - int ret = 0; - - ret = lora_phy_set_master_write_buffer((const uint8_t*) buf, len); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - ret = lora_phy_set_callback(cb, cond); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - syscall_return_t cval = command(DRIVER_NUM_LORAPHY_SPI, 2, len, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int lora_phy_read_write(const char* write, - char* read, - size_t len, - subscribe_upcall cb, bool* cond) { - int ret = 0; - - ret = lora_phy_set_master_read_buffer((uint8_t*) read, len); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - return lora_phy_write(write, len, cb, cond); -} - -int lora_phy_write_sync(const char* write, - size_t len) { - bool cond = false; - int ret = 0; - - ret = lora_phy_set_master_read_buffer(NULL, 0); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - int err = lora_phy_write(write, len, lora_phy_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} - -int lora_phy_read_write_sync(const char* write, - char* read, - size_t len) { - bool cond = false; - int ret = 0; - - ret = lora_phy_set_master_read_buffer(NULL, 0); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - int err = lora_phy_read_write(write, read, len, lora_phy_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} - -int lora_phy_gpio_enable_output(GPIO_Pin_t pin) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 1, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_set(GPIO_Pin_t pin) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 2, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_clear(GPIO_Pin_t pin) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 3, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_toggle(GPIO_Pin_t pin) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 4, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_enable_input(GPIO_Pin_t pin, GPIO_InputMode_t pin_config) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 5, pin, pin_config); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_read(GPIO_Pin_t pin, int* pin_value) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 6, pin, 0); - return tock_command_return_u32_to_returncode(rval, (uint32_t*) pin_value); -} - -int lora_phy_gpio_enable_interrupt(GPIO_Pin_t pin, GPIO_InterruptMode_t irq_config) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 7, pin, irq_config); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_disable_interrupt(GPIO_Pin_t pin) { - syscall_return_t rval = command(DRIVER_NUM_LORAPHY_GPIO, 8, pin, 0); - return tock_command_return_novalue_to_returncode(rval); -} - -int lora_phy_gpio_interrupt_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_LORAPHY_GPIO, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} diff --git a/libtock/lora_phy.h b/libtock/lora_phy.h deleted file mode 100644 index 70f0a6c1e..000000000 --- a/libtock/lora_phy.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "tock.h" -#include "gpio.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_LORAPHY_SPI 0x30003 -#define DRIVER_NUM_LORAPHY_GPIO 0x30004 - -int lora_phy_set_callback(subscribe_upcall callback, void* callback_args); - -int lora_phy_set_master_write_buffer(const uint8_t* buffer, uint32_t len); -int lora_phy_set_master_read_buffer(uint8_t* buffer, uint32_t len); - -/* Rate is the Hz of the SPI clock. So a rate of 100000 - * is a 100kHZ clock. */ -int lora_phy_set_rate(int rate); -int lora_phy_get_rate(void); - - /* false means sample on a leading (low to high) clock edge - * true means sample on a trailing (high to low) clock edge */ -int lora_phy_set_phase(bool phase); -int lora_phy_get_phase(void); - - /* false means an idle clock is low - * true means an idle clock is high. */ -int lora_phy_set_polarity(bool pol); -int lora_phy_get_polarity(void); - -int lora_phy_write_byte(unsigned char byte); -int lora_phy_read_buf(const char* str, size_t len); -int lora_phy_write(const char* str, size_t len, subscribe_upcall cb, bool* cond); -int lora_phy_read_write(const char* write, char* read, size_t len, subscribe_upcall cb, bool* cond); - -int lora_phy_write_sync(const char* write, size_t len); -int lora_phy_read_write_sync(const char* write, char* read, size_t len); - -int lora_phy_gpio_enable_output(GPIO_Pin_t pin); -int lora_phy_gpio_set(GPIO_Pin_t pin); -int lora_phy_gpio_clear(GPIO_Pin_t pin); -int lora_phy_gpio_toggle(GPIO_Pin_t pin); -int lora_phy_gpio_enable_input(GPIO_Pin_t pin, GPIO_InputMode_t pin_config); -int lora_phy_gpio_read(GPIO_Pin_t pin, int* pin_value); -int lora_phy_gpio_enable_interrupt(GPIO_Pin_t pin, GPIO_InterruptMode_t irq_config); -int lora_phy_gpio_disable_interrupt(GPIO_Pin_t pin); -int lora_phy_gpio_interrupt_callback(subscribe_upcall callback, void* callback_args); - - -#ifdef __cplusplus -} -#endif diff --git a/libtock/lps25hb.c b/libtock/lps25hb.c deleted file mode 100644 index db45dbd40..000000000 --- a/libtock/lps25hb.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "lps25hb.h" -#include "tock.h" - -struct lps25hb_data { - bool fired; - int value; -}; - -static struct lps25hb_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void lps25hb_upcall(int value, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - struct lps25hb_data* data = (struct lps25hb_data*) ud; - data->value = value; - data->fired = true; -} - -int lps25hb_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_LPS25HB, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int lps25hb_get_pressure (void) { - syscall_return_t com = command(DRIVER_NUM_LPS25HB, 1, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int lps25hb_get_pressure_sync (int* pressure) { - int err; - result.fired = false; - - err = lps25hb_set_callback(lps25hb_upcall, (void*) &result); - if (err < 0) return err; - - err = lps25hb_get_pressure(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *pressure = result.value; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/lps25hb.h b/libtock/lps25hb.h deleted file mode 100644 index 4ba90f11b..000000000 --- a/libtock/lps25hb.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_LPS25HB 0x70004 - -int lps25hb_set_callback (subscribe_upcall callback, void* callback_args); -int lps25hb_get_pressure (void); - -int lps25hb_get_pressure_sync (int* pressure); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/lsm303dlhc.c b/libtock/lsm303dlhc.c deleted file mode 100644 index e8e04ad42..000000000 --- a/libtock/lsm303dlhc.c +++ /dev/null @@ -1,221 +0,0 @@ -#include - -#include "lsm303dlhc.h" - -// struct to hold values send with the callback -typedef struct l3gd20dlhc_response { - int data1; - int data2; - int data3; - bool done; // the callback has been called -} LSM303DLHCResponse; - -static void command_callback_yield (int data1, int data2, int data3, void* ud) { - LSM303DLHCResponse *response = (LSM303DLHCResponse*)ud; - if (response) { - response->data1 = data1; - response->data2 = data2; - response->data3 = data3; - response->done = true; - } -} - - -static int lsm303dlhc_subscribe(subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_LSM303DLHC, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -// Accelerometer Scale Factor -// Manual table 27, page 27 -const float SCALE_FACTOR[4] = { - 2.0 / 32768.0, - 4.0 / 32768.0, - 8.0 / 32768.0, - 16.0 / 32768.0 -}; - -// Magnetometer Range Factor -// Manual table 75, page 38 -const int RANGE_FACTOR_X_Y[8] = { - 1000, // placeholder - 1100, - 855, - 670, - 450, - 400, - 330, - 230, -}; - -// Magnetometer Range Factor -// Manual table 75, page 38 -const int RANGE_FACTOR_Z[8] = { - 1000, // placeholder - 980, - 760, - 600, - 400, - 355, - 295, - 205 -}; - -unsigned char scale_factor = 0; -unsigned char range_factor = 0; -int temp_offset = LSM303DLHC_TEMPERATURE_OFFSET; - -bool lsm303dlhc_is_present (void) { - LSM303DLHCResponse response; - response.data1 = 0; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 1, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return false; - - yield_for(&(response.done)); - - return response.data1 ? true : false; -} - -bool lsm303dlhc_set_power_mode (unsigned char power_mode, bool low_power) { - LSM303DLHCResponse response; - response.data1 = 0; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 2, power_mode, low_power ? 1 : 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return false; - - yield_for(&(response.done)); - - return response.data1 ? true : false; -} - -bool lsm303dlhc_set_accelerometer_scale_and_resolution (unsigned char scale, bool high_resolution) { - if (scale > 3) scale = 3; - LSM303DLHCResponse response; - response.data1 = 0; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 3, scale, high_resolution ? 1 : 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return false; - - yield_for(&(response.done)); - if (response.data1 == 1) { - scale_factor = scale; - } - - return response.data1 ? true : false; -} - -bool lsm303dlhc_set_temperature_and_magnetometer_rate (bool temperature, unsigned char rate) { - LSM303DLHCResponse response; - response.data1 = 0; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 4, rate, temperature ? 1 : 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return false; - - yield_for(&(response.done)); - - return response.data1 ? true : false; -} - -bool lsm303dlhc_set_magnetometer_range (unsigned char range) { - if (range > 7) range = 7; - LSM303DLHCResponse response; - response.data1 = 0; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return false; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 5, range, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return false; - - yield_for(&(response.done)); - if (response.data1 == 1) { - range_factor = range; - } - - return response.data1 ? true : false; -} - -int lsm303dlhc_read_acceleration_xyz (LSM303DLHCXYZ *xyz) { - LSM303DLHCResponse response; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 6, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - if (xyz != NULL) { - xyz->x = (float)response.data1 * SCALE_FACTOR[scale_factor]; - xyz->y = (float)response.data2 * SCALE_FACTOR[scale_factor]; - xyz->z = (float)response.data3 * SCALE_FACTOR[scale_factor]; - } - - return RETURNCODE_SUCCESS; -} - -int lsm303dlhc_read_temperature (float *temperature) { - LSM303DLHCResponse response; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 7, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - if (temperature != NULL) { - *temperature = (float)response.data1 / 8 + temp_offset; - } - - return RETURNCODE_SUCCESS; -} - -int lsm303dlhc_read_magnetometer_xyz (LSM303DLHCXYZ *xyz) { - LSM303DLHCResponse response; - response.done = false; - - int ret = lsm303dlhc_subscribe(command_callback_yield, &response); - if (ret < 0) return ret; - - syscall_return_t com = command(DRIVER_NUM_LSM303DLHC, 8, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - yield_for(&(response.done)); - if (xyz != NULL) { - printf("x %d range %d z %d\r\n", response.data1, RANGE_FACTOR_X_Y[range_factor], response.data3); - xyz->x = (float)response.data1 / RANGE_FACTOR_X_Y[range_factor]; - xyz->y = (float)response.data2 / RANGE_FACTOR_X_Y[range_factor]; - xyz->z = (float)response.data3 / RANGE_FACTOR_Z[range_factor]; - } - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/lsm303dlhc.h b/libtock/lsm303dlhc.h deleted file mode 100644 index 98a03985a..000000000 --- a/libtock/lsm303dlhc.h +++ /dev/null @@ -1,83 +0,0 @@ -/*LSM303DLHC 3D accelerometer and 3D magnetometer -* -* -* -*/ - -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_LSM303DLHC 0x70006 - -// Power Mode -#define LSM303DLHC_NORMAL 0 -#define LSM303DLHC_LOW_POWER 1 - -// Accelerometer Data Rate -// Manual page Table 20, page 25 -#define LSM303DLHC_OFF 0 -#define LSM303DLHC_1HZ 1 -#define LSM303DLHC_10HZ 2 -#define LSM303DLHC_25HZ 3 -#define LSM303DLHC_50HZ 4 -#define LSM303DLHC_100HZ 5 -#define LSM303DLHC_200HZ 6 -#define LSM303DLHC_400HZ 7 -#define LSM303DLHC_LOW_POWER_1620HZ 8 -#define LSM303DLHC_NORMAL_1344_LOW_POWER_5376HZ 9 - -#define LSM303DLHC_SCALE_2G 0 -#define LSM303DLHC_SCALE_4G 1 -#define LSM303DLHC_SCALE_8G 2 -#define LSM303DLHC_SCALE_16G 3 - -// Accelerometer Data Range -// Manual table 75, page 38 -#define LSM303DLHC_RANGE_1G 0 -#define LSM303DLHC_RANGE_1_3G 1 -#define LSM303DLHC_RANGE_1_9G 2 -#define LSM303DLHC_RANGE_2_5G 3 -#define LSM303DLHC_RANGE_4_0G 4 -#define LSM303DLHC_RANGE_4_7G 5 -#define LSM303DLHC_RANGE_5_6G 6 -#define LSM303DLHC_RANGE_8_1G 7 - -// Magnetometer Data Rate -// Manual table 72, page 25 -#define LSM303DLHC_M_0_75HZ 0 -#define LSM303DLHC_M_1_55HZ 1 -#define LSM303DLHC_M_3_0HZ 2 -#define LSM303DLHC_M_7_5HZ 3 -#define LSM303DLHC_M_15_0HZ 4 -#define LSM303DLHC_M_30_0HZ 5 -#define LSM303DLHC_M_75_0HZ 6 -#define LSM303DLHC_M_220_0HZ 7 - -// Experimental -#define LSM303DLHC_TEMPERATURE_OFFSET 17 - -typedef struct lsm303dlhcxyz { - float x; - float y; - float z; -} LSM303DLHCXYZ; - -bool lsm303dlhc_is_present (void); -bool lsm303dlhc_set_power_mode (unsigned char power_mode, bool low_power); -bool lsm303dlhc_set_accelerometer_scale_and_resolution (unsigned char scale, bool high_resolution); - -bool lsm303dlhc_set_temperature_and_magnetometer_rate (bool temperature, unsigned char rate); -bool lsm303dlhc_set_magnetometer_range (unsigned char range); - -int lsm303dlhc_read_acceleration_xyz (LSM303DLHCXYZ *xyz); -int lsm303dlhc_read_temperature (float *temperature); -int lsm303dlhc_read_magnetometer_xyz (LSM303DLHCXYZ *xyz); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/ltc294x.c b/libtock/ltc294x.c deleted file mode 100644 index cdad5ab47..000000000 --- a/libtock/ltc294x.c +++ /dev/null @@ -1,282 +0,0 @@ -#include "ltc294x.h" -#include "tock.h" - - -struct ltc294x_data { - int charge; - bool fired; -}; - -static struct ltc294x_data result = { .fired = false, .charge = 0 }; - -// Internal callback for faking synchronous reads -static void ltc294x_upcall(__attribute__ ((unused)) int callback_type, - __attribute__ ((unused)) int value, - __attribute__ ((unused)) int chip, - void* ud) { - struct ltc294x_data* data = (struct ltc294x_data*) ud; - data->charge = value; - data->fired = true; -} - -int ltc294x_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_LTC294X, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int ltc294x_read_status(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 1, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_configure(ltc294x_model_e model, - interrupt_pin_conf_e int_pin, - uint16_t prescaler, - vbat_alert_adc_mode_e vbat) { - uint8_t M = 0; - if (model == LTC2941 || model == LTC2942) { - // ltc2941/2 expects log_2 of prescaler value - for (int i = 0; i < 8; i++) { - if ((1 << i) & prescaler) { - M = i; - } - } - } else if (model == LTC2943) { - // See Table 3 in the datasheet. - switch (prescaler) { - case 1: M = 0; - break; - case 4: M = 1; - break; - case 16: M = 2; - break; - case 64: M = 3; - break; - case 256: M = 4; - break; - case 1024: M = 5; - break; - case 4096: M = 7; - break; - default: M = 4; - break; - } - } - - syscall_return_t com = command(DRIVER_NUM_LTC294X, 10, model, 0); - int ret = tock_command_return_novalue_to_returncode(com); - if (ret < 0) return ret; - - uint8_t cmd = (int_pin & 0x03) | ((M & 0x07) << 2) | ((vbat & 0x03) << 5); - com = command(DRIVER_NUM_LTC294X, 2, cmd, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_reset_charge(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 3, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_set_high_threshold(uint16_t threshold) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 4, threshold, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_set_low_threshold(uint16_t threshold) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 5, threshold, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_get_charge(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 6, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_get_voltage(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 8, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_get_current(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 9, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_shutdown(void) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 7, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_set_model(ltc294x_model_e model) { - syscall_return_t com = command(DRIVER_NUM_LTC294X, 10, model, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int ltc294x_read_status_sync(void) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_read_status(); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_configure_sync(ltc294x_model_e model, - interrupt_pin_conf_e int_pin, - uint16_t prescaler, - vbat_alert_adc_mode_e vbat) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_configure(model, int_pin, prescaler, vbat); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_reset_charge_sync(void) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_reset_charge(); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_set_high_threshold_sync(uint16_t threshold) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_set_high_threshold(threshold); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_set_low_threshold_sync(uint16_t threshold) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_set_low_threshold(threshold); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_get_charge_sync(int* charge) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_get_charge(); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - *charge = result.charge; - - return RETURNCODE_SUCCESS; -} - -int ltc294x_get_voltage_sync(int* voltage) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_get_voltage(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *voltage = result.charge; - - return RETURNCODE_SUCCESS; -} - -int ltc294x_get_current_sync(int* current) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_get_current(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *current = result.charge; - - return RETURNCODE_SUCCESS; -} - -int ltc294x_shutdown_sync(void) { - int err; - result.fired = false; - - err = ltc294x_set_callback(ltc294x_upcall, (void*) &result); - if (err < 0) return err; - - err = ltc294x_shutdown(); - if (err < 0) return err; - - // Wait for the ADC callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int ltc294x_convert_to_coulomb_uah(int c, int Rsense, uint16_t prescaler, ltc294x_model_e model) { - if (model == LTC2941 || model == LTC2942) { - return (int)(c * 85 * (50.0 / Rsense) * (prescaler / 128.0)); - } else { - return (int)(c * 340 * (50.0 / Rsense) * (prescaler / 4096.0)); - } -} - -int ltc294x_convert_to_voltage_mv (int v) { - return 23.6 * (v / (float)0xFFFF) * 1000; -} - -int ltc294x_convert_to_current_ua (int c, int Rsense) { - return (int)((60.0 / Rsense) * ((c - 0x7FFF) / (float)0x7FFF) * 1000000.0); -} diff --git a/libtock/ltc294x.h b/libtock/ltc294x.h deleted file mode 100644 index 2a533e20c..000000000 --- a/libtock/ltc294x.h +++ /dev/null @@ -1,132 +0,0 @@ -#pragma once - -#include - -#include "tock.h" - -#define DRIVER_NUM_LTC294X 0x80000 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - InterruptPinDisabled = 0, - InterruptPinChargeCompleteMode = 1, - InterruptPinAlertMode = 2, -} interrupt_pin_conf_e; - -typedef enum { - // LTC2941 - VbatAlertOff = 0, - VbatAlert2V8 = 1, - VbatAlert2V9 = 2, - VbatAlert3V0 = 3, - // LTC29412/3 - ADCSleep = 0, - ADCManual = 1, - ADCScan = 2, - ADCAuto = 3, -} vbat_alert_adc_mode_e; - -typedef enum { - LTC2941 = 1, - LTC2942 = 2, - LTC2943 = 3, -} ltc294x_model_e; - - -// Set a callback for the LTC294X driver. -// -// The callback function should look like: -// -// void callback (int callback_type, int data, int data2, void* callback_args) -// -// callback_type is one of: -// 0: If the interrupt pin is setup in the kernel, the interrupt occurred. -// 1: Got the contents of the status register. `data` is: -// bit 0: Undervoltage lockout (bool) -// bit 1: VBat Alert (bool) -// bit 2: Charge Alert Low (bool) -// bit 3: Charge Alert High (bool) -// bit 4: Accumulated Charge Overflow/Underflow (bool) -// and `data2` is the Chip type: -// 1 = LTC2941 -// 2 = LTC2942 -// 3 = LTC2943 -// 2: Got the charge value. -// 3: A write operation finished. -int ltc294x_set_callback (subscribe_upcall callback, void* callback_args); - -// Get the current value of the status register. The result will be returned -// in the callback. -int ltc294x_read_status(void); - -// Setup the LTC294X by configuring its !AL/CC pin, charge counting prescaler, -// and VBat alert threshold or ADC mode. -// Will trigger a `done` callback. -int ltc294x_configure(ltc294x_model_e model, - interrupt_pin_conf_e int_pin, - uint16_t prescaler, - vbat_alert_adc_mode_e vbat); - -// Set the current accumulated charge register to 0. -// Will trigger a `done` callback. -int ltc294x_reset_charge(void); - -// Configure the high charge threshold. This will be triggered when the -// accumulated charge is greater than this value. -// Will trigger a `done` callback when the register has been set. -int ltc294x_set_high_threshold(uint16_t threshold); - -// Configure the low charge threshold. This will be triggered when the -// accumulated charge is lower than this value. -// Will trigger a `done` callback when the register has been set. -int ltc294x_set_low_threshold(uint16_t threshold); - -// Read the current charge. -// Will be returned in the callback. -int ltc294x_get_charge(void); - -// Get the current voltage. Not supported on all models. -// Will be returned in the callback. -int ltc294x_get_voltage(void); - -// Get the current current reading. Not supported on all models. -// Will be returned in the callback. -int ltc294x_get_current(void); - -// Put the LTC294X in a low power state. -// Will trigger a `done` callback. -int ltc294x_shutdown(void); - -// Configure which LTC294X chip we are actually using. -int ltc294x_set_model(ltc294x_model_e model); - - -// -// Synchronous Versions -// -int ltc294x_read_status_sync(void); -int ltc294x_configure_sync(ltc294x_model_e model, - interrupt_pin_conf_e int_pin, - uint16_t prescaler, - vbat_alert_adc_mode_e vbat); -int ltc294x_reset_charge_sync(void); -int ltc294x_set_high_threshold_sync(uint16_t threshold); -int ltc294x_set_low_threshold_sync(uint16_t threshold); -int ltc294x_get_charge_sync(int* charge); -int ltc294x_get_voltage_sync(int* voltage); -int ltc294x_get_current_sync(int* current); -int ltc294x_shutdown_sync(void); - -// -// Helpers -// -int ltc294x_convert_to_coulomb_uah(int c, int Rsense, uint16_t prescaler, ltc294x_model_e model) __attribute__((const)); -int ltc294x_convert_to_voltage_mv(int v) __attribute__((const)); -int ltc294x_convert_to_current_ua(int c, int Rsense) __attribute__((const)); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/max17205.c b/libtock/max17205.c deleted file mode 100644 index 81e3d2880..000000000 --- a/libtock/max17205.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "max17205.h" -#include "tock.h" - -struct max17205_data { - int rc; - int value0; - int value1; - bool fired; -}; - -static struct max17205_data result = { .fired = false, .rc = 0, .value0 = 0, .value1 = 0 }; -static subscribe_upcall* user_upcall = NULL; - -// Internal callback for faking synchronous reads -static void internal_user_upcall(int status, - int value0, - int value1, - void* ud) { - - struct max17205_data* data = (struct max17205_data*) ud; - data->rc = tock_status_to_returncode(status); - data->value0 = value0; - data->value1 = value1; - data->fired = true; -} - -// Lower level CB that allows us to stop more commands while busy -static void max17205_upcall(int return_code, - int value0, - int value1, - void* ud) { - if (user_upcall) { - user_upcall(return_code, value0, value1, ud); - } -} - -int max17205_set_callback (subscribe_upcall callback, void* callback_args) { - // Set the user-level calllback to the provided one - user_upcall = callback; - - // Subscribe to the callback with our lower-layer callback, but pass - // callback arguments. - subscribe_return_t sval = subscribe(DRIVER_NUM_MAX17205, 0, max17205_upcall, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int max17205_read_status(void) { - - syscall_return_t com = command(DRIVER_NUM_MAX17205, 1, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int max17205_read_soc(void) { - syscall_return_t com = command(DRIVER_NUM_MAX17205, 2, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int max17205_read_voltage_current(void) { - syscall_return_t com = command(DRIVER_NUM_MAX17205, 3, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int max17205_read_coulomb(void) { - syscall_return_t com = command(DRIVER_NUM_MAX17205, 4, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int max17205_read_rom_id(void) { - syscall_return_t com = command(DRIVER_NUM_MAX17205, 5, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int max17205_read_status_sync(uint16_t* status) { - int err; - result.fired = false; - - err = max17205_set_callback(internal_user_upcall, (void*) &result); - if (err < 0) return err; - - err = max17205_read_status(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *status = result.value0 & 0xFFFF; - - return result.rc; -} - -int max17205_read_soc_sync(uint16_t* percent, uint16_t* soc_mah, uint16_t* soc_mah_full) { - int err; - result.fired = false; - - err = max17205_set_callback(internal_user_upcall, (void*) &result); - if (err < 0) return err; - - err = max17205_read_soc(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *percent = result.value0 & 0xFFFF; - *soc_mah = (result.value1 & 0xFFFF0000) >> 16; - *soc_mah_full = result.value1 & 0xFFFF; - - return result.rc; -} - -int max17205_read_voltage_current_sync(uint16_t* voltage, int16_t* current) { - int err; - result.fired = false; - - err = max17205_set_callback(internal_user_upcall, (void*) &result); - if (err < 0) return err; - - err = max17205_read_voltage_current(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *voltage = result.value0 & 0xFFFF; - *current = result.value1 & 0xFFFF; - - return result.rc; -} - -int max17205_read_coulomb_sync(uint16_t* coulomb) { - int err; - result.fired = false; - - err = max17205_set_callback(internal_user_upcall, (void*) &result); - if (err < 0) return err; - - err = max17205_read_coulomb(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *coulomb = result.value0 & 0xFFFF; - - return result.rc; -} - -int max17205_read_rom_id_sync(uint64_t* rom_id) { - int err; - result.fired = false; - - err = max17205_set_callback(internal_user_upcall, (void*) &result); - if (err < 0) return err; - - err = max17205_read_rom_id(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - uint64_t temp = result.value0; - temp <<= 32; - temp |= result.value1 & 0x00000000FFFFFFFF; - *rom_id = temp; - - return result.rc; -} - -float max17205_get_voltage_mV(int vcount) { - return vcount * 1.25; -} - -float max17205_get_current_uA(int ccount) { - return ccount * 108; -} - -float max17205_get_percentage_mP(int percent) { - return ((float)percent / 26000.0) * 100000.0; -} - -float max17205_get_capacity_uAh(int cap) { - return (float)cap * (5.0 / .01); -} diff --git a/libtock/max17205.h b/libtock/max17205.h deleted file mode 100644 index b2eb31bf0..000000000 --- a/libtock/max17205.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_MAX17205 0x80001 - -// Set a callback for the MAX17205 driver. -// -// The callback function should look like: -// -// void callback (int return_code, int data, int data2, void* callback_args) -// -// callback_type is one of: -// read_status `data` is: -// status -// read_soc `data` is: -// percent charged in %/255 -// and `data2` is the capacity and full capacity: -// word 0 (u16): full capacity in 0.5mAh -// word 1 (u16): current capacity in 0.5mAh -// read_voltage_current `data` is: -// voltage in 1.25mV -// and 'data2' is: -// current in 156.25uA -// read_coulomb `data` is: -// raw coulombs -// -// The callback will be associated the most recent successful -// call to the driver. If a command is called during an outstanding -// command, EBUSY will be returned. -int max17205_set_callback (subscribe_upcall callback, void* callback_args); - -// Get the current status of the battery -// Result is returned in callback. -int max17205_read_status(void); - -// Get the current state of charge of the battery. -// Result is returned in callback. -int max17205_read_soc(void); - -// Get the current voltage and current of the battery. -// Result is returned in callback. -int max17205_read_voltage_current(void); - -// Get current count on the coulomb counter -int max17205_read_coulomb (void); - -// Get the unique 64bit RomID of the chip -// Result is stored in the passed in buffer -// Buffer must be at least 8 bytes long -int max17205_read_rom_id (void); - -// -// Synchronous Versions -// -int max17205_read_status_sync(uint16_t* state); -int max17205_read_soc_sync(uint16_t* percent, uint16_t* soc_mah, uint16_t* soc_mah_full); -int max17205_read_voltage_current_sync(uint16_t* voltage, int16_t* current); -int max17205_read_coulomb_sync (uint16_t* coulomb); -int max17205_read_rom_id_sync (uint64_t* rom_id_buf); - -// -// Helper functions -// -float max17205_get_voltage_mV(int vcount) __attribute__((const)); -float max17205_get_current_uA(int ccount) __attribute__((const)); -float max17205_get_percentage_mP(int percent) __attribute__((const)); -float max17205_get_capacity_uAh(int cap) __attribute__((const)); - - -#ifdef __cplusplus -} -#endif diff --git a/libtock/ble.c b/libtock/net/ble.c similarity index 100% rename from libtock/ble.c rename to libtock/net/ble.c diff --git a/libtock/ble.h b/libtock/net/ble.h similarity index 98% rename from libtock/ble.h rename to libtock/net/ble.h index e469a2326..ce51ff938 100644 --- a/libtock/ble.h +++ b/libtock/net/ble.h @@ -1,6 +1,6 @@ #pragma once -#include "tock.h" +#include "../tock.h" #ifdef __cplusplus extern "C" { @@ -30,7 +30,7 @@ extern "C" { #define ADV_IND 0x00 #define ADV_DIRECT_IND 0x01 #define ADV_NONCONN_IND 0x02 -#define ADV_SCAN_IND 0x06 +#define ADV_SCAN_IND 0x06 typedef enum { POSITIVE_10_DBM = 10, diff --git a/libtock/net/eui64.c b/libtock/net/eui64.c new file mode 100644 index 000000000..cbf839cdf --- /dev/null +++ b/libtock/net/eui64.c @@ -0,0 +1,5 @@ +#include "eui64.h" + +returncode_t libtock_eui64_get(uint64_t *eui64) { + return libtock_eui64_command_get(eui64); +} diff --git a/libtock/net/eui64.h b/libtock/net/eui64.h new file mode 100644 index 000000000..dec6933bd --- /dev/null +++ b/libtock/net/eui64.h @@ -0,0 +1,14 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/eui64_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +returncode_t libtock_eui64_get(uint64_t* eui64); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/ieee802154.c b/libtock/net/ieee802154.c new file mode 100644 index 000000000..918b799d1 --- /dev/null +++ b/libtock/net/ieee802154.c @@ -0,0 +1,694 @@ +#include + +#include "ieee802154.h" + +bool libtock_ieee802154_driver_exists(void){ + return driver_exists(DRIVER_NUM_IEEE802154); +} + +// Temporary buffer used for some commands where the system call interface +// parameters / return codes are not enough te contain the required data. +uint8_t BUF_CFG[27]; + +int libtock_ieee802154_down(void) { + // Currently unsupported: there is no way to implement this with the existing + // radio interface. + return RETURNCODE_ENOSUPPORT; +} + +returncode_t libtock_ieee802154_is_up(bool *status) { + returncode_t ret = libtock_ieee802154_command_status(); + if (ret == RETURNCODE_EOFF) { + *status = false; + } else if (ret == RETURNCODE_SUCCESS) { + *status = true; + } + + return ret; +} + +returncode_t libtock_ieee802154_set_address_short(uint16_t addr_short) { + return libtock_ieee802154_command_set_address_short(addr_short); +} + +returncode_t libtock_ieee802154_set_address_long(uint8_t *addr_long) { + if (!addr_long) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) addr_long, 8); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_set_address_long(); + + // unallow the rw buffer from the kernel so that other libtock functions + // can utilize and modify the buffer + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + return ret; +} + +returncode_t libtock_ieee802154_set_pan(uint16_t pan) { + return libtock_ieee802154_command_set_pan(pan); +} + +returncode_t libtock_ieee802154_set_channel(uint8_t channel) { + return libtock_ieee802154_command_set_channel(channel); +} + +returncode_t libtock_ieee802154_set_power(uint32_t power) { + // Cast the signed uint8_t to an uint8_t before zero-padding it. + return libtock_ieee802154_command_set_power(power); +} + +returncode_t libtock_ieee802154_config_commit(void) { + return libtock_ieee802154_command_config_commit(); +} + +returncode_t libtock_ieee802154_get_address_short(uint16_t *addr) { + if (!addr) return RETURNCODE_EINVAL; + + uint32_t addr_ret; // Command returncode holds u32 return value. + returncode_t ret = libtock_ieee802154_command_get_address_short(&addr_ret); + + // Driver adds 1 to make the value positive. + *addr = addr_ret - 1; + + return ret; +} + +returncode_t libtock_ieee802154_get_address_long(uint8_t *addr_long) { + if (!addr_long) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) addr_long, 8); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_get_address_long(); + + // unallow the rw buffer from the kernel so that other libtock functions + // can utilize and modify the buffer + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + return ret; +} + +returncode_t libtock_ieee802154_get_pan(uint16_t *pan) { + if (!pan) return RETURNCODE_EINVAL; + + uint32_t pan_ret; // Command returncode holds u32 return value. + returncode_t ret = libtock_ieee802154_command_get_pan(&pan_ret); + + // Driver adds 1 to make the value positive. + *pan = pan_ret - 1; + + return ret; +} + +returncode_t libtock_ieee802154_get_channel(uint8_t *channel) { + if (!channel) return RETURNCODE_EINVAL; + + uint32_t channel_ret; // Command returncode holds u32 return value. + returncode_t ret = libtock_ieee802154_command_get_channel(&channel_ret); + + // Driver adds 1 to make the value positive. + *channel = channel_ret - 1; + return ret; +} + +returncode_t libtock_ieee802154_get_power(uint32_t *power) { + if (!power) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_command_get_power(power); + + // Driver adds 1 to the power after casting it to unsigned, so this works + *power -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_max_neighbors(uint32_t* neighbors) { + if (!neighbors) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_command_get_max_neighbors(neighbors); + + // Driver adds 1 to the power after casting it to unsigned, so this works + *neighbors -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_num_neighbors(uint32_t* num_neighbors) { + if (!num_neighbors) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_command_get_number_neighbors(num_neighbors); + + // Driver adds 1 to the power after casting it to unsigned, so this works + *num_neighbors -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_get_neighbor_address_short(uint32_t index, uint16_t *addr) { + if (!addr) return RETURNCODE_EINVAL; + + uint32_t addr_ret; // Command returncode holds u32 return value. + returncode_t ret = libtock_ieee802154_command_get_neighbor_address_short(index, &addr_ret); + + // Driver adds 1 to ensure it is positive. + *addr = addr_ret - 1; + + return ret; +} + +returncode_t libtock_ieee802154_get_neighbor_address_long(uint32_t index, uint8_t *addr_long) { + if (!addr_long) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) addr_long, 8); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_get_neighbor_address_long(index); + + // unallow the rw buffer from the kernel so that other libtock functions + // can utilize and modify the buffer + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + return ret; +} + +returncode_t libtock_ieee802154_get_neighbor(uint32_t index, + uint16_t *addr_short, + uint8_t * addr_long) { + returncode_t ret = libtock_ieee802154_get_neighbor_address_short(index, addr_short); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_ieee802154_get_neighbor_address_long(index, addr_long); +} + +returncode_t libtock_ieee802154_add_neighbor(uint16_t addr_short, uint8_t *addr_long, uint32_t *index) { + if (!addr_long) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) addr_long, 8); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_add_neighbor(addr_short, index); + + // unallow the rw buffer from the kernel so that other libtock functions + // can utilize and modify the buffer + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + if (ret != RETURNCODE_SUCCESS) return ret; + + // Driver adds 1 to ensure it is positive. + *index -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_remove_neighbor(uint32_t index) { + return libtock_ieee802154_command_remove_neighbor(index); +} + +returncode_t libtock_ieee802154_max_keys(uint32_t* max_keys) { + returncode_t ret = libtock_ieee802154_command_get_max_keys(max_keys); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Driver adds 1 to ensure it is positive. + *max_keys -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_num_keys(uint32_t* key_count) { + returncode_t ret = libtock_ieee802154_command_get_num_keys(key_count); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Driver adds 1 to ensure it is positive. + *key_count -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_get_key_security_level(uint32_t index, security_level_t *level) { + if (!level) return RETURNCODE_EINVAL; + + uint32_t ret_level; + returncode_t ret = libtock_ieee802154_command_get_key_security_level(index, &ret_level); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Driver adds 1 to ensure it is positive. + ret_level -= 1; + *level = (security_level_t) ret_level; + + return ret; +} + +returncode_t libtock_ieee802154_key_id_bytes(key_id_mode_t key_id_mode) { + switch (key_id_mode) { + default: + case KEY_ID_IMPLICIT: + return 0; + case KEY_ID_INDEX: + return 1; + case KEY_ID_SRC_4_INDEX: + return 5; + case KEY_ID_SRC_8_INDEX: + return 9; + } +} + +returncode_t libtock_ieee802154_get_key_id(uint32_t index, + key_id_mode_t *key_id_mode, + uint8_t * key_id) { + if (!key_id_mode || !key_id) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) BUF_CFG, 10); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_get_key_id(index); + + // unallow the rw buffer from the kernel prior to accessing the buffer. + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + if (ret == RETURNCODE_SUCCESS) { + *key_id_mode = (key_id_mode_t) (BUF_CFG[0]); + memcpy(key_id, BUF_CFG + 1, libtock_ieee802154_key_id_bytes(*key_id_mode)); + } + return ret; +} + +returncode_t libtock_ieee802154_get_key(uint32_t index, uint8_t *key) { + if (!key) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) BUF_CFG, 16); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_get_key(index); + + // unallow the rw buffer from the kernel prior to accessing the buffer. + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + if (ret == RETURNCODE_SUCCESS) { + memcpy(key, BUF_CFG, 16); + } + + return ret; +} + +returncode_t libtock_ieee802154_get_key_desc(uint32_t index, + security_level_t *level, + key_id_mode_t * key_id_mode, + uint8_t * key_id, + uint8_t * key) { + returncode_t ret = libtock_ieee802154_get_key_security_level(index, level); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_get_key_id(index, key_id_mode, key_id); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_ieee802154_get_key(index, key); +} + +returncode_t libtock_ieee802154_add_key(security_level_t level, + key_id_mode_t key_id_mode, + uint8_t * key_id, + uint8_t * key, + uint32_t * index) { + if (!key) return RETURNCODE_EINVAL; + + BUF_CFG[0] = level; + BUF_CFG[1] = key_id_mode; + int bytes = libtock_ieee802154_key_id_bytes(key_id_mode); + if (bytes > 0) { + memcpy(BUF_CFG + 2, key_id, bytes); + } + memcpy(BUF_CFG + 2 + 9, key, 16); + + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) BUF_CFG, 27); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_ieee802154_command_add_key(index); + + // unallow the rw buffer from the kernel so that other libtock functions + // can utilize and modify the buffer. + libtock_ieee802154_set_readwrite_allow_cfg(NULL, 0); + + // Driver adds 1 to ensure it is positive. + *index -= 1; + + return ret; +} + +returncode_t libtock_ieee802154_remove_key(uint32_t index) { + return libtock_ieee802154_command_remove_key(index); +} + +// Internal callback for transmission +static void tx_done_upcall(int status, + int acked, + __attribute__ ((unused)) int unused2, + void * opaque) { + libtock_ieee802154_callback_send_done cb = (libtock_ieee802154_callback_send_done) opaque; + cb(status, acked); +} + +returncode_t libtock_ieee802154_send(uint32_t addr, + security_level_t level, + key_id_mode_t key_id_mode, + uint8_t * key_id, + const uint8_t * payload, + uint8_t len, + libtock_ieee802154_callback_send_done cb) { + // Setup parameters in CFG + BUF_CFG[0] = level; + BUF_CFG[1] = key_id_mode; + int bytes = libtock_ieee802154_key_id_bytes(key_id_mode); + if (bytes > 0) { + memcpy(BUF_CFG + 2, key_id, bytes); + } + + // Allow CFG buffer to the kernel + returncode_t ret = libtock_ieee802154_set_readwrite_allow_cfg((void *) BUF_CFG, 27); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Allow payload buffer to the kernel + ret = libtock_ieee802154_set_readonly_allow((void *) payload, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Subscribe the provided callback using the internal tx_done_upcall. + ret = libtock_ieee802154_set_upcall_frame_transmitted(tx_done_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Issue the send command and wait for the transmission to be done. + ret = libtock_ieee802154_command_send(addr); + if (ret != RETURNCODE_SUCCESS) return ret; + + return ret; +} + +returncode_t libtock_ieee802154_send_raw( + const uint8_t * payload, + uint8_t len, + libtock_ieee802154_callback_send_done cb) { + // Setup parameters in ALLOW_RO_TX. + returncode_t ret = libtock_ieee802154_set_readonly_allow((void *) payload, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Subscribe the provided callback using the internal tx_done_upcall. + ret = libtock_ieee802154_set_upcall_frame_transmitted(tx_done_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Issue the send command + return libtock_ieee802154_command_send_raw(); +} + +// Internal callback for receive +static void rx_done_upcall(int pans, + int dst_addr, + int src_addr, + void* opaque) { + libtock_ieee802154_callback_recv_done cb = (libtock_ieee802154_callback_recv_done) opaque; + cb(pans, dst_addr, src_addr); +} + +returncode_t libtock_ieee802154_receive(const libtock_ieee802154_rxbuf * frame, + libtock_ieee802154_callback_recv_done cb) { + // Provide the ring buffer to the kernel + returncode_t ret = libtock_ieee802154_set_readwrite_allow_rx((uint8_t *) frame, libtock_ieee802154_RING_BUFFER_LEN); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Subscribe the provided callback using the internal rx_done_upcall. + return libtock_ieee802154_set_upcall_frame_received(rx_done_upcall, cb); +} + +returncode_t libtock_reset_ring_buf(const libtock_ieee802154_rxbuf* frame, subscribe_upcall callback, void* ud) { + returncode_t ret = libtock_ieee802154_set_readwrite_allow_rx((uint8_t *) frame, + (frame) ? libtock_ieee802154_RING_BUFFER_LEN : 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_ieee802154_set_upcall_frame_received(callback, ud); +} + +uint8_t* libtock_ieee802154_read_next_frame(const libtock_ieee802154_rxbuf* frame) { + if (!frame) return NULL; + + uint8_t *rx_buf = (uint8_t *) frame; + int read_index = rx_buf[0]; + int write_index = rx_buf[1]; + if (read_index == write_index) { + return NULL; + } + rx_buf[0]++; + if (rx_buf[0] >= libtock_ieee802154_MAX_RING_BUF_FRAMES) { + rx_buf[0] = 0; + } + return &rx_buf[libtock_ieee802154_RING_BUF_META_LEN + (read_index * libtock_ieee802154_FRAME_LEN)]; +} + +int libtock_ieee802154_frame_get_length(const uint8_t *frame) { + if (!frame) return 0; + // data_offset + data_len - 2 header bytes + return frame[0] + frame[1] - 2; +} + +int libtock_ieee802154_frame_get_payload_offset(const uint8_t *frame) { + if (!frame) return 0; + return frame[0]; +} + +int libtock_ieee802154_frame_get_payload_length(const uint8_t *frame) { + if (!frame) return 0; + return frame[1]; +} + +// Utility function to determine if the source and destination PAN and +// addresses are present depending on the frame control field. This is used +// only internally as a header parsing subroutine. Supports only 2003, 2006 or +// 2015 frame versions. Returns false if the addressing mode combination is +// invalid or the frame version is not supported. All out-parameters must be +// provided. +// +// If the source pan is dropped, that means that it is the same as the +// destination pan, which must be present. +static bool libtock_ieee802154_get_addressing(uint16_t frame_control, + bool * dst_pan_present, + addr_mode_t *dst_mode, + bool * src_pan_present, + bool * src_pan_dropped, + addr_mode_t *src_mode) { + if (!dst_pan_present || !dst_mode || !src_pan_present || !src_pan_dropped || + !src_mode) { + return false; + } + + typedef enum { + VERSION_2003 = 0x0, + VERSION_2006 = 0x1, + VERSION_2015 = 0x2, + } version_t; + + // Fields that determine if the PANs are present + version_t version = (version_t) ((frame_control >> 12) & 0x3); + *dst_mode = (addr_mode_t) ((frame_control >> 10) & 0x3); + *src_mode = (addr_mode_t) ((frame_control >> 14) & 0x3); + bool pan_id_compression = (frame_control >> 6) & 0x1; + bool dst_present = dst_mode != ADDR_NONE; + bool src_present = src_mode != ADDR_NONE; + + // The flags that we are trying to determine + *src_pan_dropped = false; + + // IEEE 802.15.4: Section 7.2.1.5 determines whether the PANs are present + // depending on the pan ID compression field and the addressing modes. + if (version == VERSION_2015) { + if (dst_present) { + if (src_present) { + *src_pan_dropped = pan_id_compression; + *dst_pan_present = true; + *src_pan_present = !pan_id_compression; + } else { + *dst_pan_present = !pan_id_compression; + *src_pan_present = false; + } + } else { + if (src_present) { + *dst_pan_present = false; + *src_pan_present = !pan_id_compression; + } else { + *dst_pan_present = pan_id_compression; + *src_pan_present = false; + } + } + } else if (version == VERSION_2003 || version == VERSION_2006) { + *src_pan_dropped = pan_id_compression; + *dst_pan_present = dst_present; + *src_pan_present = src_present && !src_pan_dropped; + } else { + return false; + } + + // Check validity of addressing modes + if (*src_pan_dropped && !*dst_pan_present) { + return 0xff; + } + + return true; +} + +// Utility function to obtain the frame control field from a frame +static void libtock_ieee802154_get_frame_control(const uint8_t *frame, uint16_t *frame_control) { + if (!frame || !frame_control) return; + *frame_control = ((uint16_t) frame[libtock_ieee802154_FRAME_META_LEN]) | + (((uint16_t) frame[libtock_ieee802154_FRAME_META_LEN + 1]) << 8); +} + +// Utility function to obtain the address offset from a frame +static void libtock_ieee802154_get_addr_offset(const uint8_t *frame, uint16_t *addr_offset, uint16_t *frame_control, + const uint16_t *SEQ_SUPPRESSED) { + if (!frame || !addr_offset || !frame_control || !SEQ_SUPPRESSED) return; + *addr_offset = ((*frame_control & *SEQ_SUPPRESSED) ? 2 : 3) + libtock_ieee802154_FRAME_META_LEN; +} + +addr_mode_t libtock_ieee802154_frame_get_dst_addr(__attribute__ ((unused)) const uint8_t * frame, + __attribute__ ((unused)) uint16_t * short_addr, + __attribute__ ((unused)) uint8_t * long_addr) { + if (!frame) return ADDR_NONE; + + uint16_t frame_control; + libtock_ieee802154_get_frame_control(frame, &frame_control); + + bool dst_pan_present, src_pan_present, src_pan_dropped; + addr_mode_t dst_mode, src_mode; + if (!libtock_ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, + &src_pan_present, &src_pan_dropped, &src_mode)) { + return ADDR_NONE; + } + + // The addressing fields are after the sequence number, which can be ommitted + const uint16_t SEQ_SUPPRESSED = 0x0100; + uint16_t addr_offset; + libtock_ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); + + if (dst_pan_present) addr_offset += 2; + + if (dst_mode == ADDR_SHORT && short_addr) { + *short_addr = ((uint16_t) frame[addr_offset]) | + (((uint16_t) frame[addr_offset + 1]) << 8); + } + if (dst_mode == ADDR_LONG && long_addr) { + int i; + for (i = 0; i < 8; i++) { + long_addr[i] = frame[addr_offset + 7 - i]; + } + } + + return dst_mode; +} + +addr_mode_t libtock_ieee802154_frame_get_src_addr(__attribute__ ((unused)) const uint8_t * frame, + __attribute__ ((unused)) uint16_t * short_addr, + __attribute__ ((unused)) uint8_t * long_addr) { + if (!frame) return ADDR_NONE; + + uint16_t frame_control; + libtock_ieee802154_get_frame_control(frame, &frame_control); + + bool dst_pan_present, src_pan_present, src_pan_dropped; + addr_mode_t dst_mode, src_mode; + if (!libtock_ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, + &src_pan_present, &src_pan_dropped, &src_mode)) { + return ADDR_NONE; + } + + // The addressing fields are after the sequence number, which can be ommitted + const uint16_t SEQ_SUPPRESSED = 0x0100; + uint16_t addr_offset; + libtock_ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); + + if (dst_pan_present) addr_offset += 2; + if (dst_mode == ADDR_SHORT) { + addr_offset += 2; + } else if (dst_mode == ADDR_LONG) { + addr_offset += 8; + } + if (src_pan_present) addr_offset += 2; + + if (src_mode == ADDR_SHORT && short_addr) { + *short_addr = ((uint16_t) frame[addr_offset]) | + (((uint16_t) frame[addr_offset + 1]) << 8); + } + if (src_mode == ADDR_LONG && long_addr) { + int i; + for (i = 0; i < 8; i++) { + long_addr[i] = frame[addr_offset + 7 - i]; + } + } + + return src_mode; +} + +bool libtock_ieee802154_frame_get_dst_pan(__attribute__ ((unused)) const uint8_t * frame, + __attribute__ ((unused)) uint16_t * pan) { + if (!frame) return false; + + uint16_t frame_control; + libtock_ieee802154_get_frame_control(frame, &frame_control); + + bool dst_pan_present, src_pan_present, src_pan_dropped; + addr_mode_t dst_mode, src_mode; + if (!libtock_ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, + &src_pan_present, &src_pan_dropped, &src_mode)) { + return false; + } + + // The addressing fields are after the sequence number, which can be ommitted + const uint16_t SEQ_SUPPRESSED = 0x0100; + uint16_t addr_offset; + libtock_ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); + + if (dst_pan_present && pan) { + *pan = ((uint16_t) frame[addr_offset]) | + (((uint16_t) frame[addr_offset + 1]) << 8); + } + + return dst_pan_present; +} + +bool libtock_ieee802154_frame_get_src_pan(__attribute__ ((unused)) const uint8_t * frame, + __attribute__ ((unused)) uint16_t * pan) { + if (!frame) return false; + + uint16_t frame_control; + libtock_ieee802154_get_frame_control(frame, &frame_control); + + bool dst_pan_present, src_pan_present, src_pan_dropped; + addr_mode_t dst_mode, src_mode; + if (!libtock_ieee802154_get_addressing(frame_control, &dst_pan_present, &dst_mode, + &src_pan_present, &src_pan_dropped, &src_mode)) { + return false; + } + + // The addressing fields are after the sequence number, which can be ommitted + const uint16_t SEQ_SUPPRESSED = 0x0100; + uint16_t addr_offset; + libtock_ieee802154_get_addr_offset(frame, &addr_offset, &frame_control, &SEQ_SUPPRESSED); + + if (src_pan_dropped) { + // We can assume that the destination pan is present. + if (pan) { + *pan = ((uint16_t) frame[addr_offset]) | + (((uint16_t) frame[addr_offset + 1]) << 8); + } + } else { + if (dst_pan_present) addr_offset += 2; + if (dst_mode == ADDR_SHORT) { + addr_offset += 2; + } else if (dst_mode == ADDR_LONG) { + addr_offset += 8; + } + + if (src_pan_present && pan) { + *pan = ((uint16_t) frame[addr_offset]) | + (((uint16_t) frame[addr_offset + 1]) << 8); + } + } + + return src_pan_present || src_pan_dropped; +} diff --git a/libtock/ieee802154.h b/libtock/net/ieee802154.h similarity index 65% rename from libtock/ieee802154.h rename to libtock/net/ieee802154.h index 97f922879..5cb8dcc59 100644 --- a/libtock/ieee802154.h +++ b/libtock/net/ieee802154.h @@ -1,22 +1,23 @@ #pragma once -#include "tock.h" +#include "../tock.h" +#include "syscalls/ieee802154_syscalls.h" /* IEEE 802.15.4 system call interface */ -// The libtock-c IEEE 802.15.4 driver consists of a set of system calls +// The libtock-c IEEE 802.15.4 driver consists of a set of system calls // and data types to interface with the kernel. To receive, the user process -// must provide a ring buffer to the kernel of the type `ieee802154_rxbuf`. +// must provide a ring buffer to the kernel of the type `libtock_ieee802154_rxbuf`. // Upon receiving a frame, the kernel will write the frame into the ring buffer -// and schedule an upcall that is to be be handled by the userprocess. Before -// reading the frame, the userprocess must call `reset_ring_buffer` to +// and schedule an upcall that is to be be handled by the userprocess. Before +// reading the frame, the userprocess must call `reset_ring_buffer` to // unallow the ring buffer and unsubscribe upcalls (so as to clear pending upcalls). // The userprocess can then read the frame from the ring buffer and process it. // Given the non-deterministic nature of upcalls, the userprocess must carefully // handle receiving upcalls. There exists a risk of dropping 15.4 packets while // reading from the ring buffer (as the ring buffer is unallowed while reading). -// This can be handled by utilizing two ring buffers and alternating which -// belongs to the kernel and which is being read from. An example of this can be -// found in libtock-c/ot-tock/platform/platform-tock/system.c. Alternatively, +// This can be handled by utilizing two ring buffers and alternating which +// belongs to the kernel and which is being read from. An example of this can be +// found in libtock-c/ot-tock/platform/platform-tock/system.c. Alternatively, // the user can also utilize a single ring buffer if dropped frames may be permissible // (see libtock-c/examples/tests/ieee802154/radio_rx/main.c for an example of this). @@ -24,111 +25,110 @@ extern "C" { #endif -// Check for presence of the driver -bool ieee802154_driver_exists(void); +typedef void (*libtock_ieee802154_callback_send_done)(statuscode_t, bool); +typedef void (*libtock_ieee802154_callback_recv_done)(int, int, int); -// Synchronously enable the 802.15.4 radio. Returns once the radio is fully -// initialized. -int ieee802154_up(void); +// Check for presence of the driver +bool libtock_ieee802154_driver_exists(void); -// Disable the 802.15.4 radio. -int ieee802154_down(void); +// Disable the 802.15.4 radio. -- NOT SUPPORTED -- +int libtock_ieee802154_down(void); // Returns true if the 802.15.4 radio is up. -bool ieee802154_is_up(void); +returncode_t libtock_ieee802154_is_up(bool *status); // IEEE 802.15.4 device configuration interface. After any calls to -// ieee_802154_set_*, ieee802154_config_commit must be called at least once. +// ieee_802154_set_*, libtock_ieee802154_config_commit must be called at least once. // Otherwise, it is not guaranteed that the configuration will reach the underlying // MAC device. Also note that this state is shared between multiple processes. // Sets the short MAC address (16 bits). // `addr` (in): Short MAC address. -int ieee802154_set_address(unsigned short addr); +returncode_t libtock_ieee802154_set_address_short(uint16_t addr); // Sets the long MAC address (64 bits) // `addr_long` (in): Long MAC address. Must point to 8 bytes of valid memory. -int ieee802154_set_address_long(unsigned char *addr_long); +returncode_t libtock_ieee802154_set_address_long(uint8_t *addr_long); // Sets the 802.15.4 PAN ID (16 bits) // `pan` (in): PAN ID. -int ieee802154_set_pan(unsigned short pan); +returncode_t libtock_ieee802154_set_pan(uint16_t pan); // Sets the 802.15.4 channel. // `channel` (in): 802.15.4 channel. 11 <= channel <= 26. -int ieee802154_set_channel(unsigned char channel); +returncode_t libtock_ieee802154_set_channel(uint8_t channel); // Sets the 802.15.4 transmission power. // `power` (in): Transmission power. -17 <= power <= 4. -int ieee802154_set_power(char power); +returncode_t libtock_ieee802154_set_power(uint32_t power); // Commits any new configuration state to the radio. -int ieee802154_config_commit(void); +returncode_t libtock_ieee802154_config_commit(void); // Gets the short MAC address. Returns TOCK_SUCCESS if the address was // successfully written into `addr`. // `addr` (out): Short MAC address. -int ieee802154_get_address(unsigned short *addr); +returncode_t libtock_ieee802154_get_address_short(uint16_t *addr); // Gets the long MAC address. Returns TOCK_SUCCESS if the address was // successfully written into `addr_long`. // `addr_long` (out): Long MAC address. Must point to 8 bytes of valid memory. -int ieee802154_get_address_long(unsigned char *addr_long); +returncode_t libtock_ieee802154_get_address_long(uint8_t *addr_long); // Gets the 802.15.4 PAN ID. Returns TOCK_SUCCESS if the PAN ID was successfully // written into `pan`. // `pan` (out): PAN ID. -int ieee802154_get_pan(unsigned short *pan); +returncode_t libtock_ieee802154_get_pan(uint16_t *pan); // Gets the 802.15.4 channel. Returns TOCK_SUCCESS if the channel was // successfully written into `channel`. // `channel` (out): 802.15.4 channel. If successful, `channel` will satisfy 11 // <= channel <= 26. -int ieee802154_get_channel(unsigned char *channel); +returncode_t libtock_ieee802154_get_channel(uint8_t *channel); // Gets the 802.15.4 transmission power. Returns TOCK_SUCCESS if the power // was successfully written into `power`. // `power` (out): Transmission power. If successful, `power` will satisfy // -17 <= power <= 4. -int ieee802154_get_power(char *power); +returncode_t libtock_ieee802154_get_power(uint32_t *power); // IEEE 802.15.4 neighbor list management. The list of known neighbors is // implemented as a variable-sized (up to a maximum of -// `ieee802154_max_neighbors()`) list of (short address, long address) pairs. -// List indices are maintained in the range [0, `ieee802154_max_neighbors()` - -// 1] and are stable between calls to `ieee802154_remove_neighbor()`. +// `libtock_ieee802154_max_neighbors()`) list of (short address, long address) pairs. +// List indices are maintained in the range [0, `libtock_ieee802154_max_neighbors()` - +// 1] and are stable between calls to `libtock_ieee802154_remove_neighbor()`. // Retrieves the maximum number of neighbors supported. -int ieee802154_max_neighbors(int* neighbors); +returncode_t libtock_ieee802154_max_neighbors(uint32_t* neighbors); // Retrieves the current number of neighbors. -int ieee802154_num_neighbors(int* neighbors); +returncode_t libtock_ieee802154_num_neighbors(uint32_t* neighbors); // Retrieves the short address of the neighbor at index `index` into `addr`. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in neighbor list. // `addr` (out): Short address of neighbor at `index`. -int ieee802154_get_neighbor_address(unsigned index, unsigned short *addr); +returncode_t libtock_ieee802154_get_neighbor_address_short(uint32_t index, uint16_t *addr); // Retrieves the long address of the neighbor at index `index` into `addr_long`. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in neighbor list. // `addr_long` (out): Long address of neighbor at `index`. Must point to 8 // bytes of valid memory. -int ieee802154_get_neighbor_address_long(unsigned index, unsigned char *addr_long); +returncode_t libtock_ieee802154_get_neighbor_address_long(uint32_t index, uint8_t *addr_long); // Retrieves the neighbor at index `index` into `addr` and `addr_long`. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in neighbor list. // `addr` (out): Short address of neighbor at `index`. // `addr_long` (out): Long address of neighbor at `index`. Must point to 8 // bytes of valid memory. -int ieee802154_get_neighbor(unsigned index, - unsigned short *addr, - unsigned char *addr_long); +returncode_t libtock_ieee802154_get_neighbor(uint32_t index, + uint16_t *addr_short, + uint8_t *addr_long); // Adds a new neighbor to the neighbor list. // If successful, returns TOCK_SUCCESS and writes the list index of the new neighbor // or existing neighbor with matching addresses into `index`. // `addr` (in): Short address of new neighbor. // `addr_long` (in): Long address of new neighbor. Must point to 8 bytes of valid memory. // `index` (out): New index in neighbor list. Can be NULL if the index is not needed. -int ieee802154_add_neighbor(unsigned short addr, unsigned char *addr_long, unsigned *index); +returncode_t libtock_ieee802154_add_neighbor(uint16_t addr_short, uint8_t *addr_long, uint32_t *index); // Removes the neighbor at `index`. If successful, returns TOCK_SUCCESS, // otherwise TOCK_EINVAL. -int ieee802154_remove_neighbor(unsigned index); +returncode_t libtock_ieee802154_remove_neighbor(uint32_t index); // IEEE 802.15.4 key list management. The list of known keys is implemented as -// a variable-sized (up to a maximum of `ieee802154_max_keys()`) list of +// a variable-sized (up to a maximum of `libtock_ieee802154_max_keys()`) list of // (security level, key id, key) tuples. List indices are maintained in the -// range [0, `ieee802154_max_keys()` - 1] and are stable between calls to -// `ieee802154_remove_key()`. +// range [0, `libtock_ieee802154_max_keys()` - 1] and are stable between calls to +// `libtock_ieee802154_remove_key()`. // Enum for representing IEEE 802.15.4 security levels in C. typedef enum { @@ -150,14 +150,14 @@ typedef enum { } key_id_mode_t; // Retrieves the maximum number of keys supported. -int ieee802154_max_keys(int* keys); +returncode_t libtock_ieee802154_max_keys(uint32_t* keys); // Retrieves the current number of keys. -int ieee802154_num_keys(int* keys); +returncode_t libtock_ieee802154_num_keys(uint32_t* keys); // Retrieves the security level of the key at index `index` into `level`. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in key list. // `level` (out): Security level of key at `index`. Will not be SEC_LEVEL_NONE. -int ieee802154_get_key_security_level(unsigned index, security_level_t *level); +returncode_t libtock_ieee802154_get_key_security_level(uint32_t index, security_level_t *level); // Retrieves the key id of the key at index `index` into `key_id_mode` // and `key_id`. If successful, returns TOCK_SUCCESS. // `index` (in): Index in key list. @@ -170,31 +170,31 @@ int ieee802154_get_key_security_level(unsigned index, security_level_t *level); // be written to `key_id`. // - KEY_ID_SRC_8_INDEX: The key source (8 bytes) and index (1 byte) will // be written to `key_id`. -int ieee802154_get_key_id(unsigned index, +returncode_t libtock_ieee802154_get_key_id(uint32_t index, key_id_mode_t *key_id_mode, - unsigned char *key_id); + uint8_t *key_id); // Returns the number of bytes that will be taken up by a key id with the given // `key_id_mode`. Returns either 0, 1, 5, or 9. If the key ID mode is invalid, -// returns 0. See `ieee802154_get_key_id()` for details. -int ieee802154_key_id_bytes(key_id_mode_t key_id_mode); +// returns 0. See `libtock_ieee802154_get_key_id()` for details. +returncode_t libtock_ieee802154_key_id_bytes(key_id_mode_t key_id_mode); // Retrieves the key at index `index` into `key`. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in key list. // `key` (out): Key. Must point to 16 bytes of valid memory. -int ieee802154_get_key(unsigned index, unsigned char *key); +returncode_t libtock_ieee802154_get_key(uint32_t index, uint8_t *key); // Retrieves the key at index `index` along with all the accompanying information. // If successful, returns TOCK_SUCCESS. // `index` (in): Index in key list. // `level` (out): Security level of key at `index`. Will not be SEC_LEVEL_NONE. // `key_id_mode` (out): Key ID mode of key at `index`. // `key_id` (out): Optional data depending on the value of `key_id_mode`. -// Must point to 9 bytes of valid memory. See `ieee802154_get_key_id()` for details. +// Must point to 9 bytes of valid memory. See `libtock_ieee802154_get_key_id()` for details. // `key` (out): Key. Must point to 16 bytes of valid memory. -int ieee802154_get_key_desc(unsigned index, +returncode_t libtock_ieee802154_get_key_desc(uint32_t index, security_level_t *level, key_id_mode_t *key_id_mode, - unsigned char *key_id, - unsigned char *key); + uint8_t *key_id, + uint8_t *key); // Adds a new key into the list of keys, if space remains. // If successful, returns TOCK_SUCCESS and writes the list index of the new key // or existing key with matching addresses into `index`. If an existing key @@ -209,20 +209,20 @@ int ieee802154_get_key_desc(unsigned index, // - KEY_ID_SRC_8_INDEX: The key source (8 bytes) and index (1 byte). Must point to // 9 bytes of valid memory. // `key` (in): The key. Must point to 16 bytes of valid memory. -int ieee802154_add_key(security_level_t level, +returncode_t libtock_ieee802154_add_key(security_level_t level, key_id_mode_t key_id_mode, - unsigned char *key_id, - unsigned char *key, - unsigned *index); + uint8_t *key_id, + uint8_t *key, + uint32_t *index); // Removes the key at `index`. If successful, returns TOCK_SUCCESS, // otherwise TOCK_EINVAL. -int ieee802154_remove_key(unsigned index); +returncode_t libtock_ieee802154_remove_key(uint32_t index); // IEEE 802.15.4 transmission and reception functions. // Transmission is sequenced across multiple processes, but received frames are exposed to all // processes. -// Sends an IEEE 802.15.4 frame synchronously. The desired key must first be +// Sends an IEEE 802.15.4 frame asynchronously. The desired key must first be // added to the key list. It is then looked up with the security level and key // ID provided. Returns TOCK_SUCCESS or TOCK_ENOACK on successful transmission, // depending on whether or not an ACK was received. @@ -231,65 +231,67 @@ int ieee802154_remove_key(unsigned index); // `key_id_mode` is meaningless and can be set to 0. // `key_id_mode` (in): The key ID mode, if `level` is not SEC_LEVEL_NONE. // `key_id` (in): Optional data depending on the value of `key_id_mode` if -// `level` is not SEC_LEVEL_NONE. See `ieee802154_add_key`. +// `level` is not SEC_LEVEL_NONE. See `libtock_ieee802154_add_key`. // `payload` (in): Buffer containing the desired frame payload. Must point to // `len` bytes of valid memory. // `len` (in): Length of frame payload. -int ieee802154_send(unsigned short addr, +// `cb` (in): Callback to call when the frame is sent. The callback will receive two arguments: +// - `result`: The result of the send operation (returncode). +// - `acked`: Whether the frame was acknowledged by the receiver. +returncode_t libtock_ieee802154_send(uint32_t addr, security_level_t level, key_id_mode_t key_id_mode, - unsigned char *key_id, - const char *payload, - unsigned char len); + uint8_t *key_id, + const uint8_t *payload, + uint8_t len, + libtock_ieee802154_callback_send_done cb); -// Sends an IEEE 802.15.4 frame synchronously. This is an alternative and contemporary -// to the `ieee802154_send` function. This provides an interface for userprocesses to -// form a frame (including headers, security, CRC etc) entirely in the userprocess. -// `ieee802154_send_raw` then takes this formed frame buffer and passes the frame +// Sends an IEEE 802.15.4 frame asynchronously. This is an alternative and contemporary +// to the `libtock_ieee802154_send` function. This provides an interface for userprocesses to +// form a frame (including headers, security, CRC etc) entirely in the userprocess. +// `libtock_ieee802154_send_raw` then takes this formed frame buffer and passes the frame // to the 15.4 capsule which sends the buffer (without altering the frame). // `payload` (in): Buffer containing the desired frame payload. // `len` (in): Length of frame payload. -int ieee802154_send_raw(const char * payload, - unsigned char len); +// `cb` (in): Callback to call when the frame is sent. The callback will receive two arguments: +// - `result`: The result of the send operation (returncode). +// - `acked`: Whether the frame was acknowledged by the receiver. +returncode_t libtock_ieee802154_send_raw(const uint8_t * payload, + uint8_t len, + libtock_ieee802154_callback_send_done cb); // Maximum size required of a buffer to contain the IEEE 802.15.4 frame data // passed to userspace from the kernel. Consists of 3 extra bytes followed by // the whole IEEE 802.15.4 MTU, which is 127 bytes. The packet is of the following // form: | data_offset | data_len | mic_len | 15.4 frame | -#define IEEE802154_FRAME_META_LEN 3 -#define IEEE802154_FRAME_LEN (IEEE802154_FRAME_META_LEN + 127) +#define libtock_ieee802154_FRAME_META_LEN 3 +#define libtock_ieee802154_FRAME_LEN (libtock_ieee802154_FRAME_META_LEN + 127) -// Size of the ring buffer expected by the kernel. The ring buffer is of the following +// Size of the ring buffer expected by the kernel. The ring buffer is of the following // form: | read index | write index | frame 1 | frame 2 | ... | frame n |. // Dependent on the application, the number of frames contained in the ring buffer -// can be increased or decreased by changing the value of IEEE802154_MAX_RING_BUF_FRAMES. -#define IEEE802154_RING_BUF_META_LEN 2 -#define IEEE802154_MAX_RING_BUF_FRAMES 3 -#define IEEE802154_RING_BUFFER_LEN (IEEE802154_RING_BUF_META_LEN + IEEE802154_MAX_RING_BUF_FRAMES * IEEE802154_FRAME_LEN) +// can be increased or decreased by changing the value of libtock_ieee802154_MAX_RING_BUF_FRAMES. +#define libtock_ieee802154_RING_BUF_META_LEN 2 +#define libtock_ieee802154_MAX_RING_BUF_FRAMES 3 +#define libtock_ieee802154_RING_BUFFER_LEN (libtock_ieee802154_RING_BUF_META_LEN + libtock_ieee802154_MAX_RING_BUF_FRAMES * libtock_ieee802154_FRAME_LEN) // Type for the 15.4 ring buffer. -typedef char ieee802154_rxbuf[IEEE802154_RING_BUFFER_LEN]; - -// Waits synchronously for an IEEE 802.15.4 frame. -// `frame` (in): Buffer in which to put the full IEEE 802.15.4 frame data. Note -// that the data written might include more than just the IEEE 802.15.4 frame itself. -// Use `ieee802154_frame_get_*` to interact with the resulting frame. -int ieee802154_receive_sync(const ieee802154_rxbuf *frame); +typedef uint8_t libtock_ieee802154_rxbuf[libtock_ieee802154_RING_BUFFER_LEN]; // Waits asynchronously for an IEEE 802.15.4 frame. Only waits for one frame. // To receive more, subscribe to this event again after processing one. // `callback` (in): Callback to call when a frame is received. // `frame` (in): Buffer in which to put the full IEEE 802.15.4 frame data. See -// `ieee802154_receive_sync` for more details. +// `libtock_ieee802154_receive_sync` for more details. // // The callback will receive three arguments containing information about the header // of the received frame: // `pans`: ((destination PAN ID if present else 0) << 16) | (source PANID if present else 0) // `dst_addr`: (addressing mode << 16) | (short address if address is short else 0) // `src_addr`: (addressing mode << 16) | (short address if address is short else 0) -int ieee802154_receive(subscribe_upcall callback, - const ieee802154_rxbuf *frame, - void* ud); +returncode_t libtock_ieee802154_receive( + const libtock_ieee802154_rxbuf *frame, + libtock_ieee802154_callback_recv_done cb); // IEEE 802.15.4 received frame inspection functions. The frames are returned // to userspace in a particular format that might include more bytes than just @@ -303,69 +305,66 @@ typedef enum { } addr_mode_t; // Gets the length of the received frame. -// `frame` (in): The frame data provided by ieee802154_receive_*. -int ieee802154_frame_get_length(const char *frame); +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. +int libtock_ieee802154_frame_get_length(const uint8_t *frame); // Gets the offset into `frame` of the data payload in the frame. -// `frame` (in): The frame data provided by ieee802154_receive_*. -int ieee802154_frame_get_payload_offset(const char *frame); +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. +int libtock_ieee802154_frame_get_payload_offset(const uint8_t *frame); // Gets the length of the data payload in the frame. -// `frame` (in): The frame data provided by ieee802154_receive_*. -int ieee802154_frame_get_payload_length(const char *frame); +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. +int libtock_ieee802154_frame_get_payload_length(const uint8_t *frame); // Gets the destination address of the received frame. Returns the addressing // mode, and if an address is present, writes the address into `short_addr` or // `long_addr`. If the out parameters are provided as NULL, this just returns // the addressing mode. Also returns ADDR_NONE if the frame is invalid. -// `frame` (in): The frame data provided by ieee802154_receive_*. +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. // `short_addr` (out): The destination address of the frame, if it is short. // `long_addr` (out): The destination address of the frame, if it is long. Must // point to 8 bytes of valid memory, if not null. -addr_mode_t ieee802154_frame_get_dst_addr(const char *frame, - unsigned short *short_addr, - unsigned char *long_addr); +addr_mode_t libtock_ieee802154_frame_get_dst_addr(const uint8_t *frame, + uint16_t *short_addr, + uint8_t *long_addr); // Gets the source address of the received frame. Returns the addressing mode, // and if an address is present, writes the address into `short_addr` or // `long_addr`. If the out parameters are provided as NULL, this just returns // the addressing mode. Also returns ADDR_NONE if the frame is invalid. -// `frame` (in): The frame data provided by ieee802154_receive_*. +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. // `short_addr` (out): The source address of the frame, if it is short. // `long_addr` (out): The source address of the frame, if it is long. Must // point to 8 bytes of valid memory, if not null. -addr_mode_t ieee802154_frame_get_src_addr(const char *frame, - unsigned short *short_addr, - unsigned char *long_addr); +addr_mode_t libtock_ieee802154_frame_get_src_addr(const uint8_t *frame, + uint16_t *short_addr, + uint8_t *long_addr); // Gets the destination PAN ID of the received frame. Returns `true` if it // is present and writes it into `pan`, otherwise returns `false`. // Also returns `false` if the frame is invalid in any way. -// `frame` (in): The frame data provided by ieee802154_receive_*. +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. // `pan` (out): The destination PAN ID if it is present. Can be set to NULL, in // which case nothing will be written. -bool ieee802154_frame_get_dst_pan(const char *frame, - unsigned short *pan); +bool libtock_ieee802154_frame_get_dst_pan(const uint8_t *frame, + uint16_t *pan); // Gets the source PAN ID of the received frame. Returns `true` if it is // present and writes it into `pan`, otherwise returns `false`. The source PAN // ID is considered "present" if it is either included explicitly or is set to // match the destination PAN ID. // Also returns `false` if the frame is invalid in any way. -// `frame` (in): The frame data provided by ieee802154_receive_*. +// `frame` (in): The frame data provided by libtock_ieee802154_receive_*. // `pan` (out): The source PAN ID if it is present. Can be set to NULL, in // which case nothing will be written. -bool ieee802154_frame_get_src_pan(const char *frame, - unsigned short *pan); - -// Unallow any allowed rx buffer by allowing a null pointer. -bool ieee802154_unallow_rx_buf(void); +bool libtock_ieee802154_frame_get_src_pan(const uint8_t *frame, + uint16_t *pan); // Reads the next frame from the ring buffer. If the ring buffer is empty, // returns NULL. The pointer returned points to the first index of the // received frame. -char* ieee802154_read_next_frame(const ieee802154_rxbuf* frame); +uint8_t* libtock_ieee802154_read_next_frame(const libtock_ieee802154_rxbuf* frame); -// Resets the ring buffer shared with the kernel to either be disabled or prepared for the next +// Resets the ring buffer shared with the kernel to either be disabled or prepared for the next // received packet. To disable the ring buffer, the user should pass a NULL value to the `frame` // and `callback` arguments. To prepare for the next received packets, the caller should pass the // relevant buffer/callback to the `frame` and `callback` arguments. Note, this function clears // all pending RX upcalls. -bool reset_ring_buf(const ieee802154_rxbuf* frame, subscribe_upcall callback, void* ud); +returncode_t libtock_reset_ring_buf(const libtock_ieee802154_rxbuf* frame, subscribe_upcall callback, void* ud); #ifdef __cplusplus } diff --git a/libtock/net/lora_phy.c b/libtock/net/lora_phy.c new file mode 100644 index 000000000..e3418aea9 --- /dev/null +++ b/libtock/net/lora_phy.c @@ -0,0 +1,80 @@ +#include "lora_phy.h" + +static void lora_phy_spi_upcall(__attribute__ ((unused)) int unused0, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_lora_phy_callback_spi cb = (libtock_lora_phy_callback_spi) opaque; + cb(RETURNCODE_SUCCESS); +} + +returncode_t libtock_lora_phy_write(const uint8_t* buf, + uint32_t len, + libtock_lora_phy_callback_spi cb) { + returncode_t ret; + + ret = libtock_lora_phy_set_readonly_allow_master_write_buffer(buf, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_lora_phy_set_upcall_spi(lora_phy_spi_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_lora_phy_command_read_write(len); + return ret; +} + +returncode_t libtock_lora_phy_read_write(const uint8_t* write, + uint8_t* read, + uint32_t len, + libtock_lora_phy_callback_spi cb) { + returncode_t ret; + + ret = libtock_lora_phy_set_readwrite_allow_master_read_buffer(read, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_lora_phy_write(write, len, cb); +} + +static void lora_phy_gpio_upcall( int pin_number, + int val, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_gpio_callback_interrupt cb = (libtock_gpio_callback_interrupt) opaque; + cb(pin_number, val == 1); +} + +returncode_t libtock_lora_phy_gpio_enable_output(uint32_t pin) { + return libtock_lora_phy_gpio_command_enable_output(pin); +} + +returncode_t libtock_lora_phy_gpio_set(uint32_t pin) { + return libtock_lora_phy_gpio_command_set(pin); +} + +returncode_t libtock_lora_phy_gpio_clear(uint32_t pin) { + return libtock_lora_phy_gpio_command_clear(pin); +} + +returncode_t libtock_lora_phy_gpio_toggle(uint32_t pin){ + return libtock_lora_phy_gpio_command_toggle(pin); +} + +returncode_t libtock_lora_phy_gpio_enable_input(uint32_t pin, libtock_gpio_input_mode_t pin_config){ + return libtock_lora_phy_gpio_command_enable_input(pin, (uint32_t) pin_config); +} + +returncode_t libtock_lora_phy_gpio_read(uint32_t pin, int* pin_value){ + return libtock_lora_phy_gpio_command_read(pin, (uint32_t*) pin_value); +} + +returncode_t libtock_lora_phy_gpio_enable_interrupt(uint32_t pin, libtock_gpio_interrupt_mode_t irq_config){ + return libtock_lora_phy_gpio_command_enable_interrupt(pin, (uint32_t) irq_config); +} + +returncode_t libtock_lora_phy_gpio_disable_interrupt(uint32_t pin){ + return libtock_lora_phy_gpio_command_disable_interrupt(pin); +} + +returncode_t libtock_lora_phy_gpio_set_callback(libtock_gpio_callback_interrupt cb) { + return libtock_lora_phy_gpio_command_interrupt_callback(lora_phy_gpio_upcall, cb); +} diff --git a/libtock/net/lora_phy.h b/libtock/net/lora_phy.h new file mode 100644 index 000000000..e0c2d7f01 --- /dev/null +++ b/libtock/net/lora_phy.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/lora_phy_syscalls.h" +#include "../peripherals/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for a LoRa PHY SPI callback. +// +// - `arg1` (`returncode_t`): Status from doing the SPI transaction. +typedef void (*libtock_lora_phy_callback_spi)(returncode_t); + +returncode_t libtock_lora_phy_write(const uint8_t* buf, + uint32_t len, + libtock_lora_phy_callback_spi cb); + +returncode_t libtock_lora_phy_read_write(const uint8_t* write, + uint8_t* read, + uint32_t len, + libtock_lora_phy_callback_spi cb); + +returncode_t libtock_lora_phy_gpio_enable_output(uint32_t pin); +returncode_t libtock_lora_phy_gpio_set(uint32_t pin); +returncode_t libtock_lora_phy_gpio_clear(uint32_t pin); +returncode_t libtock_lora_phy_gpio_toggle(uint32_t pin); +returncode_t libtock_lora_phy_gpio_enable_input(uint32_t pin, libtock_gpio_input_mode_t pin_config); +returncode_t libtock_lora_phy_gpio_read(uint32_t pin, int* pin_value); +returncode_t libtock_lora_phy_gpio_enable_interrupt(uint32_t pin, libtock_gpio_interrupt_mode_t irq_config); +returncode_t libtock_lora_phy_gpio_disable_interrupt(uint32_t pin); +returncode_t libtock_lora_phy_gpio_set_callback(libtock_gpio_callback_interrupt cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/nrf51_serialization.c b/libtock/net/nrf51_serialization.c new file mode 100644 index 000000000..2f7fc8706 --- /dev/null +++ b/libtock/net/nrf51_serialization.c @@ -0,0 +1,19 @@ +#include "nrf51_serialization.h" + +returncode_t libtock_nrf51_serialization_reset(void) { + return libtock_nrf51_serialization_command_reset(); +} + +returncode_t libtock_nrf51_serialization_write(uint8_t* tx, int tx_len) { + returncode_t ret; + + ret = libtock_nrf51_serialization_set_readonly_allow_write_buffer(tx, tx_len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_nrf51_serialization_command_write(); + return ret; +} + +returncode_t libtock_nrf51_serialization_read(int rx_len, int* bytes_read) { + return libtock_nrf51_serialization_command_read(rx_len, (uint32_t*) bytes_read); +} diff --git a/libtock/net/nrf51_serialization.h b/libtock/net/nrf51_serialization.h new file mode 100644 index 000000000..6416a91dd --- /dev/null +++ b/libtock/net/nrf51_serialization.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/nrf51_serialization_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Toggle the reset line to the nRF51 chip to reset the BLE MCU. +returncode_t libtock_nrf51_serialization_reset(void); + +// Write a packet to the BLE Serialization connectivity processor. +returncode_t libtock_nrf51_serialization_write(uint8_t* tx, int tx_len); + +// Receive into the buffer passed in to +// `libtock_nrf51_serialization_set_readwrite_allow_receive_buffer` previously. +returncode_t libtock_nrf51_serialization_read(int rx_len, int* bytes_read); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/eui64.c b/libtock/net/syscalls/eui64_syscalls.c similarity index 55% rename from libtock/eui64.c rename to libtock/net/syscalls/eui64_syscalls.c index 45cef8aba..7281782f2 100644 --- a/libtock/eui64.c +++ b/libtock/net/syscalls/eui64_syscalls.c @@ -1,15 +1,7 @@ -#include "eui64.h" - -bool libtock_eui64_exists(void){ - return driver_exists(DRIVER_NUM_EUI64); -} +#include "eui64_syscalls.h" returncode_t libtock_eui64_command_get(uint64_t* eui64) { // Issue the command to the kernel syscall_return_t cval = command(DRIVER_NUM_EUI64, EUI64_CMD_GETTER, 0, 0); return tock_command_return_u64_to_returncode(cval, eui64); } - -returncode_t libtock_eui64_get(uint64_t *eui64) { - return libtock_eui64_command_get(eui64); -} diff --git a/libtock/net/syscalls/eui64_syscalls.h b/libtock/net/syscalls/eui64_syscalls.h new file mode 100644 index 000000000..112afb579 --- /dev/null +++ b/libtock/net/syscalls/eui64_syscalls.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_EUI64 0x30006 +#define EUI64_CMD_GETTER 1 + +returncode_t libtock_eui64_command_get(uint64_t* eui64); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/syscalls/ieee802154_syscalls.c b/libtock/net/syscalls/ieee802154_syscalls.c new file mode 100644 index 000000000..4ec1a4c4b --- /dev/null +++ b/libtock/net/syscalls/ieee802154_syscalls.c @@ -0,0 +1,164 @@ +#include "ieee802154_syscalls.h" + +returncode_t libtock_ieee802154_set_upcall_frame_received(subscribe_upcall callback, void* opaque){ + subscribe_return_t sval = subscribe(DRIVER_NUM_IEEE802154, SUBSCRIBE_RX, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} +returncode_t libtock_ieee802154_set_upcall_frame_transmitted(subscribe_upcall callback, void* opaque){ + subscribe_return_t sval = subscribe(DRIVER_NUM_IEEE802154, SUBSCRIBE_TX, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_ieee802154_set_readonly_allow(const uint8_t* buffer, uint32_t len){ + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_IEEE802154, ALLOW_RO_TX, buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_ieee802154_set_readwrite_allow_rx(uint8_t* buffer, uint32_t len){ + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_IEEE802154, ALLOW_RW_RX, buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} +returncode_t libtock_ieee802154_set_readwrite_allow_cfg(uint8_t* buffer, uint32_t len){ + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_IEEE802154, ALLOW_RW_CFG, buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +bool libtock_ieee802154_exists(void){ + return driver_exists(DRIVER_NUM_IEEE802154); +} + +returncode_t libtock_ieee802154_command_status(void){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_STATUS, 0, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_set_address_short(uint16_t addr_short){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_STATUS, addr_short, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_set_address_long(void){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SET_ADDR_LONG, 0, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_set_pan(uint16_t pan){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SET_PAN, pan, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_set_channel(uint8_t channel){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SET_CHANNEL, channel, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_set_power(uint32_t power){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SET_POWER, power, 0); + return tock_command_return_novalue_to_returncode(com); + +} + +returncode_t libtock_ieee802154_command_config_commit(void){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_CONFIG_COMMIT, 0, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_get_address_short(uint32_t *addr_short){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_ADDR_SHORT, 0, 0); + return tock_command_return_u32_to_returncode(com, addr_short); +} + +returncode_t libtock_ieee802154_command_get_address_long(void){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_ADDR_LONG, 0, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_get_pan(uint32_t *pan){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_PAN, 0, 0); + return tock_command_return_u32_to_returncode(com, pan); +} + +returncode_t libtock_ieee802154_command_get_channel(uint32_t *channel){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_CHANNEL, 0, 0); + return tock_command_return_u32_to_returncode(com, channel); +} + +returncode_t libtock_ieee802154_command_get_power(uint32_t *power){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_POWER, 0, 0); + return tock_command_return_u32_to_returncode(com, power); +} + +returncode_t libtock_ieee802154_command_get_max_neighbors(uint32_t *max_neighbors){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_MAX_NEIGHBORS, 0, 0); + return tock_command_return_u32_to_returncode(com, max_neighbors); +} + +returncode_t libtock_ieee802154_command_get_number_neighbors(uint32_t *neighbor_count){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_NUM_NEIGHBORS, 0, 0); + return tock_command_return_u32_to_returncode(com, neighbor_count); +} + +returncode_t libtock_ieee802154_command_get_neighbor_address_short(uint32_t index, uint32_t *addr_short){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_NEIGHBOR_ADDR_SHORT, index, 0); + return tock_command_return_u32_to_returncode(com, addr_short); +} + +returncode_t libtock_ieee802154_command_get_neighbor_address_long(uint32_t index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_NEIGHBOR_ADDR_LONG, index, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_add_neighbor(uint16_t addr_short, uint32_t *index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_ADD_NEIGHBOR, addr_short, 0); + return tock_command_return_u32_to_returncode(com, index); +} + +returncode_t libtock_ieee802154_command_remove_neighbor(uint32_t index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_REMOVE_NEIGHBOR, index, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_get_max_keys(uint32_t *max_key_count){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_MAX_KEYS, 0, 0); + return tock_command_return_u32_to_returncode(com, max_key_count); +} + +returncode_t libtock_ieee802154_command_get_num_keys(uint32_t *key_count){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_NUM_KEYS, 0, 0); + return tock_command_return_u32_to_returncode(com, key_count); +} + +returncode_t libtock_ieee802154_command_get_key_security_level(uint32_t index, uint32_t *level){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_KEY_LEVEL, index, 0); + return tock_command_return_u32_to_returncode(com, level); +} + +returncode_t libtock_ieee802154_command_get_key_id(uint32_t index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_KEY_ID, index, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_get_key(uint32_t index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_GET_KEY, index, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_add_key(uint32_t *index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_ADD_KEY, 0, 0); + return tock_command_return_u32_to_returncode(com, index); +} + +returncode_t libtock_ieee802154_command_remove_key(uint32_t index){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_REMOVE_KEY, index, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_send(uint16_t addr_short){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SEND, addr_short, 0); + return tock_command_return_novalue_to_returncode(com); +} + +returncode_t libtock_ieee802154_command_send_raw(void){ + syscall_return_t com = command(DRIVER_NUM_IEEE802154, COMMAND_SEND_RAW, 0, 0); + return tock_command_return_novalue_to_returncode(com); +} diff --git a/libtock/net/syscalls/ieee802154_syscalls.h b/libtock/net/syscalls/ieee802154_syscalls.h new file mode 100644 index 000000000..5dfc20b40 --- /dev/null +++ b/libtock/net/syscalls/ieee802154_syscalls.h @@ -0,0 +1,94 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_IEEE802154 0x30001 +#define ALLOW_RW_RX 0 +#define ALLOW_RW_CFG 1 + +#define ALLOW_RO_TX 0 + +#define SUBSCRIBE_RX 0 +#define SUBSCRIBE_TX 1 + +#define COMMAND_STATUS 1 +#define COMMAND_SET_ADDR_SHORT 2 +#define COMMAND_SET_ADDR_LONG 3 +#define COMMAND_SET_PAN 4 +#define COMMAND_SET_CHANNEL 5 +#define COMMAND_SET_POWER 6 +#define COMMAND_CONFIG_COMMIT 7 + +#define COMMAND_GET_ADDR_SHORT 8 +#define COMMAND_GET_ADDR_LONG 9 +#define COMMAND_GET_PAN 10 +#define COMMAND_GET_CHANNEL 11 +#define COMMAND_GET_POWER 12 + +#define COMMAND_MAX_NEIGHBORS 13 +#define COMMAND_NUM_NEIGHBORS 14 +#define COMMAND_GET_NEIGHBOR_ADDR_SHORT 15 +#define COMMAND_GET_NEIGHBOR_ADDR_LONG 16 +#define COMMAND_ADD_NEIGHBOR 17 +#define COMMAND_REMOVE_NEIGHBOR 18 + +#define COMMAND_GET_MAX_KEYS 19 +#define COMMAND_GET_NUM_KEYS 20 +#define COMMAND_GET_KEY_LEVEL 21 +#define COMMAND_GET_KEY_ID 22 +#define COMMAND_GET_KEY 23 +#define COMMAND_ADD_KEY 24 +#define COMMAND_REMOVE_KEY 25 +#define COMMAND_SEND 26 +#define COMMAND_SEND_RAW 27 + +// IEEE 802.15.4 subscribe upcalls syscalls // +returncode_t libtock_ieee802154_set_upcall_frame_received(subscribe_upcall callback, void* opaque); +returncode_t libtock_ieee802154_set_upcall_frame_transmitted(subscribe_upcall callback, void* opaque); + +// IEEE 802.15.4 allow read only buffer syscalls // +returncode_t libtock_ieee802154_set_readonly_allow(const uint8_t* buffer, uint32_t len); + +// IEEE 802.15.4 allow read write buffer syscalls // +returncode_t libtock_ieee802154_set_readwrite_allow_rx(uint8_t* buffer, uint32_t len); +returncode_t libtock_ieee802154_set_readwrite_allow_cfg(uint8_t* buffer, uint32_t len); + +// Check for presence of the driver +bool libtock_ieee802154_exists(void); + +// IEEE 802.15.4 command syscalls // +returncode_t libtock_ieee802154_command_status(void); +returncode_t libtock_ieee802154_command_set_address_short(uint16_t addr_short); +returncode_t libtock_ieee802154_command_set_address_long(void); +returncode_t libtock_ieee802154_command_set_pan(uint16_t pan); +returncode_t libtock_ieee802154_command_set_channel(uint8_t channel); +returncode_t libtock_ieee802154_command_set_power(uint32_t power); +returncode_t libtock_ieee802154_command_config_commit(void); +returncode_t libtock_ieee802154_command_get_address_short(uint32_t *addr_short); +returncode_t libtock_ieee802154_command_get_address_long(void); +returncode_t libtock_ieee802154_command_get_pan(uint32_t *pan); +returncode_t libtock_ieee802154_command_get_channel(uint32_t *channel); +returncode_t libtock_ieee802154_command_get_power(uint32_t *power); +returncode_t libtock_ieee802154_command_get_max_neighbors(uint32_t *max_neighbors); +returncode_t libtock_ieee802154_command_get_number_neighbors(uint32_t *num_neighbors); +returncode_t libtock_ieee802154_command_get_neighbor_address_short(uint32_t index, uint32_t *addr_short); +returncode_t libtock_ieee802154_command_get_neighbor_address_long(uint32_t index); +returncode_t libtock_ieee802154_command_add_neighbor(uint16_t addr_short, uint32_t *index); +returncode_t libtock_ieee802154_command_remove_neighbor(uint32_t index); +returncode_t libtock_ieee802154_command_get_max_keys(uint32_t* max_keys); +returncode_t libtock_ieee802154_command_get_num_keys(uint32_t* num_keys); +returncode_t libtock_ieee802154_command_get_key_security_level(uint32_t index, uint32_t *level); +returncode_t libtock_ieee802154_command_get_key_id(uint32_t index); +returncode_t libtock_ieee802154_command_get_key(uint32_t index); +returncode_t libtock_ieee802154_command_add_key(uint32_t *index); +returncode_t libtock_ieee802154_command_remove_key(uint32_t index); +returncode_t libtock_ieee802154_command_send(uint16_t addr_short); +returncode_t libtock_ieee802154_command_send_raw(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/syscalls/lora_phy_syscalls.c b/libtock/net/syscalls/lora_phy_syscalls.c new file mode 100644 index 000000000..7ffab682d --- /dev/null +++ b/libtock/net/syscalls/lora_phy_syscalls.c @@ -0,0 +1,70 @@ +#include "lora_phy_syscalls.h" + +bool libtock_lora_phy_exists(void) { + return driver_exists(DRIVER_NUM_LORA_PHY_SPI) && driver_exists(DRIVER_NUM_LORA_PHY_GPIO); +} + +returncode_t libtock_lora_phy_set_upcall_spi(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_LORA_PHY_SPI, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_lora_phy_set_readonly_allow_master_write_buffer(const uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_LORA_PHY_SPI, 0, (const void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_lora_phy_set_readwrite_allow_master_read_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_LORA_PHY_SPI, 0, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_lora_phy_command_read_write(uint32_t length) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_SPI, 2, length, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_enable_output(uint32_t pin) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 1, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_set(uint32_t pin) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 2, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_clear(uint32_t pin) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 3, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_toggle(uint32_t pin) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 4, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_enable_input(uint32_t pin, uint32_t pin_config) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 5, pin, pin_config); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_read(uint32_t pin, uint32_t* pin_value) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 6, pin, 0); + return tock_command_return_u32_to_returncode(cval, pin_value); +} + +returncode_t libtock_lora_phy_gpio_command_enable_interrupt(uint32_t pin, uint32_t irq_config) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 7, pin, irq_config); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_disable_interrupt(uint32_t pin) { + syscall_return_t cval = command(DRIVER_NUM_LORA_PHY_GPIO, 8, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_lora_phy_gpio_command_interrupt_callback(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_LORA_PHY_GPIO, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} diff --git a/libtock/net/syscalls/lora_phy_syscalls.h b/libtock/net/syscalls/lora_phy_syscalls.h new file mode 100644 index 000000000..8dda3820f --- /dev/null +++ b/libtock/net/syscalls/lora_phy_syscalls.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_LORA_PHY_SPI 0x30003 +#define DRIVER_NUM_LORA_PHY_GPIO 0x30004 + +bool libtock_lora_phy_exists(void); + +returncode_t libtock_lora_phy_set_upcall_spi(subscribe_upcall callback, void* opaque); + +returncode_t libtock_lora_phy_set_readonly_allow_master_write_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_lora_phy_set_readwrite_allow_master_read_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_lora_phy_command_read_write(uint32_t length); + +returncode_t libtock_lora_phy_gpio_command_enable_output(uint32_t pin); + +returncode_t libtock_lora_phy_gpio_command_set(uint32_t pin); + +returncode_t libtock_lora_phy_gpio_command_clear(uint32_t pin); + +returncode_t libtock_lora_phy_gpio_command_toggle(uint32_t pin); + +returncode_t libtock_lora_phy_gpio_command_enable_input(uint32_t pin, uint32_t pin_config); + +returncode_t libtock_lora_phy_gpio_command_read(uint32_t pin, uint32_t* pin_value); + +returncode_t libtock_lora_phy_gpio_command_enable_interrupt(uint32_t pin, uint32_t irq_config); + +returncode_t libtock_lora_phy_gpio_command_disable_interrupt(uint32_t pin); + +returncode_t libtock_lora_phy_gpio_command_interrupt_callback(subscribe_upcall callback, void* opaque); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/syscalls/nrf51_serialization_syscalls.c b/libtock/net/syscalls/nrf51_serialization_syscalls.c new file mode 100644 index 000000000..4ef94d7c3 --- /dev/null +++ b/libtock/net/syscalls/nrf51_serialization_syscalls.c @@ -0,0 +1,46 @@ +#include "nrf51_serialization_syscalls.h" + +// #define NRF51_SERIALIZATION_COMMAND_CHECK 0 +#define NRF51_SERIALIZATION_COMMAND_WRITE 1 +#define NRF51_SERIALIZATION_COMMAND_READ 2 +#define NRF51_SERIALIZATION_COMMAND_RESET 3 + + +bool libtock_nrf51_serialization_exists(void) { + return driver_exists(DRIVER_NUM_NRF51_SERIALIZATION); +} + +returncode_t libtock_nrf51_serialization_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_NRF51_SERIALIZATION, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_nrf51_serialization_set_readwrite_allow_receive_buffer(uint8_t* rx, uint32_t rx_len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_NRF51_SERIALIZATION, 0, rx, rx_len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_nrf51_serialization_set_readonly_allow_write_buffer(uint8_t* tx, uint32_t tx_len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_NRF51_SERIALIZATION, 0, tx, tx_len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_nrf51_serialization_command_reset(void) { + syscall_return_t cval = command(DRIVER_NUM_NRF51_SERIALIZATION, + NRF51_SERIALIZATION_COMMAND_RESET, + 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_nrf51_serialization_command_write(void) { + syscall_return_t cval = command(DRIVER_NUM_NRF51_SERIALIZATION, + NRF51_SERIALIZATION_COMMAND_WRITE, + 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_nrf51_serialization_command_read(uint32_t rx_len, uint32_t* bytes_read) { + syscall_return_t cval = command(DRIVER_NUM_NRF51_SERIALIZATION, + NRF51_SERIALIZATION_COMMAND_READ, rx_len, 0); + return tock_command_return_u32_to_returncode(cval, bytes_read); +} diff --git a/libtock/net/syscalls/nrf51_serialization_syscalls.h b/libtock/net/syscalls/nrf51_serialization_syscalls.h new file mode 100644 index 000000000..0452ac875 --- /dev/null +++ b/libtock/net/syscalls/nrf51_serialization_syscalls.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_NRF51_SERIALIZATION 0x80004 + +// Check if this driver exists. +bool libtock_nrf51_serialization_exists(void); + +// Set the upcall function. +returncode_t libtock_nrf51_serialization_set_upcall(subscribe_upcall callback, void* opaque); + +// Pass the RX buffer for the UART module to use. +returncode_t libtock_nrf51_serialization_set_readwrite_allow_receive_buffer(uint8_t* rx, uint32_t rx_len); + +// Set the buffer to send from. +returncode_t libtock_nrf51_serialization_set_readonly_allow_write_buffer(uint8_t* tx, uint32_t tx_len); + +// Reset the nRF51 chip +returncode_t libtock_nrf51_serialization_command_reset(void); + +// Write the write buffer. +returncode_t libtock_nrf51_serialization_command_write(void); + +// Read into the read buffer. `bytes_read` is set to the number of bytes +// received. +returncode_t libtock_nrf51_serialization_command_read(uint32_t rx_len, uint32_t* bytes_read); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/net/syscalls/udp_syscalls.c b/libtock/net/syscalls/udp_syscalls.c new file mode 100644 index 000000000..859ece194 --- /dev/null +++ b/libtock/net/syscalls/udp_syscalls.c @@ -0,0 +1,58 @@ +#include "udp_syscalls.h" + +bool libtock_udp_exists(void){ + return driver_exists(DRIVER_NUM_UDP); +} + +// UDP Subscribe Upcall Syscalls // +returncode_t libtock_udp_set_upcall_frame_received(subscribe_upcall callback, void* opaque){ + subscribe_return_t sval = subscribe(DRIVER_NUM_UDP, SUBSCRIBE_RX, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_udp_set_upcall_frame_transmitted(subscribe_upcall callback, void* opaque){ + subscribe_return_t sval = subscribe(DRIVER_NUM_UDP, SUBSCRIBE_TX, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +// UDP Read/Write Allow Syscalls // +returncode_t libtock_udp_set_readonly_allow(const uint8_t* buffer, uint32_t len){ + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_UDP, ALLOW_RO_TX, (const void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_udp_set_readwrite_allow_rx(const uint8_t* buffer, uint32_t len){ + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_UDP, ALLOW_RW_RX, (void *) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_udp_set_readwrite_allow_cfg(const uint8_t* buffer, uint32_t len){ + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_UDP, ALLOW_RW_CFG, (void *) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_udp_set_readwrite_allow_rx_cfg(const uint8_t* buffer, uint32_t len){ + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_UDP, ALLOW_RW_RX_CFG, (void *) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +// UDP Command Syscalls // +returncode_t libtock_udp_command_get_ifaces(size_t len){ + syscall_return_t cval = command(DRIVER_NUM_UDP, COMMAND_GET_IFACES, len, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_udp_command_send(void){ + syscall_return_t cval = command(DRIVER_NUM_UDP, UDP_COMMAND_SEND, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_udp_command_bind(void){ + syscall_return_t cval = command(DRIVER_NUM_UDP, COMMAND_BIND, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_udp_command_get_max_tx_len(int* len){ + syscall_return_t cval = command(DRIVER_NUM_UDP, COMMAND_GET_TX_LEN, 0, 0); + return tock_command_return_u32_to_returncode(cval, (uint32_t*) len); +} \ No newline at end of file diff --git a/libtock/net/syscalls/udp_syscalls.h b/libtock/net/syscalls/udp_syscalls.h new file mode 100644 index 000000000..004f89dc9 --- /dev/null +++ b/libtock/net/syscalls/udp_syscalls.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_UDP 0x30002 + +#define ALLOW_RO_TX 0 + +#define ALLOW_RW_RX 0 +#define ALLOW_RW_CFG 1 +#define ALLOW_RW_RX_CFG 2 + +#define SUBSCRIBE_RX 0 +#define SUBSCRIBE_TX 1 + +#define COMMAND_GET_IFACES 1 +#define UDP_COMMAND_SEND 2 +#define COMMAND_BIND 3 +#define COMMAND_GET_TX_LEN 4 + +bool libtock_udp_exists(void); + +returncode_t libtock_udp_set_upcall_frame_received(subscribe_upcall callback, void* opaque); +returncode_t libtock_udp_set_upcall_frame_transmitted(subscribe_upcall callback, void* opaque); + +returncode_t libtock_udp_set_readonly_allow(const uint8_t* buffer, uint32_t len); +returncode_t libtock_udp_set_readwrite_allow_rx(const uint8_t* buffer, uint32_t len); +returncode_t libtock_udp_set_readwrite_allow_cfg(const uint8_t* buffer, uint32_t len); +returncode_t libtock_udp_set_readwrite_allow_rx_cfg(const uint8_t* buffer, uint32_t len); + + +returncode_t libtock_udp_command_get_ifaces(size_t len); +returncode_t libtock_udp_command_send(void); +returncode_t libtock_udp_command_bind(void); +returncode_t libtock_udp_command_get_max_tx_len(int* len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/net/udp.c b/libtock/net/udp.c new file mode 100644 index 000000000..54de0d009 --- /dev/null +++ b/libtock/net/udp.c @@ -0,0 +1,113 @@ +#include + +#include "udp.h" + +returncode_t libtock_udp_bind(sock_handle_t *handle, sock_addr_t *addr, unsigned char *buf_bind_cfg) { + // Pass interface to listen on and space for kernel to write src addr + // of received packets + // In current design, buf_bind_cfg will still be written with addresses of external + // senders sending addresses to the bound port even if the client application has + // not set up a receive callback on this port. Of course, the client application + // does not have to read these addresses or worry about them. + returncode_t ret; + + memcpy(&(handle->addr), addr, sizeof(sock_addr_t)); + int bytes = sizeof(sock_addr_t); + + ret = libtock_udp_set_readwrite_allow_rx_cfg((void *) buf_bind_cfg, 2 * bytes); + if (ret != RETURNCODE_SUCCESS) return ret; + + memcpy(buf_bind_cfg + bytes, &(handle->addr), bytes); + + // Set up source address/port pair for sending. Store it in tx_cfg + // Notably, the pair chosen must match the address/port to which the + // app is bound, unless the kernel changes in the future to allow for + // sending from a port to which the app is not bound. + // HACK!! This is not static. + unsigned char BUF_TX_CFG[2 * sizeof(sock_addr_t)]; + memcpy(BUF_TX_CFG, &(handle->addr), bytes); + ret = libtock_udp_set_readwrite_allow_cfg((void *) BUF_TX_CFG, 2 * bytes); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_udp_command_bind(); +} + +returncode_t libtock_udp_close(__attribute__ ((unused)) sock_handle_t *handle) { + returncode_t ret; + // HACK!! This is not static. + unsigned char zero_addr[2 * sizeof(sock_addr_t)] = {0}; + int bytes = sizeof(sock_addr_t); + + // call allow here to prevent any issues if close is called before bind + // Driver 'closes' when 0 addr is bound to + ret = libtock_udp_set_readwrite_allow_rx_cfg((void *) zero_addr, 2 * bytes); + if (ret != RETURNCODE_SUCCESS) return ret; + + memset(zero_addr, 0, 2 * bytes); + ret = libtock_udp_command_bind(); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_udp_set_readwrite_allow_rx_cfg(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Remove the callback. + return libtock_udp_set_upcall_frame_received(NULL, NULL); +} + +static void udp_send_done_upcall (int status, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void * opaque) { + libtock_udp_callback_send_done cb = (libtock_udp_callback_send_done) opaque; + cb(status); +} + +returncode_t libtock_udp_send(void *buf, size_t len, + sock_addr_t *dst_addr, libtock_udp_callback_send_done cb) { + returncode_t ret; + unsigned char BUF_TX_CFG[2 * sizeof(sock_addr_t)]; + + // Set dest addr + // NOTE: bind() must be called previously for this to work + // If bind() has not been called, command(COMMAND_SEND) will return RESERVE + int bytes = sizeof(sock_addr_t); + memcpy(BUF_TX_CFG + bytes, dst_addr, bytes); + + // Set message buffer + ret = libtock_udp_set_readonly_allow(buf, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_udp_set_upcall_frame_transmitted(udp_send_done_upcall, cb); +} + +static void udp_recv_done_upcall(int length, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void * opaque) { + libtock_udp_callback_recv_done cb = (libtock_udp_callback_recv_done) opaque; + cb(TOCK_STATUSCODE_SUCCESS, length); +} + +returncode_t libtock_udp_recv(void *buf, size_t len, libtock_udp_callback_recv_done cb) { + // TODO: verify that this functions returns error if this app is not + // bound to a socket yet. Probably allow should fail..? + returncode_t ret; + + ret = libtock_udp_set_readwrite_allow_rx((void *) buf, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_udp_set_upcall_frame_received(udp_recv_done_upcall, cb); +} + +returncode_t libtock_udp_list_ifaces(ipv6_addr_t *ifaces, size_t len) { + if (!ifaces) return RETURNCODE_EINVAL; + + returncode_t ret = libtock_udp_set_readwrite_allow_cfg((void *)ifaces, len * sizeof(ipv6_addr_t)); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_udp_command_get_ifaces(len); +} + +returncode_t libtock_udp_get_max_tx_len(int* length) { + return libtock_udp_command_get_max_tx_len(length); +} diff --git a/libtock/udp.h b/libtock/net/udp.h similarity index 53% rename from libtock/udp.h rename to libtock/net/udp.h index ad0e6aa37..d37098e4d 100644 --- a/libtock/udp.h +++ b/libtock/net/udp.h @@ -1,9 +1,7 @@ #pragma once -#include -#include - -#include "tock.h" +#include "../tock.h" +#include "syscalls/udp_syscalls.h" #ifdef __cplusplus extern "C" { @@ -24,9 +22,16 @@ typedef struct sock_handle { sock_addr_t addr; } sock_handle_t; + +/// Callback for when a tx is completed. +typedef void (*libtock_udp_callback_send_done) (statuscode_t); + +/// Callback for when a rx is completed. +typedef void (*libtock_udp_callback_recv_done) (statuscode_t, int); + // Creates a new datagram socket bound to an address. // Returns 0 on success, negative on failure. -int udp_socket(sock_handle_t *handle, sock_addr_t *addr); +returncode_t libtock_udp_create_socket(sock_handle_t *handle, sock_addr_t *addr); // Takes in an addess and a handle, and copies the address into // the handle. @@ -35,34 +40,31 @@ int udp_socket(sock_handle_t *handle, sock_addr_t *addr); // the bound port, and ensures that all sent packets will have // the bound port as their src address. // Returns 0 on successful bind, negative on failure. -int udp_bind(sock_handle_t *handle, sock_addr_t *addr, unsigned char *buf_bind_cfg); +returncode_t libtock_udp_bind(sock_handle_t *handle, sock_addr_t *addr, unsigned char *buf_bind_cfg); // Closes a socket. // Currently only one socket can exist per app, so this fn // simply closes any connected socket // Returns 0 on success, negative on failure. -int udp_close(sock_handle_t *handle); - -// Sends data on a socket. Requires binding to a port first. -// Returns 0 on success, negative on failure. -ssize_t udp_send_to(void *buf, size_t len, sock_addr_t *dst_addr); +returncode_t libtock_udp_close(sock_handle_t *handle); // Receives messages from that socket asynchronously. -// The callback is passed the return code for the reception. +// The callback is passed the return code for the reception +// in addition to the length of the received packet. // Returns 0 on successful bind, negative on failure. -ssize_t udp_recv(subscribe_upcall callback, void *buf, size_t len); +returncode_t libtock_udp_recv(void *buf, size_t len, libtock_udp_callback_recv_done cb); -// Receives messages from the bound socket synchronously. -// Returns 0 on successful reception, negative on failure. -// Hangs until reception occurs unless there is a failure during a bind or reception. -ssize_t udp_recv_sync(void *buf, size_t len); +// Sends a message to the destination address asynchronously +// The callback is passed the return code for the transmission. +returncode_t libtock_udp_send(void *buf, size_t len, + sock_addr_t *dst_addr, libtock_udp_callback_send_done cb); // Lists `len` interfaces at the array pointed to by `ifaces`. // Returns the _total_ number of interfaces, negative on failure. -int udp_list_ifaces(ipv6_addr_t *ifaces, size_t len); +returncode_t libtock_udp_list_ifaces(ipv6_addr_t *ifaces, size_t len); // Returns the maximum length udp payload that the app can transmit -int udp_get_max_tx_len(int* length); +returncode_t libtock_udp_get_max_tx_len(int* length); #ifdef __cplusplus } diff --git a/libtock/ninedof.c b/libtock/ninedof.c deleted file mode 100644 index b87d4eba7..000000000 --- a/libtock/ninedof.c +++ /dev/null @@ -1,117 +0,0 @@ -#include - -#include "math.h" -#include "ninedof.h" - -struct ninedof_data { - int x; - int y; - int z; - bool fired; -}; - -static struct ninedof_data res = { .fired = false }; - -// internal callback for faking synchronous reads -static void ninedof_upcall(int x, int y, int z, void* ud) { - struct ninedof_data* result = (struct ninedof_data*) ud; - result->x = x; - result->y = y; - result->z = z; - result->fired = true; -} - -double ninedof_read_accel_mag(void) { - struct ninedof_data result = { .fired = false }; - int err; - - err = ninedof_subscribe(ninedof_upcall, (void*)(&result)); - if (err < 0) return err; - - err = ninedof_start_accel_reading(); - if (err < 0) return err; - - yield_for(&result.fired); - - return sqrt(result.x * result.x + result.y * result.y + result.z * result.z); -} - -int ninedof_subscribe(subscribe_upcall callback, void* userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_NINEDOF, 0, callback, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -int ninedof_start_accel_reading(void) { - syscall_return_t ret = command(DRIVER_NUM_NINEDOF, 1, 0, 0); - return tock_command_return_novalue_to_returncode(ret); -} - -int ninedof_start_magnetometer_reading(void) { - syscall_return_t ret = command(DRIVER_NUM_NINEDOF, 100, 0, 0); - return tock_command_return_novalue_to_returncode(ret); -} - -int ninedof_start_gyro_reading(void) { - syscall_return_t ret = command(DRIVER_NUM_NINEDOF, 200, 0, 0); - return tock_command_return_novalue_to_returncode(ret); -} - -int ninedof_read_acceleration_sync(int* x, int* y, int* z) { - int err; - res.fired = false; - - err = ninedof_subscribe(ninedof_upcall, (void*) &res); - if (err < 0) return err; - - err = ninedof_start_accel_reading(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&res.fired); - - *x = res.x; - *y = res.y; - *z = res.z; - - return RETURNCODE_SUCCESS; -} - -int ninedof_read_magnetometer_sync(int* x, int* y, int* z) { - int err; - res.fired = false; - - err = ninedof_subscribe(ninedof_upcall, (void*) &res); - if (err < 0) return err; - - err = ninedof_start_magnetometer_reading(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&res.fired); - - *x = res.x; - *y = res.y; - *z = res.z; - - return RETURNCODE_SUCCESS; -} - -int ninedof_read_gyroscope_sync(int* x, int* y, int* z) { - int err; - res.fired = false; - - err = ninedof_subscribe(ninedof_upcall, (void*) &res); - if (err < 0) return err; - - err = ninedof_start_gyro_reading(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&res.fired); - - *x = res.x; - *y = res.y; - *z = res.z; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/ninedof.h b/libtock/ninedof.h deleted file mode 100644 index d4db7a99a..000000000 --- a/libtock/ninedof.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_NINEDOF 0x60004 - -// Proivide a callback function for acceleration readings -int ninedof_subscribe(subscribe_upcall callback, void* userdata); -// Read acceleration and relay to callback function -int ninedof_start_accel_reading(void); -// Read magnetometer and relay to callback function -int ninedof_start_magnetometer_reading(void); -// Read gyroscope and relay to callback function -int ninedof_start_gyro_reading(void); -// Read square of magnitude of acceleration (blocking) -double ninedof_read_accel_mag(void); - -// Get the magnitude of acceleration in the X,Y,Z directions. Blocking. -int ninedof_read_acceleration_sync(int* x, int* y, int* z); - -// Get a reading from the magnetometer. Blocking. -int ninedof_read_magnetometer_sync(int* x, int* y, int* z); - -// Get a reading from the gyroscope. Blocking. -int ninedof_read_gyroscope_sync(int* x, int* y, int* z); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/nrf51_serialization.c b/libtock/nrf51_serialization.c deleted file mode 100644 index 52d36f214..000000000 --- a/libtock/nrf51_serialization.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "nrf51_serialization.h" - -// #define NRF51_SERIALIZATION_COMMAND_CHECK 0 -#define NRF51_SERIALIZATION_COMMAND_WRITE 1 -#define NRF51_SERIALIZATION_COMMAND_READ 2 -#define NRF51_SERIALIZATION_COMMAND_RESET 3 - - -int nrf51_serialization_reset (void) { - // Reset the nRF51 chip - syscall_return_t cval = command(DRIVER_NUM_NRF_SERIALIZATION, - NRF51_SERIALIZATION_COMMAND_RESET, - 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int nrf51_serialization_subscribe (subscribe_upcall cb) { - subscribe_return_t sval = subscribe(DRIVER_NUM_NRF_SERIALIZATION, 0, cb, NULL); - return tock_subscribe_return_to_returncode(sval); -} - -int nrf51_serialization_setup_receive_buffer (char* rx, int rx_len) { - // Pass the RX buffer for the UART module to use. - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_NRF_SERIALIZATION, 0, rx, rx_len); - return tock_allow_rw_return_to_returncode(aval); -} - - - -int nrf51_serialization_write(char* tx, int tx_len) { - // Pass in the TX buffer. - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_NRF_SERIALIZATION, 0, tx, tx_len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - // Write the data. - syscall_return_t cval = command(DRIVER_NUM_NRF_SERIALIZATION, - NRF51_SERIALIZATION_COMMAND_WRITE, - 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int nrf51_serialization_read(int rx_len) { - int read_len; - syscall_return_t cval = command(DRIVER_NUM_NRF_SERIALIZATION, - NRF51_SERIALIZATION_COMMAND_READ, rx_len, 0); - int ret = tock_command_return_u32_to_returncode(cval, (uint32_t*) &read_len); - if (ret < 0) return ret; - - // This shouldn't return a length and an error, but it is the signature - // libnrfserialization expects. - return read_len; // Actual read length -} diff --git a/libtock/nrf51_serialization.h b/libtock/nrf51_serialization.h deleted file mode 100644 index e68c69377..000000000 --- a/libtock/nrf51_serialization.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_NRF_SERIALIZATION 0x80004 - -// Toggle the reset line to the nRF51 chip to reset the BLE MCU. -__attribute__ ((warn_unused_result)) -int nrf51_serialization_reset (void); - -// Give the BLE Serialization / UART layer a callback to call when -// a packet is received and when a TX is finished. -__attribute__ ((warn_unused_result)) -int nrf51_serialization_subscribe (subscribe_upcall cb); - -// Pass a buffer for the driver to write received UART bytes to. -__attribute__ ((warn_unused_result)) -int nrf51_serialization_setup_receive_buffer (char* rx, int rx_len); - -// Write a packet to the BLE Serialization connectivity processor. -__attribute__ ((warn_unused_result)) -int nrf51_serialization_write(char* tx, int tx_len); - -// Receive into the buffer passed in to `setup_receive_buffer` previously -__attribute__ ((warn_unused_result)) -int nrf51_serialization_read(int rx_len); - - -#ifdef __cplusplus -} -#endif diff --git a/libtock/pca9544a.c b/libtock/pca9544a.c deleted file mode 100644 index 6c6663077..000000000 --- a/libtock/pca9544a.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "pca9544a.h" -#include "tock.h" - -struct pca9544a_data { - bool fired; - int value; -}; - -static struct pca9544a_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void pca9544a_upcall(__attribute__ ((unused)) int value, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - struct pca9544a_data* data = (struct pca9544a_data*) ud; - data->value = value; - data->fired = true; -} - - -int pca9544a_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_PCA9544A, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int pca9544a_select_channels(uint32_t channels) { - syscall_return_t com = command(DRIVER_NUM_PCA9544A, 1, channels, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int pca9544a_disable_all_channels(void) { - syscall_return_t com = command(DRIVER_NUM_PCA9544A, 2, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int pca9544a_read_interrupts(void) { - syscall_return_t com = command(DRIVER_NUM_PCA9544A, 3, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int pca9544a_read_selected(void) { - syscall_return_t com = command(DRIVER_NUM_PCA9544A, 4, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - - - -int pca9544a_select_channels_sync(uint32_t channels) { - int err; - result.fired = false; - - err = pca9544a_set_callback(pca9544a_upcall, (void*) &result); - if (err < 0) return err; - - err = pca9544a_select_channels(channels); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int pca9544a_disable_all_channels_sync(void) { - int err; - result.fired = false; - - err = pca9544a_set_callback(pca9544a_upcall, (void*) &result); - if (err < 0) return err; - - err = pca9544a_disable_all_channels(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - return RETURNCODE_SUCCESS; -} - -int pca9544a_read_interrupts_sync(int* value) { - int err; - result.fired = false; - - err = pca9544a_set_callback(pca9544a_upcall, (void*) &result); - if (err < 0) return err; - - err = pca9544a_read_interrupts(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *value = result.value; - - return RETURNCODE_SUCCESS; -} - -int pca9544a_read_selected_sync(int* value) { - int err; - result.fired = false; - - err = pca9544a_set_callback(pca9544a_upcall, (void*) &result); - if (err < 0) return err; - - err = pca9544a_read_selected(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *value = result.value; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/pca9544a.h b/libtock/pca9544a.h deleted file mode 100644 index 2d0f5bc76..000000000 --- a/libtock/pca9544a.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_PCA9544A 0x80002 - -int pca9544a_set_callback(subscribe_upcall callback, void* callback_args); - -// Set which of the I2C selector's channels are active. -// channels is an 8 bit bitmask -int pca9544a_select_channels(uint32_t channels); - -// Disable all channels on the I2C selector. -int pca9544a_disable_all_channels(void); - -// Get which channels are asserting interrupts. -int pca9544a_read_interrupts(void); - -// Get which channels are currently selected. -int pca9544a_read_selected(void); - - -// -// Synchronous Versions -// -int pca9544a_select_channels_sync(uint32_t channels); -int pca9544a_disable_all_channels_sync(void); -int pca9544a_read_interrupts_sync(int* value); -int pca9544a_read_selected_sync(int* value); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/peripherals/adc.c b/libtock/peripherals/adc.c new file mode 100644 index 000000000..95f3fc157 --- /dev/null +++ b/libtock/peripherals/adc.c @@ -0,0 +1,106 @@ +#include "adc.h" + + +// Internal callback for routing to operation-specific callbacks +// +// callback_type - number indicating which type of callback occurred +// arg1, arg2 - meaning varies based on callback_type +// callback_args - user data passed into the set_callback function +// +// Possible callbacks +// SingleSample: single sample operation is complete +// arg1 - channel number that collected sample corresponds to +// arg2 - sample value +// MultipleSample: sampling a buffer worth of data is complete +// arg1 - channel in lower 8 bits, +// number of samples collected in upper 24 bits +// arg2 - pointer to buffer filled with samples +// ContinuousSample: a buffer of sample data is ready +// arg1 - channel in lower 8 bits, +// number of samples collected in upper 24 bits +// arg2 - pointer to buffer filled with samples +static void adc_routing_upcall(int callback_type, + int arg1, + int arg2, + void* opaque) { + libtock_adc_callbacks* callbacks = (libtock_adc_callbacks*) opaque; + + switch (callback_type) { + case libtock_adc_SingleSample: + if (callbacks->single_sample_callback) { + uint8_t channel = (uint8_t)arg1; + uint16_t sample = (uint16_t)arg2; + callbacks->single_sample_callback(channel, sample); + } + break; + + case libtock_adc_ContinuousSample: + if (callbacks->continuous_sample_callback) { + uint8_t channel = (uint8_t)arg1; + uint16_t sample = (uint16_t)arg2; + callbacks->continuous_sample_callback(channel, sample); + } + break; + + case libtock_adc_SingleBuffer: + if (callbacks->buffered_sample_callback) { + uint8_t channel = (uint8_t)(arg1 & 0xFF); + uint32_t length = ((arg1 >> 8) & 0xFFFFFF); + uint16_t* buffer = (uint16_t*)arg2; + callbacks->buffered_sample_callback(channel, length, buffer); + } + break; + + case libtock_adc_ContinuousBuffer: + if (callbacks->continuous_buffered_sample_callback) { + uint8_t channel = (uint8_t)(arg1 & 0xFF); + uint32_t length = ((arg1 >> 8) & 0xFFFFFF); + uint16_t* buffer = (uint16_t*)arg2; + callbacks->continuous_buffered_sample_callback(channel, length, buffer); + } + break; + } +} + + +returncode_t libtock_adc_set_buffer(uint16_t* buffer, uint32_t length) { + return libtock_adc_set_readwrite_allow_set_buffer((uint8_t*) buffer, length * 2); +} + +returncode_t libtock_adc_set_double_buffer(uint16_t* buffer, uint32_t length) { + return libtock_adc_set_readwrite_allow_set_double_buffer((uint8_t*) buffer, length * 2); + +} + +returncode_t libtock_adc_channel_count(int* count) { + return libtock_adc_command_channel_count(count); +} + +returncode_t libtock_adc_single_sample(uint8_t channel, libtock_adc_callbacks* callbacks) { + returncode_t ret = libtock_adc_set_upcall(adc_routing_upcall, callbacks); + if (ret != RETURNCODE_SUCCESS) return ret; + return libtock_adc_command_single_sample(channel); +} + +returncode_t libtock_adc_continuous_sample(uint8_t channel, uint32_t frequency, libtock_adc_callbacks* callbacks) { + returncode_t ret = libtock_adc_set_upcall(adc_routing_upcall, callbacks); + if (ret != RETURNCODE_SUCCESS) return ret; + return libtock_adc_command_continuous_sample(channel, frequency); +} + +returncode_t libtock_adc_buffered_sample(uint8_t channel, uint32_t frequency, libtock_adc_callbacks* callbacks) { + returncode_t ret = libtock_adc_set_upcall(adc_routing_upcall, callbacks); + if (ret != RETURNCODE_SUCCESS) return ret; + return libtock_adc_command_buffered_sample(channel, frequency); +} + +returncode_t libtock_adc_continuous_buffered_sample(uint8_t channel, uint32_t frequency, + libtock_adc_callbacks* callbacks) { + returncode_t ret = libtock_adc_set_upcall(adc_routing_upcall, callbacks); + if (ret != RETURNCODE_SUCCESS) return ret; + return libtock_adc_command_continuous_buffered_sample(channel, frequency); +} + +returncode_t libtock_adc_stop_sampling(void) { + return libtock_adc_command_stop_sampling(); +} diff --git a/libtock/peripherals/adc.h b/libtock/peripherals/adc.h new file mode 100644 index 000000000..642911cc0 --- /dev/null +++ b/libtock/peripherals/adc.h @@ -0,0 +1,123 @@ +#pragma once + +#include + +#include "../tock.h" +#include "syscalls/adc_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +// mode of the ADC +// Used to tell which operation a callback corresponds to +typedef enum { + libtock_adc_SingleSample = 0, + libtock_adc_ContinuousSample = 1, + libtock_adc_SingleBuffer = 2, + libtock_adc_ContinuousBuffer = 3 +} libtock_adc_mode; + + + +// Function signature for ADC single sample callback. +// +// - `arg1` (`uint8_t`): Channel number. +// - `arg2` (`uint16_t`): ADC sample. +typedef void (*libtock_adc_callback_single_sample)(uint8_t, uint16_t); + +// Function signature for ADC continuous sample callback. +// +// - `arg1` (`uint8_t`): Channel number. +// - `arg2` (`uint16_t`): ADC sample. +typedef void (*libtock_adc_callback_continuous_sample)(uint8_t, uint16_t); + +// Function signature for ADC buffered sample callback. +// +// - `arg1` (`uint8_t`): Channel number. +// - `arg2` (`uint32_t`): Number of samples. +// - `arg2` (`uint16_t`): Buffer of samples. +typedef void (*libtock_adc_callback_buffered_sample)(uint8_t, uint32_t, uint16_t*); + +// Function signature for ADC continuous buffered sample callback. +// +// - `arg1` (`uint8_t`): Channel number. +// - `arg2` (`uint32_t`): Number of samples. +// - `arg2` (`uint16_t`): Buffer of samples. +typedef void (*libtock_adc_callback_continuous_buffered_sample)(uint8_t, uint32_t, uint16_t*); + + + +typedef struct { + libtock_adc_callback_single_sample single_sample_callback; + libtock_adc_callback_continuous_sample continuous_sample_callback; + libtock_adc_callback_buffered_sample buffered_sample_callback; + libtock_adc_callback_buffered_sample continuous_buffered_sample_callback; +} libtock_adc_callbacks; + + + +// ***** System Call Interface ***** + + + +// provides an application buffer to the ADC driver to fill with samples +// +// buffer - pointer to buffer to fill with samples +// length - number of samples requested, must be less than or equal to buffer +// length +returncode_t libtock_adc_set_buffer(uint16_t* buffer, uint32_t length); + +// provide an application buffer to fill with samples when continuously +// sampling +// +// buffer - pointer to buffer to fill with samples +// length - number of samples requested, must be less than or equal to buffer +// length +returncode_t libtock_adc_set_double_buffer(uint16_t* buffer, uint32_t length); + + + +// query how many channels are available in the ADC driver +returncode_t libtock_adc_channel_count(int* count); + +// request a single analog sample +// +// channel - number of the channel to be sampled +returncode_t libtock_adc_single_sample(uint8_t channel, libtock_adc_callbacks* callbacks); + +// request an repeated analog samples at a given frequency +// +// channel - number of the channel to be sampled +// frequency - rate in samples per second to collect data at +returncode_t libtock_adc_continuous_sample(uint8_t channel, uint32_t frequency, libtock_adc_callbacks* callbacks); + +// request a buffer full of samples from the ADC +// +// channel - number of the channel to be sampled +// frequency - rate in samples per second to collect data at +returncode_t libtock_adc_buffered_sample(uint8_t channel, uint32_t frequency, libtock_adc_callbacks* callbacks); + +// request continuous ADC sampling +// Alternates between the two provided application buffers +// +// channel - number of the channel to be sampled +// frequency - rate in samples per second to collect data at +returncode_t libtock_adc_continuous_buffered_sample(uint8_t channel, uint32_t frequency, libtock_adc_callbacks* callbacks); + +// cancel an outstanding ADC operation +// No callback will occur from the prior ADC operation. The ADC may not be +// immediately ready to use again if a single sample was canceled. Usually used +// to stop a continuous sampling operation +returncode_t libtock_adc_stop_sampling(void); + + + + + + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/analog_comparator.c b/libtock/peripherals/analog_comparator.c new file mode 100644 index 000000000..eef279259 --- /dev/null +++ b/libtock/peripherals/analog_comparator.c @@ -0,0 +1,17 @@ +#include "analog_comparator.h" + +returncode_t libtock_analog_comparator_count(int* count) { + return libtock_analog_comparator_command_count((uint32_t*) count); +} + +returncode_t libtock_analog_comparator_comparison(uint8_t channel, bool* comparison) { + return libtock_analog_comparator_command_comparison(channel, (uint32_t*) comparison); +} + +returncode_t libtock_analog_comparator_start_comparing(uint8_t channel) { + return libtock_analog_comparator_command_start_comparing(channel); +} + +returncode_t libtock_analog_comparator_stop_comparing(uint8_t channel) { + return libtock_analog_comparator_command_stop_comparing(channel); +} diff --git a/libtock/peripherals/analog_comparator.h b/libtock/peripherals/analog_comparator.h new file mode 100644 index 000000000..70fe83ddf --- /dev/null +++ b/libtock/peripherals/analog_comparator.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/analog_comparator_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Request the number of available ACs. +returncode_t libtock_analog_comparator_count(int* count); + +// Compare the voltages of two pins (if one is higher than the other) on the +// corresponding AC by doing a single comparison. +// +// - channel - index of the analog comparator channel, starting at 0. +// - comparison - set to true if is higher +returncode_t libtock_analog_comparator_comparison(uint8_t channel, bool* comparison); + +// Enable interrupt-based comparisons. This will make the AC listen and send an +// interrupt as soon as Vp > Vn. +// +// - channel - index of the analog comparator channel, starting at 0. +returncode_t libtock_analog_comparator_start_comparing(uint8_t channel); + +// Disable interrupt-based comparisons. This will make the AC stop listening, +// and thereby stop sending interrupts. +// +// - channel - index of the analog comparator channel, starting at 0. +returncode_t libtock_analog_comparator_stop_comparing(uint8_t channel); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/crc.c b/libtock/peripherals/crc.c new file mode 100644 index 000000000..3a694e619 --- /dev/null +++ b/libtock/peripherals/crc.c @@ -0,0 +1,20 @@ +#include "crc.h" + +static void crc_upcall(int status, int v1, __attribute__((unused)) int v2, void *opaque) { + libtock_crc_callback_computed cb = (libtock_crc_callback_computed) opaque; + cb(status, v1); +} + +returncode_t libtock_crc_compute(const uint8_t* buf, uint32_t buflen, libtock_crc_alg_t algorithm, + libtock_crc_callback_computed cb) { + returncode_t ret; + + ret = libtock_crc_set_readonly_allow(buf, buflen); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_crc_set_upcall(crc_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_crc_command_request(algorithm, buflen); + return ret; +} diff --git a/libtock/peripherals/crc.h b/libtock/peripherals/crc.h new file mode 100644 index 000000000..273c6ef9c --- /dev/null +++ b/libtock/peripherals/crc.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/crc_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for CRC callback. +// +// - `arg1` (`returncode_t`): Status of the crc. +// - `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; + +// Compute a CRC value over the given buffer using the given algorithm. +returncode_t libtock_crc_compute(const uint8_t* buf, uint32_t buflen, libtock_crc_alg_t algorithm, libtock_crc_callback_computed cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/dac.c b/libtock/peripherals/dac.c new file mode 100644 index 000000000..7d92a90da --- /dev/null +++ b/libtock/peripherals/dac.c @@ -0,0 +1,9 @@ +#include "dac.h" + +returncode_t libtock_dac_initialize(void) { + return libtock_dac_command_initialize(); +} + +returncode_t libtock_dac_set_value(uint32_t value) { + return libtock_dac_command_set_value(value); +} diff --git a/libtock/peripherals/dac.h b/libtock/peripherals/dac.h new file mode 100644 index 000000000..d5bfb5d70 --- /dev/null +++ b/libtock/peripherals/dac.h @@ -0,0 +1,18 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/dac_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize the Digital-to-Analog converter. +returncode_t libtock_dac_initialize(void); + +// Set the level for the DAC. +returncode_t libtock_dac_set_value(uint32_t value); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/gpio.c b/libtock/peripherals/gpio.c new file mode 100644 index 000000000..23f73f90e --- /dev/null +++ b/libtock/peripherals/gpio.c @@ -0,0 +1,53 @@ +#include "gpio.h" + +static void gpio_upcall(int pin_number, + int pin_level, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_gpio_callback_interrupt cb = (libtock_gpio_callback_interrupt) opaque; + cb((uint32_t) pin_number, pin_level == 1); +} + +returncode_t libtock_gpio_count(int* count) { + return libtock_gpio_command_count((uint32_t*) count); +} + +returncode_t libtock_gpio_set_interrupt_callback(libtock_gpio_callback_interrupt cb) { + return libtock_gpio_set_upcall(gpio_upcall, cb); +} + +returncode_t libtock_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 libtock_gpio_enable_output(uint32_t pin){ + return libtock_gpio_command_enable_output(pin); +} + +returncode_t libtock_gpio_set(uint32_t pin) { + return libtock_gpio_command_set(pin); +} + +returncode_t libtock_gpio_clear(uint32_t pin) { + return libtock_gpio_command_clear(pin); +} + +returncode_t libtock_gpio_toggle(uint32_t pin) { + return libtock_gpio_command_toggle(pin); +} + +returncode_t libtock_gpio_read(uint32_t pin, int* pin_value) { + return libtock_gpio_command_read(pin, (uint32_t*) pin_value); +} + +returncode_t libtock_gpio_enable_interrupt(uint32_t pin, libtock_gpio_interrupt_mode_t irq_config) { + return libtock_gpio_command_enable_interrupt(pin, (uint32_t) irq_config); +} + +returncode_t libtock_gpio_disable_interrupt(uint32_t pin) { + return libtock_gpio_command_disable_interrupt(pin); +} + +returncode_t libtock_gpio_disable(uint32_t pin) { + return libtock_gpio_command_disable(pin); +} diff --git a/libtock/peripherals/gpio.h b/libtock/peripherals/gpio.h new file mode 100644 index 000000000..990a12b6d --- /dev/null +++ b/libtock/peripherals/gpio.h @@ -0,0 +1,68 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/gpio_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for gpio interrupts +// +// - `arg1` (`uint32_t`): Pin number of the pin that interrupted. +// - `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; + +// Returns the number of GPIO pins configured on the board. +returncode_t libtock_gpio_count(int* count); + +// Set the callback function that is called when a GPIO interrupt fires. +returncode_t libtock_gpio_set_interrupt_callback(libtock_gpio_callback_interrupt cb); + +// Set the pin as an input. +// +// `pin_config` configures the pin with a pull up, pull down, or neither. +returncode_t libtock_gpio_enable_input(uint32_t pin, libtock_gpio_input_mode_t pin_config); + +// Set the pin as an output. +returncode_t libtock_gpio_enable_output(uint32_t pin); + +// Set the pin high. +returncode_t libtock_gpio_set(uint32_t pin); + +// Set the pin low. +returncode_t libtock_gpio_clear(uint32_t pin); + +// Toggle the pin. +returncode_t libtock_gpio_toggle(uint32_t pin); + +// Read the state of an input pin. +returncode_t libtock_gpio_read(uint32_t pin, int* pin_value); + +// Enable interrupts for the pin. +// +// The callback function needs to be set via +// `libtock_gpio_set_interrupt_callback()`. +returncode_t libtock_gpio_enable_interrupt(uint32_t pin, libtock_gpio_interrupt_mode_t irq_config); + +// Disable interrupts for the pin. +returncode_t libtock_gpio_disable_interrupt(uint32_t pin); + +// Completely disable the pin allowing it to go into its lowest power mode. +returncode_t libtock_gpio_disable(uint32_t pin); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/gpio_async.c b/libtock/peripherals/gpio_async.c new file mode 100644 index 000000000..57ff7d9be --- /dev/null +++ b/libtock/peripherals/gpio_async.c @@ -0,0 +1,83 @@ +#include "gpio_async.h" + +static void gpio_async_upcall_interrupt( int pin_number, + int value, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_gpio_async_callback_interrupt cb = (libtock_gpio_async_callback_interrupt) opaque; + cb(0, (uint32_t) pin_number, value == 1); +} + +static void gpio_async_upcall_command(__attribute__ ((unused)) int unused1, + int value, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_gpio_async_callback_command cb = (libtock_gpio_async_callback_command) opaque; + cb(RETURNCODE_SUCCESS, value); +} + +returncode_t libtock_gpio_async_set_interrupt_callback(libtock_gpio_async_callback_interrupt cb) { + return libtock_gpio_async_set_upcall_interrupt(gpio_async_upcall_interrupt, cb); +} + +static returncode_t gpio_async_operation(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb, + returncode_t (*op)(uint32_t, uint8_t)) { + returncode_t ret; + + ret = libtock_gpio_async_set_upcall_command(gpio_async_upcall_command, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = op(port, pin); + return ret; +} + +returncode_t libtock_gpio_async_make_output(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_make_output); +} + +returncode_t libtock_gpio_async_clear(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_set); +} + +returncode_t libtock_gpio_async_set(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_clear); +} + +returncode_t libtock_gpio_async_toggle(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_toggle); +} + +returncode_t libtock_gpio_async_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config, + libtock_gpio_async_callback_command cb) { + returncode_t ret; + + ret = libtock_gpio_async_set_upcall_command(gpio_async_upcall_command, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_gpio_async_command_make_input(port, pin, (uint32_t) pin_config); + return ret; + +} + +returncode_t libtock_gpio_async_read(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_read); +} + +returncode_t libtock_gpio_async_enable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_interrupt_mode_t irq_config, + libtock_gpio_async_callback_command cb) { + returncode_t ret; + + ret = libtock_gpio_async_set_upcall_command(gpio_async_upcall_command, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_gpio_async_command_enable_interrupt(port, pin, (uint32_t) irq_config); + return ret; +} + +returncode_t libtock_gpio_async_disable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_disable_interrupt); +} + +returncode_t libtock_gpio_async_disable(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb) { + return gpio_async_operation(port, pin, cb, libtock_gpio_async_command_disable); +} diff --git a/libtock/peripherals/gpio_async.h b/libtock/peripherals/gpio_async.h new file mode 100644 index 000000000..494bc5cc9 --- /dev/null +++ b/libtock/peripherals/gpio_async.h @@ -0,0 +1,46 @@ +#pragma once + +#include "gpio.h" +#include "../tock.h" +#include "syscalls/gpio_async_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for async gpio interrupts +// +// - `arg1` (`uint32_t`): Port number of the pin that interrupted. +// - `arg2` (`uint32_t`): Pin number of the pin that interrupted. +// - `arg3` (`bool`): If the value is high (true) or low (false). +typedef void (*libtock_gpio_async_callback_interrupt)(uint32_t, uint32_t, bool); + +// Function signature for GPIO async callback. +// +// - `arg1` (`returncode_t`): Status of the command operation. +// - `arg2` (`bool`): On a read if the value is high (true) or low (false). +typedef void (*libtock_gpio_async_callback_command)(returncode_t, bool); + +returncode_t libtock_gpio_async_set_interrupt_callback(libtock_gpio_async_callback_interrupt cb); + +returncode_t libtock_gpio_async_make_output(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_clear(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_set(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_toggle(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_read(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_enable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_interrupt_mode_t irq_config, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_disable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +returncode_t libtock_gpio_async_disable(uint32_t port, uint8_t pin, libtock_gpio_async_callback_command cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/i2c_master.c b/libtock/peripherals/i2c_master.c similarity index 100% rename from libtock/i2c_master.c rename to libtock/peripherals/i2c_master.c diff --git a/libtock/i2c_master.h b/libtock/peripherals/i2c_master.h similarity index 96% rename from libtock/i2c_master.h rename to libtock/peripherals/i2c_master.h index 92e87f8ca..2b19fd8f2 100644 --- a/libtock/i2c_master.h +++ b/libtock/peripherals/i2c_master.h @@ -1,6 +1,6 @@ #pragma once -#include "tock.h" +#include "../tock.h" #ifdef __cplusplus extern "C" { diff --git a/libtock/i2c_master_slave.c b/libtock/peripherals/i2c_master_slave.c similarity index 100% rename from libtock/i2c_master_slave.c rename to libtock/peripherals/i2c_master_slave.c diff --git a/libtock/i2c_master_slave.h b/libtock/peripherals/i2c_master_slave.h similarity index 98% rename from libtock/i2c_master_slave.h rename to libtock/peripherals/i2c_master_slave.h index 15282274e..a9476aa21 100644 --- a/libtock/i2c_master_slave.h +++ b/libtock/peripherals/i2c_master_slave.h @@ -1,6 +1,6 @@ #pragma once -#include "tock.h" +#include "../tock.h" #ifdef __cplusplus extern "C" { diff --git a/libtock/peripherals/rng.c b/libtock/peripherals/rng.c new file mode 100644 index 000000000..1c8ce8a70 --- /dev/null +++ b/libtock/peripherals/rng.c @@ -0,0 +1,23 @@ +#include "rng.h" + +// Internal upcall. +static void rng_upcall(__attribute__ ((unused)) int callback_type, + int received, + __attribute__ ((unused)) int val2, + void* opaque) { + libtock_rng_callback cb = (libtock_rng_callback) opaque; + cb(RETURNCODE_SUCCESS, received); +} + +returncode_t libtock_rng_get_random_bytes(uint8_t* buf, uint32_t len, uint32_t num, libtock_rng_callback cb) { + returncode_t ret; + + ret = libtock_rng_set_upcall(rng_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_rng_set_allow_readwrite(buf, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_rng_command_get_random(num); + return ret; +} diff --git a/libtock/peripherals/rng.h b/libtock/peripherals/rng.h new file mode 100644 index 000000000..9325e674b --- /dev/null +++ b/libtock/peripherals/rng.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/rng_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for callbacks when randomness is available. +// +// - `arg1` (`returncode_t`): Returncode indicating status of the RNG call. +// - `arg2` (`int`): Number of random bytes available. +typedef void (*libtock_rng_callback)(returncode_t, int); + +// Get random bytes. +// +// Asynchronous RNG request. Registers callback and buffer and starts RNG. +// +// - buf: buffer to store the random bytes in. +// - len: length of buffer. +// - num: number of random bytes requested. +// - cb: callback when random bytes are available. +returncode_t libtock_rng_get_random_bytes(uint8_t* buf, uint32_t len, uint32_t num, libtock_rng_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/rtc.c b/libtock/peripherals/rtc.c new file mode 100644 index 000000000..a7f894b25 --- /dev/null +++ b/libtock/peripherals/rtc.c @@ -0,0 +1,65 @@ +#include "rtc.h" + +// DateTime codifies Date structure into two u32 (int) numbers +// date: first number (year, month, day_of_the_month): +// - last 5 bits store the day_of_the_month +// - previous 4 bits store the month +// - previous 12 bits store the year +// time: second number (day_of_the_week, hour, minute, seconds): +// - last 6 bits store the seconds +// - previous 6 store the minute +// - previous 5 store the hour +// - previous 3 store the day_of_the_week +static void rtc_convert_args_to_date(uint32_t date, uint32_t time, libtock_rtc_date_t* out) { + out->year = date % (1 << 21) / (1 << 9); + out->month = date % (1 << 9) / (1 << 5); + out->day = date % (1 << 5); + + out->day_of_week = time % (1 << 20) / (1 << 17); + out->hour = time % (1 << 17) / (1 << 12); + out->minute = time % (1 << 12) / (1 << 6); + out->seconds = time % (1 << 6); +} + +static void rtc_date_cb(int status, + int date, + int time, + void* opaque) { + libtock_rtc_callback_date cb = (libtock_rtc_callback_date) opaque; + libtock_rtc_date_t rtc_date; + + rtc_convert_args_to_date((uint32_t) date, (uint32_t) time, &rtc_date); + cb(status, rtc_date); +} + +static void rtc_set_cb(int status, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + void* opaque) { + libtock_rtc_callback_done cb = (libtock_rtc_callback_done) opaque; + cb(status); +} + +returncode_t libtock_rtc_get_date(libtock_rtc_callback_date cb) { + returncode_t ret; + + ret = libtock_rtc_set_upcall(rtc_date_cb, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_rtc_command_get_date(); + return ret; +} + +returncode_t libtock_rtc_set_date(libtock_rtc_date_t* set_date, libtock_rtc_callback_done cb) { + 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; + + returncode_t ret; + + ret = libtock_rtc_set_upcall(rtc_set_cb, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_rtc_command_set_date(date, time); + return ret; +} diff --git a/libtock/peripherals/rtc.h b/libtock/peripherals/rtc.h new file mode 100644 index 000000000..9d128af21 --- /dev/null +++ b/libtock/peripherals/rtc.h @@ -0,0 +1,66 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/rtc_syscalls.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. +// - `arg2` (`libtock_rtc_date_t`): Current date. +typedef void (*libtock_rtc_callback_date)(returncode_t, libtock_rtc_date_t); + +// Function signature for operation done callbacks. +// +// - `arg1` (`returncode_t`): Returncode indicating status. +typedef void (*libtock_rtc_callback_done)(returncode_t); + + +// Get the current date. +// +// The callback will be issued with the current date and time. +returncode_t libtock_rtc_get_date(libtock_rtc_callback_date cb); + +// Set the date and time. +// +// The callback will be issued when the time and date have been set. +returncode_t libtock_rtc_set_date(libtock_rtc_date_t* set_date, libtock_rtc_callback_done cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/spi_controller.c b/libtock/peripherals/spi_controller.c new file mode 100644 index 000000000..8aef802dd --- /dev/null +++ b/libtock/peripherals/spi_controller.c @@ -0,0 +1,80 @@ +#include "spi_controller.h" + +returncode_t libtock_spi_controller_set_chip_select(uint32_t chip_select) { + return libtock_spi_controller_command_set_chip_select(chip_select); +} + +returncode_t libtock_spi_controller_get_chip_select(uint32_t* chip_select) { + return libtock_spi_controller_command_get_chip_select(chip_select); +} + +returncode_t libtock_spi_controller_set_rate(uint32_t rate) { + return libtock_spi_controller_command_set_rate(rate); +} + +returncode_t libtock_spi_controller_get_rate(uint32_t* rate) { + return libtock_spi_controller_command_get_rate(rate); +} + +returncode_t libtock_spi_controller_set_phase(bool phase) { + return libtock_spi_controller_command_set_phase(phase); +} + +returncode_t libtock_spi_controller_get_phase(uint32_t* phase) { + return libtock_spi_controller_command_get_phase(phase); +} + +returncode_t libtock_spi_controller_set_polarity(bool polarity) { + return libtock_spi_controller_command_set_polarity(polarity); +} + +returncode_t libtock_spi_controller_get_polarity(uint32_t* polarity) { + return libtock_spi_controller_command_get_polarity(polarity); +} + +returncode_t libtock_spi_controller_hold_low(void) { + return libtock_spi_controller_command_hold_low(); +} + +returncode_t libtock_spi_controller_release_low(void) { + return libtock_spi_controller_command_release_low(); +} + +returncode_t libtock_spi_controller_write_byte(unsigned char byte) { + return libtock_spi_controller_command_write_byte((uint32_t) byte); +} + +static void spi_controller_upcall(__attribute__ ((unused)) int unused0, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_spi_controller_callback cb = (libtock_spi_controller_callback) opaque; + cb(RETURNCODE_SUCCESS); +} + +returncode_t libtock_spi_controller_write(const uint8_t* buffer, + size_t len, + libtock_spi_controller_callback cb) { + returncode_t ret; + + ret = libtock_spi_controller_allow_readonly_write((uint8_t*) buffer, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_spi_controller_set_upcall(spi_controller_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_spi_controller_command_read_write_bytes(len); + return ret; +} + +returncode_t libtock_spi_controller_read_write(const uint8_t* write, + uint8_t* read, + size_t len, + libtock_spi_controller_callback cb) { + returncode_t ret; + + ret = libtock_spi_controller_allow_readwrite_read(read, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_spi_controller_write(write, len, cb); +} diff --git a/libtock/peripherals/spi_controller.h b/libtock/peripherals/spi_controller.h new file mode 100644 index 000000000..868bd93fa --- /dev/null +++ b/libtock/peripherals/spi_controller.h @@ -0,0 +1,64 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/spi_controller_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for SPI callback. +// +// - `arg1` (`returncode_t`): Status from reading/writing SPI data. +typedef void (*libtock_spi_controller_callback)(returncode_t); + +// Set the chip select. +returncode_t libtock_spi_controller_set_chip_select(uint32_t chip_select); + +// Get the chip select. This will always return 0. +returncode_t libtock_spi_controller_get_chip_select(uint32_t* chip_select); + +/* Set the rate. Rate is the Hz of the SPI clock. So a rate of 100000 + * is a 100kHZ clock. */ +returncode_t libtock_spi_controller_set_rate(uint32_t rate); + +/* Get the rate. Rate is the Hz of the SPI clock. So a rate of 100000 + * is a 100kHZ clock. */ +returncode_t libtock_spi_controller_get_rate(uint32_t* rate); + +/* Set the SPI phase. + * false means sample on a leading (low to high) clock edge + * true means sample on a trailing (high to low) clock edge */ +returncode_t libtock_spi_controller_set_phase(bool phase); + +// Get the SPI phase. +returncode_t libtock_spi_controller_get_phase(uint32_t* phase); + +// Set the SPI polarity. False means idle clock is low. +returncode_t libtock_spi_controller_set_polarity(bool polarity); + +// Get the SPI polarity. +returncode_t libtock_spi_controller_get_polarity(uint32_t* polarity); + +/* Only partially supported, depending on implementation. In some cases + allows a process to hold its chip select line low over multiple SPI + operations*/ +returncode_t libtock_spi_controller_hold_low(void); + +// Releases a held low chip select line, if supported. +returncode_t libtock_spi_controller_release_low(void); + +returncode_t libtock_spi_controller_write_byte(unsigned char byte); + +returncode_t libtock_spi_controller_write(const uint8_t* buffer, + size_t len, + libtock_spi_controller_callback cb); + +returncode_t libtock_spi_controller_read_write(const uint8_t* write, + uint8_t* read, + size_t len, + libtock_spi_controller_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/spi_peripheral.c b/libtock/peripherals/spi_peripheral.c new file mode 100644 index 000000000..369f12520 --- /dev/null +++ b/libtock/peripherals/spi_peripheral.c @@ -0,0 +1,61 @@ +#include "spi_peripheral.h" + +// Return the chip select. This will always return 0. +returncode_t libtock_spi_peripheral_get_chip_select(uint32_t* chip_select){ + return libtock_spi_peripheral_command_get_chip_select(chip_select); +} + + +returncode_t libtock_spi_peripheral_get_phase(uint32_t* phase){ + return libtock_spi_peripheral_command_get_phase(phase); +} + + +returncode_t libtock_spi_peripheral_set_phase(bool phase){ + return libtock_spi_peripheral_command_set_phase(phase); +} + + +returncode_t libtock_spi_peripheral_get_polarity(uint32_t* polarity){ + return libtock_spi_peripheral_command_get_polarity(polarity); +} + + +returncode_t libtock_spi_peripheral_set_polarity(bool polarity){ + return libtock_spi_peripheral_command_set_polarity(polarity); +} + +static void spi_peripheral_upcall(__attribute__ ((unused)) int unused0, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, + void* opaque) { + libtock_spi_peripheral_callback cb = (libtock_spi_peripheral_callback) opaque; + cb(RETURNCODE_SUCCESS); +} + +returncode_t libtock_spi_peripheral_write(const uint8_t* buffer, + size_t len, + libtock_spi_peripheral_callback cb) { + returncode_t ret; + + ret = libtock_spi_peripheral_allow_readonly_write((uint8_t*) buffer, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_spi_peripheral_set_upcall(spi_peripheral_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_spi_peripheral_command_write(len); + return ret; +} + +returncode_t libtock_spi_peripheral_read_write(const uint8_t* write, + uint8_t* read, + size_t len, + libtock_spi_peripheral_callback cb) { + returncode_t ret; + + ret = libtock_spi_peripheral_allow_readwrite_read(read, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + return libtock_spi_peripheral_write(write, len, cb); +} diff --git a/libtock/peripherals/spi_peripheral.h b/libtock/peripherals/spi_peripheral.h new file mode 100644 index 000000000..e78b4f4f4 --- /dev/null +++ b/libtock/peripherals/spi_peripheral.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/spi_peripheral_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for SPI peripheral callback. +// +// - `arg1` (`returncode_t`): Status from reading/writing SPI data. +typedef void (*libtock_spi_peripheral_callback)(returncode_t); + + +// Get the chip select. This will always return 0. +returncode_t libtock_spi_peripheral_get_chip_select(uint32_t* chip_select); + +// Get the SPI phase. +returncode_t libtock_spi_peripheral_get_phase(uint32_t* phase); + +// Set the SPI phase. +returncode_t libtock_spi_peripheral_set_phase(bool phase); + +// Get the SPI polarity. +returncode_t libtock_spi_peripheral_get_polarity(uint32_t* polarity); + +// Set the SPI polarity. +returncode_t libtock_spi_peripheral_set_polarity(bool polarity); + +// Write a buffer on the SPI bus. The callback will be triggered after it is +// written. +returncode_t libtock_spi_peripheral_write(const uint8_t* buffer, + size_t len, + libtock_spi_peripheral_callback cb); + +// Write a buffer on the SPI bus and also capture the incoming data. The +// callback will be triggered after it is written. +returncode_t libtock_spi_peripheral_read_write(const uint8_t* write, + uint8_t* read, + size_t len, + libtock_spi_peripheral_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/syscalls/adc_syscalls.c b/libtock/peripherals/syscalls/adc_syscalls.c new file mode 100644 index 000000000..aca18559f --- /dev/null +++ b/libtock/peripherals/syscalls/adc_syscalls.c @@ -0,0 +1,60 @@ +#include "adc_syscalls.h" + +bool libtock_adc_exists(void) { + return driver_exists(DRIVER_NUM_ADC); +} + +returncode_t libtock_adc_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_ADC, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_adc_set_readwrite_allow_set_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t rval = allow_readwrite(DRIVER_NUM_ADC, 0, buffer, len); + return tock_allow_rw_return_to_returncode(rval); +} + +returncode_t libtock_adc_set_readwrite_allow_set_double_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t rval = allow_readwrite(DRIVER_NUM_ADC, 1, buffer, len); + return tock_allow_rw_return_to_returncode(rval); +} + +returncode_t libtock_adc_command_channel_count(int* count) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 0, 0, 0); + return tock_command_return_u32_to_returncode(cval, (uint32_t*) count); +} + +returncode_t libtock_adc_command_single_sample(uint8_t channel) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 1, channel, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_adc_command_continuous_sample(uint8_t channel, uint32_t frequency) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 2, channel, frequency); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_adc_command_buffered_sample(uint8_t channel, uint32_t frequency) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 3, channel, frequency); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_adc_command_continuous_buffered_sample(uint8_t channel, uint32_t frequency) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 4, channel, frequency); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_adc_command_stop_sampling(void) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 5, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_adc_command_get_reference_voltage (uint32_t* reference_voltage) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 102, 0, 0); + return tock_command_return_u32_to_returncode(cval, reference_voltage); +} + +returncode_t libtock_adc_command_get_resolution_bits (uint32_t* resolution) { + syscall_return_t cval = command(DRIVER_NUM_ADC, 101, 0, 0); + return tock_command_return_u32_to_returncode(cval, resolution); +} diff --git a/libtock/peripherals/syscalls/adc_syscalls.h b/libtock/peripherals/syscalls/adc_syscalls.h new file mode 100644 index 000000000..83c91aa7f --- /dev/null +++ b/libtock/peripherals/syscalls/adc_syscalls.h @@ -0,0 +1,38 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_ADC 0x5 + +bool libtock_adc_exists(void); + +returncode_t libtock_adc_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_adc_set_readwrite_allow_set_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_adc_set_readwrite_allow_set_double_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_adc_command_channel_count(int* count); + +returncode_t libtock_adc_command_single_sample(uint8_t channel); + +returncode_t libtock_adc_command_continuous_sample(uint8_t channel, uint32_t frequency); + +returncode_t libtock_adc_command_buffered_sample(uint8_t channel, uint32_t frequency); + +returncode_t libtock_adc_command_continuous_buffered_sample(uint8_t channel, uint32_t frequency); + +returncode_t libtock_adc_command_stop_sampling(void); + +returncode_t libtock_adc_command_get_reference_voltage(uint32_t* reference_voltage); + +returncode_t libtock_adc_command_get_resolution_bits(uint32_t* resolution); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/syscalls/alarm_syscalls.c b/libtock/peripherals/syscalls/alarm_syscalls.c new file mode 100644 index 000000000..0279b16b1 --- /dev/null +++ b/libtock/peripherals/syscalls/alarm_syscalls.c @@ -0,0 +1,36 @@ +#include "alarm_syscalls.h" + +bool libtock_alarm_exists(void) { + return driver_exists(DRIVER_NUM_ALARM); +} + +int libtock_alarm_set_upcall(subscribe_upcall callback, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_ALARM, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +int libtock_alarm_command_get_frequency(uint32_t* frequency) { + syscall_return_t rval = command(DRIVER_NUM_ALARM, 1, 0, 0); + return tock_command_return_u32_to_returncode(rval, frequency); +} + +int libtock_alarm_command_read(uint32_t* time) { + syscall_return_t rval = command(DRIVER_NUM_ALARM, 2, 0, 0); + return tock_command_return_u32_to_returncode(rval, time); +} + +int libtock_alarm_command_stop(void) { + syscall_return_t rval = command(DRIVER_NUM_ALARM, 3, 0, 0); + return tock_command_return_novalue_to_returncode(rval); +} + +int libtock_alarm_command_set_relative(uint32_t dt, uint32_t* actual) { + syscall_return_t rval = command(DRIVER_NUM_ALARM, 5, dt, 0); + return tock_command_return_u32_to_returncode(rval, actual); +} + +int libtock_alarm_command_set_absolute(uint32_t reference, uint32_t dt) { + syscall_return_t rval = command(DRIVER_NUM_ALARM, 6, reference, dt); + uint32_t unused; + return tock_command_return_u32_to_returncode(rval, &unused); +} diff --git a/libtock/peripherals/syscalls/alarm_syscalls.h b/libtock/peripherals/syscalls/alarm_syscalls.h new file mode 100644 index 000000000..4aa3edfb9 --- /dev/null +++ b/libtock/peripherals/syscalls/alarm_syscalls.h @@ -0,0 +1,62 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_ALARM 0x0 + +// Check if the alarm driver is available on this board. +bool libtock_alarm_exists(void); + +/* + * Sets the callback for alarms + * + * When invoked, the callback's first argument will be the alarm value at which + * the alarm was fired. + */ +int libtock_alarm_set_upcall(subscribe_upcall callback, void *opaque); + +/* + * Get the the alarm frequency in Hz. + */ +int libtock_alarm_command_get_frequency(uint32_t* frequency); + +/* + * Get the current alarm counter. + */ +int libtock_alarm_command_read(uint32_t* time); + +/* + * Stops any outstanding hardware alarm. + * + * Side-effects: cancels any existing/outstanding alarms + */ +int libtock_alarm_command_stop(void); + +/* + * Starts a oneshot alarm + * + * expiration - relative expiration value from when kernel handles syscall. + * Sets *actual to the time the actual alarm was set for by the kernel. + * + * Side-effects: cancels any existing/outstanding alarms + */ +int libtock_alarm_command_set_relative(uint32_t dt, uint32_t* actual); + +/* + * Starts a oneshot alarm + * + * expiration - absolute expiration value = reference + dt. + * Using reference + dt allows library to distinguish expired alarms from + * alarms in the far future. + * + * Side-effects: cancels any existing/outstanding alarms + */ +int libtock_alarm_command_set_absolute(uint32_t reference, uint32_t dt); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/syscalls/analog_comparator_syscalls.c b/libtock/peripherals/syscalls/analog_comparator_syscalls.c new file mode 100644 index 000000000..a6100a58f --- /dev/null +++ b/libtock/peripherals/syscalls/analog_comparator_syscalls.c @@ -0,0 +1,30 @@ +#include "analog_comparator_syscalls.h" + +bool libtock_analog_comparator_exists(void) { + return driver_exists(DRIVER_NUM_ANALOG_COMPARATOR); +} + +returncode_t libtock_analog_comparator_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_ANALOG_COMPARATOR, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_analog_comparator_command_comparison(uint8_t channel, uint32_t* comparison) { + syscall_return_t cval = command(DRIVER_NUM_ANALOG_COMPARATOR, 1, channel, 0); + return tock_command_return_u32_to_returncode(cval, comparison); +} + +returncode_t libtock_analog_comparator_command_start_comparing(uint8_t channel) { + syscall_return_t cval = command(DRIVER_NUM_ANALOG_COMPARATOR, 2, channel, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_analog_comparator_command_stop_comparing(uint8_t channel) { + syscall_return_t cval = command(DRIVER_NUM_ANALOG_COMPARATOR, 3, channel, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_analog_comparator_command_count(uint32_t* count) { + syscall_return_t cval = command(DRIVER_NUM_ANALOG_COMPARATOR, 4, 0, 0); + return tock_command_return_u32_to_returncode(cval, count); +} diff --git a/libtock/peripherals/syscalls/analog_comparator_syscalls.h b/libtock/peripherals/syscalls/analog_comparator_syscalls.h new file mode 100644 index 000000000..8f48fa84e --- /dev/null +++ b/libtock/peripherals/syscalls/analog_comparator_syscalls.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_ANALOG_COMPARATOR 0x7 + +bool libtock_analog_comparator_exists(void); + +// Set the upcall function called by the AC when an interrupt is received. +// +// - callback - pointer to function to be called +// - callback_args - pointer to data provided to the callback +returncode_t libtock_analog_comparator_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_analog_comparator_command_comparison(uint8_t channel, uint32_t* comparison); + +returncode_t libtock_analog_comparator_command_start_comparing(uint8_t channel); + +returncode_t libtock_analog_comparator_command_stop_comparing(uint8_t channel); + +returncode_t libtock_analog_comparator_command_count(uint32_t* count); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/syscalls/crc_syscalls.c b/libtock/peripherals/syscalls/crc_syscalls.c new file mode 100644 index 000000000..962e00f98 --- /dev/null +++ b/libtock/peripherals/syscalls/crc_syscalls.c @@ -0,0 +1,20 @@ +#include "crc_syscalls.h" + +bool libtock_crc_exists(void) { + return driver_exists(DRIVER_NUM_CRC); +} + +returncode_t libtock_crc_set_upcall(subscribe_upcall callback, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_CRC, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_crc_set_readonly_allow(const uint8_t* buf, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_CRC, 0, (void*) buf, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_crc_command_request(uint32_t algorithm, uint32_t len) { + syscall_return_t cval = command(DRIVER_NUM_CRC, 1, algorithm, len); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/crc_syscalls.h b/libtock/peripherals/syscalls/crc_syscalls.h new file mode 100644 index 000000000..dc46c1544 --- /dev/null +++ b/libtock/peripherals/syscalls/crc_syscalls.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_CRC 0x40002 + +// Check if CRC driver is installed. +bool libtock_crc_exists(void); + +// Register a callback to receive CRC results. +returncode_t libtock_crc_set_upcall(subscribe_upcall callback, void *opaque); + +// Provide the buffer over which to compute a CRC. +returncode_t libtock_crc_set_readonly_allow(const uint8_t* buf, uint32_t len); + +// Request a CRC computation asynchronously +// +// The callback and buffer must be provided first. +// +// If `SUCCESS` is returned, the result will be provided to the registered +// callback. +// +// Returns `EBUSY` if a computation is already in progress. Returns `ESIZE` if +// the buffer is too big for the unit. +returncode_t libtock_crc_command_request(uint32_t algorithm, uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/syscalls/dac_syscalls.c b/libtock/peripherals/syscalls/dac_syscalls.c new file mode 100644 index 000000000..969e37506 --- /dev/null +++ b/libtock/peripherals/syscalls/dac_syscalls.c @@ -0,0 +1,15 @@ +#include "dac_syscalls.h" + +bool libtock_dac_exists(void) { + return driver_exists(DRIVER_NUM_DAC); +} + +returncode_t libtock_dac_command_initialize(void) { + syscall_return_t cval = command(DRIVER_NUM_DAC, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_dac_command_set_value(uint32_t value) { + syscall_return_t cval = command(DRIVER_NUM_DAC, 2, value, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/dac_syscalls.h b/libtock/peripherals/syscalls/dac_syscalls.h new file mode 100644 index 000000000..82dc8a62b --- /dev/null +++ b/libtock/peripherals/syscalls/dac_syscalls.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_DAC 0x6 + +// Check if the DAC driver exists. +bool libtock_dac_exists(void); + +// Command to initialize the digital-to-analog converter (DAC). +returncode_t libtock_dac_command_initialize(void); + +// Set the level of the DAC. +returncode_t libtock_dac_command_set_value(uint32_t value); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/syscalls/gpio_async_syscalls.c b/libtock/peripherals/syscalls/gpio_async_syscalls.c new file mode 100644 index 000000000..ad4c439cd --- /dev/null +++ b/libtock/peripherals/syscalls/gpio_async_syscalls.c @@ -0,0 +1,65 @@ +#include "gpio_async_syscalls.h" + +#define CONCAT_PORT_DATA(port, data) (((data & 0xFFFF) << 16) | (port & 0xFFFF)) + + + +bool libtock_gpio_async_exists(void) { + return driver_exists(DRIVER_NUM_GPIO_ASYNC); +} + +returncode_t libtock_gpio_async_set_upcall_command(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_GPIO_ASYNC, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_gpio_async_set_upcall_interrupt(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_GPIO_ASYNC, 1, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_gpio_async_command_make_output(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 1, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_set(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 2, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_clear(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 3, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_toggle(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 4, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 5, pin, CONCAT_PORT_DATA(port, pin_config)); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_read(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 6, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_enable_interrupt(uint32_t port, uint8_t pin, + libtock_gpio_interrupt_mode_t irq_config) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 7, pin, CONCAT_PORT_DATA(port, irq_config)); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_disable_interrupt(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 8, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_async_command_disable(uint32_t port, uint8_t pin) { + syscall_return_t cval = command(DRIVER_NUM_GPIO_ASYNC, 9, pin, port); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/gpio_async_syscalls.h b/libtock/peripherals/syscalls/gpio_async_syscalls.h new file mode 100644 index 000000000..6826a6b6b --- /dev/null +++ b/libtock/peripherals/syscalls/gpio_async_syscalls.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../tock.h" +#include "../gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_GPIO_ASYNC 0x80003 + +#define CONCAT_PORT_DATA(port, data) (((data & 0xFFFF) << 16) | (port & 0xFFFF)) + +bool libtock_gpio_async_exists(void); +returncode_t libtock_gpio_async_set_upcall_command(subscribe_upcall callback, void* opaque); +returncode_t libtock_gpio_async_set_upcall_interrupt(subscribe_upcall callback, void* opaque); +returncode_t libtock_gpio_async_command_make_output(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_set(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_clear(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_toggle(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config); +returncode_t libtock_gpio_async_command_read(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_enable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_interrupt_mode_t irq_config); +returncode_t libtock_gpio_async_command_disable_interrupt(uint32_t port, uint8_t pin); +returncode_t libtock_gpio_async_command_disable(uint32_t port, uint8_t pin); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/syscalls/gpio_syscalls.c b/libtock/peripherals/syscalls/gpio_syscalls.c new file mode 100644 index 000000000..2351d3be9 --- /dev/null +++ b/libtock/peripherals/syscalls/gpio_syscalls.c @@ -0,0 +1,60 @@ +#include "gpio_syscalls.h" + +bool libtock_gpio_exists(void) { + return driver_exists(GPIO_DRIVER_NUM); +} + +returncode_t libtock_gpio_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(GPIO_DRIVER_NUM, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_gpio_command_count(uint32_t* count) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 10, 0, 0); + return tock_command_return_u32_to_returncode(cval, count); +} + +returncode_t libtock_gpio_command_enable_output(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 1, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_enable_input(uint32_t pin, uint32_t pin_config) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 5, pin, pin_config); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_set(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 2, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_clear(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 3, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_toggle(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 4, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_read(uint32_t pin, uint32_t* pin_value) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 6, pin, 0); + return tock_command_return_u32_to_returncode(cval, pin_value); +} + +returncode_t libtock_gpio_command_enable_interrupt(uint32_t pin, uint32_t irq_config) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 7, pin, irq_config); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_disable_interrupt(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 8, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_gpio_command_disable(uint32_t pin) { + syscall_return_t cval = command(GPIO_DRIVER_NUM, 9, pin, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/gpio_syscalls.h b/libtock/peripherals/syscalls/gpio_syscalls.h new file mode 100644 index 000000000..f7f175e41 --- /dev/null +++ b/libtock/peripherals/syscalls/gpio_syscalls.h @@ -0,0 +1,50 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIO_DRIVER_NUM 0x4 + +// Check if the GPIO driver is available in the kernel. +bool libtock_gpio_exists(void); + +// Set the upcall for getting GPIO pin interrupts. +returncode_t libtock_gpio_set_upcall(subscribe_upcall callback, void* opaque); + +// Get the number of GPIO pins available on the board. +returncode_t libtock_gpio_command_count(uint32_t* count); + +// Set a pin as an output. +returncode_t libtock_gpio_command_enable_output(uint32_t pin); + +// Set a pin as an input with an optional pull-up/down. +returncode_t libtock_gpio_command_enable_input(uint32_t pin, uint32_t pin_config); + +// Set an output pin high. +returncode_t libtock_gpio_command_set(uint32_t pin); + +// Set an output pin low. +returncode_t libtock_gpio_command_clear(uint32_t pin); + +// Toggle an output pin. +returncode_t libtock_gpio_command_toggle(uint32_t pin); + +// Read the level of an input pin. +returncode_t libtock_gpio_command_read(uint32_t pin, uint32_t* pin_value); + +// Enable interrupts on an input pin. +returncode_t libtock_gpio_command_enable_interrupt(uint32_t pin, uint32_t irq_config); + +// Disable interrupts on an input pin. +returncode_t libtock_gpio_command_disable_interrupt(uint32_t pin); + +// Disable a pin and minimize the power draw from the pin. +returncode_t libtock_gpio_command_disable(uint32_t pin); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/syscalls/rng_syscalls.c b/libtock/peripherals/syscalls/rng_syscalls.c new file mode 100644 index 000000000..96b49ce3b --- /dev/null +++ b/libtock/peripherals/syscalls/rng_syscalls.c @@ -0,0 +1,20 @@ +#include "rng_syscalls.h" + +bool libtock_rng_exists(void) { + return driver_exists(DRIVER_NUM_RNG); +} + +returncode_t libtock_rng_set_allow_readwrite(uint8_t* buf, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_RNG, 0, (void*) buf, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_rng_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_RNG, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_rng_command_get_random(uint32_t num_bytes) { + syscall_return_t cval = command(DRIVER_NUM_RNG, 1, num_bytes, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/rng_syscalls.h b/libtock/peripherals/syscalls/rng_syscalls.h new file mode 100644 index 000000000..51dd247dc --- /dev/null +++ b/libtock/peripherals/syscalls/rng_syscalls.h @@ -0,0 +1,32 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_RNG 0x40001 + +// Check if the RNG driver exists. +bool libtock_rng_exists(void); + +// Allows buffer to hold received randomness. +// +// - buffer: pointer to uint8_t array to store randomness +// - len: length of buffer. +returncode_t libtock_rng_set_allow_readwrite(uint8_t* buf, uint32_t len); + +// Registers an upcall function that is called when requested randomness is +// obtained or provided buffer is full. +returncode_t libtock_rng_set_upcall(subscribe_upcall callback, void* opaque); + +// Starts random number generator. +// +// - num_bytes: number of random bytes requested. +returncode_t libtock_rng_command_get_random(uint32_t num_bytes); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/syscalls/rtc_syscalls.c b/libtock/peripherals/syscalls/rtc_syscalls.c new file mode 100644 index 000000000..46ffb4818 --- /dev/null +++ b/libtock/peripherals/syscalls/rtc_syscalls.c @@ -0,0 +1,20 @@ +#include "rtc_syscalls.h" + +bool libtock_rtc_exists(void) { + return driver_exists(DRIVER_NUM_RTC); +} + +returncode_t libtock_rtc_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_RTC, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_rtc_command_get_date(void) { + syscall_return_t cval = command(DRIVER_NUM_RTC, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_rtc_command_set_date(uint32_t date, uint32_t time) { + syscall_return_t cval = command(DRIVER_NUM_RTC, 2, date, time); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/rtc_syscalls.h b/libtock/peripherals/syscalls/rtc_syscalls.h new file mode 100644 index 000000000..ed9dc41d1 --- /dev/null +++ b/libtock/peripherals/syscalls/rtc_syscalls.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_RTC 0x00090007 + +// Check if the RTC driver exists. +bool libtock_rtc_exists(void); + +// Set the upcall for get and set complete callbacks. +returncode_t libtock_rtc_set_upcall(subscribe_upcall callback, void* opaque); + +// Command to get the date. +returncode_t libtock_rtc_command_get_date(void); + +// Command to set the date. +returncode_t libtock_rtc_command_set_date(uint32_t date, uint32_t time); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock/peripherals/syscalls/spi_controller_syscalls.c b/libtock/peripherals/syscalls/spi_controller_syscalls.c new file mode 100644 index 000000000..3c672fddf --- /dev/null +++ b/libtock/peripherals/syscalls/spi_controller_syscalls.c @@ -0,0 +1,81 @@ +#include "spi_controller_syscalls.h" + +bool libtock_spi_controller_exists(void) { + return driver_exists(DRIVER_NUM_SPI_CONTROLLER); +} + +returncode_t libtock_spi_controller_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SPI_CONTROLLER, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_spi_controller_allow_readwrite_read(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SPI_CONTROLLER, 0, buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_spi_controller_allow_readonly_write(uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SPI_CONTROLLER, 0, buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_spi_controller_command_write_byte(uint32_t byte) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 1, byte, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_read_write_bytes(uint32_t len) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 2, len, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_set_chip_select(uint32_t chip_select) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 3, chip_select, 0); + return tock_command_return_novalue_to_returncode(cval); +} + + +returncode_t libtock_spi_controller_command_get_chip_select(uint32_t* chip_select) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 4, 0, 0); + return tock_command_return_u32_to_returncode(cval, chip_select); +} + +returncode_t libtock_spi_controller_command_set_rate(uint32_t rate) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 5, rate, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_get_rate(uint32_t* rate) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 6, 0, 0); + return tock_command_return_u32_to_returncode(cval, rate); +} + +returncode_t libtock_spi_controller_command_set_phase(bool phase) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 7, (unsigned char)phase, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_get_phase(uint32_t* phase) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 8, 0, 0); + return tock_command_return_u32_to_returncode(cval, phase); +} + +returncode_t libtock_spi_controller_command_set_polarity(bool polarity) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 9, (unsigned char) polarity, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_get_polarity(uint32_t* polarity) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 10, 0, 0); + return tock_command_return_u32_to_returncode(cval, polarity); +} + +returncode_t libtock_spi_controller_command_hold_low(void) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 11, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_controller_command_release_low(void) { + syscall_return_t cval = command(DRIVER_NUM_SPI_CONTROLLER, 12, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/spi_controller_syscalls.h b/libtock/peripherals/syscalls/spi_controller_syscalls.h new file mode 100644 index 000000000..583775e4e --- /dev/null +++ b/libtock/peripherals/syscalls/spi_controller_syscalls.h @@ -0,0 +1,62 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SPI_CONTROLLER 0x20001 + +// Check if the SPI driver is available on this board. +bool libtock_spi_controller_exists(void); + +// Set the upcall function. +returncode_t libtock_spi_controller_set_upcall(subscribe_upcall callback, void* opaque); + +// Allow a buffer for reading SPI data. +returncode_t libtock_spi_controller_allow_readwrite_read(uint8_t* buffer, uint32_t len); + +// Allow a buffer for writing SPI data. +returncode_t libtock_spi_controller_allow_readonly_write(uint8_t* buffer, uint32_t len); + +// Return the chip select. This will always return 0. +returncode_t libtock_spi_controller_command_get_chip_select(uint32_t* chip_select); + +// Set the chip select. Not supported in upstream kernel as of 4/9/24. +returncode_t libtock_spi_controller_command_set_chip_select(uint32_t chip_select); + +// Set the SPI rate. +returncode_t libtock_spi_controller_command_set_rate(uint32_t rate); + +// Get the SPI rate. +returncode_t libtock_spi_controller_command_get_rate(uint32_t* rate); + +// Get the current SPI phase. +returncode_t libtock_spi_controller_command_get_phase(uint32_t* phase); + +// Set the SPI phase. +returncode_t libtock_spi_controller_command_set_phase(bool phase); + +// Get the current SPI polarity. +returncode_t libtock_spi_controller_command_get_polarity(uint32_t* polarity); + +// Set the SPI polarity. +returncode_t libtock_spi_controller_command_set_polarity(bool polarity); + +// Hold chip select line low over multiple SPI operations. +// Only partially supported depending on implementation. +returncode_t libtock_spi_controller_command_hold_low(void); + +// Release chip select line low. +returncode_t libtock_spi_controller_command_release_low(void); + +// Write a single byte +returncode_t libtock_spi_controller_command_write_byte(uint32_t byte); + +// Read / Write into allowed buffers +returncode_t libtock_spi_controller_command_read_write_bytes(uint32_t len); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/peripherals/syscalls/spi_peripheral_syscalls.c b/libtock/peripherals/syscalls/spi_peripheral_syscalls.c new file mode 100644 index 000000000..2f3364f98 --- /dev/null +++ b/libtock/peripherals/syscalls/spi_peripheral_syscalls.c @@ -0,0 +1,50 @@ +#include "spi_peripheral_syscalls.h" + +bool libtock_spi_peripheral_exists(void) { + return driver_exists(DRIVER_NUM_SPI_PERIPHERAL); +} + +returncode_t libtock_spi_peripheral_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SPI_PERIPHERAL, 1, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_spi_peripheral_allow_readwrite_read(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SPI_PERIPHERAL, 0, buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_spi_peripheral_allow_readonly_write(uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SPI_PERIPHERAL, 0, buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_spi_peripheral_command_write(uint32_t len) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 1, len, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_peripheral_command_get_chip_select(uint32_t* chip_select) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 2, 0, 0); + return tock_command_return_u32_to_returncode(cval, chip_select); +} + +returncode_t libtock_spi_peripheral_command_set_phase(bool phase) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 3, phase, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_peripheral_command_get_phase(uint32_t* phase) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 4, 0, 0); + return tock_command_return_u32_to_returncode(cval, phase); +} + +returncode_t libtock_spi_peripheral_command_set_polarity(bool polarity) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 5, polarity, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_spi_peripheral_command_get_polarity(uint32_t* polarity) { + syscall_return_t cval = command(DRIVER_NUM_SPI_PERIPHERAL, 6, 0, 0); + return tock_command_return_u32_to_returncode(cval, polarity); +} diff --git a/libtock/peripherals/syscalls/spi_peripheral_syscalls.h b/libtock/peripherals/syscalls/spi_peripheral_syscalls.h new file mode 100644 index 000000000..e4ac86bc3 --- /dev/null +++ b/libtock/peripherals/syscalls/spi_peripheral_syscalls.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SPI_PERIPHERAL 0x20002 + +// Check if the SPI peripheral driver is available on this board. +bool libtock_spi_peripheral_exists(void); + +// Set the upcall function. +returncode_t libtock_spi_peripheral_set_upcall(subscribe_upcall callback, void* opaque); + +// Allow a buffer for reading SPI data. +returncode_t libtock_spi_peripheral_allow_readwrite_read(uint8_t* buffer, uint32_t len); + +// Allow a buffer for writing SPI data. +returncode_t libtock_spi_peripheral_allow_readonly_write(uint8_t* buffer, uint32_t len); + +// Command for SPI write. +returncode_t libtock_spi_peripheral_command_write(uint32_t len); + +// Return the chip select. This will always return 0. +returncode_t libtock_spi_peripheral_command_get_chip_select(uint32_t* chip_select); + +// Get the current SPI phase. +returncode_t libtock_spi_peripheral_command_get_phase(uint32_t* phase); + +// Set the SPI phase. +returncode_t libtock_spi_peripheral_command_set_phase(bool phase); + +// Get the current SPI polarity. +returncode_t libtock_spi_peripheral_command_get_polarity(uint32_t* polarity); + +// Set the SPI polarity. +returncode_t libtock_spi_peripheral_command_set_polarity(bool polarity); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/libtock/peripherals/syscalls/usb_syscalls.c b/libtock/peripherals/syscalls/usb_syscalls.c new file mode 100644 index 000000000..fbae2ea0a --- /dev/null +++ b/libtock/peripherals/syscalls/usb_syscalls.c @@ -0,0 +1,15 @@ +#include "usb_syscalls.h" + +bool libtock_usb_exists(void) { + return driver_exists(DRIVER_NUM_USB); +} + +returncode_t libtock_usb_set_upcall(subscribe_upcall upcall, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_USB, 0, upcall, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_usb_command_enable_and_attach(void) { + syscall_return_t cval = command(DRIVER_NUM_USB, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/peripherals/syscalls/usb_syscalls.h b/libtock/peripherals/syscalls/usb_syscalls.h new file mode 100644 index 000000000..9a3be9d23 --- /dev/null +++ b/libtock/peripherals/syscalls/usb_syscalls.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_USB 0x20005 + +// Check if the USB syscall driver exists. +bool libtock_usb_exists(void); + +// Set the USB upcall. +returncode_t libtock_usb_set_upcall(subscribe_upcall upcall, void *opaque); + +// Enable the USB connection. +returncode_t libtock_usb_command_enable_and_attach(void); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/peripherals/usb.c b/libtock/peripherals/usb.c new file mode 100644 index 000000000..17fddb700 --- /dev/null +++ b/libtock/peripherals/usb.c @@ -0,0 +1,19 @@ +#include "usb.h" + +static void usb_upcall(int status, + __attribute__((unused)) int v1, + __attribute__((unused)) int v2, + void* opaque) { + libtock_usb_callback_attached cb = (libtock_usb_callback_attached) opaque; + cb(tock_status_to_returncode(status)); +} + +returncode_t libtock_usb_enable_and_attach(libtock_usb_callback_attached cb) { + returncode_t err; + + err = libtock_usb_set_upcall(usb_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_usb_command_enable_and_attach(); + return err; +} diff --git a/libtock/peripherals/usb.h b/libtock/peripherals/usb.h new file mode 100644 index 000000000..7453c454d --- /dev/null +++ b/libtock/peripherals/usb.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/usb_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for USB callback. +// +// - `arg1` (`returncode_t`): Status from attaching USB. SUCCESS if all inputs +// are valid, else EINVAL. +typedef void (*libtock_usb_callback_attached)(returncode_t); + +// Enable the USB controller and attach to the bus. +// +// Returns `EINVAL` if usb_subscribe() has not previously been called to +// register a callback. Returns `SUCCESS` if the callback is present and will be +// used to report completion of this operation. +returncode_t libtock_usb_enable_and_attach(libtock_usb_callback_attached cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/pressure.c b/libtock/pressure.c deleted file mode 100644 index 48520e0e0..000000000 --- a/libtock/pressure.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "pressure.h" -#include "tock.h" - -struct data { - bool fired; - int press; -}; - -static struct data result = { .fired = false }; - -// Internal upcall for faking synchronous reads -static void press_upcall(int press, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - void* ud) { - struct data* data = (struct data*) ud; - data->press = press; - data->fired = true; -} - -bool pressure_exists(void) { - return driver_exists(DRIVER_NUM_PRESSURE); -} - -int pressure_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_PRESSURE, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int pressure_read(void) { - syscall_return_t cval = command(DRIVER_NUM_PRESSURE, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int pressure_read_sync(int* pressure) { - int err; - result.fired = false; - - err = pressure_set_callback(press_upcall, (void*) &result); - if (err < 0) return err; - - err = pressure_read(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *pressure = result.press; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/pressure.h b/libtock/pressure.h deleted file mode 100644 index be0885d92..000000000 --- a/libtock/pressure.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_PRESSURE 0x60008 - -// check if pressure sensor exists -bool pressure_exists(void); - -// units: pressure in hPa - -// function to be called when the pressure measurement is finished -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int pressure_set_callback (subscribe_upcall callback, void* callback_args); - -// initiate a pressure measurement used both for synchronous and asynchronous readings -int pressure_read(void); - - -// initiate a synchronous pressure measurement -// -// pressure - pointer/address where the result of the pressure reading should be stored -int pressure_read_sync (int* pressure); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/proximity.c b/libtock/proximity.c deleted file mode 100644 index d5c5c11bc..000000000 --- a/libtock/proximity.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "proximity.h" -#include "tock.h" -#include - -struct thresholds { - uint8_t lower_threshold; - uint8_t higher_threshold; -}; - -// structure to store threshold values to be sent to the driver -static struct thresholds threshes = {.lower_threshold = 0, .higher_threshold = 175}; - -struct data { - bool fired; - int proximity; -}; - -static struct data result = {.fired = false}; - -// Internal callback for faking synchronous reads -static void cb(int proximity, - __attribute__((unused)) int unused, - __attribute__((unused)) int unused1, - void * ud) { - struct data *data = (struct data *)ud; - data->proximity = proximity; - data->fired = true; -} - -int proximity_set_callback(subscribe_upcall upcall, void *callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_PROXIMITY, 0, upcall, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int proximity_read(void) { - syscall_return_t com = command(DRIVER_NUM_PROXIMITY, 1, 0, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int proximity_read_on_interrupt(void) { - syscall_return_t com = command(DRIVER_NUM_PROXIMITY, 2, threshes.lower_threshold, threshes.higher_threshold); - return tock_command_return_novalue_to_returncode(com); -} - -int proximity_set_interrupt_thresholds(uint8_t lower, uint8_t upper) { - threshes.lower_threshold = lower; - threshes.higher_threshold = upper; - return 0; -} - -int proximity_read_sync(uint8_t *proximity) { - int err; - result.fired = false; - - err = proximity_set_callback(cb, (void *)&result); - if (err < 0) { - return err; - } - - err = proximity_read(); - if (err < 0) { - return err; - } - - yield_for(&result.fired); - - *proximity = result.proximity; - - return RETURNCODE_SUCCESS; -} - -int proximity_read_on_interrupt_sync(uint8_t *proximity) { - - int err; - result.fired = false; - - err = proximity_set_callback(cb, (void *)&result); - if (err < 0) { - return err; - } - - err = proximity_read_on_interrupt(); - if (err < 0) { - return err; - } - - yield_for(&result.fired); - - *proximity = result.proximity; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/proximity.h b/libtock/proximity.h deleted file mode 100644 index 87d8b0fc5..000000000 --- a/libtock/proximity.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "tock.h" - -#define DRIVER_NUM_PROXIMITY 0x60005 - -#ifdef _cplusplus -extern "C" { -#endif - -// function to be called when the system call is finished -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int proximity_set_callback (subscribe_upcall callback, void* callback_args); - -// Read proximity asynchronously (no callback) -int proximity_read(void); - -// Read proximity synchronously (via an internal callback) -// This function queries the sensor for a proximity reading which is then returned via the callback. -// A proximity value is of the following range [0,255] where '255' indicates the closest measurable distance and '0' that no object is detected. -// -// proximity - pointer to byte-sized proximity data returned from the sensor. -int proximity_read_sync(uint8_t* proximity); - -// Return proximity value on interrupt asynchronously (no callback) -// This function can be used to wait for the sensor to detect a proximity reading in the user-specified range. -// This range is determined by the `proximity_set_interrupt_thresholds` arguments. -int proximity_read_on_interrupt(void); - -// Return proximity value on interrupt synchronously (via an internal callback) -// This function can be used to wait for the sensor to detect a proximity reading in the user-specified range. -// This range is determined by the `proximity_set_interrupt_thresholds` arguments. -// A proximity value is of the following range [0,255] where '255' indicates the closest measurable distance and '0' that no object is detected. -// -// proximity - pointer to byte-sized proximity data returned from the sensor. -int proximity_read_on_interrupt_sync(uint8_t* proximity); - -// Set thresholds for interrupts (no syscalls involved) -// -// The proximity sensor fires an interrupt (which executes the callback sent by the `proximity_read_on_interrupt_sync()` function) -// The interrupt is fired when the following logic statement is true `(reading >= upper_threshold) || (reading <= lower_threshold)` -// -// lower - lower interrupt threshold for sensor --> range is [0,255] -// upper - upper interrupt threshold for sensor --> range is [0,255] -int proximity_set_interrupt_thresholds(uint8_t lower, uint8_t upper); - - -#ifdef _cplusplus -} -#endif \ No newline at end of file diff --git a/libtock/read_only_state.c b/libtock/read_only_state.c deleted file mode 100644 index b999c638b..000000000 --- a/libtock/read_only_state.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "read_only_state.h" - -bool read_only_state_exists(void) { - return driver_exists(READ_ONLY_STATEDRIVER_NUM); -} - -int read_only_state_get_version(void) { - syscall_return_t res = command(READ_ONLY_STATEDRIVER_NUM, 1, 0, 0); - - if (res.type != TOCK_SYSCALL_SUCCESS_U32) { - return RETURNCODE_ENOSUPPORT; - } else { - return res.data[0]; - } -} - -int read_only_state_allocate_region(void* base, int len) { - allow_userspace_r_return_t buf; - - if (len < READ_ONLY_STATEBUFFER_LEN) { - // The buffer is not long enough - return RETURNCODE_ESIZE; - } - - buf = allow_userspace_read(READ_ONLY_STATEDRIVER_NUM, 0, base, len); - - if (!buf.success) { - return tock_status_to_returncode(buf.status); - } - return RETURNCODE_SUCCESS; -} - -uint32_t read_only_state_get_pending_tasks(void* base) { - uint32_t* ptr = base; - return ptr[1]; -} - -uint64_t read_only_state_get_ticks(void* base) { - uint32_t* ptr = base; - - // Start with the high bytes set to 0 - uint32_t high, low; - - do { - // Get the high bytes the value in memory - high = ptr[3]; - // Read the low bytes - low = ptr[2]; - // If the high bytes don't match what is still in memory re-try - // the load - } while (high != ptr[3]); - - return ((uint64_t)high << 32) | low; -} - -int read_only_state_quick_yield(void* base) { - if (yield_check_tasks()) { - return 1; - } else { - uint32_t tasks = read_only_state_get_pending_tasks(base); - - if (tasks > 0) { - // Waiting tasks, call yield - yield(); - } - - return tasks; - } -} diff --git a/libtock/read_only_state.h b/libtock/read_only_state.h deleted file mode 100644 index 4579d76bc..000000000 --- a/libtock/read_only_state.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define READ_ONLY_STATEDRIVER_NUM 0x00009 - -// We currently support ROS version 1 -// Version 1: -// |-------------------------| -// | Count (u32) | -// |-------------------------| -// | Pending Tasks (u32) | -// |-------------------------| -// | | -// | Time Ticks (u64) | -// |-------------------------| -#define READ_ONLY_STATEBUFFER_LEN (4 * 4 + 4 * 4 + 8 * 4) - -bool read_only_state_exists(void); - -// Get the latest version of the read only state supported by the kernel. -int read_only_state_get_version(void); - -// Share a buffer with the kernel to use for read only state -// -// `base` the buffer to use -// `len` should be READ_ONLY_STATEBUFFER_LEN -int read_only_state_allocate_region(void* base, int len); - -// Use the read only state buffer provided by `base` -// to get the number of pending tasks. -uint32_t read_only_state_get_pending_tasks(void* base); - -// Use the read only state buffer provided by `base` -// to get the current time returned from the kernel. -uint64_t read_only_state_get_ticks(void* base); - -// Use ROS to check if there are any pending tasks. If there are -// we yield, if not then we return immediately without any syscalls. -// -// If there are no pending tasks returns 0. -// If there are pending tasks returns the number of pending tasks before -// yield is called. That is is returning 1 there will be no more tasks -// pending (as long as no new tasks occurred) -// On error returns a negative value. -int read_only_state_quick_yield(void* base); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/rng.c b/libtock/rng.c deleted file mode 100644 index 25437848b..000000000 --- a/libtock/rng.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "tock.h" -#include -#include - -struct rng_data { - bool fired; - int received; -}; - -// Global state for faking synchronous reads using a callback and -// yield -static struct rng_data result = { .fired = false, .received = 0 }; - -// Internal callback for faking synchronous reads -static void rng_upcall(__attribute__ ((unused)) int callback_type, - int received, - __attribute__ ((unused)) int val2, - void* ud) { - struct rng_data* data = (struct rng_data*) ud; - data->fired = true; - data->received = received; -} - -int rng_set_buffer(uint8_t* buf, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_RNG, 0, (void*) buf, len); - return tock_allow_rw_return_to_returncode(aval); -} - -int rng_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_RNG, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int rng_get_random(int num_bytes) { - syscall_return_t com = command(DRIVER_NUM_RNG, 1, num_bytes, 0); - return tock_command_return_novalue_to_returncode(com); -} - -int rng_async(subscribe_upcall callback, uint8_t* buf, uint32_t len, uint32_t num) { - int ret = rng_set_callback(callback, NULL); - if (ret < 0) return ret; - - ret = rng_set_buffer(buf, len); - if (ret < 0) return ret; - - return rng_get_random(num); -} - -int rng_sync(uint8_t* buf, uint32_t len, uint32_t num, int* num_received) { - int ret = rng_set_buffer(buf, len); - if (ret < 0) return ret; - - ret = rng_set_callback(rng_upcall, (void*) &result); - if (ret < 0) return ret; - - result.fired = false; - ret = rng_get_random(num); - if (ret < 0) return ret; - - yield_for(&result.fired); - - *num_received = result.received; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/rng.h b/libtock/rng.h deleted file mode 100644 index 36dc96a51..000000000 --- a/libtock/rng.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_RNG 0x40001 - -/* rng_async - * Asynchronous RNG request. Registers callback and buffer and starts RNG. - * callback: user defined callback. - * buf: user defined buffer. - * len: length of buffer. - * num: number of random bytes requested. - * returns 0 on success, negative on failure. - */ -int rng_async(subscribe_upcall callback, uint8_t* buf, uint32_t len, uint32_t num); - -/* rng_sync - * Synchronous RNG request. - * buf: user defined buffer. - * len: length of buffer. - * num: number of random bytes requested. - * num_received: pointer which will be set with number of bytes received. - * returns ReturnCode. - */ -int rng_sync(uint8_t* buf, uint32_t len, uint32_t num, int* num_received); - -/* rng_set_callback() - * Registers a callback function that is called when requested randomness is - * obtained or provided buffer is full. Call this before rng_get_random(). - * callback: user defined callback function of the form: - * void user_callback(int callback_type, int received, int unused, void* return); - * where receieved is the number of random bytes actually returned by the rng. - * callback_args: unused. - */ -int rng_set_callback(subscribe_upcall callback, void* callback_args); - -/* rng_set_buffer() - * Registers buffer to hold received randomness. Call before rng_get_random(). - * buffer: pointer to uint8_t array to store randomness - * len: length of buffer. - */ -int rng_set_buffer(uint8_t* buf, uint32_t len); - -/* rng_get_random - * Starts random number generator. Call after rng_set_callback and - * rng_set_buffer. - * num_bytes: number of random bytes requested. - */ -int rng_get_random(int num_bytes); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/rtc.c b/libtock/rtc.c deleted file mode 100644 index 93f73e444..000000000 --- a/libtock/rtc.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "rtc.h" -#include -#include - -int date, time; - -static void rtc_cb(int status __attribute__ ((unused)), - int upcall1, - int upcall2, - void* ud __attribute__ ((unused))){ - date = upcall1; - time = upcall2; -} - -int get_date(struct Date *put_date){ - subscribe_return_t sub = subscribe(DRIVER_NUM_RTC, 0, rtc_cb, malloc(sizeof(struct DateTime))); - if (!sub.success) { - return tock_status_to_returncode(sub.status); - } - - syscall_return_t rval = command(DRIVER_NUM_RTC, 1, 0, 0); - if (!(rval.type == 128)) { - printf("%d", rval.type); - } - - struct Date date_result = { - .year = date % (1 << 21) / (1 << 9), - .month = date % (1 << 9) / (1 << 5), - .day = date % (1 << 5), - - .day_of_week = time % (1 << 20) / (1 << 17), - .hour = time % (1 << 17) / (1 << 12), - .minute = time % (1 << 12) / (1 << 6), - .seconds = time % (1 << 6) - }; - - *put_date = date_result; - return tock_command_return_novalue_to_returncode(rval); -} - -int set_date(const struct Date *set_date){ - date = set_date->year * (1 << 9) + set_date->month * (1 << 5) + set_date->day; - time = set_date->day_of_week * - (1 << 17) + set_date->hour * (1 << 12) + set_date->minute * (1 << 6) + set_date->seconds; - - syscall_return_t rval = command(DRIVER_NUM_RTC, 2, date, time); - return tock_command_return_novalue_to_returncode(rval); -} diff --git a/libtock/rtc.h b/libtock/rtc.h deleted file mode 100644 index bde55cd0f..000000000 --- a/libtock/rtc.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_RTC 0x00090007 - -#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 -struct Date{ - int year; - int month; - int day; - int day_of_week; - int hour; - int minute; - int seconds; -}; - -// DateTime codifies Date structure into two u32 (int) numbers -// date: first number (year, month, day_of_the_month): -// - last 5 bits store the day_of_the_month -// - previous 4 bits store the month -// - previous 12 bits store the year -// time: second number (day_of_the_week, hour, minute, seconds): -// - last 6 bits store the seconds -// - previous 6 store the minute -// - previous 5 store the hour -// - previous 3 store the day_of_the_week -struct DateTime{ - int date; - int time; -}; - -// Fetches current date from registers and writes it to get_date -int get_date(struct Date *get_date); - -// Writes set_date into the registers -int set_date(const struct Date *set_date); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/screen.c b/libtock/screen.c deleted file mode 100644 index 784d3f7eb..000000000 --- a/libtock/screen.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "screen.h" -#include "tock.h" -#include - -typedef struct { - int error; - int data1; - int data2; - bool done; -} ScreenReturn; - -static void screen_callback(int status, - int data1, - int data2, - void* ud) { - ScreenReturn *fbr = (ScreenReturn*)ud; - fbr->error = tock_status_to_returncode(status); - fbr->data1 = data1; - fbr->data2 = data2; - fbr->done = true; -} - -static uint8_t *buffer = NULL; -static size_t buffer_len = 0; - -int screen_subscribe (subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_SCREEN, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -int screen_allow (const void* ptr, size_t size) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SCREEN, 0, ptr, size); - return tock_allow_ro_return_to_returncode(aval); -} - -int screen_get_supported_resolutions (int* resolutions) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 11, 0, 0); - if (com.type == TOCK_SYSCALL_SUCCESS_U32) { - *resolutions = com.data[0]; - return RETURNCODE_SUCCESS; - } else if (com.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(com.data[0]); - } else { - return RETURNCODE_EINVAL; - } -} - -int screen_get_supported_resolution (size_t index, size_t *width, size_t *height) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 12, index, 0); - if (com.type == TOCK_SYSCALL_SUCCESS_U32_U32) { - *width = com.data[0]; - *height = com.data[1]; - return RETURNCODE_SUCCESS; - } else if (com.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(com.data[0]); - } else { - return RETURNCODE_EINVAL; - } -} - -int screen_get_supported_pixel_formats (int* formats) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 13, 0, 0); - if (com.type == TOCK_SYSCALL_SUCCESS_U32) { - *formats = com.data[0]; - return RETURNCODE_SUCCESS; - } else if (com.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(com.data[0]); - } else { - return RETURNCODE_EINVAL; - } -} - -int screen_get_supported_pixel_format (size_t index, int* format) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 14, index, 0); - if (com.type == TOCK_SYSCALL_SUCCESS_U32) { - *format = com.data[0]; - return RETURNCODE_SUCCESS; - } else if (com.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(com.data[0]); - } else { - return RETURNCODE_EINVAL; - } -} - -bool screen_setup_enabled (void) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 1, 0, 0); - return com.type == TOCK_SYSCALL_SUCCESS_U32 && com.data[0] != 0; -} - -int screen_set_brightness (size_t brightness) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 3, brightness, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_invert_on (void) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 4, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_invert_off (void) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 5, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_init (size_t len) -{ - int r = TOCK_STATUSCODE_SUCCESS; - if (buffer != NULL) { - r = TOCK_STATUSCODE_ALREADY; - } else { - buffer = (uint8_t*)calloc(1, len); - if (buffer != NULL) { - buffer_len = len; - r = TOCK_STATUSCODE_SUCCESS; - } else { - r = TOCK_STATUSCODE_FAIL; - } - } - return r; -} - -uint8_t * screen_buffer (void) -{ - return buffer; -} - -int screen_get_resolution (size_t *width, size_t *height) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 23, 0, 0); - if (com.type == TOCK_SYSCALL_SUCCESS_U32_U32) { - *width = com.data[0]; - *height = com.data[1]; - return RETURNCODE_SUCCESS; - } else if (com.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(com.data[0]); - } else { - return RETURNCODE_EINVAL; - } -} - -int screen_set_resolution (size_t width, size_t height) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 24, width, height); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_get_bits_per_pixel (size_t format) -{ - switch (format) { - case SCREEN_PIXEL_FORMAT_MONO: - return 1; - - case SCREEN_PIXEL_FORMAT_RGB_233: - return 8; - - case SCREEN_PIXEL_FORMAT_RGB_565: - return 16; - - case SCREEN_PIXEL_FORMAT_RGB_888: - return 24; - - case SCREEN_PIXEL_FORMAT_ARGB_8888: - return 32; - - default: - return 0; - } -} - -int screen_get_pixel_format (int* format) { - ScreenReturn fbr; - fbr.data1 = SCREEN_PIXEL_FORMAT_ERROR; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 25, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - *format = fbr.data1; - ret = fbr.error; - } - } - return ret; -} - -int screen_set_pixel_format (size_t format) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 26, format, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_get_rotation (int* rotation) { - ScreenReturn fbr; - fbr.data1 = SCREEN_ROTATION_NORMAL; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 21, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - *rotation = fbr.data1; - ret = fbr.error; - } - } - return ret; -} - -int screen_set_rotation (size_t rotation) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 22, rotation, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_set_color (size_t position, size_t color) { - // TODO color mode - int r = RETURNCODE_SUCCESS; - if (position < buffer_len - 2) { - buffer[position * 2] = (color >> 8) & 0xFF; - buffer[position * 2 + 1] = color & 0xFF; - } else { - r = RETURNCODE_ESIZE; - } - return r; -} - -int screen_set_frame (uint16_t x, uint16_t y, uint16_t width, uint16_t height) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_subscribe(screen_callback, &fbr); - if (ret == RETURNCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 100, ((x & 0xFFFF) << 16) | ((y & 0xFFFF)), - ((width & 0xFFFF) << 16) | ((height & 0xFFFF))); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == RETURNCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - return ret; -} - -int screen_fill (size_t color) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_set_color(0, color); - if (ret < 0) return ret; - - ret = screen_allow(buffer, buffer_len); - if (ret == TOCK_STATUSCODE_SUCCESS) { - ret = screen_subscribe(screen_callback, &fbr); - if (ret == TOCK_STATUSCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 300, 0, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == TOCK_STATUSCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - screen_allow(NULL, 0); - } - return ret; -} - -int screen_write (size_t length) { - ScreenReturn fbr; - fbr.done = false; - - int ret = screen_allow(buffer, buffer_len); - if (ret == TOCK_STATUSCODE_SUCCESS) { - ret = screen_subscribe(screen_callback, &fbr); - if (ret == TOCK_STATUSCODE_SUCCESS) { - syscall_return_t com = command(DRIVER_NUM_SCREEN, 200, length, 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == TOCK_STATUSCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } - } - screen_allow(NULL, 0); - } - return ret; -} diff --git a/libtock/screen.h b/libtock/screen.h deleted file mode 100644 index acf24b3cf..000000000 --- a/libtock/screen.h +++ /dev/null @@ -1,66 +0,0 @@ -// Screen API - -#pragma once - -#include "tock.h" - -#define SCREEN_ROTATION_NORMAL 0 -#define SCREEN_ROTATION_90 1 -#define SCREEN_ROTATION_180 2 -#define SCREEN_ROTATION_270 3 - -#define SCREEN_PIXEL_FORMAT_MONO 0 -#define SCREEN_PIXEL_FORMAT_RGB_233 1 -#define SCREEN_PIXEL_FORMAT_RGB_565 2 -#define SCREEN_PIXEL_FORMAT_RGB_888 3 -#define SCREEN_PIXEL_FORMAT_ARGB_8888 4 - -#define SCREEN_PIXEL_FORMAT_ERROR -1 - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_SCREEN 0x90001 - -// init -int screen_init (size_t len); -uint8_t * screen_buffer (void); - -// syscalls -int screen_subscribe (subscribe_upcall cb, void *userdata); -int screen_allow (const void* ptr, size_t size); - -// query -bool screen_setup_enabled (void); -int screen_get_supported_resolutions (int* resolutions); -int screen_get_supported_resolution (size_t index, size_t *width, size_t *height); -int screen_get_supported_pixel_formats (int* formats); -int screen_get_supported_pixel_format (size_t index, int* format); - -// power -int screen_set_brightness (size_t brightness); -int screen_invert_on (void); -int screen_invert_off (void); - -// pixel format -int screen_get_bits_per_pixel (size_t format); -int screen_get_pixel_format (int* format); -int screen_set_pixel_format (size_t format); - -// resolution and rotation -int screen_get_resolution (size_t *width, size_t *height); -int screen_set_resolution (size_t width, size_t height); - -int screen_get_rotation (int* rotation); -int screen_set_rotation (size_t rotation); - -// drawing -int screen_set_color (size_t position, size_t color); -int screen_set_frame (uint16_t x, uint16_t y, uint16_t width, uint16_t height); -int screen_fill (size_t color); -int screen_write (size_t length); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/sdcard.c b/libtock/sdcard.c deleted file mode 100644 index db3cd8bc0..000000000 --- a/libtock/sdcard.c +++ /dev/null @@ -1,170 +0,0 @@ -// SD card interface - -#include "sdcard.h" -#include "tock.h" - -// used for creating synchronous versions of functions -// -// fired - set when callback has been called -// block_size - block size of SD card, set upon initialization complete -// size_in_kB - size in kilobytes of SD card, set upon initialization complete -// error - error code signalled in callback, 0 if successful -typedef struct { - bool fired; - uint32_t block_size; - uint32_t size_in_kB; - int32_t error; -} sdcard_data_t; - -// Internal callback for creating synchronous functions -// -// callback_type - number indicating which type of callback occurred -// arg1, arg2 - meaning varies based on callback_type -// callback_args - user data passed into the set_callback function -// -// Possible callbacks -// 0: card_detection_changed, SD card was either installed or removed -// arg1, arg2 - no meaning -// 1: init_done, intialization completed successfully -// arg1 - block_size, block size of SD card in bytes -// arg2 - size_in_kB, total size of SD card in kilobytes -// 2: read_done, read block completed successfully -// arg1 - len, number of bytes read -// 3: write_done, write block completed successfully -// arg1 - len, number of bytes written -// 4: error, an error occurred -// arg1 - error, number representing the error that occurred -static void sdcard_upcall (int callback_type, int arg1, int arg2, void* callback_args) { - - sdcard_data_t* result = (sdcard_data_t*) callback_args; - switch (callback_type) { - case 0: - // card_detection_changed - result->error = RETURNCODE_EUNINSTALLED; - break; - - case 1: - // init_done - result->block_size = arg1; - result->size_in_kB = arg2; - result->error = RETURNCODE_SUCCESS; - break; - - case 2: - // read_done - result->error = RETURNCODE_SUCCESS; - break; - - case 3: - // write_done - result->error = RETURNCODE_SUCCESS; - break; - - case 4: - // error - // This is not a STATUSCODE, but rather an SD Card specific error - // See capsule sdcard.rs `enum SdCardError` - result->error = arg1; - break; - } - result->fired = true; -} - -int sdcard_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_SDCARD, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int sdcard_set_read_buffer (uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SDCARD, 0, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -int sdcard_set_write_buffer (uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SDCARD, 0, (void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int sdcard_is_installed (void) { - syscall_return_t cval = command(DRIVER_NUM_SDCARD, 1, 0, 0); - uint32_t result = 0; - tock_command_return_u32_to_returncode(cval, &result); - return (int)result; -} - -int sdcard_initialize (void) { - syscall_return_t cval = command(DRIVER_NUM_SDCARD, 2, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int sdcard_initialize_sync (uint32_t* block_size, uint32_t* size_in_kB) { - int err; - sdcard_data_t result; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = sdcard_set_callback(sdcard_upcall, (void*) &result); - if (err < 0) return err; - - err = sdcard_initialize(); - if (err < 0) return err; - - // wait for callback - yield_for(&result.fired); - - // copy args - if (block_size != NULL) { - *block_size = result.block_size; - } - if (size_in_kB != NULL) { - *size_in_kB = result.size_in_kB; - } - - return result.error; -} - -int sdcard_read_block (uint32_t sector) { - syscall_return_t cval = command(DRIVER_NUM_SDCARD, 3, sector, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int sdcard_read_block_sync (uint32_t sector) { - int err; - sdcard_data_t result; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = sdcard_set_callback(sdcard_upcall, (void*) &result); - if (err < 0) return err; - - err = sdcard_read_block(sector); - if (err < 0) return err; - - // wait for callback - yield_for(&result.fired); - - return result.error; -} - -int sdcard_write_block (uint32_t sector) { - syscall_return_t cval = command(DRIVER_NUM_SDCARD, 4, sector, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int sdcard_write_block_sync (uint32_t sector) { - int err; - sdcard_data_t result; - result.fired = false; - result.error = RETURNCODE_SUCCESS; - - err = sdcard_set_callback(sdcard_upcall, (void*) &result); - if (err < 0) return err; - - err = sdcard_write_block(sector); - if (err < 0) return err; - - // wait for callback - yield_for(&result.fired); - - return result.error; -} diff --git a/libtock/sdcard.h b/libtock/sdcard.h deleted file mode 100644 index 2cad3ac05..000000000 --- a/libtock/sdcard.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_SDCARD 0x50002 - -// set a callback function for SD card commands -// Callback is called upon command completion or when an error occurs. See -// `sdcard_cb` in sdcard.c for callback documentation -// -// returns 0 if successful, < 0 if an error occurrs -int sdcard_set_callback (subscribe_upcall callback, void* callback_args); - -// set a buffer that data read from the SD card will be placed into -// this buffer can be reused across multiple read calls -// -// returns 0 if successful, < 0 if an error occurrs -int sdcard_set_read_buffer (uint8_t* buffer, uint32_t len); - -// set a buffer containing data to write to the SD card -// this buffer can be reused across multiple write calls by changing its -// contents. No need to call this function a second time -// -// returns 0 if successful, < 0 if an error occurrs -int sdcard_set_write_buffer (uint8_t* buffer, uint32_t len); - -// check if an SD card is installed -// Completes synchronously -// -// returns 1 if installed, 0 if not installed, < 0 if an error occurrs -int sdcard_is_installed (void); - -// initialize an SD card asynchronously -// Note that for a newly powered-on SD card, initialization can take over -// 100 ms to complete. Expects a callback to have already been set. Callback -// will be called when either initialization is complete or an error occurs -// -// returns 0 if started successfully, < 0 if an error occurrs -int sdcard_initialize (void); - -// initialize an SD card synchronously -// Note that for a newly powered-on SD card, initialization can take over -// 100 ms to complete -// -// block_size - set to the block size of the SD card, if not NULL -// size_in_kB - set to the size of the SD card in kilobytes, if not NULL -// -// returns 0 if SD card is now initialized, < 0 if an error occurrs -int sdcard_initialize_sync (uint32_t* block_size, uint32_t* size_in_kB); - -// read a single block from an SD card asynchronously -// Expects a read_buffer and a callback to already have been set up. Callback -// will be called when either the block has been read or an error occurs. When -// the callback is successful, data will be in the read_buffer -// -// sector - sector address of the block to be read -// -// returns 0 if started successfully, < 0 if an error occurrs -int sdcard_read_block (uint32_t sector); - -// read a single block from an SD card synchronously -// Expects a read_buffer to already have been set up. When the command -// completes successfully, data will be in the read_buffer -// -// sector - sector address of the block to be read -// -// returns 0 if the block has been read, < 0 if an error occurrs -int sdcard_read_block_sync (uint32_t sector); - -// write a single block to an SD card asynchronously -// Expects a write_buffer and a callback to already have been set up. Data in -// the write_buffer will be written to the SD card. Callback will be called -// when either the block has been written or an error occurs -// -// sector - sector address of the block to be written -// -// returns 0 if started successfully, < 0 if an error occurrs -int sdcard_write_block (uint32_t sector); - -// write a single block to an SD card synchronously -// Expects a write_buffer to already have been set up. Data in the write_buffer -// will be written to the SD card -// -// sector - sector address of the block to be written -// -// returns 0 if the block has been written, < 0 if an error occurrs -int sdcard_write_block_sync (uint32_t sector); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/sensors/ambient_light.c b/libtock/sensors/ambient_light.c new file mode 100644 index 000000000..c02ccc29f --- /dev/null +++ b/libtock/sensors/ambient_light.c @@ -0,0 +1,19 @@ +#include "ambient_light.h" + +// callback for synchronous reads +static void ambient_light_upcall(int intensity, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, void* opaque) { + libtock_ambient_light_callback cb = (libtock_ambient_light_callback) opaque; + cb(RETURNCODE_SUCCESS, intensity); +} + +returncode_t libtock_ambient_light_read_intensity(libtock_ambient_light_callback cb) { + returncode_t err; + + err = libtock_ambient_light_set_upcall(ambient_light_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_ambient_light_command_start_intensity_reading(); + return err; +} diff --git a/libtock/sensors/ambient_light.h b/libtock/sensors/ambient_light.h new file mode 100644 index 000000000..be8052b5b --- /dev/null +++ b/libtock/sensors/ambient_light.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/ambient_light_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for ambient light data callback. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`int`): Ambient light reading in lux (lx). +typedef void (*libtock_ambient_light_callback)(returncode_t, int); + + +// Request an ambient light reading. +// +// The callback will be triggered with the result in lux. +returncode_t libtock_ambient_light_read_intensity(libtock_ambient_light_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/humidity.c b/libtock/sensors/humidity.c new file mode 100644 index 000000000..b7cf5bbd3 --- /dev/null +++ b/libtock/sensors/humidity.c @@ -0,0 +1,18 @@ +#include "humidity.h" + +static void humidity_upcall(int humidity, + __attribute__ ((unused)) int unused1, + __attribute__ ((unused)) int unused2, void* opaque) { + libtock_humidity_callback cb = (libtock_humidity_callback) opaque; + cb(RETURNCODE_SUCCESS, humidity); +} + +returncode_t libtock_humidity_read(libtock_humidity_callback cb) { + returncode_t err; + + err = libtock_humidity_set_upcall(humidity_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_humidity_command_read(); + return err; +} diff --git a/libtock/sensors/humidity.h b/libtock/sensors/humidity.h new file mode 100644 index 000000000..483030669 --- /dev/null +++ b/libtock/sensors/humidity.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/humidity_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for humidity data callback. +// +// - `arg1` (`int`): Returncode indicating status from sampling the sensor. +// - `arg2` (`int`): Humidity in hundredths of percent. +typedef void (*libtock_humidity_callback)(returncode_t, int); + +// Start a humidity measurement. The reading will be provided via the callback. +returncode_t libtock_humidity_read(libtock_humidity_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/ninedof.c b/libtock/sensors/ninedof.c new file mode 100644 index 000000000..351f51196 --- /dev/null +++ b/libtock/sensors/ninedof.c @@ -0,0 +1,38 @@ +#include "ninedof.h" + +// internal callback for faking synchronous reads +static void ninedof_upcall(int x, int y, int z, void* opaque) { + libtock_ninedof_callback cb = (libtock_ninedof_callback) opaque; + cb(RETURNCODE_SUCCESS, x, y, z); +} + + +returncode_t libtock_ninedof_read_accelerometer(libtock_ninedof_callback cb) { + returncode_t err; + + err = libtock_ninedof_set_upcall(ninedof_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_ninedof_command_start_accelerometer_reading(); + return err; +} + +returncode_t libtock_ninedof_read_magnetometer(libtock_ninedof_callback cb) { + returncode_t err; + + err = libtock_ninedof_set_upcall(ninedof_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_ninedof_command_start_magnetometer_reading(); + return err; +} + +returncode_t libtock_ninedof_read_gyroscope(libtock_ninedof_callback cb) { + returncode_t err; + + err = libtock_ninedof_set_upcall(ninedof_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_ninedof_command_start_gyroscope_reading(); + return err; +} diff --git a/libtock/sensors/ninedof.h b/libtock/sensors/ninedof.h new file mode 100644 index 000000000..1eacb0eff --- /dev/null +++ b/libtock/sensors/ninedof.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/ninedof_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for ninedof data callbacks. This callback is general for +// the different 9-DOF sensors. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`int`): Reading in x dimension. +// - `arg3` (`int`): Reading in y dimension. +// - `arg4` (`int`): Reading in z dimension. +typedef void (*libtock_ninedof_callback)(returncode_t, int, int, int); + + +// Read the accelerometer. +// +// The X, Y, Z and measurements will be returned via the callback. +returncode_t libtock_ninedof_read_accelerometer(libtock_ninedof_callback cb); + +// Read the magnetometer. +// +// The X, Y, Z and measurements will be returned via the callback. +returncode_t libtock_ninedof_read_magnetometer(libtock_ninedof_callback cb); + +// Read the gyroscope. +// +// The X, Y, Z and measurements will be returned via the callback. +returncode_t libtock_ninedof_read_gyroscope(libtock_ninedof_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/pressure.c b/libtock/sensors/pressure.c new file mode 100644 index 000000000..b3ec0b2bd --- /dev/null +++ b/libtock/sensors/pressure.c @@ -0,0 +1,19 @@ +#include "pressure.h" + +static void pressure_upcall(int pressure, + __attribute__ ((unused)) int unused, + __attribute__ ((unused)) int unused1, + void* opaque) { + libtock_pressure_callback cb = (libtock_pressure_callback) opaque; + cb(RETURNCODE_SUCCESS, pressure); +} + +returncode_t libtock_pressure_read(libtock_pressure_callback cb) { + returncode_t err; + + err = libtock_pressure_set_upcall(pressure_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_pressure_command_read(); + return err; +} diff --git a/libtock/sensors/pressure.h b/libtock/sensors/pressure.h new file mode 100644 index 000000000..026412ed6 --- /dev/null +++ b/libtock/sensors/pressure.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/pressure_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for pressure data callback. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`int`): Pressure reading in hPa. +typedef void (*libtock_pressure_callback)(returncode_t, int); + +// Initiate a pressure measurement and call the callback with the reading when +// finished. +returncode_t libtock_pressure_read(libtock_pressure_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/proximity.c b/libtock/sensors/proximity.c new file mode 100644 index 000000000..f6cbb9e2e --- /dev/null +++ b/libtock/sensors/proximity.c @@ -0,0 +1,31 @@ +#include "proximity.h" + +// Internal callback for faking synchronous reads +static void proximity_cb(int proximity, + __attribute__((unused)) int unused, + __attribute__((unused)) int unused1, + void * opaque) { + libtock_proximity_callback cb = (libtock_proximity_callback) opaque; + cb(RETURNCODE_SUCCESS, (uint8_t) proximity); +} + +returncode_t libtock_proximity_read(libtock_proximity_callback cb) { + returncode_t err; + + err = libtock_proximity_set_upcall(proximity_cb, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_proximity_command_read(); + return err; +} + +returncode_t libtock_proximity_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold, + libtock_proximity_callback cb) { + returncode_t err; + + err = libtock_proximity_set_upcall(proximity_cb, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_proximity_command_read_on_interrupt(lower_threshold, higher_threshold); + return err; +} diff --git a/libtock/sensors/proximity.h b/libtock/sensors/proximity.h new file mode 100644 index 000000000..5be7125e5 --- /dev/null +++ b/libtock/sensors/proximity.h @@ -0,0 +1,31 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/proximity_syscalls.h" + +#ifdef _cplusplus +extern "C" { +#endif + +// Function signature for proximity data callback. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`uint8_t`): Proximity value in the range [0,255] where '255' +// indicates the closest measurable distance and '0' that no object is +// detected. +typedef void (*libtock_proximity_callback)(returncode_t, uint8_t); + +// Read proximity asynchronously. +// +// This function queries the sensor for a proximity reading which is then +// returned via the callback. +returncode_t libtock_proximity_read(libtock_proximity_callback cb); + +// Read proximity asynchronously within a specified window. This function can be +// used to wait for the sensor to detect a proximity reading in the +// user-specified range. +returncode_t libtock_proximity_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold, libtock_proximity_callback cb); + +#ifdef _cplusplus +} +#endif \ No newline at end of file diff --git a/libtock/sensors/sound_pressure.c b/libtock/sensors/sound_pressure.c new file mode 100644 index 000000000..f6264ff20 --- /dev/null +++ b/libtock/sensors/sound_pressure.c @@ -0,0 +1,19 @@ +#include "sound_pressure.h" + +static void sound_pressure_upcall(int sound_pressure, + __attribute__ ((unused)) int unused, + __attribute__ ((unused)) int unused1, + void* opaque) { + libtock_sound_pressure_callback cb = (libtock_sound_pressure_callback) opaque; + cb(RETURNCODE_SUCCESS, (uint8_t) sound_pressure); +} + +returncode_t libtock_sound_pressure_read(libtock_sound_pressure_callback cb) { + returncode_t err; + + err = libtock_sound_pressure_set_upcall(sound_pressure_upcall, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_sound_pressure_command_read(); + return err; +} diff --git a/libtock/sensors/sound_pressure.h b/libtock/sensors/sound_pressure.h new file mode 100644 index 000000000..340c0afec --- /dev/null +++ b/libtock/sensors/sound_pressure.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/sound_pressure_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for sound pressure data callback. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`uint8_t`): Sound pressure reading in dB. +typedef void (*libtock_sound_pressure_callback)(returncode_t, uint8_t); + +// Initiate an ambient sound pressure measurement. +// +// The sound pressure reading will be returned via the callback. +returncode_t libtock_sound_pressure_read(libtock_sound_pressure_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/ambient_light_syscalls.c b/libtock/sensors/syscalls/ambient_light_syscalls.c new file mode 100644 index 000000000..6232073ed --- /dev/null +++ b/libtock/sensors/syscalls/ambient_light_syscalls.c @@ -0,0 +1,15 @@ +#include "ambient_light_syscalls.h" + +bool libtock_ambient_light_exists(void) { + return driver_exists(DRIVER_NUM_AMBIENT_LIGHT); +} + +returncode_t libtock_ambient_light_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_AMBIENT_LIGHT, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_ambient_light_command_start_intensity_reading(void) { + syscall_return_t cval = command(DRIVER_NUM_AMBIENT_LIGHT, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/ambient_light_syscalls.h b/libtock/sensors/syscalls/ambient_light_syscalls.h new file mode 100644 index 000000000..6f8848109 --- /dev/null +++ b/libtock/sensors/syscalls/ambient_light_syscalls.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_AMBIENT_LIGHT 0x60002 + +// Check if the ambient light driver exists. +bool libtock_ambient_light_exists(void); + +// Configure the upcall when the reading is ready. +returncode_t libtock_ambient_light_set_upcall(subscribe_upcall callback, void* opaque); + +// Request a sensor reading. +returncode_t libtock_ambient_light_command_start_intensity_reading(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/humidity_syscalls.c b/libtock/sensors/syscalls/humidity_syscalls.c new file mode 100644 index 000000000..38a6e8730 --- /dev/null +++ b/libtock/sensors/syscalls/humidity_syscalls.c @@ -0,0 +1,15 @@ +#include "humidity_syscalls.h" + +bool libtock_humidity_exists(void) { + return driver_exists(DRIVER_NUM_HUMIDITY); +} + +returncode_t libtock_humidity_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_HUMIDITY, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_humidity_command_read(void) { + syscall_return_t rval = command(DRIVER_NUM_HUMIDITY, 1, 0, 0); + return tock_command_return_novalue_to_returncode(rval); +} diff --git a/libtock/sensors/syscalls/humidity_syscalls.h b/libtock/sensors/syscalls/humidity_syscalls.h new file mode 100644 index 000000000..bd89a67b3 --- /dev/null +++ b/libtock/sensors/syscalls/humidity_syscalls.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_HUMIDITY 0x60001 + +// Check if the humidity driver is installed. +bool libtock_humidity_exists(void); + +// Configure the upcall for when the reading is ready. +returncode_t libtock_humidity_set_upcall(subscribe_upcall callback, void* opaque); + +// Read the sensor. +returncode_t libtock_humidity_command_read(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/ninedof_syscalls.c b/libtock/sensors/syscalls/ninedof_syscalls.c new file mode 100644 index 000000000..1869e3d1a --- /dev/null +++ b/libtock/sensors/syscalls/ninedof_syscalls.c @@ -0,0 +1,25 @@ +#include "ninedof_syscalls.h" + +bool libtock_ninedof_exists(void) { + return driver_exists(DRIVER_NUM_NINEDOF); +} + +returncode_t libtock_ninedof_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_NINEDOF, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_ninedof_command_start_accelerometer_reading(void) { + syscall_return_t cval = command(DRIVER_NUM_NINEDOF, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_ninedof_command_start_magnetometer_reading(void) { + syscall_return_t cval = command(DRIVER_NUM_NINEDOF, 100, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_ninedof_command_start_gyroscope_reading(void) { + syscall_return_t cval = command(DRIVER_NUM_NINEDOF, 200, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/ninedof_syscalls.h b/libtock/sensors/syscalls/ninedof_syscalls.h new file mode 100644 index 000000000..164d2f8bd --- /dev/null +++ b/libtock/sensors/syscalls/ninedof_syscalls.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_NINEDOF 0x60004 + +// Check if a ninedof sensor exists. +bool libtock_ninedof_exists(void); + +// Configure the upcall for the ninedof driver. +returncode_t libtock_ninedof_set_upcall(subscribe_upcall callback, void* opaque); + +// Start an accelerometer reading. +returncode_t libtock_ninedof_command_start_accelerometer_reading(void); + +// Start a magnetometer reading. +returncode_t libtock_ninedof_command_start_magnetometer_reading(void); + +// Start a gyroscope reading. +returncode_t libtock_ninedof_command_start_gyroscope_reading(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/pressure_syscalls.c b/libtock/sensors/syscalls/pressure_syscalls.c new file mode 100644 index 000000000..10e1b9afd --- /dev/null +++ b/libtock/sensors/syscalls/pressure_syscalls.c @@ -0,0 +1,15 @@ +#include "pressure_syscalls.h" + +bool libtock_pressure_exists(void) { + return driver_exists(DRIVER_NUM_PRESSURE); +} + +returncode_t libtock_pressure_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_PRESSURE, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_pressure_command_read(void) { + syscall_return_t cval = command(DRIVER_NUM_PRESSURE, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/pressure_syscalls.h b/libtock/sensors/syscalls/pressure_syscalls.h new file mode 100644 index 000000000..a035908c9 --- /dev/null +++ b/libtock/sensors/syscalls/pressure_syscalls.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_PRESSURE 0x60008 + +// Check if the pressure driver exists. +bool libtock_pressure_exists(void); + +// Set the upcall for the pressure sensor. +returncode_t libtock_pressure_set_upcall(subscribe_upcall callback, void* opaque); + +// Read the pressure sensor. +returncode_t libtock_pressure_command_read(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/proximity_syscalls.c b/libtock/sensors/syscalls/proximity_syscalls.c new file mode 100644 index 000000000..be11556d5 --- /dev/null +++ b/libtock/sensors/syscalls/proximity_syscalls.c @@ -0,0 +1,20 @@ +#include "proximity_syscalls.h" + +bool libtock_proximity_exists(void) { + return driver_exists(DRIVER_NUM_PROXIMITY); +} + +returncode_t libtock_proximity_set_upcall(subscribe_upcall upcall, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_PROXIMITY, 0, upcall, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_proximity_command_read(void) { + syscall_return_t cval = command(DRIVER_NUM_PROXIMITY, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_proximity_command_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold) { + syscall_return_t cval = command(DRIVER_NUM_PROXIMITY, 2, lower_threshold, higher_threshold); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/proximity_syscalls.h b/libtock/sensors/syscalls/proximity_syscalls.h new file mode 100644 index 000000000..fad056198 --- /dev/null +++ b/libtock/sensors/syscalls/proximity_syscalls.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_PROXIMITY 0x60005 + +// Check if the proximity driver exists. +bool libtock_proximity_exists(void); + +// Configure the upcall for the driver. +returncode_t libtock_proximity_set_upcall(subscribe_upcall upcall, void *opaque); + +// Read the proximity sensor. +returncode_t libtock_proximity_command_read(void); + +// Configure the proximity sensor to use interrupts. +returncode_t libtock_proximity_command_read_on_interrupt(uint32_t lower_threshold, uint32_t higher_threshold); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/sound_pressure_syscalls.c b/libtock/sensors/syscalls/sound_pressure_syscalls.c new file mode 100644 index 000000000..33c960b6d --- /dev/null +++ b/libtock/sensors/syscalls/sound_pressure_syscalls.c @@ -0,0 +1,25 @@ +#include "sound_pressure_syscalls.h" + +bool libtock_sound_pressure_exists(void) { + return driver_exists(DRIVER_NUM_SOUND_PRESSURE); +} + +returncode_t libtock_sound_pressure_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SOUND_PRESSURE, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_sound_pressure_command_enable(void) { + syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 2, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_sound_pressure_command_disable(void) { + syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 3, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_sound_pressure_command_read(void) { + syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/sound_pressure_syscalls.h b/libtock/sensors/syscalls/sound_pressure_syscalls.h new file mode 100644 index 000000000..ea414886e --- /dev/null +++ b/libtock/sensors/syscalls/sound_pressure_syscalls.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SOUND_PRESSURE 0x60006 + +// Check if the sound pressure sensor exists. +bool libtock_sound_pressure_exists(void); + +// Set the upcall function for the sound pressure sensor. +returncode_t libtock_sound_pressure_set_upcall(subscribe_upcall callback, void* opaque); + +// Enable the sound pressure sensor. +returncode_t libtock_sound_pressure_command_enable(void); + +// Disable the sound pressure sensor. +returncode_t libtock_sound_pressure_command_disable(void); + +// Read the sound pressure sensor. +returncode_t libtock_sound_pressure_command_read(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/temperature_syscalls.c b/libtock/sensors/syscalls/temperature_syscalls.c new file mode 100644 index 000000000..d8791c26b --- /dev/null +++ b/libtock/sensors/syscalls/temperature_syscalls.c @@ -0,0 +1,15 @@ +#include "temperature_syscalls.h" + +bool libtock_temperature_exists(void) { + return driver_exists(DRIVER_NUM_TEMPERATURE); +} + +returncode_t libtock_temperature_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_TEMPERATURE, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_temperature_command_read(void) { + syscall_return_t cval = command(DRIVER_NUM_TEMPERATURE, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/temperature_syscalls.h b/libtock/sensors/syscalls/temperature_syscalls.h new file mode 100644 index 000000000..7484da622 --- /dev/null +++ b/libtock/sensors/syscalls/temperature_syscalls.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_TEMPERATURE 0x60000 + +// Check if temperature sensor exists. +bool libtock_temperature_exists(void); + +// units: temperature in hundredths of degrees centigrade. + +// Set the callback function to be called when the temperature measurement is +// finished. +// +// callback - pointer to function to be called +// opaque - pointer to data provided to the callback +returncode_t libtock_temperature_set_upcall(subscribe_upcall callback, void* opaque); + +// Initiate an ambient temperature measurement. +returncode_t libtock_temperature_command_read(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/syscalls/touch_syscalls.c b/libtock/sensors/syscalls/touch_syscalls.c new file mode 100644 index 000000000..c62880237 --- /dev/null +++ b/libtock/sensors/syscalls/touch_syscalls.c @@ -0,0 +1,55 @@ +#include "touch_syscalls.h" + +bool libtock_touch_exists(void) { + return driver_exists(DRIVER_NUM_TOUCH); +} + +returncode_t libtock_touch_set_upcall_single_touch(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_TOUCH, 0, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_touch_set_upcall_gesture(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_TOUCH, 1, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_touch_set_upcall_multi_touch(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_TOUCH, 2, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_touch_set_allow_readwrite_multi_touch(void* data, int len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_TOUCH, 2, data, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_touch_command_get_number_of_touches(uint32_t* touches) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 100, 0, 0); + return tock_command_return_u32_to_returncode(cval, touches); +} + +returncode_t libtock_touch_command_enable_single_touch(void) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 1, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_touch_command_disable_single_touch(void) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 2, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_touch_command_enable_multi_touch(void) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 11, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_touch_command_disable_multi_touch(void) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 12, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_touch_command_multi_touch_next(void) { + syscall_return_t cval = command(DRIVER_NUM_TOUCH, 10, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/sensors/syscalls/touch_syscalls.h b/libtock/sensors/syscalls/touch_syscalls.h new file mode 100644 index 000000000..f87e8b860 --- /dev/null +++ b/libtock/sensors/syscalls/touch_syscalls.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_TOUCH 0x90002 + +// Check if touch sensor exists. +bool libtock_touch_exists(void); + +// Set the upcall for upcalls on a single touch. +returncode_t libtock_touch_set_upcall_single_touch(subscribe_upcall callback, void* opaque); + +// Set the upcall for upcalls on a multiple touch event. +returncode_t libtock_touch_set_upcall_multi_touch(subscribe_upcall callback, void* opaque); + +// Set the upcall for a gesture callback. +returncode_t libtock_touch_set_upcall_gesture(subscribe_upcall callback, void* opaque); + +// Allow a buffer for receiving multi touch events. +returncode_t libtock_touch_set_allow_readwrite_multi_touch(void* data, int len); + +// Command to get a count of touches. +returncode_t libtock_touch_command_get_number_of_touches(uint32_t* touches); + +// Enable single touch events. +returncode_t libtock_touch_command_enable_single_touch(void); + +// Disable single touch events. +returncode_t libtock_touch_command_disable_single_touch(void); + +// Enable multi touch events. +returncode_t libtock_touch_command_enable_multi_touch(void); + +// Disable multi touch events. +returncode_t libtock_touch_command_disable_multi_touch(void); + +// Request next multi touch event. +returncode_t libtock_touch_command_multi_touch_next(void); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/temperature.c b/libtock/sensors/temperature.c new file mode 100644 index 000000000..2952aa310 --- /dev/null +++ b/libtock/sensors/temperature.c @@ -0,0 +1,20 @@ +#include "temperature.h" + +// Internal upcall for passing to the syscall driver. +static void temperature_upcall(int temp, + __attribute__ ((unused)) int unused, + __attribute__ ((unused)) int unused1, + void* opaque) { + libtock_temperature_callback cb = (libtock_temperature_callback) opaque; + cb(RETURNCODE_SUCCESS, temp); +} + +returncode_t libtock_temperature_read(libtock_temperature_callback cb) { + returncode_t ret; + + ret = libtock_temperature_set_upcall(temperature_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_temperature_command_read(); + return ret; +} diff --git a/libtock/sensors/temperature.h b/libtock/sensors/temperature.h new file mode 100644 index 000000000..fb7f21037 --- /dev/null +++ b/libtock/sensors/temperature.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/temperature_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for temperature data callback. +// +// - `arg1` (`returncode_t`): Status from sampling the sensor. +// - `arg2` (`int`): Temperature reading in hundredths of degrees centigrade. +typedef void (*libtock_temperature_callback)(returncode_t, int); + +// Initiate an ambient temperature measurement and return results via the `cb`. +returncode_t libtock_temperature_read(libtock_temperature_callback cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sensors/touch.c b/libtock/sensors/touch.c new file mode 100644 index 000000000..5fd3804ee --- /dev/null +++ b/libtock/sensors/touch.c @@ -0,0 +1,121 @@ +#include + +#include "touch.h" + +static void single_touch_upcall(int status, + int xy, + __attribute__ ((unused)) int unused1, + void* opaque) { + libtock_touch_touch_callback cb = (libtock_touch_touch_callback) opaque; + + uint16_t x = (uint16_t) (((uint32_t) xy) >> 16); + uint16_t y = (uint16_t) (((uint32_t) xy) & 0xFFFF); + + cb(status, x, y); +} + +static void multi_touch_upcall(int num_events, + int dropped_events, + int lost_touches, + void* opaque) { + libtock_touch_multi_touch_callback cb = (libtock_touch_multi_touch_callback) opaque; + + cb(RETURNCODE_SUCCESS, num_events, dropped_events, lost_touches); +} + +static void gesture_upcall(int gesture, + __attribute__ ((unused)) int unused0, + __attribute__ ((unused)) int unused1, + void* opaque) { + libtock_touch_gesture_callback cb = (libtock_touch_gesture_callback) opaque; + + cb(RETURNCODE_SUCCESS, gesture); +} + +returncode_t libtock_touch_get_number_of_touches(int* touches) { + return libtock_touch_command_get_number_of_touches((uint32_t*) touches); +} + +returncode_t libtock_touch_enable_single_touch(libtock_touch_touch_callback cb) { + returncode_t ret; + + ret = libtock_touch_set_upcall_single_touch(single_touch_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_touch_command_enable_single_touch(); + return ret; +} + +returncode_t libtock_touch_disable_single_touch(void) { + returncode_t ret; + + ret = libtock_touch_set_upcall_single_touch(NULL, NULL); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_touch_command_disable_single_touch(); + return ret; +} + +returncode_t libtock_touch_enable_multi_touch(libtock_touch_event_t* buffer, int max_touches, + libtock_touch_multi_touch_callback cb) { + returncode_t ret; + + ret = libtock_touch_set_allow_readwrite_multi_touch(buffer, max_touches * sizeof(libtock_touch_event_t)); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_touch_set_upcall_multi_touch(multi_touch_upcall, cb); + return ret; + +} + +returncode_t libtock_touch_disable_multi_touch(void) { + returncode_t ret; + + ret = libtock_touch_set_allow_readwrite_multi_touch(NULL, 0); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_touch_set_upcall_multi_touch(NULL, NULL); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_touch_command_disable_multi_touch(); + return ret; +} + +returncode_t libtock_touch_allocate_multi_touch_buffer(int max_touches, libtock_touch_event_t** buffer) { + libtock_touch_event_t* multi_touch_buffer; + multi_touch_buffer = (libtock_touch_event_t*) malloc(max_touches * sizeof(libtock_touch_event_t)); + + if (multi_touch_buffer == NULL) { + return RETURNCODE_ENOMEM; + } else { + *buffer = multi_touch_buffer; + return RETURNCODE_SUCCESS; + } +} + +returncode_t libtock_touch_get_gestures(libtock_touch_gesture_callback cb) { + return libtock_touch_set_upcall_gesture(gesture_upcall, cb); +} + +returncode_t libtock_touch_multi_touch_next(void) { + return libtock_touch_command_multi_touch_next(); +} + + +// get multi touch + +returncode_t libtock_touch_read_touch_from_buffer(libtock_touch_event_t* buffer, int index, + uint8_t *id, uint8_t *status, uint8_t *x, uint8_t *y, + uint8_t *size, uint8_t *pressure) { + if (buffer != NULL) { + *id = buffer[index].id; + *status = buffer[index].status; + *x = buffer[index].x; + *y = buffer[index].y; + *size = buffer[index].size; + *pressure = buffer[index].pressure; + return RETURNCODE_SUCCESS; + } else { + return RETURNCODE_ENOMEM; + } +} diff --git a/libtock/sensors/touch.h b/libtock/sensors/touch.h new file mode 100644 index 000000000..74cdd0286 --- /dev/null +++ b/libtock/sensors/touch.h @@ -0,0 +1,88 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/touch_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +// Function signature for touch data callback. +// +// - `arg1` (`int`): Status from touch device. +// - `arg2` (`uint16_t`): X coordinate of the touch event. +// - `arg3` (`uint16_t`): Y coordinate of the touch event. +typedef void (*libtock_touch_touch_callback)(int, uint16_t, uint16_t); + +// Function signature for multi touch data callback. +// +// - `arg1` (`returncode_t`): Status from touch device. +// - `arg2` (`int`): Number of touch events. +// - `arg3` (`int`): Number of dropped events. +// - `arg4` (`int`): Number of events that did not fit in the buffer. +typedef void (*libtock_touch_multi_touch_callback)(returncode_t, int, int, int); + +// Function signature for gesture callback. +// +// - `arg1` (`returncode_t`): Status from touch device. +// - `arg2` (`int`): Gesture type. +typedef void (*libtock_touch_gesture_callback)(returncode_t, int); + + +#define LIBTOCK_TOUCH_STATUS_RELEASED 0 +#define LIBTOCK_TOUCH_STATUS_PRESSED 1 +#define LIBTOCK_TOUCH_STATUS_MOVED 2 +#define LIBTOCK_TOUCH_STATUS_UNSTARTED 3 + +#define GESTURE_NO 0 +#define GESTURE_SWIPE_UP 1 +#define GESTURE_SWIPE_DOWN 2 +#define GESTURE_SWIPE_LEFT 3 +#define GESTURE_SWIPE_RIGHT 4 +#define GESTURE_ZOOM_IN 5 +#define GESTURE_ZOOM_OUT 6 + + +typedef struct __attribute__((__packed__)) { + unsigned char id; + unsigned char status; + unsigned short x; + unsigned short y; + unsigned char size; + unsigned char pressure; +} libtock_touch_event_t; + +// buffer data format +// 0 1 2 4 6 7 8 ... +// +---------+-------------+------------------+------------------+-----------+---------------+--------- ... +// | id (u8) | status (u8) | x (u16) | y (u16) | size (u8) | pressure (u8) | ... +// +---------+-------------+------------------+------------------+-----------+---------------+--------- ... +// | Touch 0 | Touch 1 ... + + + +returncode_t libtock_touch_get_number_of_touches(int* touches); + +returncode_t libtock_touch_enable_single_touch(libtock_touch_touch_callback cb); + +returncode_t libtock_touch_disable_single_touch(void); + +returncode_t libtock_touch_enable_multi_touch(libtock_touch_event_t* buffer, int max_touches, libtock_touch_multi_touch_callback cb); + +returncode_t libtock_touch_disable_multi_touch(void); + +returncode_t libtock_touch_allocate_multi_touch_buffer(int max_touches, libtock_touch_event_t** buffer); + +returncode_t libtock_touch_get_gestures(libtock_touch_gesture_callback cb); + +// Every multi touch event needs to be acked +returncode_t libtock_touch_multi_touch_next(void); + +returncode_t libtock_touch_read_touch_from_buffer(libtock_touch_event_t* buffer, int index, + uint8_t *id, uint8_t *status, uint8_t *x, uint8_t *y, + uint8_t *size, uint8_t *pressure); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/services/README.md b/libtock/services/README.md new file mode 100644 index 000000000..800d17e31 --- /dev/null +++ b/libtock/services/README.md @@ -0,0 +1,9 @@ +Libtock Services +================ + +This directory holds higher-level services that build on top of the raw syscalls +defined in other folders in the `libtock` directory. + +Unlike the other libtock interfaces, services defined in this folder can have +internal state, though any functionality that requires calls to `yield()` +still belongs in `libtock-sync`. diff --git a/libtock/alarm_timer.c b/libtock/services/alarm.c similarity index 50% rename from libtock/alarm_timer.c rename to libtock/services/alarm.c index eedbbb003..674ff5877 100644 --- a/libtock/alarm_timer.c +++ b/libtock/services/alarm.c @@ -1,6 +1,4 @@ #include "alarm.h" -#include "internal/alarm.h" -#include "timer.h" #include #include @@ -9,9 +7,9 @@ static int within_range(uint32_t a, uint32_t b, uint32_t c) { return (b - a) < (b - c); } -static alarm_t* root = NULL; +static libtock_alarm_t* root = NULL; -static void root_insert(alarm_t* alarm) { +static void root_insert(libtock_alarm_t* alarm) { if (root == NULL) { root = alarm; root->next = NULL; @@ -19,14 +17,14 @@ static void root_insert(alarm_t* alarm) { return; } - alarm_t **cur = &root; - alarm_t *prev = NULL; + libtock_alarm_t **cur = &root; + libtock_alarm_t *prev = NULL; while (*cur != NULL) { uint32_t cur_expiration = (*cur)->reference + (*cur)->dt; uint32_t new_expiration = alarm->reference + alarm->dt; if (!within_range(alarm->reference, cur_expiration, new_expiration)) { // insert before - alarm_t *tmp = *cur; + libtock_alarm_t *tmp = *cur; *cur = alarm; alarm->next = tmp; alarm->prev = prev; @@ -43,11 +41,11 @@ static void root_insert(alarm_t* alarm) { } -static alarm_t* root_pop(void) { +static libtock_alarm_t* root_pop(void) { if (root == NULL) { return NULL; } else { - alarm_t *res = root; + libtock_alarm_t *res = root; root = root->next; if (root != NULL) { root->prev = NULL; @@ -57,34 +55,35 @@ static alarm_t* root_pop(void) { } } -static alarm_t* root_peek(void) { +static libtock_alarm_t* root_peek(void) { return root; } -static void callback( __attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - __attribute__ ((unused)) void* ud) { - for (alarm_t* alarm = root_peek(); alarm != NULL; alarm = root_peek()) { +static void alarm_upcall( __attribute__ ((unused)) int kernel_now, + __attribute__ ((unused)) int scheduled, + __attribute__ ((unused)) int unused2, + __attribute__ ((unused)) void* opaque) { + for (libtock_alarm_t* alarm = root_peek(); alarm != NULL; alarm = root_peek()) { uint32_t now; - alarm_internal_read(&now); + libtock_alarm_command_read(&now); // has the alarm not expired yet? (distance from `now` has to be larger or // equal to distance from current clock value. if (alarm->dt > now - alarm->reference) { - alarm_internal_set(alarm->reference, alarm->dt); + libtock_alarm_command_set_absolute(alarm->reference, alarm->dt); break; } else { root_pop(); if (alarm->callback) { uint32_t expiration = alarm->reference + alarm->dt; - tock_enqueue(alarm->callback, now, expiration, 0, alarm->ud); + alarm->callback(now, expiration, alarm->ud); } } } } -int alarm_at(uint32_t reference, uint32_t dt, subscribe_upcall cb, void* ud, alarm_t* alarm) { +static int libtock_alarm_at_internal(uint32_t reference, uint32_t dt, libtock_alarm_callback cb, void* ud, + libtock_alarm_t* alarm) { alarm->reference = reference; alarm->dt = dt; alarm->callback = cb; @@ -94,19 +93,23 @@ int alarm_at(uint32_t reference, uint32_t dt, subscribe_upcall cb, void* ud, ala root_insert(alarm); int i = 0; - for (alarm_t* cur = root_peek(); cur != NULL; cur = cur->next) { + for (libtock_alarm_t* cur = root_peek(); cur != NULL; cur = cur->next) { i++; } if (root_peek() == alarm) { - alarm_internal_subscribe((subscribe_upcall*)callback, NULL); + libtock_alarm_set_upcall((subscribe_upcall*)alarm_upcall, NULL); - return alarm_internal_set(alarm->reference, alarm->dt); + return libtock_alarm_command_set_absolute(alarm->reference, alarm->dt); } return RETURNCODE_SUCCESS; } -void alarm_cancel(alarm_t* alarm) { +int libtock_alarm_at(uint32_t reference, uint32_t dt, libtock_alarm_callback cb, void* opaque, libtock_alarm_t* alarm) { + return libtock_alarm_at_internal(reference, dt, cb, opaque, alarm); +} + +void libtock_alarm_cancel(libtock_alarm_t* alarm) { if (alarm->prev != NULL) { alarm->prev->next = alarm->next; } @@ -117,7 +120,7 @@ void alarm_cancel(alarm_t* alarm) { if (root == alarm) { root = alarm->next; if (root != NULL) { - alarm_internal_set(root->reference, root->dt); + libtock_alarm_command_set_absolute(root->reference, root->dt); } } @@ -126,98 +129,51 @@ void alarm_cancel(alarm_t* alarm) { } -// Timer implementation - -int timer_in(uint32_t ms, subscribe_upcall cb, void* ud, tock_timer_t *timer) { +int libtock_alarm_in_ms(uint32_t ms, libtock_alarm_callback cb, void* opaque, libtock_alarm_t *alarm) { uint32_t frequency; - alarm_internal_frequency(&frequency); + libtock_alarm_command_get_frequency(&frequency); uint32_t interval = (ms / 1000) * frequency + (ms % 1000) * (frequency / 1000); uint32_t now; - alarm_internal_read(&now); - return alarm_at(now, interval, cb, ud, &timer->alarm); + libtock_alarm_command_read(&now); + return libtock_alarm_at(now, interval, cb, opaque, alarm); } -static void repeating_upcall( uint32_t now, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - tock_timer_t* repeating = (tock_timer_t*)ud; - uint32_t interval = repeating->interval; - uint32_t cur_exp = repeating->alarm.reference + interval; - alarm_at(cur_exp, interval, (subscribe_upcall*)repeating_upcall, - (void*)repeating, &repeating->alarm); - repeating->cb(now, cur_exp, 0, repeating->ud); +static void alarm_repeating_cb( uint32_t now, __attribute__ ((unused)) uint32_t scheduled, void* opaque) { + libtock_alarm_repeating_t* repeating = (libtock_alarm_repeating_t*) opaque; + uint32_t interval = repeating->interval; + uint32_t cur_exp = repeating->alarm.reference + interval; + libtock_alarm_at_internal(cur_exp, interval, (libtock_alarm_callback)alarm_repeating_cb, + (void*)repeating, &repeating->alarm); + repeating->cb(now, cur_exp, repeating->ud); } -void timer_every(uint32_t ms, subscribe_upcall cb, void* ud, tock_timer_t* repeating) { + +void libtock_alarm_repeating_every(uint32_t ms, libtock_alarm_callback cb, void* opaque, + libtock_alarm_repeating_t* repeating) { uint32_t frequency; - alarm_internal_frequency(&frequency); + libtock_alarm_command_get_frequency(&frequency); uint32_t interval = (ms / 1000) * frequency + (ms % 1000) * (frequency / 1000); repeating->interval = interval; repeating->cb = cb; - repeating->ud = ud; + repeating->ud = opaque; uint32_t now; - alarm_internal_read(&now); - alarm_at(now, interval, (subscribe_upcall*)repeating_upcall, - (void*)repeating, &repeating->alarm); -} - -void timer_cancel(tock_timer_t* timer) { - alarm_cancel(&timer->alarm); + libtock_alarm_command_read(&now); + libtock_alarm_at_internal(now, interval, alarm_repeating_cb, + (void*)repeating, &repeating->alarm); } -static void delay_upcall(__attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - *((bool*)ud) = true; -} - -int delay_ms(uint32_t ms) { - bool cond = false; - tock_timer_t timer; - int rc; - - if ((rc = timer_in(ms, delay_upcall, &cond, &timer)) != RETURNCODE_SUCCESS) { - return rc; - } - - yield_for(&cond); - return rc; -} - -static void yield_for_timeout_upcall(__attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - void* ud) { - *((bool*)ud) = true; -} - -int yield_for_with_timeout(bool* cond, uint32_t ms) { - bool timeout = false; - tock_timer_t timer; - timer_in(ms, yield_for_timeout_upcall, &timeout, &timer); - - while (!*cond) { - if (timeout) { - return RETURNCODE_FAIL; - } - - yield(); - } - - timer_cancel(&timer); - return RETURNCODE_SUCCESS; +void libtock_alarm_repeating_cancel(libtock_alarm_repeating_t* repeating) { + libtock_alarm_cancel(&repeating->alarm); } -int gettimeasticks(struct timeval *tv, __attribute__ ((unused)) void *tzvp) +int libtock_alarm_gettimeasticks(struct timeval *tv, __attribute__ ((unused)) void *tzvp) { uint32_t frequency, now, seconds, remainder; - alarm_internal_frequency(&frequency); - alarm_internal_read(&now); + libtock_alarm_command_get_frequency(&frequency); + libtock_alarm_command_read(&now); // The microsecond calculation will overflow in the intermediate scaling of // (remainder * 1000) if the remainder is approximately greater than 4e6. Because diff --git a/libtock/services/alarm.h b/libtock/services/alarm.h new file mode 100644 index 000000000..9c5ec4a02 --- /dev/null +++ b/libtock/services/alarm.h @@ -0,0 +1,127 @@ +/* + * This module allows the client to initiate alarms and receive + * callbacks when those alarms have expired. Clients can set one-shot alarms to + * fire at particular clock values (`libtock_alarm_at`) or periodic alarms + * (`libtock_alarm_repeating_every`) + * + * The client should not assume anything about the underlying clock used by an + * implementation other than that it is running at sufficient frequency to + * deliver at least millisecond granularity and that it is a 32-bit clock (i.e. + * it will wrap at 2^32 clock ticks). + */ + +#pragma once + +#include "../tock.h" +#include "../peripherals/syscalls/alarm_syscalls.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Function signature for alarm callback. +// +// - `arg1` (`now`): The current time when this callback was enqueued by the +// kernel. +// - `arg2` (`scheduled`): The time (reference + dt) that this alarm was +// originally scheduled to fire at. +// - `arg3` (`opaque`): An arbitrary user pointer passed back to the callback. +typedef void (*libtock_alarm_callback)(uint32_t, uint32_t, void*); + +/** \brief Opaque handle to a single-shot alarm. + * + * An opaque handle to an alarm created by `alarm_at` or `alarm_in`. Memory + * management is handled by the underlying implementation. + */ +typedef struct alarm { + uint32_t reference; + uint32_t dt; + libtock_alarm_callback callback; + void* ud; + struct alarm* next; + struct alarm* prev; +} libtock_alarm_t; + +/** \brief Opaque handle to a repeating alarm. + * + * An opaque handle to a repeating alarm created by `libtock_alarm_repeating_every`. + */ +typedef struct alarm_repeating { + uint32_t interval; + libtock_alarm_callback cb; + void* ud; + libtock_alarm_t alarm; +} libtock_alarm_repeating_t; + + +/** \brief Create a new alarm to fire at a particular clock value. + * + * The `alarm` parameter is allocated by the caller and must live as long as + * the alarm is outstanding. + * + * \param reference: the reference time from which the alarm is being set + * \param dt: the time after reference that the alarm should fire + * \param callback a callback to be invoked when the alarm expires. + * \param userdata passed to the callback. + * \param a pointer to a new alarm_t to be used by the implementation to keep + * track of the alarm. + * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. + */ +int libtock_alarm_at(uint32_t reference, uint32_t dt, libtock_alarm_callback cb, void* opaque, libtock_alarm_t *alarm); + +/** \brief Cancels an existing alarm. + * + * The caller is responsible for freeing the `alarm_t`. + * + * \param alarm + */ +void libtock_alarm_cancel(libtock_alarm_t*); + +// Use this to implement _gettimeofday yourself as libtock-c doesn't provide +// an implementation. +// +// See https://github.com/tock/libtock-c/pull/355#issuecomment-1841351091 for +// more details +// +// ```c +// int _gettimeofday(struct timeval *tv, void *tzvp) { +// return libtock_alarm_gettimeasticks(tv, tzvp); +// } +// ``` +int libtock_alarm_gettimeasticks(struct timeval *tv, void *tzvp); + +/** \brief Create a new alarm to fire in `ms` milliseconds. + * + * \param ms the number of milliseconds to fire the alarm after. + * \param callback a callback to be invoked when the alarm expires. + * \param opaque pointer passed to the callback. + * \param A handle to the alarm that was created. + * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. + */ +int libtock_alarm_in_ms(uint32_t ms, libtock_alarm_callback cb, void* opaque, libtock_alarm_t* alarm); + +/** \brief Create a new repeating alarm to fire every `ms` milliseconds. + * + * The `alarm_repeating` parameter is allocated by the caller and must live as long as + * the repeating alarm is outstanding. + * + * \param ms the interval to fire the alarm at in milliseconds. + * \param callback a callback to be invoked when the alarm expires. + * \param opaque pointer passed to the callback. + * \param a pointer to a new alarm_repeating_t to be used by the implementation to + * keep track of the alarm. + */ +void libtock_alarm_repeating_every(uint32_t ms, libtock_alarm_callback cb, void* opaque, libtock_alarm_repeating_t* alarm_repeating); + +/** \brief Cancels an existing repeating alarm. + * + * \param alarm_repeating + */ +void libtock_alarm_repeating_cancel(libtock_alarm_repeating_t* alarm_repeating); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sha.h b/libtock/sha.h deleted file mode 100644 index bf4f10633..000000000 --- a/libtock/sha.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int sha_set_callback (subscribe_upcall callback, void* callback_args); - -int sha_set_data_buffer(uint8_t* buffer, uint32_t len); -int sha_set_dest_buffer(uint8_t* buffer, uint32_t len); - -int sha_set_algorithm(uint8_t hash); -int sha_run(void); -int sha_update(void); -int sha_finish(void); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/sound_pressure.c b/libtock/sound_pressure.c deleted file mode 100644 index 4b2a6fed0..000000000 --- a/libtock/sound_pressure.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "sound_pressure.h" -#include "tock.h" - -struct data { - bool fired; - unsigned char temp; -}; - -static struct data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void cb(int temp, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - void* ud) { - struct data* data = (struct data*) ud; - data->temp = (unsigned char)temp; - data->fired = true; -} - -bool sound_pressure_exists(void) { - return driver_exists(DRIVER_NUM_SOUND_PRESSURE); -} - -int sound_pressure_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_SOUND_PRESSURE, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int sound_pressure_read(void) { - syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -// enable sound pressure sensor -int sound_pressure_enable(void) { - syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 2, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -// disable sound pressure sensor -int sound_pressure_disable(void) { - syscall_return_t cval = command(DRIVER_NUM_SOUND_PRESSURE, 3, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int sound_pressure_read_sync(unsigned char* sound_pressure) { - int err; - result.fired = false; - - err = sound_pressure_set_callback(cb, (void*) &result); - if (err < 0) return err; - - err = sound_pressure_read(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *sound_pressure = result.temp; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/sound_pressure.h b/libtock/sound_pressure.h deleted file mode 100644 index a29a7771f..000000000 --- a/libtock/sound_pressure.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_SOUND_PRESSURE 0x60006 - -// check if sound pressure sensor exists -bool sound_pressure_exists(void); - -// units: sound_pressure in DB. - -// function to be called when the temperature measurement is finished -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int sound_pressure_set_callback (subscribe_upcall callback, void* callback_args); - - -// initiate an ambient sound_pressure measurement used both for synchronous and asynchronous readings -int sound_pressure_read(void); - -// enable sound pressure sensor -int sound_pressure_enable(void); - -// disable sound pressure sensor -int sound_pressure_disable(void); - - -// initiate a synchronous ambient sound_pressure measurement -// -// sound_pressure - pointer/address where the result of the sound_pressure reading should be stored -int sound_pressure_read_sync (unsigned char* sound_pressure); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/spi.c b/libtock/spi.c deleted file mode 100644 index de6c0b980..000000000 --- a/libtock/spi.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "spi.h" - -__attribute__((const)) -int spi_init(void) { - return 0; -} - -int spi_set_chip_select(unsigned char cs) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 3, cs, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_get_chip_select(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 4, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_set_rate(int rate) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 5, rate, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_get_rate(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 6, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_set_phase(bool phase) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 7, (unsigned char)phase, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_get_phase(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 8, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_set_polarity(bool pol) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 9, (unsigned char)pol, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_get_polarity(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 10, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_hold_low(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 11, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_release_low(void) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 12, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_write_byte(unsigned char byte) { - syscall_return_t cval = command(DRIVER_NUM_SPI, 1, byte, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_SPI, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int spi_set_master_write_buffer(const uint8_t* buffer, uint32_t len) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SPI, 0, (const void*) buffer, len); - return tock_allow_ro_return_to_returncode(aval); -} - -int spi_set_master_read_buffer(uint8_t* buffer, uint32_t len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SPI, 0, (void*) buffer, len); - return tock_allow_rw_return_to_returncode(aval); -} - -static void spi_upcall(__attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - __attribute__ ((unused)) void* ud) { - *((bool*)ud) = true; -} - -int spi_write(const char* buf, - size_t len, - subscribe_upcall cb, bool* cond) { - int ret = 0; - - ret = spi_set_master_write_buffer((const uint8_t*) buf, len); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - ret = spi_set_callback(cb, cond); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - syscall_return_t cval = command(DRIVER_NUM_SPI, 2, len, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_read_write(const char* write, - char* read, - size_t len, - subscribe_upcall cb, bool* cond) { - int ret = 0; - - ret = spi_set_master_read_buffer((uint8_t*) read, len); - if (ret != RETURNCODE_SUCCESS) { - return ret; - } - - return spi_write(write, len, cb, cond); -} - -int spi_write_sync(const char* write, - size_t len) { - bool cond = false; - - int err = spi_write(write, len, spi_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} - -int spi_read_write_sync(const char* write, - char* read, - size_t len) { - bool cond = false; - - int err = spi_read_write(write, read, len, spi_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} diff --git a/libtock/spi.h b/libtock/spi.h deleted file mode 100644 index f29eaae94..000000000 --- a/libtock/spi.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_SPI 0x20001 - -int spi_set_callback(subscribe_upcall callback, void* callback_args); - -int spi_set_master_write_buffer(const uint8_t* buffer, uint32_t len); -int spi_set_master_read_buffer(uint8_t* buffer, uint32_t len); - -/* SPI system calls */ -int spi_init(void); -/* All SPI operations depend on which peripheral is - * active, determined by set_chip_select. Configuration - * of a peripheral is persistent; e.g., setting the rate R - * for peripheral 3, then switching to peripheral 2, - * peripheral 2 will not necessarily have rate R. Then - * back to peripheral 3, it still has rate R.*/ -int spi_set_chip_select(unsigned char cs); -int spi_get_chip_select(void); - -/* Rate is the Hz of the SPI clock. So a rate of 100000 - * is a 100kHZ clock. */ -int spi_set_rate(int rate); -int spi_get_rate(void); - - /* false means sample on a leading (low to high) clock edge - * true means sample on a trailing (high to low) clock edge */ -int spi_set_phase(bool phase); -int spi_get_phase(void); - - /* false means an idle clock is low - * true means an idle clock is high. */ -int spi_set_polarity(bool pol); -int spi_get_polarity(void); - - /* Only partially supported, depending on implementation. In some cases - allows a process to hold its chip select line low over multiple SPI - operations*/ -int spi_hold_low(void); -int spi_release_low(void); - -int spi_write_byte(unsigned char byte); -int spi_read_buf(const char* str, size_t len); -int spi_write(const char* str, size_t len, subscribe_upcall cb, bool* cond); -int spi_read_write(const char* write, char* read, size_t len, subscribe_upcall cb, bool* cond); - -int spi_write_sync(const char* write, size_t len); -int spi_read_write_sync(const char* write, char* read, size_t len); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/spi_peripheral.c b/libtock/spi_peripheral.c deleted file mode 100644 index ff887c3e7..000000000 --- a/libtock/spi_peripheral.c +++ /dev/null @@ -1,91 +0,0 @@ -#include - -int spi_peripheral_get_chip_select(void) { - syscall_return_t cval = command(SPI_PERIPHERAL, 2, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_peripheral_set_phase(bool phase) { - syscall_return_t cval = command(SPI_PERIPHERAL, 3, (unsigned char)phase, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_peripheral_get_phase(void) { - syscall_return_t cval = command(SPI_PERIPHERAL, 4, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_peripheral_set_polarity(bool pol) { - syscall_return_t cval = command(SPI_PERIPHERAL, 5, (unsigned char)pol, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_peripheral_get_polarity(void) { - syscall_return_t cval = command(SPI_PERIPHERAL, 6, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -/* This registers a callback for when the peripheral is selected. */ -int spi_peripheral_chip_selected(subscribe_upcall cb, bool* cond) { - subscribe_return_t sval = subscribe(SPI_PERIPHERAL, 1, cb, cond); - return tock_subscribe_return_to_returncode(sval); -} - -int spi_peripheral_read_buf(char* str, size_t len) { - allow_rw_return_t aval = allow_readwrite(SPI_PERIPHERAL, 0, str, len); - return tock_allow_rw_return_to_returncode(aval); -} - -static void spi_peripheral_upcall(__attribute__ ((unused)) int unused0, - __attribute__ ((unused)) int unused1, - __attribute__ ((unused)) int unused2, - __attribute__ ((unused)) void* ud) { - *((bool*)ud) = true; -} - -int spi_peripheral_write(const char* str, - size_t len, - subscribe_upcall cb, bool* cond) { - allow_ro_return_t aval = allow_readonly(SPI_PERIPHERAL, 0, str, len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - subscribe_return_t sval = subscribe(SPI_PERIPHERAL, 0, cb, cond); - if (!sval.success) return tock_status_to_returncode(sval.status); - - syscall_return_t cval = command(SPI_PERIPHERAL, 1, len, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int spi_peripheral_read_write(const char* write, - char* read, - size_t len, - subscribe_upcall cb, bool* cond) { - - allow_rw_return_t aval = allow_readwrite(SPI_PERIPHERAL, 0, (void*)read, len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - return spi_peripheral_write(write, len, cb, cond); -} - -int spi_peripheral_write_sync(const char* write, - size_t len) { - bool cond = false; - - int err = spi_peripheral_write(write, len, spi_peripheral_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} - -int spi_peripheral_read_write_sync(const char* write, - char* read, - size_t len) { - bool cond = false; - - int err = spi_peripheral_read_write(write, read, len, spi_peripheral_upcall, &cond); - if (err < 0) return err; - - yield_for(&cond); - return RETURNCODE_SUCCESS; -} diff --git a/libtock/spi_peripheral.h b/libtock/spi_peripheral.h deleted file mode 100644 index 6b61e7d9a..000000000 --- a/libtock/spi_peripheral.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SPI_PERIPHERAL 0x20002 - -/* SPI system calls */ -/* Get chip select always returns 0 in peripheral mode. */ -int spi_peripheral_get_chip_select(void); - - /* false means sample on a leading (low to high) clock edge - * true means sample on a trailing (high to low) clock edge */ -int spi_peripheral_set_phase(bool phase); -int spi_peripheral_get_phase(void); - - /* false means an idle clock is low - * true means an idle clock is high. */ -int spi_peripheral_set_polarity(bool pol); -int spi_peripheral_get_polarity(void); - -/* This registers a callback for when the peripheral is selected. */ -int spi_peripheral_chip_selected(subscribe_upcall cb, bool* cond); - -int spi_peripheral_read_buf(char* str, size_t len); -int spi_peripheral_write(const char* str, size_t len, subscribe_upcall cb, bool* cond); -int spi_peripheral_read_write(const char* write, char* read, size_t len, subscribe_upcall cb, bool* cond); - -int spi_peripheral_write_sync(const char* write, size_t len); -int spi_peripheral_read_write_sync(const char* write, char* read, size_t len); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/storage/app_state.c b/libtock/storage/app_state.c new file mode 100644 index 000000000..8bba31cf3 --- /dev/null +++ b/libtock/storage/app_state.c @@ -0,0 +1,57 @@ +#include + +#include "app_state.h" + + +// Internal callback for synchronous interfaces +static void app_state_upcall(__attribute__ ((unused)) int callback_type, + __attribute__ ((unused)) int value, + __attribute__ ((unused)) int unused, + void* opaque) { + libtock_app_state_callback cb = (libtock_app_state_callback) opaque; + cb(RETURNCODE_SUCCESS); +} + + +static returncode_t app_state_init(void) { + returncode_t ret; + + ret = libtock_app_state_set_readonly_allow(_app_state_ram_pointer, _app_state_size); + if (ret != RETURNCODE_SUCCESS) return ret; + + // Check that we have a region to use for this. + int number_regions = tock_app_number_writeable_flash_regions(); + if (number_regions == 0) return RETURNCODE_ENOMEM; + + // Get the pointer to flash which we need to ask the kernel where it is. + _app_state_flash_pointer = tock_app_writeable_flash_region_begins_at(0); + + _app_state_inited = true; + return RETURNCODE_SUCCESS; +} + +returncode_t libtock_app_state_load(void) { + if (!_app_state_inited) { + int err; + err = app_state_init(); + if (err != RETURNCODE_SUCCESS) return err; + } + + memcpy(_app_state_ram_pointer, _app_state_flash_pointer, _app_state_size); + return RETURNCODE_SUCCESS; +} + +returncode_t libtock_app_state_save(libtock_app_state_callback cb) { + returncode_t err; + + if (!_app_state_inited) { + err = app_state_init(); + if (err != RETURNCODE_SUCCESS) return err; + } + + err = libtock_app_state_set_upcall(app_state_upcall, (void*) cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_app_state_command_save((uint32_t) _app_state_flash_pointer); + return err; +} diff --git a/libtock/app_state.h b/libtock/storage/app_state.h similarity index 72% rename from libtock/app_state.h rename to libtock/storage/app_state.h index da80f4714..4ffbab311 100644 --- a/libtock/app_state.h +++ b/libtock/storage/app_state.h @@ -34,15 +34,13 @@ // if (ret != 0) prinrf("ERROR(%i): Could not write back to flash.\n", ret); // } +#include "../tock.h" +#include "syscalls/app_state_syscalls.h" + #ifdef __cplusplus extern "C" { #endif -#include "tock.h" - -#define DRIVER_NUM_APP_FLASH 0x50000 - - // Declare an application state structure // // This macro does a little extra bookkeeping, however it should look @@ -57,27 +55,36 @@ extern "C" { // The variable `memory_copy` is available as regular C structure, however // users must explicitly `load` and `save` application state as appropriate. // Note that each process may only use APP_STATE_DECLARE once. -#define APP_STATE_DECLARE(_type, _identifier) \ +#define LIBTOCK_APP_STATE_DECLARE(_type, _identifier) \ __attribute__((section(".app_state"))) \ _type _app_state_flash; \ _type _identifier; \ void* _app_state_flash_pointer = NULL; \ - void* _app_state_ram_pointer = &_identifier; \ - size_t _app_state_size = sizeof(_type); + void* _app_state_ram_pointer = &_identifier; \ + size_t _app_state_size = sizeof(_type); \ + bool _app_state_inited = false; + + +// Function signature save done callbacks. +// +// - `arg1` (`returncode_t`): Status of save operation. +typedef void (*libtock_app_state_callback)(returncode_t); + extern void* _app_state_flash_pointer; extern void* _app_state_ram_pointer; extern size_t _app_state_size; +extern bool _app_state_inited; + + + +// Load application state from persistent storage into the in-memory storage +// location. +returncode_t libtock_app_state_load(void); -// Load application state from persistent storage -__attribute__ ((warn_unused_result)) -int app_state_load_sync(void); +// Save the application state to persistent storage. +returncode_t libtock_app_state_save(libtock_app_state_callback cb); -// Save application state to persistent storage -__attribute__ ((warn_unused_result)) -int app_state_save(subscribe_upcall callback, void* callback_args); -__attribute__ ((warn_unused_result)) -int app_state_save_sync(void); #ifdef __cplusplus diff --git a/libtock/storage/kv.c b/libtock/storage/kv.c new file mode 100644 index 000000000..e33a17f7a --- /dev/null +++ b/libtock/storage/kv.c @@ -0,0 +1,83 @@ +#include "kv.h" + +static void kv_upcall_get( int err, + int length, + __attribute__ ((unused)) int unused2, + void* opaque) { + + libtock_kv_callback_get cb = (libtock_kv_callback_get) opaque; + cb(tock_status_to_returncode(err), length); +} + + +static void kv_upcall_done( int err, + __attribute__ ((unused)) int length, + __attribute__ ((unused)) int unused2, + void* opaque) { + + libtock_kv_callback_done cb = (libtock_kv_callback_done) opaque; + cb(tock_status_to_returncode(err)); +} + +returncode_t libtock_kv_get(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, + libtock_kv_callback_get cb) { + returncode_t err; + + err = libtock_kv_set_upcall(kv_upcall_get, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_set_readonly_allow_key_buffer(key_buffer, key_len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_set_readwrite_allow_output_buffer(ret_buffer, ret_len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_command_get(); + return err; +} + +static returncode_t kv_insert(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, + uint32_t val_len, returncode_t (*op_fn)(void), libtock_kv_callback_done cb){ + returncode_t err; + + err = libtock_kv_set_upcall(kv_upcall_done, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_set_readonly_allow_key_buffer(key_buffer, key_len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_set_readonly_allow_input_buffer(val_buffer, val_len); + if (err != RETURNCODE_SUCCESS) return err; + + // Do the requested set/add/update operation. + err = op_fn(); + return err; +} + +returncode_t libtock_kv_set(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_command_set, cb); +} + +returncode_t libtock_kv_add(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_command_add, cb); +} + +returncode_t libtock_kv_update(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb) { + return kv_insert(key_buffer, key_len, val_buffer, val_len, libtock_kv_command_update, cb); +} + +returncode_t libtock_kv_delete(const uint8_t* key_buffer, uint32_t key_len, libtock_kv_callback_done cb) { + returncode_t err; + + err = libtock_kv_set_upcall(kv_upcall_done, cb); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_set_readonly_allow_key_buffer(key_buffer, key_len); + if (err != RETURNCODE_SUCCESS) return err; + + err = libtock_kv_command_delete(); + return err; +} diff --git a/libtock/storage/kv.h b/libtock/storage/kv.h new file mode 100644 index 000000000..f243e6d34 --- /dev/null +++ b/libtock/storage/kv.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/kv_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for KV get callbacks. +// +// - `arg1` (`returncode_t`): Status of kv operation. +// - `arg2` (`int`): Length of get. +typedef void (*libtock_kv_callback_get)(returncode_t, int); + +// Function signature for KV callbacks. +// +// - `arg1` (`returncode_t`): Status of kv operation. +typedef void (*libtock_kv_callback_done)(returncode_t); + + +returncode_t libtock_kv_get(const uint8_t* key_buffer, uint32_t key_len, uint8_t* ret_buffer, uint32_t ret_len, + libtock_kv_callback_get cb); + +returncode_t libtock_kv_set(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb); + +returncode_t libtock_kv_add(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb); + +returncode_t libtock_kv_update(const uint8_t* key_buffer, uint32_t key_len, const uint8_t* val_buffer, uint32_t val_len, + libtock_kv_callback_done cb); + +returncode_t libtock_kv_delete(const uint8_t* key_buffer, uint32_t key_len, libtock_kv_callback_done cb); + + +#ifdef __cplusplus +} +#endif diff --git a/libtock/storage/nonvolatile_storage.c b/libtock/storage/nonvolatile_storage.c new file mode 100644 index 000000000..c9b37791a --- /dev/null +++ b/libtock/storage/nonvolatile_storage.c @@ -0,0 +1,49 @@ +#include "nonvolatile_storage.h" + +static void write_done(int length, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + void* opaque) { + libtock_nonvolatile_storage_callback_write cb = (libtock_nonvolatile_storage_callback_write) opaque; + cb(RETURNCODE_SUCCESS, length); +} + +static void read_done(int length, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + void* opaque) { + libtock_nonvolatile_storage_callback_read cb = (libtock_nonvolatile_storage_callback_read) opaque; + cb(RETURNCODE_SUCCESS, length); +} + +returncode_t libtock_nonvolatile_storage_get_number_bytes(uint32_t* number_bytes) { + return libtock_nonvolatile_storage_command_get_number_bytes(number_bytes); +} + +returncode_t libtock_nonvolatile_storage_write(uint32_t offset, uint32_t length, uint8_t* buffer, + uint32_t buffer_length, libtock_nonvolatile_storage_callback_write cb) { + returncode_t ret; + + ret = libtock_nonvolatile_storage_set_upcall_write_done(write_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_nonvolatile_storage_set_allow_readonly_write_buffer(buffer, buffer_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_nonvolatile_storage_command_write(offset, length); + return ret; +} + +returncode_t libtock_nonvolatile_storage_read(uint32_t offset, uint32_t length, uint8_t* buffer, uint32_t buffer_length, + libtock_nonvolatile_storage_callback_read cb) { + returncode_t ret; + + ret = libtock_nonvolatile_storage_set_upcall_read_done(read_done, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_nonvolatile_storage_set_allow_readwrite_read_buffer(buffer, buffer_length); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_nonvolatile_storage_command_read(offset, length); + return ret; +} diff --git a/libtock/storage/nonvolatile_storage.h b/libtock/storage/nonvolatile_storage.h new file mode 100644 index 000000000..6f25ade6c --- /dev/null +++ b/libtock/storage/nonvolatile_storage.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/nonvolatile_storage_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for nonvolatile storage write callbacks. +// +// - `arg1` (`returncode_t`): Status of write. +// - `arg2` (`int`): Length written. +typedef void (*libtock_nonvolatile_storage_callback_write)(returncode_t, int); + +// Function signature for nonvolatile storage read callbacks. +// +// - `arg1` (`returncode_t`): Status of read. +// - `arg2` (`int`): Length ead. +typedef void (*libtock_nonvolatile_storage_callback_read)(returncode_t, int); + +// Get the number of bytes available for storage. +returncode_t libtock_nonvolatile_storage_get_number_bytes(uint32_t* number_bytes); + +// Write `length` bytes from `buffer` to the storage starting at `offset`. +returncode_t libtock_nonvolatile_storage_write(uint32_t offset, uint32_t length, uint8_t* buffer, uint32_t buffer_length, libtock_nonvolatile_storage_callback_write cb); + +// Read `length` bytes into `buffer` from the storage starting at `offset`. +returncode_t libtock_nonvolatile_storage_read(uint32_t offset, uint32_t length, uint8_t* buffer, uint32_t buffer_length, libtock_nonvolatile_storage_callback_read cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/storage/sdcard.c b/libtock/storage/sdcard.c new file mode 100644 index 000000000..4f984b102 --- /dev/null +++ b/libtock/storage/sdcard.c @@ -0,0 +1,98 @@ +#include "sdcard.h" + +// Internal callback for creating synchronous functions +// +// callback_type - number indicating which type of callback occurred +// arg1, arg2 - meaning varies based on callback_type +// callback_args - user data passed into the set_callback function +// +// Possible callbacks +// 0: card_detection_changed, SD card was either installed or removed +// arg1, arg2 - no meaning +// 1: init_done, initialization completed successfully +// arg1 - block_size, block size of SD card in bytes +// arg2 - size_in_kB, total size of SD card in kilobytes +// 2: read_done, read block completed successfully +// arg1 - len, number of bytes read +// 3: write_done, write block completed successfully +// arg1 - len, number of bytes written +// 4: error, an error occurred +// arg1 - error, number representing the error that occurred +static void sdcard_upcall(int callback_type, int arg1, int arg2, void* opaque) { + switch (callback_type) { + case 0: { + // card_detection_changed + libtock_sdcard_callback_operations cb = (libtock_sdcard_callback_operations) opaque; + cb(RETURNCODE_EUNINSTALLED); + break; + } + + case 1: { + // init_done + libtock_sdcard_callback_initialized cb = (libtock_sdcard_callback_initialized) opaque; + cb(RETURNCODE_SUCCESS, arg1, arg2); + break; + } + + case 2: { + // read_done + libtock_sdcard_callback_operations cb = (libtock_sdcard_callback_operations) opaque; + cb(RETURNCODE_SUCCESS); + break; + } + + case 3: { + // write_done + libtock_sdcard_callback_operations cb = (libtock_sdcard_callback_operations) opaque; + cb(RETURNCODE_SUCCESS); + break; + } + + case 4: { + // error + // This is not a STATUSCODE, but rather an SD Card specific error + // See capsule sdcard.rs `enum SdCardError` + libtock_sdcard_callback_operations cb = (libtock_sdcard_callback_operations) opaque; + cb(arg1); + break; + } + } +} + +returncode_t libtock_sdcard_initialize(libtock_sdcard_callback_initialized cb) { + returncode_t ret; + + ret = libtock_sdcard_set_upcall(sdcard_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sdcard_command_initialize(); + return ret; +} + +returncode_t libtock_sdcard_read_block(uint32_t sector, uint8_t* buffer, uint32_t len, + libtock_sdcard_callback_operations cb) { + returncode_t ret; + + ret = libtock_sdcard_set_upcall(sdcard_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sdcard_set_readwrite_allow_read_buffer(buffer, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sdcard_command_read_block(sector); + return ret; +} + +returncode_t libtock_sdcard_write_block(uint32_t sector, uint8_t* buffer, uint32_t len, + libtock_sdcard_callback_operations cb) { + returncode_t ret; + + ret = libtock_sdcard_set_upcall(sdcard_upcall, cb); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sdcard_set_readonly_allow_write_buffer(buffer, len); + if (ret != RETURNCODE_SUCCESS) return ret; + + ret = libtock_sdcard_command_write_block(sector); + return ret; +} diff --git a/libtock/storage/sdcard.h b/libtock/storage/sdcard.h new file mode 100644 index 000000000..b09523a17 --- /dev/null +++ b/libtock/storage/sdcard.h @@ -0,0 +1,59 @@ +#pragma once + +#include "../tock.h" +#include "syscalls/sdcard_syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Function signature for SD card initialization callback. +// +// - `arg1` (`returncode_t`): Status of the init operation. +// - `arg2` (`uint32_t`): block_size, block size of SD card in bytes. +// - `arg3` (`uint32_t`): size_in_kB, total size of SD card in kilobytes. +typedef void (*libtock_sdcard_callback_initialized)(returncode_t, uint32_t, uint32_t); + +// Function signature for SD card general callback. +// +// - `arg1` (`returncode_t`): Status of the init operation. +typedef void (*libtock_sdcard_callback_operations)(returncode_t); + +// Initialize an SD card asynchronously. +// +// Note that for a newly powered-on SD card, initialization can take over 100 ms +// to complete. Expects a callback to have already been set. Callback will be +// called when either initialization is complete or an error occurs. +returncode_t libtock_sdcard_initialize(libtock_sdcard_callback_initialized cb); + +// Read a single block from an SD card asynchronously. +// +// Expects a read_buffer and a callback to already have been set up. Callback +// will be called when either the block has been read or an error occurs. When +// the callback is successful, data will be in the read_buffer. +// +// ## Arguments +// +// - `sector`: sector address of the block to be read. +// - `buffer`: buffer to read into. +// - `len`: len of buffer. +// - `cb`: callback. +returncode_t libtock_sdcard_read_block(uint32_t sector, uint8_t* buffer, uint32_t len, libtock_sdcard_callback_operations cb); + +// Write a single block to an SD card asynchronously. +// +// Expects a write_buffer and a callback to already have been set up. Data in +// the write_buffer will be written to the SD card. Callback will be called when +// either the block has been written or an error occurs. +// +// ## Arguments +// +// - `sector`: sector address of the block to be read. +// - `buffer`: buffer to write from. +// - `len`: len of buffer. +// - `cb`: callback. +returncode_t libtock_sdcard_write_block(uint32_t sector, uint8_t* buffer, uint32_t len, libtock_sdcard_callback_operations cb); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/storage/syscalls/app_state_syscalls.c b/libtock/storage/syscalls/app_state_syscalls.c new file mode 100644 index 000000000..72192b84b --- /dev/null +++ b/libtock/storage/syscalls/app_state_syscalls.c @@ -0,0 +1,20 @@ +#include "app_state_syscalls.h" + +bool libtock_app_state_exists(void) { + return driver_exists(DRIVER_NUM_APP_STATE); +} + +returncode_t libtock_app_state_set_upcall(subscribe_upcall cb, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_APP_STATE, 0, cb, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_app_state_set_readonly_allow(const uint8_t* buf, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_APP_STATE, 0, buf, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_app_state_command_save(uint32_t flash_pointer) { + syscall_return_t cval = command(DRIVER_NUM_APP_STATE, 1, flash_pointer, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/storage/syscalls/app_state_syscalls.h b/libtock/storage/syscalls/app_state_syscalls.h new file mode 100644 index 000000000..930d92240 --- /dev/null +++ b/libtock/storage/syscalls/app_state_syscalls.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_APP_STATE 0x50000 + +// Check if the app state system call driver is available on this board. +bool libtock_app_state_exists(void); + +// Configure the upcall for the app state driver. +returncode_t libtock_app_state_set_upcall(subscribe_upcall cb, void* opaque); + +// Share the buffer with the app state driver. +returncode_t libtock_app_state_set_readonly_allow(const uint8_t* ptr, uint32_t size); + +// Tell the driver to write the buffer to the flash storage. +returncode_t libtock_app_state_command_save(uint32_t flash_pointer); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/storage/syscalls/kv_syscalls.c b/libtock/storage/syscalls/kv_syscalls.c new file mode 100644 index 000000000..6c4d48667 --- /dev/null +++ b/libtock/storage/syscalls/kv_syscalls.c @@ -0,0 +1,62 @@ +#include "kv_syscalls.h" + +#define TOCK_KV_CB 0 + +#define TOCK_KV_KEY_BUF 0 +#define TOCK_KV_INPUT_BUF 1 +#define TOCK_KV_OUTPUT_BUF 0 + +#define TOCK_KV_GET 1 +#define TOCK_KV_SET 2 +#define TOCK_KV_DELETE 3 +#define TOCK_KV_ADD 4 +#define TOCK_KV_UPDATE 5 + +bool libtock_kv_exists(void) { + return driver_exists(DRIVER_NUM_KV); +} + +returncode_t libtock_kv_set_upcall(subscribe_upcall callback, void* opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_KV, TOCK_KV_CB, callback, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_kv_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_KV, TOCK_KV_KEY_BUF, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_kv_set_readonly_allow_input_buffer(const uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_KV, TOCK_KV_INPUT_BUF, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_kv_set_readwrite_allow_output_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_KV, TOCK_KV_OUTPUT_BUF, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_kv_command_get(void) { + syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_GET, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_kv_command_set(void) { + syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_SET, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_kv_command_delete(void) { + syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_DELETE, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_kv_command_add(void) { + syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_ADD, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_kv_command_update(void) { + syscall_return_t cval = command(DRIVER_NUM_KV, TOCK_KV_UPDATE, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/storage/syscalls/kv_syscalls.h b/libtock/storage/syscalls/kv_syscalls.h new file mode 100644 index 000000000..09a19909b --- /dev/null +++ b/libtock/storage/syscalls/kv_syscalls.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_KV 0x50003 + +bool libtock_kv_exists(void); + +returncode_t libtock_kv_set_upcall(subscribe_upcall callback, void* opaque); + +returncode_t libtock_kv_set_readonly_allow_key_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_kv_set_readonly_allow_input_buffer(const uint8_t* buffer, uint32_t len); + +returncode_t libtock_kv_set_readwrite_allow_output_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_kv_command_get(void); + +returncode_t libtock_kv_command_set(void); + +returncode_t libtock_kv_command_delete(void); + +returncode_t libtock_kv_command_add(void); + +returncode_t libtock_kv_command_update(void); + +#ifdef __cplusplus +} +#endif + diff --git a/libtock/storage/syscalls/nonvolatile_storage_syscalls.c b/libtock/storage/syscalls/nonvolatile_storage_syscalls.c new file mode 100644 index 000000000..7c476c09d --- /dev/null +++ b/libtock/storage/syscalls/nonvolatile_storage_syscalls.c @@ -0,0 +1,40 @@ +#include "nonvolatile_storage_syscalls.h" + +bool libtock_nonvolatile_storage_exists(void) { + return driver_exists(DRIVER_NUM_NONVOLATILE_STORAGE); +} + +returncode_t libtock_nonvolatile_storage_set_upcall_read_done(subscribe_upcall cb, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_NONVOLATILE_STORAGE, 0, cb, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_nonvolatile_storage_set_upcall_write_done(subscribe_upcall cb, void *opaque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_NONVOLATILE_STORAGE, 1, cb, opaque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_nonvolatile_storage_set_allow_readwrite_read_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_NONVOLATILE_STORAGE, 0, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_nonvolatile_storage_set_allow_readonly_write_buffer(uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_NONVOLATILE_STORAGE, 0, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_nonvolatile_storage_command_get_number_bytes(uint32_t* number_bytes) { + syscall_return_t cval = command(DRIVER_NUM_NONVOLATILE_STORAGE, 1, 0, 0); + return tock_command_return_u32_to_returncode(cval, number_bytes); +} + +returncode_t libtock_nonvolatile_storage_command_read(uint32_t offset, uint32_t length) { + syscall_return_t cval = command(DRIVER_NUM_NONVOLATILE_STORAGE, 2, offset, length); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_nonvolatile_storage_command_write(uint32_t offset, uint32_t length) { + syscall_return_t cval = command(DRIVER_NUM_NONVOLATILE_STORAGE, 3, offset, length); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/storage/syscalls/nonvolatile_storage_syscalls.h b/libtock/storage/syscalls/nonvolatile_storage_syscalls.h new file mode 100644 index 000000000..152aefb22 --- /dev/null +++ b/libtock/storage/syscalls/nonvolatile_storage_syscalls.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_NONVOLATILE_STORAGE 0x50001 + +bool libtock_nonvolatile_storage_exists(void); + +returncode_t libtock_nonvolatile_storage_set_upcall_read_done(subscribe_upcall cb, void *opaque); + +returncode_t libtock_nonvolatile_storage_set_upcall_write_done(subscribe_upcall cb, void *opaque); + +returncode_t libtock_nonvolatile_storage_set_allow_readwrite_read_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_nonvolatile_storage_set_allow_readonly_write_buffer(uint8_t* buffer, uint32_t len); + +returncode_t libtock_nonvolatile_storage_command_get_number_bytes(uint32_t* number_bytes); + +returncode_t libtock_nonvolatile_storage_command_read(uint32_t offset, uint32_t length); + +returncode_t libtock_nonvolatile_storage_command_write(uint32_t offset, uint32_t length); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/storage/syscalls/sdcard_syscalls.c b/libtock/storage/syscalls/sdcard_syscalls.c new file mode 100644 index 000000000..dd50a62ca --- /dev/null +++ b/libtock/storage/syscalls/sdcard_syscalls.c @@ -0,0 +1,35 @@ +#include "sdcard_syscalls.h" + +bool libtock_sdcard_exists(void) { + return driver_exists(DRIVER_NUM_SDCARD); +} + +returncode_t libtock_sdcard_set_upcall(subscribe_upcall callback, void* opque) { + subscribe_return_t sval = subscribe(DRIVER_NUM_SDCARD, 0, callback, opque); + return tock_subscribe_return_to_returncode(sval); +} + +returncode_t libtock_sdcard_set_readwrite_allow_read_buffer(uint8_t* buffer, uint32_t len) { + allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_SDCARD, 0, (void*) buffer, len); + return tock_allow_rw_return_to_returncode(aval); +} + +returncode_t libtock_sdcard_set_readonly_allow_write_buffer(uint8_t* buffer, uint32_t len) { + allow_ro_return_t aval = allow_readonly(DRIVER_NUM_SDCARD, 0, (void*) buffer, len); + return tock_allow_ro_return_to_returncode(aval); +} + +returncode_t libtock_sdcard_command_initialize(void) { + syscall_return_t cval = command(DRIVER_NUM_SDCARD, 2, 0, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_sdcard_command_read_block(uint32_t sector) { + syscall_return_t cval = command(DRIVER_NUM_SDCARD, 3, sector, 0); + return tock_command_return_novalue_to_returncode(cval); +} + +returncode_t libtock_sdcard_command_write_block(uint32_t sector) { + syscall_return_t cval = command(DRIVER_NUM_SDCARD, 4, sector, 0); + return tock_command_return_novalue_to_returncode(cval); +} diff --git a/libtock/storage/syscalls/sdcard_syscalls.h b/libtock/storage/syscalls/sdcard_syscalls.h new file mode 100644 index 000000000..73cb8ea58 --- /dev/null +++ b/libtock/storage/syscalls/sdcard_syscalls.h @@ -0,0 +1,54 @@ +#pragma once + +#include "../../tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_SDCARD 0x50002 + +// Check if an SD Card driver is installed. +bool libtock_sdcard_exists(void); + +// Set a callback function for SD card commands. +returncode_t libtock_sdcard_set_upcall(subscribe_upcall callback, void* opque); + +// Set a buffer that data read from the SD card will be placed into. +returncode_t libtock_sdcard_set_readwrite_allow_read_buffer(uint8_t* buffer, uint32_t len); + +// Set a buffer containing data to write to the SD card. +returncode_t libtock_sdcard_set_readonly_allow_write_buffer(uint8_t* buffer, uint32_t len); + +// Initialize an SD card asynchronously. +// +// Note that for a newly powered-on SD card, initialization can take over 100 ms +// to complete. Expects a callback to have already been set. Callback will be +// called when either initialization is complete or an error occurs. +returncode_t libtock_sdcard_command_initialize(void); + +// Read a single block from an SD card asynchronously. +// +// Expects a read_buffer and a callback to already have been set up. Callback +// will be called when either the block has been read or an error occurs. When +// the callback is successful, data will be in the read_buffer. +// +// ## Arguments +// +// - `sector`: sector address of the block to be read. +returncode_t libtock_sdcard_command_read_block(uint32_t sector); + +// Write a single block to an SD card asynchronously. +// +// Expects a write_buffer and a callback to already have been set up. Data in +// the write_buffer will be written to the SD card. Callback will be called when +// either the block has been written or an error occurs. +// +// ## Arguments +// +// - `sector`: sector address of the block to be written +returncode_t libtock_sdcard_command_write_block(uint32_t sector); + +#ifdef __cplusplus +} +#endif diff --git a/libtock/sys.c b/libtock/sys.c index 790c3fcf6..2c84a5c1f 100644 --- a/libtock/sys.c +++ b/libtock/sys.c @@ -2,7 +2,7 @@ #include #include -#include "console.h" +#include "interface/console.h" #include "tock.h" // XXX Suppress unused parameter warnings for this file as the implementations @@ -40,11 +40,6 @@ int _open(const char* path, int flags, ...) { return -1; } -int _write(int fd, const void *buf, uint32_t count) -{ - putnstr((const char*)buf, count); - return count; -} int _close(int fd) { return -1; diff --git a/libtock/temperature.c b/libtock/temperature.c deleted file mode 100644 index 3da58b414..000000000 --- a/libtock/temperature.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "temperature.h" -#include "tock.h" - -struct data { - bool fired; - int temp; -}; - -static struct data result = { .fired = false }; - -// Internal upcall for faking synchronous reads -static void temp_upcall(int temp, - __attribute__ ((unused)) int unused, - __attribute__ ((unused)) int unused1, - void* ud) { - struct data* data = (struct data*) ud; - data->temp = temp; - data->fired = true; -} - -bool temperature_exists(void) { - return driver_exists(DRIVER_NUM_TEMPERATURE); -} - -int temperature_set_callback(subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_TEMPERATURE, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int temperature_read(void) { - syscall_return_t cval = command(DRIVER_NUM_TEMPERATURE, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int temperature_read_sync(int* temperature) { - int err; - result.fired = false; - - err = temperature_set_callback(temp_upcall, (void*) &result); - if (err < 0) return err; - - err = temperature_read(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *temperature = result.temp; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/temperature.h b/libtock/temperature.h deleted file mode 100644 index 58379ac75..000000000 --- a/libtock/temperature.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_TEMPERATURE 0x60000 - -// check if temperature sensor exists -bool temperature_exists(void); - -// units: temperature in hundredths of degrees centigrade. - -// function to be called when the temperature measurement is finished -// -// callback - pointer to function to be called -// callback_args - pointer to data provided to the callback -int temperature_set_callback (subscribe_upcall callback, void* callback_args); - -// initiate an ambient temperature measurement used both for synchronous and asynchronous readings -int temperature_read(void); - - -// initiate a synchronous ambient temperature measurement -// -// temperature - pointer/address where the result of the temperature reading should be stored -int temperature_read_sync (int* temperature); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/text_screen.c b/libtock/text_screen.c deleted file mode 100644 index 73e210718..000000000 --- a/libtock/text_screen.c +++ /dev/null @@ -1,241 +0,0 @@ -#include "text_screen.h" -#include "tock.h" -#include - -typedef struct { - int error; - int data1; - int data2; - bool done; -} TextScreenReturn; - -static void text_screen_callback(int status, - int data1, - int data2, - void* ud) { - TextScreenReturn *ret = (TextScreenReturn*) ud; - ret->error = tock_status_to_returncode(status); - ret->data1 = data1; - ret->data2 = data2; - ret->done = true; -} - -static uint8_t *buffer = NULL; -static size_t buffer_len = 0; - -static int text_screen_subscribe (subscribe_upcall cb, void *userdata) { - subscribe_return_t sval = subscribe(DRIVER_NUM_TEXT_SCREEN, 0, cb, userdata); - return tock_subscribe_return_to_returncode(sval); -} - -static int text_screen_command (int command_num, int data1, int data2) { - syscall_return_t cval = command(DRIVER_NUM_TEXT_SCREEN, command_num, data1, data2); - return tock_command_return_novalue_to_returncode(cval); -} - -static int text_screen_allow (const void* ptr, size_t size) { - allow_ro_return_t aval = allow_readonly(DRIVER_NUM_TEXT_SCREEN, 0, ptr, size); - return tock_allow_ro_return_to_returncode(aval); -} - -int text_screen_init (size_t len) -{ - int r = RETURNCODE_SUCCESS; - if (buffer != NULL) { - r = RETURNCODE_EALREADY; - } else { - buffer = (uint8_t*) calloc(1, len); - if (buffer != NULL) { - buffer_len = len; - r = text_screen_allow(buffer, len); - } else { - r = RETURNCODE_FAIL; - } - } - return r; -} - -uint8_t* text_screen_buffer (void) -{ - return buffer; -} - -int text_screen_display_on (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(2, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_display_off (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(3, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_blink_on (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(4, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_blink_off (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(5, 0, 0); - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_show_cursor (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(6, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_hide_cursor (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(7, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_clear (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(9, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_home (void) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(10, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_set_cursor (uint8_t col, uint8_t row) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(11, col, row); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_write (size_t len) -{ - TextScreenReturn ret; - ret.done = false; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(8, len, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - return ret.error; -} - -int text_screen_get_size (size_t* width, size_t* height) -{ - TextScreenReturn ret; - ret.done = false; - ret.data1 = 0; - ret.data2 = 0; - - int err = text_screen_subscribe(text_screen_callback, &ret); - if (err < 0) return err; - - err = text_screen_command(1, 0, 0); - if (err < 0) return err; - - yield_for(&ret.done); - - *width = ret.data1; - *height = ret.data2; - - return ret.error; -} diff --git a/libtock/text_screen.h b/libtock/text_screen.h deleted file mode 100644 index ced1e2f00..000000000 --- a/libtock/text_screen.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_TEXT_SCREEN 0x90003 - -int text_screen_init (size_t len); -uint8_t* text_screen_buffer (void); - -int text_screen_display_on (void); -int text_screen_display_off (void); -int text_screen_blink_on (void); -int text_screen_blink_off (void); -int text_screen_show_cursor (void); -int text_screen_hide_cursor (void); -int text_screen_clear (void); -int text_screen_home (void); - -int text_screen_get_size (size_t* width, size_t* height); - -int text_screen_set_cursor (uint8_t col, uint8_t row); -int text_screen_write (size_t len); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/libtock/timer.h b/libtock/timer.h deleted file mode 100644 index 30c8bef5d..000000000 --- a/libtock/timer.h +++ /dev/null @@ -1,100 +0,0 @@ -/** @file timer.h - * @brief Timer function prototypes - * - * The timer module allows the client to receive callbacks when single-shot or - * periodic timers expire. Timers are measured at millisecond granularity, - * regardless of the hardware clock's native frequency. In addition, the - * `delay_ms` function is a blocking call that returns after the given number - * of milliseconds. - * - * # Structures - * - * `tock_timer_t` represents a handle to a timer. - * - * ## Example - * - * static void callback(int now, int interval, int arg2, char* str) { - * printf("%s\n", str); - * } - * - * timer_in(1000, callback, (void*)"1 second elapsed"); - * timer_repeating(2000, callback, (void*)"Another 2 seconds elapsed"); - * - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tock.h" -#include "alarm.h" - -/** \brief Opaque handle to a repeating alarm. - * - * An opaque handle to a repeating alarm created by `alarm_every`. - */ -typedef struct tock_timer { - uint32_t interval; - subscribe_upcall* cb; - void* ud; - alarm_t alarm; -} tock_timer_t; - - - -/** \brief Create a new alarm to fire in `ms` milliseconds. - * - * \param ms the number of milliseconds to fire the alarm after. - * \param callback a callback to be invoked when the alarm expires. - * \param userdata passed to the callback. - * \param A handle to the alarm that was created. - * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. - */ -int timer_in(uint32_t ms, subscribe_upcall, void*, tock_timer_t* timer); - -/** \brief Create a new repeating alarm to fire every `ms` milliseconds. - * - * The `timer` parameter is allocated by the caller and must live as long as - * the timer is outstanding. - * - * \param ms the interval to fire the alarm at in milliseconds. - * \param callback a callback to be invoked when the alarm expires. - * \param userdata passed to the callback. - * \param a pointer to a new tock_timer_t to be used by the implementation to - * keep track of the alarm. - */ -void timer_every(uint32_t ms, subscribe_upcall, void*, tock_timer_t* timer); - -/** \brief Cancels an existing alarm. - * - * \param alarm - */ -void timer_cancel(tock_timer_t*); - -/** \brief Blocks for the given amount of time in millisecond. - * - * This is a blocking version of `alarm_in`. Instead of calling a user - * specified callback, it blocks the current call-stack. - * - * \param ms the number of milliseconds to delay for. - * \return An error code. Either RETURNCODE_SUCCESS or RETURNCODE_FAIL. - */ -int delay_ms(uint32_t ms); - -/** \brief Functions as yield_for with a timeout. - * - * This yields on a condition variable, but will return early - * if that condition is not met before the timeout in milliseconds. - * - * \param cond the condition to yield_for. - * \param ms the amount of time before returning without the condition. - * \return An error code. Either TOCK_SUCCESS or TOCK_FAIL for timeout. - */ -int yield_for_with_timeout(bool* cond, uint32_t ms); - - -#ifdef __cplusplus -} -#endif diff --git a/libtock/touch.c b/libtock/touch.c deleted file mode 100644 index fc1013089..000000000 --- a/libtock/touch.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "touch.h" -#include - -static int touch_subscribe(int subscribe_num, subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_TOUCH, subscribe_num, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -static int touch_allow(int allow_num, void* data, int len) { - allow_rw_return_t aval = allow_readwrite(DRIVER_NUM_TOUCH, allow_num, data, len); - return tock_allow_rw_return_to_returncode(aval); -} - -static touch_t *multi_touch_buffer = NULL; -static unsigned char num_touches = 0; - -static touch_callback *single_touch_upcall = NULL; -static gesture_callback *gesture_upcall = NULL; - -static void touch_single_touch_callback (int status, int xy, int data2 __attribute__((unused)), void *ud) { - if (single_touch_upcall) single_touch_upcall(status, ((unsigned int)xy >> 16), (unsigned int)xy & 0xFFFF, ud); -} - -static void touch_gesture_callback (int gesture, int data1 __attribute__((unused)), int data2 __attribute__( - (unused)), void *ud) { - if (gesture_upcall) gesture_upcall(gesture, ud); -} - -int get_number_of_touches (int* touches) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 100, 0, 0); - return tock_command_return_u32_to_returncode(cval, (uint32_t*) touches); -} - -int enable_single_touch(void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int disable_single_touch(void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 2, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int single_touch_set_callback (touch_callback cb, void* ud) { - single_touch_upcall = cb; - return touch_subscribe(0, cb != NULL ? touch_single_touch_callback : NULL, ud); -} - -int enable_multi_touch(void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 11, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int disable_multi_touch(void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 12, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int multi_touch_set_callback (touch_callback cb, void* ud, int max_touches) { - int err = RETURNCODE_SUCCESS; - if (cb != NULL) { - if (multi_touch_buffer == NULL) { - multi_touch_buffer = (touch_t*)malloc(max_touches * sizeof(touch_t)); - if (multi_touch_buffer) { - num_touches = max_touches; - err = touch_allow(2, multi_touch_buffer, max_touches * sizeof(touch_t)); - if (err == RETURNCODE_SUCCESS) { - err = touch_subscribe(2, cb, ud); - } - if (err != RETURNCODE_SUCCESS) { - free(multi_touch_buffer); - multi_touch_buffer = NULL; - } - } else { - err = RETURNCODE_ENOMEM; - } - } else { - err = RETURNCODE_EALREADY; - } - } else { - if (multi_touch_buffer != NULL) { - num_touches = 0; - touch_allow(2, NULL, 0); - err = touch_subscribe(2, cb, ud); - free(multi_touch_buffer); - multi_touch_buffer = NULL; - } - } - return err; -} - -int gesture_set_callback (gesture_callback cb, void* ud) { - gesture_upcall = cb; - return touch_subscribe(1, cb != NULL ? touch_gesture_callback : NULL, ud); -} - -// get multi touch - -int read_touch (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y) { - if (index < num_touches) { - if (multi_touch_buffer != NULL) { - *id = multi_touch_buffer[index].id; - *status = multi_touch_buffer[index].status; - *x = multi_touch_buffer[index].x; - *y = multi_touch_buffer[index].y; - return RETURNCODE_SUCCESS; - } else { - return RETURNCODE_ENOMEM; - } - } else { - return RETURNCODE_EINVAL; - } -} - -int read_touch_full (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y, - unsigned char *size, unsigned char *pressure) { - if (multi_touch_buffer != NULL) { - int err = read_touch(index, id, status, x, y); - if (err == RETURNCODE_SUCCESS) { - *size = multi_touch_buffer[index].size; - *pressure = multi_touch_buffer[index].pressure; - } - return err; - } else { - return RETURNCODE_ENOMEM; - } -} - -int multi_touch_next (void) { - syscall_return_t cval = command(DRIVER_NUM_TOUCH, 10, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} diff --git a/libtock/touch.h b/libtock/touch.h deleted file mode 100644 index 0e86fa97d..000000000 --- a/libtock/touch.h +++ /dev/null @@ -1,56 +0,0 @@ -// Touch Panel Library - -#pragma once - -#include "tock.h" - -#define DRIVER_NUM_TOUCH 0x90002 - -#define TOUCH_STATUS_RELEASED 0 -#define TOUCH_STATUS_PRESSED 1 -#define TOUCH_STATUS_MOVED 2 -#define TOUCH_STATUS_UNSTARTED 3 - -#define GESTURE_NO 0 -#define GESTURE_SWIPE_UP 1 -#define GESTURE_SWIPE_DOWN 2 -#define GESTURE_SWIPE_LEFT 3 -#define GESTURE_SWIPE_RIGHT 4 -#define GESTURE_ZOOM_IN 5 -#define GESTURE_ZOOM_OUT 6 - -typedef void (touch_callback)(int, int, int, void*); -typedef void (gesture_callback)(int, void*); - -typedef struct __attribute__((__packed__)) { - unsigned char id; - unsigned char status; - unsigned short x; - unsigned short y; - unsigned char size; - unsigned char pressure; -} touch_t; - -// buffer data format -// 0 1 2 4 6 7 8 ... -// +---------+-------------+------------------+------------------+-----------+---------------+--------- ... -// | id (u8) | status (u8) | x (u16) | y (u16) | size (u8) | pressure (u8) | ... -// +---------+-------------+------------------+------------------+-----------+---------------+--------- ... -// | Touch 0 | Touch 1 ... - -int get_number_of_touches (int* touches); - -int enable_single_touch(void); -int disable_single_touch(void); -int single_touch_set_callback (touch_callback cb, void* ud); - -int enable_multi_touch(void); -int disable_multi_touch(void); -int multi_touch_set_callback (touch_callback cb, void* ud, int max_touches); -int gesture_set_callback (gesture_callback cb, void* ud); - -int read_touch (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y); -int read_touch_full (int index, unsigned char *id, unsigned char *status, unsigned short *x, unsigned short *y, unsigned char *size, unsigned char *pressure); - -// Every multi touch event needs to be acked -int multi_touch_next (void); diff --git a/libtock/tsl2561.c b/libtock/tsl2561.c deleted file mode 100644 index 7d076412f..000000000 --- a/libtock/tsl2561.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "tock.h" -#include "tsl2561.h" - -struct tsl2561_data { - bool fired; - int value; -}; - -static struct tsl2561_data result = { .fired = false }; - -// Internal callback for faking synchronous reads -static void tsl2561_upcall(__attribute__ ((unused)) int callback_type, - int value, - __attribute__ ((unused)) int unused2, - void* ud) { - struct tsl2561_data* data = (struct tsl2561_data*) ud; - data->value = value; - data->fired = true; -} - -int tsl2561_set_callback (subscribe_upcall callback, void* callback_args) { - subscribe_return_t sval = subscribe(DRIVER_NUM_TSL2561, 0, callback, callback_args); - return tock_subscribe_return_to_returncode(sval); -} - -int tsl2561_get_lux (void) { - syscall_return_t cval = command(DRIVER_NUM_TSL2561, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int tsl2561_get_lux_sync (int* lux) { - int err; - result.fired = false; - - err = tsl2561_set_callback(tsl2561_upcall, (void*) &result); - if (err < 0) return err; - - err = tsl2561_get_lux(); - if (err < 0) return err; - - // Wait for the callback. - yield_for(&result.fired); - - *lux = result.value; - - return RETURNCODE_SUCCESS; -} diff --git a/libtock/tsl2561.h b/libtock/tsl2561.h deleted file mode 100644 index 597a9088c..000000000 --- a/libtock/tsl2561.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_TSL2561 0x70000 - -int tsl2561_set_callback (subscribe_upcall callback, void* callback_args); -int tsl2561_get_lux (void); - -int tsl2561_get_lux_sync (int* lux); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/udp.c b/libtock/udp.c deleted file mode 100644 index 2210c2536..000000000 --- a/libtock/udp.c +++ /dev/null @@ -1,159 +0,0 @@ -#include - -#include "tock.h" -#include "udp.h" - -const int UDP_DRIVER = 0x30002; - -static const int ALLOW_RX = 0; -static const int ALLOW_RO_TX = 0; -static const int ALLOW_CFG = 1; -static const int ALLOW_RX_CFG = 2; - -static const int SUBSCRIBE_RX = 0; -static const int SUBSCRIBE_TX = 1; - -// COMMAND 0 is driver existence check -static const int COMMAND_GET_IFACES = 1; -static const int COMMAND_SEND = 2; -static const int COMMAND_BIND = 3; -static const int COMMAND_GET_TX_LEN = 4; - -static unsigned char BUF_TX_CFG[2 * sizeof(sock_addr_t)]; -static unsigned char zero_addr[2 * sizeof(sock_addr_t)]; - -int udp_bind(sock_handle_t *handle, sock_addr_t *addr, unsigned char *buf_bind_cfg) { - // Pass interface to listen on and space for kernel to write src addr - // of received packets - // In current design, buf_bind_cfg will still be written with addresses of external - // senders sending addresses to the bound port even if the client application has - // not set up a receive callback on this port. Of course, the client application - // does not have to read these addresses or worry about them. - memcpy(&(handle->addr), addr, sizeof(sock_addr_t)); - int bytes = sizeof(sock_addr_t); - allow_rw_return_t aval = allow_readwrite(UDP_DRIVER, ALLOW_RX_CFG, (void *) buf_bind_cfg, 2 * bytes); - if (!aval.success) return tock_status_to_returncode(aval.status); - - memcpy(buf_bind_cfg + bytes, &(handle->addr), bytes); - - // Set up source address/port pair for sending. Store it in tx_cfg - // Notably, the pair chosen must match the address/port to which the - // app is bound, unless the kernel changes in the future to allow for - // sending from a port to which the app is not bound. - aval = allow_readwrite(UDP_DRIVER, ALLOW_CFG, (void *) BUF_TX_CFG, 2 * bytes); - if (!aval.success) return tock_status_to_returncode(aval.status); - - memcpy(BUF_TX_CFG, &(handle->addr), bytes); - - syscall_return_t cval = command(UDP_DRIVER, COMMAND_BIND, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int udp_close(__attribute__ ((unused)) sock_handle_t *handle) { - int bytes = sizeof(sock_addr_t); - // call allow here to prevent any issues if close is called before bind - // Driver 'closes' when 0 addr is bound to - allow_rw_return_t aval = allow_readwrite(UDP_DRIVER, ALLOW_RX_CFG, (void *) zero_addr, 2 * bytes); - if (!aval.success) return tock_status_to_returncode(aval.status); - - memset(zero_addr, 0, 2 * bytes); - syscall_return_t cval = command(UDP_DRIVER, COMMAND_BIND, 0, 0); - int err = tock_command_return_novalue_to_returncode(cval); - if (err < 0) return err; - - // Remove the callback. - subscribe_return_t sval = subscribe(UDP_DRIVER, SUBSCRIBE_RX, NULL, (void *) NULL); - return tock_subscribe_return_to_returncode(sval); -} - -static int tx_result; -static void tx_done_callback(int status, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void * ud) { - tx_result = tock_status_to_returncode(status); - *((bool *) ud) = true; -} - -ssize_t udp_send_to(void *buf, size_t len, - sock_addr_t *dst_addr) { - // Set dest addr - // NOTE: bind() must be called previously for this to work - // If bind() has not been called, command(COMMAND_SEND) will return RESERVE - int bytes = sizeof(sock_addr_t); - memcpy(BUF_TX_CFG + bytes, dst_addr, bytes); - - // Set message buffer - allow_ro_return_t aval = allow_readonly(UDP_DRIVER, ALLOW_RO_TX, buf, len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - bool tx_done = false; - subscribe_return_t sval = subscribe(UDP_DRIVER, SUBSCRIBE_TX, tx_done_callback, (void *) &tx_done); - if (!sval.success) return tock_status_to_returncode(sval.status); - - syscall_return_t ret = command(UDP_DRIVER, COMMAND_SEND, 0, 0); - if (ret.type == TOCK_SYSCALL_FAILURE) { - return tock_status_to_returncode(ret.data[0]); - } - // ret.val == 1 indicates packet successfully passed to radio synchronously. - // However, wait for send_done to see if tx was successful, then return that result - // ret.val == 0 indicates packet will be sent asynchronously. Thus, 2 callbacks will be received. - // the first callback will indicate if the packet was ultimately passed to the radio succesfully. - // The second callback will only occur if the first callback is SUCCESS - and the second callback - // in this case is the result of the tx itself (as reported by the radio). - // However, it is the case in practice that if the first callback is success, the second callback - // is received before the first callback finishes. Thus, no need to wait for two callbacks in either - // case -- this design just ensures that errors in passing the packet down to the radio will still - // be returned to the sender even when transmission occurs asynchronously. - yield_for(&tx_done); - return tx_result; -} - -static int rx_result; -static void rx_done_callback(int result, - __attribute__ ((unused)) int arg2, - __attribute__ ((unused)) int arg3, - void * ud) { - rx_result = result; - *((bool *) ud) = true; -} - -ssize_t udp_recv_sync(void *buf, size_t len) { - allow_rw_return_t aval = allow_readwrite(UDP_DRIVER, ALLOW_RX, (void *) buf, len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - bool rx_done = false; - subscribe_return_t sval = subscribe(UDP_DRIVER, SUBSCRIBE_RX, rx_done_callback, (void *) &rx_done); - if (!sval.success) return tock_status_to_returncode(sval.status); - - yield_for(&rx_done); - return rx_result; -} - -ssize_t udp_recv(subscribe_upcall callback, void *buf, size_t len) { - - // TODO: verify that this functions returns error if this app is not - // bound to a socket yet. Probably allow should fail..? - - allow_rw_return_t aval = allow_readwrite(UDP_DRIVER, ALLOW_RX, (void *) buf, len); - if (!aval.success) return tock_status_to_returncode(aval.status); - - subscribe_return_t sval = subscribe(UDP_DRIVER, SUBSCRIBE_RX, callback, NULL); - return tock_subscribe_return_to_returncode(sval); -} - -int udp_list_ifaces(ipv6_addr_t *ifaces, size_t len) { - - if (!ifaces) return RETURNCODE_EINVAL; - - allow_rw_return_t aval = allow_readwrite(UDP_DRIVER, ALLOW_CFG, (void *)ifaces, len * sizeof(ipv6_addr_t)); - if (!aval.success) return tock_status_to_returncode(aval.status); - - syscall_return_t cval = command(UDP_DRIVER, COMMAND_GET_IFACES, len, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -int udp_get_max_tx_len(int* length) { - syscall_return_t cval = command(UDP_DRIVER, COMMAND_GET_TX_LEN, 0, 0); - return tock_command_return_u32_to_returncode(cval, (uint32_t*) length); -} diff --git a/libtock/usb.c b/libtock/usb.c deleted file mode 100644 index 261f02832..000000000 --- a/libtock/usb.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "usb.h" - -int usb_exists(void) { - return driver_exists(DRIVER_NUM_USB); -} - -int usb_subscribe(subscribe_upcall upcall, void *ud) { - subscribe_return_t sval = subscribe(DRIVER_NUM_USB, 0, upcall, ud); - return tock_subscribe_return_to_returncode(sval); -} - -int usb_enable_and_attach_async(void) { - syscall_return_t cval = command(DRIVER_NUM_USB, 1, 0, 0); - return tock_command_return_novalue_to_returncode(cval); -} - -struct data { - bool fired; - int rcode; -}; - -static void callback(int status, - __attribute__((unused)) int v1, - __attribute__((unused)) int v2, - void * data) -{ - struct data *d = data; - d->fired = true; - d->rcode = tock_status_to_returncode(status); -} - -int usb_enable_and_attach(void) -{ - int err; - - struct data d = { .fired = false }; - - err = usb_subscribe(callback, (void *) &d); - if (err < 0) return err; - - err = usb_enable_and_attach_async(); - if (err < 0) return err; - - yield_for(&d.fired); - - return d.rcode; -} diff --git a/libtock/usb.h b/libtock/usb.h deleted file mode 100644 index 535f713ba..000000000 --- a/libtock/usb.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_USB 0x20005 - -// Does the driver exist? -int usb_exists(void); - -// Register a callback to receive asynchronous results -// -// The callback will receive these parameters, in order: -// status: SUCCESS if all inputs are valid, else EINVAL -int usb_subscribe(subscribe_upcall, void *); - -// Enable the USB controller and attach to the bus -// -// Returns EINVAL if usb_subscribe() has not previously been called to register a callback. -// Returns SUCCESS if the callback is present and will be used -// to report completion of this operation. -// -int usb_enable_and_attach_async(void); - -int usb_enable_and_attach(void); - -#ifdef __cplusplus -} -#endif diff --git a/libtock/usb_keyboard_hid.h b/libtock/usb_keyboard_hid.h deleted file mode 100644 index 74df82ff4..000000000 --- a/libtock/usb_keyboard_hid.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "tock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DRIVER_NUM_USBKEYBOARDHID 0x90005 - -int usb_keyboard_hid_set_callback(subscribe_upcall callback, void* callback_args); -int usb_keyboard_hid_set_receive_buffer(uint8_t* buffer, uint32_t len); -int usb_keyboard_hid_set_send_buffer(uint8_t* buffer, uint32_t len); -int usb_keyboard_hid_send(void); - -// Send a raw keyboard HID packet. `buffer` must be at least 64 bytes. -int usb_keyboard_hid_send_sync(uint8_t* buffer, uint32_t len); - -// Send one ASCII character -int usb_keyboard_hid_send_letter_sync(char letter); - -// Send an array of ASCII characters -int usb_keyboard_hid_send_string_sync(char* str, int length); - - -#ifdef __cplusplus -} -#endif diff --git a/u8g2/Makefile b/u8g2/Makefile index 0b7899789..6b55615d5 100644 --- a/u8g2/Makefile +++ b/u8g2/Makefile @@ -18,6 +18,7 @@ $(LIBNAME)_SRCS_ALL += $($(LIBNAME)_DIR)/u8g2-tock.c $(LIBNAME)_SRCS := $(filter-out $(LIB_SRC_DIR)/csrc/u8g2_buffer.c,$($(LIBNAME)_SRCS_ALL)) # Need libtock headers +override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR) override CPPFLAGS += -I$(TOCK_USERLAND_BASE_DIR)/libtock override CPPFLAGS += -I$(LIB_SRC_DIR)/csrc diff --git a/u8g2/u8g2-tock.c b/u8g2/u8g2-tock.c index e8c57b502..3c86f7ccd 100644 --- a/u8g2/u8g2-tock.c +++ b/u8g2/u8g2-tock.c @@ -4,26 +4,10 @@ #include -#include +#include #include "u8g2-tock.h" -typedef struct { - int error; - int data1; - int data2; - bool done; -} ScreenReturn; - -// Callback when screen operation finishes. -static void u8g2_callback(int status, int data1, int data2, void* ud) { - ScreenReturn *fbr = (ScreenReturn*) ud; - fbr->error = tock_status_to_returncode(status); - fbr->data1 = data1; - fbr->data2 = data2; - fbr->done = true; -} - // Copy of the page size function from the u8g2_buffer.c file we can't include. static size_t page_size_bytes(u8g2_t* u8g2) { size_t cnt; @@ -72,8 +56,8 @@ static uint8_t u8x8_d_ssd1306_tock(u8x8_t *u8x8, // Update the default display_info with actual information from the // kernel. - size_t width = 0, height = 0; - screen_get_resolution(&width, &height); + uint32_t width = 0, height = 0; + libtock_screen_get_resolution(&width, &height); u8x8_ssd1306_tock.tile_width = width/8; u8x8_ssd1306_tock.tile_height = height/8; u8x8_ssd1306_tock.pixel_width = width; @@ -128,24 +112,10 @@ void u8g2_SendBuffer(u8g2_t *u8g2) { // Set the frame to the entire region. uint16_t width = u8g2_GetU8x8(u8g2)->display_info->pixel_width; uint16_t height = u8g2_GetU8x8(u8g2)->display_info->pixel_height; - screen_set_frame(0, 0, width, height); - - int ret = screen_allow(u8g2->tile_buf_ptr, page_size_bytes(u8g2)); - if (ret != TOCK_STATUSCODE_SUCCESS) return; - - ScreenReturn fbr; - fbr.done = false; - ret = screen_subscribe(u8g2_callback, &fbr); - if (ret != TOCK_STATUSCODE_SUCCESS) return; - - syscall_return_t com = command(DRIVER_NUM_SCREEN, 200, page_size_bytes(u8g2), 0); - ret = tock_command_return_novalue_to_returncode(com); - if (ret == TOCK_STATUSCODE_SUCCESS) { - yield_for(&fbr.done); - ret = fbr.error; - } + libtocksync_screen_set_frame(0, 0, width, height); - screen_allow(NULL, 0); + // Write the data to the screen. + libtocksync_screen_write(u8g2->tile_buf_ptr, page_size_bytes(u8g2), page_size_bytes(u8g2)); } diff --git a/examples/courses/2018-11-SenSys/README.md b/wip/courses/2018-11-SenSys/README.md similarity index 100% rename from examples/courses/2018-11-SenSys/README.md rename to wip/courses/2018-11-SenSys/README.md diff --git a/examples/courses/2018-11-SenSys/important-client/app1/Makefile b/wip/courses/2018-11-SenSys/important-client/app1/Makefile similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app1/Makefile rename to wip/courses/2018-11-SenSys/important-client/app1/Makefile diff --git a/examples/courses/2018-11-SenSys/important-client/app1/README.md b/wip/courses/2018-11-SenSys/important-client/app1/README.md similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app1/README.md rename to wip/courses/2018-11-SenSys/important-client/app1/README.md diff --git a/examples/courses/2018-11-SenSys/important-client/app1/main.c b/wip/courses/2018-11-SenSys/important-client/app1/main.c similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app1/main.c rename to wip/courses/2018-11-SenSys/important-client/app1/main.c diff --git a/examples/courses/2018-11-SenSys/important-client/app2/Makefile b/wip/courses/2018-11-SenSys/important-client/app2/Makefile similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app2/Makefile rename to wip/courses/2018-11-SenSys/important-client/app2/Makefile diff --git a/examples/courses/2018-11-SenSys/important-client/app2/README.md b/wip/courses/2018-11-SenSys/important-client/app2/README.md similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app2/README.md rename to wip/courses/2018-11-SenSys/important-client/app2/README.md diff --git a/examples/courses/2018-11-SenSys/important-client/app2/main.c b/wip/courses/2018-11-SenSys/important-client/app2/main.c similarity index 100% rename from examples/courses/2018-11-SenSys/important-client/app2/main.c rename to wip/courses/2018-11-SenSys/important-client/app2/main.c diff --git a/wip/courses/2018-11-SenSys/sensys_udp_rx/Makefile b/wip/courses/2018-11-SenSys/sensys_udp_rx/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/wip/courses/2018-11-SenSys/sensys_udp_rx/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/courses/2018-11-SenSys/sensys_udp_rx/README.md b/wip/courses/2018-11-SenSys/sensys_udp_rx/README.md similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/README.md rename to wip/courses/2018-11-SenSys/sensys_udp_rx/README.md diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/main.c b/wip/courses/2018-11-SenSys/sensys_udp_rx/main.c similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/main.c rename to wip/courses/2018-11-SenSys/sensys_udp_rx/main.c diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/.gitignore b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/.gitignore similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/.gitignore rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/.gitignore diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/package-lock.json b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/package-lock.json similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/package-lock.json rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/package-lock.json diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/package.json b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/package.json similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/package.json rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/package.json diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/static/index.html b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/static/index.html similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/static/index.html rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/static/index.html diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/static/node.html b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/static/node.html similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/static/node.html rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/static/node.html diff --git a/examples/courses/2018-11-SenSys/sensys_udp_rx/server/stream.js b/wip/courses/2018-11-SenSys/sensys_udp_rx/server/stream.js similarity index 100% rename from examples/courses/2018-11-SenSys/sensys_udp_rx/server/stream.js rename to wip/courses/2018-11-SenSys/sensys_udp_rx/server/stream.js diff --git a/examples/courses/README.md b/wip/courses/README.md similarity index 100% rename from examples/courses/README.md rename to wip/courses/README.md diff --git a/wip/lora/sensor-receive/main.cc b/wip/lora/sensor-receive/main.cc index b08ab86d2..96139ec8b 100644 --- a/wip/lora/sensor-receive/main.cc +++ b/wip/lora/sensor-receive/main.cc @@ -12,10 +12,6 @@ // include the hardware abstraction layer #include "libtockHal.h" -// Include some libtock-c helpers -#include -#include - #define BUFFER_LEN 64 // the entry point for the program diff --git a/wip/lora/sensor-transmit/main.cc b/wip/lora/sensor-transmit/main.cc index 1a1995d71..1319099e7 100644 --- a/wip/lora/sensor-transmit/main.cc +++ b/wip/lora/sensor-transmit/main.cc @@ -13,8 +13,8 @@ #include "libtockHal.h" // Include some libtock-c helpers -#include -#include +#include +#include #define BUFFER_LEN 64 diff --git a/wip/spi/spi_buf/Makefile b/wip/spi/spi_buf/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/wip/spi/spi_buf/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/spi/spi_buf/main.c b/wip/spi/spi_buf/main.c similarity index 100% rename from examples/tests/spi/spi_buf/main.c rename to wip/spi/spi_buf/main.c diff --git a/wip/spi/spi_byte/Makefile b/wip/spi/spi_byte/Makefile new file mode 100644 index 000000000..b9cdd0fa3 --- /dev/null +++ b/wip/spi/spi_byte/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/spi/spi_byte/main.c b/wip/spi/spi_byte/main.c similarity index 100% rename from examples/tests/spi/spi_byte/main.c rename to wip/spi/spi_byte/main.c diff --git a/examples/tests/spi/spi_controller_transfer/Makefile b/wip/spi/spi_controller_transfer/Makefile similarity index 100% rename from examples/tests/spi/spi_controller_transfer/Makefile rename to wip/spi/spi_controller_transfer/Makefile diff --git a/examples/tests/spi/spi_controller_transfer/README.md b/wip/spi/spi_controller_transfer/README.md similarity index 100% rename from examples/tests/spi/spi_controller_transfer/README.md rename to wip/spi/spi_controller_transfer/README.md diff --git a/examples/tests/spi/spi_controller_transfer/main.c b/wip/spi/spi_controller_transfer/main.c similarity index 100% rename from examples/tests/spi/spi_controller_transfer/main.c rename to wip/spi/spi_controller_transfer/main.c diff --git a/examples/tests/spi/spi_peripheral/Makefile b/wip/spi/spi_peripheral/Makefile similarity index 100% rename from examples/tests/spi/spi_peripheral/Makefile rename to wip/spi/spi_peripheral/Makefile diff --git a/examples/tests/spi/spi_peripheral/README.md b/wip/spi/spi_peripheral/README.md similarity index 100% rename from examples/tests/spi/spi_peripheral/README.md rename to wip/spi/spi_peripheral/README.md diff --git a/examples/tests/spi/spi_peripheral/main.c b/wip/spi/spi_peripheral/main.c similarity index 100% rename from examples/tests/spi/spi_peripheral/main.c rename to wip/spi/spi_peripheral/main.c diff --git a/examples/tests/spi/spi_peripheral_transfer/Makefile b/wip/spi/spi_peripheral_transfer/Makefile similarity index 100% rename from examples/tests/spi/spi_peripheral_transfer/Makefile rename to wip/spi/spi_peripheral_transfer/Makefile diff --git a/examples/tests/spi/spi_peripheral_transfer/README.md b/wip/spi/spi_peripheral_transfer/README.md similarity index 100% rename from examples/tests/spi/spi_peripheral_transfer/README.md rename to wip/spi/spi_peripheral_transfer/README.md diff --git a/examples/tests/spi/spi_peripheral_transfer/main.c b/wip/spi/spi_peripheral_transfer/main.c similarity index 100% rename from examples/tests/spi/spi_peripheral_transfer/main.c rename to wip/spi/spi_peripheral_transfer/main.c