mirror of
https://github.com/demik/quack.git
synced 2025-01-13 12:31:48 +00:00
Quadrature and Bluetooth tinkering
This commit is contained in:
parent
4375cc43d4
commit
a878a80bc0
@ -3,7 +3,8 @@ set(srcs "adb.c"
|
|||||||
"esp_hid_gap.c"
|
"esp_hid_gap.c"
|
||||||
"gpio.c"
|
"gpio.c"
|
||||||
"led.c"
|
"led.c"
|
||||||
"main.c")
|
"main.c"
|
||||||
|
"quad.c")
|
||||||
|
|
||||||
set(include_dirs ".")
|
set(include_dirs ".")
|
||||||
|
|
||||||
|
10
main/adb.c
10
main/adb.c
@ -65,14 +65,15 @@ void adb_init(void) {
|
|||||||
|
|
||||||
/* If jumper is set, switch to ADB host mode */
|
/* If jumper is set, switch to ADB host mode */
|
||||||
if (gpio_get_level(GPIO_ADBSRC) == 0)
|
if (gpio_get_level(GPIO_ADBSRC) == 0)
|
||||||
xTaskCreatePinnedToCore(&adb_task_host, "ADB_HOST", 6 * 1024, NULL, tskADB_PRIORITY, NULL, 1);
|
xTaskCreatePinnedToCore(adb_task_host, "ADB_HOST", 6 * 1024, NULL, tskADB_PRIORITY, NULL, 1);
|
||||||
else
|
else
|
||||||
xTaskCreatePinnedToCore(&adb_task_mouse, "ADB_MOUSE", 6 * 1024, NULL, tskADB_PRIORITY, NULL, 1);
|
xTaskCreatePinnedToCore(adb_task_mouse, "ADB_MOUSE", 6 * 1024, NULL, tskADB_PRIORITY, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adb_task_host(void *pvParameters) {
|
void adb_task_host(void *pvParameters) {
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
|
|
||||||
|
/* put green led to steady if BT is disabled. Otherwise BT init will do it */
|
||||||
if (gpio_get_level(GPIO_BTOFF) == 0)
|
if (gpio_get_level(GPIO_BTOFF) == 0)
|
||||||
xTaskNotify(t_green, LED_ON, eSetValueWithOverwrite);
|
xTaskNotify(t_green, LED_ON, eSetValueWithOverwrite);
|
||||||
ESP_LOGI("ADB", "ADB host started");
|
ESP_LOGI("ADB", "ADB host started");
|
||||||
@ -80,7 +81,7 @@ void adb_task_host(void *pvParameters) {
|
|||||||
/* poll the mouse like a maniac. It will answer only if there is user input */
|
/* poll the mouse like a maniac. It will answer only if there is user input */
|
||||||
ESP_ERROR_CHECK(rmt_driver_install(RMT_RX_CHANNEL, 200, 0));
|
ESP_ERROR_CHECK(rmt_driver_install(RMT_RX_CHANNEL, 200, 0));
|
||||||
|
|
||||||
while (1) {
|
while (true) {
|
||||||
vTaskDelay(20 / portTICK_PERIOD_MS);
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||||
adb_tx_cmd(ADB_MOUSE|ADB_TALK|ADB_REG0);
|
adb_tx_cmd(ADB_MOUSE|ADB_TALK|ADB_REG0);
|
||||||
data = adb_rx_mouse();
|
data = adb_rx_mouse();
|
||||||
@ -88,7 +89,8 @@ void adb_task_host(void *pvParameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void adb_task_mouse(void *pvParameters) {
|
void adb_task_mouse(void *pvParameters) {
|
||||||
|
ESP_LOGI("ADB", "ADB mouse started");
|
||||||
|
vTaskSuspend(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dur( uint32_t level, uint32_t duration ) {
|
int dur( uint32_t level, uint32_t duration ) {
|
||||||
|
113
main/blue.c
113
main/blue.c
@ -39,6 +39,10 @@
|
|||||||
/* debug tag */
|
/* debug tag */
|
||||||
static const char *TAG = "blue";
|
static const char *TAG = "blue";
|
||||||
|
|
||||||
|
/* private functions */
|
||||||
|
static esp_hid_raw_report_map_t *blue_hid_rm_get(esp_hidh_dev_t *dev);
|
||||||
|
static esp_hid_report_item_t blue_hid_ri_find(esp_hidh_dev_t *d, esp_hid_usage_t u, uint8_t t, uint8_t p);
|
||||||
|
|
||||||
void hidh_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data)
|
void hidh_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data)
|
||||||
{
|
{
|
||||||
esp_hidh_event_t event = (esp_hidh_event_t)id;
|
esp_hidh_event_t event = (esp_hidh_event_t)id;
|
||||||
@ -142,14 +146,15 @@ void blue_init(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(esp_hidh_init(&config));
|
ESP_ERROR_CHECK(esp_hidh_init(&config));
|
||||||
|
esp_log_level_set("event", ESP_LOG_INFO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* at this point, everything but bluetooth is started.
|
* at this point, everything but bluetooth is started.
|
||||||
* put green steady, start blinking blue and keep scanning until a device is found
|
* put green steady, start blinking blue and keep scanning until a device is found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
xTaskNotify(t_green, LED_ON, eSetValueWithOverwrite);
|
xTaskNotify(t_green, LED_ON, eSetValueWithOverwrite);
|
||||||
xTaskNotify(t_blue, LED_SLOW, eSetValueWithOverwrite);
|
xTaskNotify(t_blue, LED_FAST, eSetValueWithOverwrite);
|
||||||
xTaskCreatePinnedToCore(blue_scan, "blue_scan", 6 * 1024, NULL, 2, NULL, 0);
|
xTaskCreatePinnedToCore(blue_scan, "blue_scan", 6 * 1024, NULL, 2, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,38 +163,85 @@ void blue_close(esp_hidh_event_data_t *p) {
|
|||||||
|
|
||||||
configASSERT(p != NULL);
|
configASSERT(p != NULL);
|
||||||
bda = esp_hidh_dev_bda_get(p->close.dev);
|
bda = esp_hidh_dev_bda_get(p->close.dev);
|
||||||
ESP_LOGI(TAG, "closed connection with device " ESP_BD_ADDR_STR ", reason: %s", ESP_BD_ADDR_HEX(bda),
|
ESP_LOGI(TAG, "closed connection with device " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(bda));
|
||||||
esp_hid_disconnect_reason_str(esp_hidh_dev_transport_get(p->close.dev), p->close.reason));
|
|
||||||
esp_hidh_dev_free(p->close.dev);
|
esp_hidh_dev_free(p->close.dev);
|
||||||
|
|
||||||
xTaskNotify(t_blue, LED_SLOW, eSetValueWithOverwrite);
|
xTaskNotify(t_blue, LED_SLOW, eSetValueWithOverwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blue_open(esp_hidh_event_data_t *p) {
|
void blue_open(esp_hidh_event_data_t *p) {
|
||||||
const uint8_t *bda = NULL;
|
const uint8_t *bda = NULL;
|
||||||
|
|
||||||
|
esp_hid_report_item_t mir; /* MOUSE INPUT REPORT */
|
||||||
|
|
||||||
configASSERT(p != NULL);
|
configASSERT(p != NULL);
|
||||||
bda = esp_hidh_dev_bda_get(p->open.dev);
|
bda = esp_hidh_dev_bda_get(p->open.dev);
|
||||||
ESP_LOGI(TAG, "opened connection with " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(bda));
|
ESP_LOGI(TAG, "opened connection with " ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX(bda));
|
||||||
|
|
||||||
//fprintf(fp, "BDA:" ESP_BD_ADDR_STR ", Status: %s, Connected: %s, Handle: %d, Usage: %s\n", ESP_BD_ADDR_HEX(dev->bda), s_bta_hh_status_names[dev->status], dev->connected ? "YES" : "NO", dev->bt.handle, esp_hid_usage_str(dev->usage));
|
/* search for MIR section */
|
||||||
|
esp_hid_raw_report_map_t *maps;
|
||||||
|
maps = blue_hid_rm_get(p->open.dev);
|
||||||
|
mir = blue_hid_ri_find(p->open.dev, ESP_HID_USAGE_MOUSE, ESP_HID_REPORT_TYPE_INPUT, ESP_HID_PROTOCOL_MODE_REPORT);
|
||||||
|
|
||||||
//ESP_LOGI(TAG, "opened connection with "
|
|
||||||
// ESP_LOGI(TAG, "PID: 0x%04x, VID: 0x%04x, VERSION: 0x%04x\n", p->open.dev->config.product_id, p->open.dev->config.vendor_id, p->open.dev->config.version);
|
|
||||||
//fprintf(fp, "Report Map Length: %d\n", dev->config.report_maps[0].len);
|
|
||||||
|
|
||||||
//esp_hidh_dev_report_t *report = dev->reports;
|
|
||||||
//while (report) {
|
|
||||||
// fprintf(fp, " %8s %7s %6s, ID: %3u, Length: %3u\n",
|
|
||||||
// esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), esp_hid_protocol_mode_str(report->protocol_mode),
|
|
||||||
// report->report_id, report->value_len);
|
|
||||||
// report = report->next;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// (p->open.dev, stdout);
|
|
||||||
xTaskNotify(t_blue, LED_ON, eSetValueWithOverwrite);
|
xTaskNotify(t_blue, LED_ON, eSetValueWithOverwrite);
|
||||||
gpio_output_enable();
|
gpio_output_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get specific report from report map matching specified usage + type + protocol */
|
||||||
|
static esp_hid_report_item_t blue_hid_ri_find(esp_hidh_dev_t *d, esp_hid_usage_t u, uint8_t t, uint8_t p) {
|
||||||
|
size_t num_reports = 0;
|
||||||
|
esp_hid_report_item_t *reports;
|
||||||
|
esp_hid_report_item_t search;
|
||||||
|
|
||||||
|
configASSERT(d != NULL);
|
||||||
|
configASSERT(p <= ESP_HID_REPORT_TYPE_FEATURE);
|
||||||
|
configASSERT(t > 0);
|
||||||
|
|
||||||
|
esp_hidh_dev_reports_get(d, &num_reports, &reports);
|
||||||
|
memset(&search, 0, sizeof(esp_hid_report_item_t));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < num_reports; i++) {
|
||||||
|
if (reports[i].protocol_mode == p && reports[i].report_type == t && reports[i].usage == u) {
|
||||||
|
memcpy(&search, &reports[i], sizeof(esp_hid_report_item_t));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(reports);
|
||||||
|
if (search.value_len == 0) {
|
||||||
|
ESP_LOGW(TAG, "%s %s %s not found",
|
||||||
|
esp_hid_usage_str(u),
|
||||||
|
esp_hid_report_type_str(t),
|
||||||
|
esp_hid_protocol_mode_str(p));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGD(TAG, "%s %s %s is id %i size %i byte(s)",
|
||||||
|
esp_hid_usage_str(u),
|
||||||
|
esp_hid_report_type_str(t),
|
||||||
|
esp_hid_protocol_mode_str(p),
|
||||||
|
search.report_id,
|
||||||
|
search.value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get report map raw pointer. Also dump it on JTAG */
|
||||||
|
static esp_hid_raw_report_map_t *blue_hid_rm_get(esp_hidh_dev_t *dev) {
|
||||||
|
size_t num_maps = 0;
|
||||||
|
esp_hid_raw_report_map_t *maps;
|
||||||
|
|
||||||
|
configASSERT(dev != NULL);
|
||||||
|
ESP_LOGI(TAG, BLUE_SNIP);
|
||||||
|
esp_hidh_dev_report_maps_get(dev, &num_maps, &maps);
|
||||||
|
ESP_LOG_BUFFER_HEX(TAG, maps[0].data, maps[0].len);
|
||||||
|
ESP_LOGI(TAG, BLUE_SNIP);
|
||||||
|
|
||||||
|
/* looking at 4.2 SDK source, seems there is always only one map */
|
||||||
|
configASSERT(num_maps == 1);
|
||||||
|
return maps;
|
||||||
|
}
|
||||||
|
|
||||||
void blue_scan(void *pvParameters) {
|
void blue_scan(void *pvParameters) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
esp_hid_scan_result_t *mouse = NULL;
|
esp_hid_scan_result_t *mouse = NULL;
|
||||||
@ -198,28 +250,27 @@ void blue_scan(void *pvParameters) {
|
|||||||
ESP_LOGI(TAG, "starting scan on core %d…", xPortGetCoreID());
|
ESP_LOGI(TAG, "starting scan on core %d…", xPortGetCoreID());
|
||||||
esp_hid_scan(BLUE_SCAN_DURATION, &len, &results);
|
esp_hid_scan(BLUE_SCAN_DURATION, &len, &results);
|
||||||
ESP_LOGI(TAG, "scan returned %u result(s)", len);
|
ESP_LOGI(TAG, "scan returned %u result(s)", len);
|
||||||
|
xTaskNotify(t_blue, LED_SLOW, eSetValueWithOverwrite);
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
esp_hid_scan_result_t *r = results;
|
esp_hid_scan_result_t *r = results;
|
||||||
|
|
||||||
while (r) {
|
while (r) {
|
||||||
ESP_LOGI(TAG, "found %s device: " ESP_BD_ADDR_STR ", RSSI: %d, NAME: %s",
|
ESP_LOGI(TAG, "found %s %s device: " ESP_BD_ADDR_STR ", RSSI: %d, NAME: %s",
|
||||||
(r->transport == ESP_HID_TRANSPORT_BLE) ? "BLE" : "BT",
|
(r->transport == ESP_HID_TRANSPORT_BLE) ? "BLE" : "BT",
|
||||||
ESP_BD_ADDR_HEX(r->bda), r->rssi, r->name ? r->name : "");
|
esp_hid_cod_major_str(r->bt.cod.major),
|
||||||
|
ESP_BD_ADDR_HEX(r->bda), r->rssi, r->name ? r->name : "");
|
||||||
if (r->transport == ESP_HID_TRANSPORT_BLE) {
|
|
||||||
printf("APPEARANCE: 0x%04x, ", r->ble.appearance);
|
/* search for something that looks like Bluetooth Classic mouse */
|
||||||
printf("ADDR_TYPE: '%s', ", ble_addr_type_str(r->ble.addr_type));
|
if (r->transport == ESP_HID_TRANSPORT_BT &&
|
||||||
} else {
|
strcmp("PERIPHERAL", esp_hid_cod_major_str(r->bt.cod.major)) == 0
|
||||||
if (strcmp("PERIPHERAL", esp_hid_cod_major_str(r->bt.cod.major)) == 0
|
&& (r->bt.cod.minor & ESP_HID_COD_MIN_MOUSE)) {
|
||||||
&& (r->bt.cod.minor & ESP_HID_COD_MIN_MOUSE)) {
|
|
||||||
ESP_LOGI(TAG, "found generic mouse");
|
|
||||||
mouse = r;
|
mouse = r;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
r = r->next;
|
r = r->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to connect to the last mouse found
|
/* try to connect to the last candidate found */
|
||||||
if (mouse)
|
if (mouse)
|
||||||
esp_hidh_dev_open(mouse->bda, mouse->transport, mouse->ble.addr_type);
|
esp_hidh_dev_open(mouse->bda, mouse->transport, mouse->ble.addr_type);
|
||||||
else
|
else
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
/* defines */
|
/* defines */
|
||||||
#define BLUE_SCAN_DURATION 8
|
#define BLUE_SCAN_DURATION 8
|
||||||
|
#define BLUE_SNIP "---8<------------------------------------------"
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
void blue_init(void);
|
void blue_init(void);
|
||||||
|
@ -72,10 +72,6 @@ void gpio_init(void) {
|
|||||||
gpio_set_direction(GPIO_QX2, GPIO_MODE_OUTPUT);
|
gpio_set_direction(GPIO_QX2, GPIO_MODE_OUTPUT);
|
||||||
gpio_set_direction(GPIO_QY1, GPIO_MODE_OUTPUT);
|
gpio_set_direction(GPIO_QY1, GPIO_MODE_OUTPUT);
|
||||||
gpio_set_direction(GPIO_QY2, GPIO_MODE_OUTPUT);
|
gpio_set_direction(GPIO_QY2, GPIO_MODE_OUTPUT);
|
||||||
|
|
||||||
gpio_set_level(GPIO_CLICK, 1);
|
|
||||||
gpio_set_level(GPIO_QY1, 1);
|
|
||||||
gpio_set_level(GPIO_QY2, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_output_disable(void) {
|
void gpio_output_disable(void) {
|
||||||
|
11
main/main.c
11
main/main.c
@ -36,6 +36,7 @@
|
|||||||
#include "blue.h"
|
#include "blue.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
#include "quad.h"
|
||||||
|
|
||||||
/* global TAG for ESP_LOG */
|
/* global TAG for ESP_LOG */
|
||||||
static const char* TAG = "quack";
|
static const char* TAG = "quack";
|
||||||
@ -56,23 +57,27 @@ void app_main(void)
|
|||||||
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
|
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Minimum free heap size: %d bytes", esp_get_minimum_free_heap_size());
|
ESP_LOGI(TAG, "Minimum free heap size: %d bytes", esp_get_minimum_free_heap_size());
|
||||||
|
ESP_LOGI(TAG, "");
|
||||||
|
ESP_LOGI(TAG, "\\_o< \\_o< \\_o< \\_O<");
|
||||||
|
ESP_LOGI(TAG, "");
|
||||||
|
|
||||||
gpio_init();
|
gpio_init();
|
||||||
led_init();
|
led_init();
|
||||||
|
quad_init();
|
||||||
adb_init();
|
adb_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check /BTOFF and enable bluetooth if needed
|
* Check /BTOFF and enable bluetooth if needed
|
||||||
* of bluetooth is disabled, enable ADB and Quadrature outputs
|
* of bluetooth is disabled, enable quadrature outputs
|
||||||
*/
|
*/
|
||||||
if (gpio_get_level(GPIO_BTOFF) == 1)
|
if (gpio_get_level(GPIO_BTOFF) == 1)
|
||||||
blue_init();
|
blue_init();
|
||||||
else
|
else
|
||||||
gpio_output_enable();
|
gpio_output_enable();
|
||||||
|
|
||||||
/* Blink error if no inputs (/BTOFF and no /ADBSRC) */
|
/* put LED error ON if no inputs (/BTOFF and no /ADBSRC) */
|
||||||
if (gpio_get_level(GPIO_BTOFF) == 0 && gpio_get_level(GPIO_ADBSRC) == 1) {
|
if (gpio_get_level(GPIO_BTOFF) == 0 && gpio_get_level(GPIO_ADBSRC) == 1) {
|
||||||
ESP_LOGE(TAG, "Bluetooth is off and ADB is in device mode!");
|
ESP_LOGE(TAG, "Bluetooth is off and ADB is in device mode!");
|
||||||
xTaskNotify(t_red, LED_SLOW, eSetValueWithOverwrite);
|
xTaskNotify(t_red, LED_ON, eSetValueWithOverwrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
177
main/quad.c
Normal file
177
main/quad.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* quad.c
|
||||||
|
* quack
|
||||||
|
*
|
||||||
|
* Created by Michel DEPEIGE on 17/04/2021.
|
||||||
|
* Copyright (c) 2021 Michel DEPEIGE.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program (see the file COPYING); if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "driver/timer.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
|
||||||
|
#include "quad.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* global variables for tasks handles */
|
||||||
|
TaskHandle_t t_click, t_qx, t_qy;
|
||||||
|
esp_timer_handle_t quad_qx, quad_qy;
|
||||||
|
|
||||||
|
/* static functions */
|
||||||
|
static void quad_timer(void* arg);
|
||||||
|
|
||||||
|
/* phases */
|
||||||
|
const bool q1[] = {true, false, false, true};
|
||||||
|
const bool q2[] = {true, true, false, false};
|
||||||
|
|
||||||
|
/* init all leds, blink everything once and start background tasks */
|
||||||
|
void quad_init(void) {
|
||||||
|
esp_timer_create_args_t args;
|
||||||
|
|
||||||
|
/* create quadrature tasks */
|
||||||
|
xTaskCreate(quad_click, "CLICK", 1024, NULL, tskIDLE_PRIORITY + 1, &t_click);
|
||||||
|
xTaskCreate(quad_move_x, "QX", 1024, NULL, tskIDLE_PRIORITY + 1, &t_qx);
|
||||||
|
xTaskCreate(quad_move_y, "QY", 1024, NULL, tskIDLE_PRIORITY + 1, &t_qy);
|
||||||
|
|
||||||
|
/* click is active low */
|
||||||
|
gpio_set_level(GPIO_CLICK, 1);
|
||||||
|
|
||||||
|
/* init quadrature position */
|
||||||
|
gpio_set_level(GPIO_QX1, q1[0]);
|
||||||
|
gpio_set_level(GPIO_QX2, q2[0]);
|
||||||
|
gpio_set_level(GPIO_QY1, q1[0]);
|
||||||
|
gpio_set_level(GPIO_QY2, q2[0]);
|
||||||
|
|
||||||
|
/* create timers for quadrature phases */
|
||||||
|
args.callback = &quad_timer;
|
||||||
|
args.arg = &t_qx;
|
||||||
|
args.name = "quad_qx";
|
||||||
|
ESP_ERROR_CHECK(esp_timer_create(&args, &quad_qx));
|
||||||
|
args.callback = &quad_timer;
|
||||||
|
args.arg = &t_qy;
|
||||||
|
args.name = "quad_qy";
|
||||||
|
ESP_ERROR_CHECK(esp_timer_create(&args, &quad_qy));
|
||||||
|
|
||||||
|
ESP_LOGI("quad", "Quadrature tasks started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void quad_click(void *pvParameters) {
|
||||||
|
unsigned int click = 0;
|
||||||
|
|
||||||
|
(void)pvParameters;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
xTaskNotifyWait(0, 0, &click, portMAX_DELAY);
|
||||||
|
switch (click)
|
||||||
|
{
|
||||||
|
case true:
|
||||||
|
gpio_set_level(GPIO_CLICK, 0);
|
||||||
|
break;
|
||||||
|
case false:
|
||||||
|
gpio_set_level(GPIO_CLICK, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void quad_move_x(void *pvParameters) {
|
||||||
|
unsigned int value = 0;
|
||||||
|
int move = 0;
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
(void)pvParameters;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
xTaskNotifyWait(0, 0, &value, portMAX_DELAY);
|
||||||
|
assert(value != 0);
|
||||||
|
move = (signed)value;
|
||||||
|
|
||||||
|
if (move > 0) {
|
||||||
|
while (move--) {
|
||||||
|
i++;
|
||||||
|
gpio_set_level(GPIO_QX1, q1[i % 4]);
|
||||||
|
gpio_set_level(GPIO_QX2, q2[i % 4]);
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_once(quad_qx, QUAD_INTERVAL));
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (move++) {
|
||||||
|
i--;
|
||||||
|
gpio_set_level(GPIO_QX1, q1[i % 4]);
|
||||||
|
gpio_set_level(GPIO_QX2, q2[i % 4]);
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_once(quad_qx, QUAD_INTERVAL));
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void quad_move_y(void *pvParameters) {
|
||||||
|
unsigned int value = 0;
|
||||||
|
int move = 0;
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
(void)pvParameters;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
xTaskNotifyWait(0, 0, &value, portMAX_DELAY);
|
||||||
|
assert(value != 0);
|
||||||
|
move = (signed)value;
|
||||||
|
|
||||||
|
if (move > 0) {
|
||||||
|
while (move--) {
|
||||||
|
i++;
|
||||||
|
gpio_set_level(GPIO_QY1, q1[i % 4]);
|
||||||
|
gpio_set_level(GPIO_QY2, q2[i % 4]);
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_once(quad_qy, QUAD_INTERVAL));
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (move++) {
|
||||||
|
i--;
|
||||||
|
gpio_set_level(GPIO_QY1, q1[i % 4]);
|
||||||
|
gpio_set_level(GPIO_QY2, q2[i % 4]);
|
||||||
|
ESP_ERROR_CHECK(esp_timer_start_once(quad_qy, QUAD_INTERVAL));
|
||||||
|
vTaskSuspend(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* simple ISR function. Resume task that called the oneshot timer */
|
||||||
|
static void quad_timer(void* arg) {
|
||||||
|
BaseType_t xYieldRequired = pdFALSE;
|
||||||
|
|
||||||
|
xYieldRequired = xTaskResumeFromISR(arg);
|
||||||
|
|
||||||
|
/* switch context of needed */
|
||||||
|
if( xYieldRequired == pdTRUE )
|
||||||
|
portYIELD_FROM_ISR();
|
||||||
|
}
|
38
main/quad.h
Normal file
38
main/quad.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* quad.h
|
||||||
|
* quack
|
||||||
|
*
|
||||||
|
* Created by Michel DEPEIGE on 17/01/2021.
|
||||||
|
* Copyright (c) 2021 Michel DEPEIGE.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program (see the file COPYING); if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUAD_H
|
||||||
|
#define QUAD_H
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
void quad_init(void);
|
||||||
|
void quad_click(void *pvParameters);
|
||||||
|
void quad_move_x(void *pvParameters);
|
||||||
|
void quad_move_y(void *pvParameters);
|
||||||
|
|
||||||
|
/* defines */
|
||||||
|
#define QUAD_INTERVAL 100
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -842,10 +842,10 @@ CONFIG_HEAP_TRACING_OFF=y
|
|||||||
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
||||||
CONFIG_LOG_DEFAULT_LEVEL_INFO=y
|
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
|
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
||||||
CONFIG_LOG_DEFAULT_LEVEL=3
|
CONFIG_LOG_DEFAULT_LEVEL=4
|
||||||
CONFIG_LOG_COLORS=y
|
CONFIG_LOG_COLORS=y
|
||||||
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
||||||
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
||||||
|
Loading…
x
Reference in New Issue
Block a user