diff --git a/examples/tests/qdec_callback/Makefile b/examples/tests/qdec_callback/Makefile new file mode 100644 index 000000000..54d6a7969 --- /dev/null +++ b/examples/tests/qdec_callback/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/qdec_callback/README.md b/examples/tests/qdec_callback/README.md new file mode 100644 index 000000000..64684509a --- /dev/null +++ b/examples/tests/qdec_callback/README.md @@ -0,0 +1,35 @@ +QDEC Callback Test + +This test's purposed is to ensure the interrupts work +as expected and the callbacks work as expected every +time the QDEC is rotated. + +To verify the test is working properly, fire up the QDEC +timer program, and without touching the encoder, you should +see the following initial statements (If anything else is printed, +that is a signal that there was an error when setting up the QDEC): + +'Starting The [QDEC] Test App for Callbacks +QDEC has been fully initiated!' + +Then, turning the QDEC in the positive direction +one click will invoke the callback method and a new statment will +be printed: + +QDEC Absolute Position: 1 +QDEC Absolute Position: 2 +QDEC Absolute Position: 3 +QDEC Absolute Position: 4 + +Similarly, turning the QDEC in the negative direction (from the initial +starting location) one click will invoke the callback method and a new +statment will be printed: + +QDEC Absolute Position: -1 +QDEC Absolute Position: -2 +QDEC Absolute Position: -3 +QDEC Absolute Position: -4 + +These are good initial tests to ensure the QDEC is working as expected. +Continue the QDEC in both directions and see if the progression of values +displayed on the screen are logical. diff --git a/examples/tests/qdec_callback/main.c b/examples/tests/qdec_callback/main.c new file mode 100644 index 000000000..9ff890459 --- /dev/null +++ b/examples/tests/qdec_callback/main.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +static void qdec_callback(int qdec_num, + __attribute__ ((unused)) int val, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void *ud) { + printf("QDEC Absolute Position: %d\n", qdec_num); +} + +int main(void) { + printf("Starting The [QDEC] Test App for Callbacks\n"); + if (!qdec_exists()) { + printf("No QDEC driver\n"); + return -1; + } + qdec_enable(); + if (qdec_subscribe(qdec_callback, NULL) != 0) { + printf("Can't subscribe to interrupt results!"); + return -1; + } + if (!qdec_interrupt_enable()) { + printf("Can't enable interrupts!\n"); + return -1; + } + printf("QDEC has been fully initiated!\n"); + return 0; +} diff --git a/examples/tests/qdec_timer/Makefile b/examples/tests/qdec_timer/Makefile new file mode 100644 index 000000000..54d6a7969 --- /dev/null +++ b/examples/tests/qdec_timer/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/qdec_timer/README.md b/examples/tests/qdec_timer/README.md new file mode 100644 index 000000000..04780af0f --- /dev/null +++ b/examples/tests/qdec_timer/README.md @@ -0,0 +1,16 @@ +QDEC Timer Test + +This test's purposed is to ensure the interrupts work +as expected and the approximately correct displacement +is being returned with each fire of the timer. + +To verify the test is working properly, fire up the QDEC +timer program, and without touching the encoder, you should +see the statement 'Displacement val: 0' print on the screen +every 500 seconds. Turning the QDEC in the positive direction +one click will change the print statement to 'Displacement +val: 4' for one timer fired instance and then return back to +'Displacement val: 0'. Similarly, turning it in the negative +direction one click will change the print statement to +'Displacement val: -4' for one timer fired instance and then +return back to 'Displacement val: 0'. diff --git a/examples/tests/qdec_timer/main.c b/examples/tests/qdec_timer/main.c new file mode 100644 index 000000000..59006cd7d --- /dev/null +++ b/examples/tests/qdec_timer/main.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +static void timer_fired ( __attribute__ ((unused)) int arg0, + __attribute__ ((unused)) int arg1, + __attribute__ ((unused)) int arg2, + __attribute__ ((unused)) void *ud) { + int qdec_num = qdec_displacement(); + printf("Displacement val: %d\n", qdec_num); +} + +int main(void) { + printf("Starting The [QDEC] Test App for Timers\n"); + if (!qdec_exists()) { + printf("No QDEC driver\n"); + return -1; + } + qdec_enable(); + if (!qdec_interrupt_enable()) { + printf("Can't enable interrupts!\n"); + return -1; + } + printf("QDEC has been fully initiated!\n"); + static tock_timer_t timer; + timer_every(500, timer_fired, NULL, &timer); + printf("Timer set!\n"); + return 0; +} diff --git a/libtock/qdec.c b/libtock/qdec.c new file mode 100644 index 000000000..9ea5f765e --- /dev/null +++ b/libtock/qdec.c @@ -0,0 +1,25 @@ +#include "qdec.h" + +bool qdec_exists(void) { + return command(DRIVER_NUM_QDEC, 0, 0, 0) >= 0; +} + +bool qdec_enable(void) { + return command(DRIVER_NUM_QDEC, 1, 0, 0) >= 0; +} + +bool qdec_disable(void) { + return command(DRIVER_NUM_QDEC, 2, 0, 0) >= 0; +} + +bool qdec_interrupt_enable(void) { + return command(DRIVER_NUM_QDEC, 3, 0, 0) >= 0; +} + +int qdec_subscribe(subscribe_cb callback, void* callback_args) { + return subscribe(DRIVER_NUM_QDEC, 0, callback, callback_args); +} + +int qdec_displacement(void) { + return command(DRIVER_NUM_QDEC, 4, 0, 0); +} diff --git a/libtock/qdec.h b/libtock/qdec.h new file mode 100644 index 000000000..73ce58c81 --- /dev/null +++ b/libtock/qdec.h @@ -0,0 +1,37 @@ +/** + * Quadrature Decoder (QDEC) + * + * A QDEC provides buffered decoding of quadrature-encoded signals. It is suitable + * for mechanical and optical sensors. + * + * Use for the QDEC would be hooking up a rotary encoder or other optical encoder to + * the respective ports and using the below series of function to decode the signals + * sent by the encoders and turn them into useful metrics (i.e. displacement) + * + */ +#pragma once + +#include "tock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRIVER_NUM_QDEC 0x90003 + +/*Verifies the existence of the QDEC*/ +bool qdec_exists(void); +/*Enables the QDEC*/ +bool qdec_enable(void); +/*Disables the QDEC*/ +bool qdec_disable(void); +/*Enables QDEC interrupts needed to get displacement values*/ +bool qdec_interrupt_enable(void); +/*Subscribes the app to QDEC interrupt calls*/ +int qdec_subscribe(subscribe_cb callback, void* callback_args); +/*Gets the displacement of the QDEC from its last stopped position*/ +int qdec_displacement(void); + +#ifdef __cplusplus +} +#endif