1
0
mirror of https://github.com/whowechina/iidx_pico.git synced 2024-11-24 06:50:13 +01:00

AS5600 analog support

This commit is contained in:
whowechina 2023-04-09 22:37:03 +08:00
parent 1b5d27fad6
commit dd1b500f1b
4 changed files with 79 additions and 9 deletions

View File

@ -12,7 +12,7 @@ function(make_firmware board board_def)
target_include_directories(${board} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(${board} PRIVATE
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
hardware_i2c tinyusb_device tinyusb_board)
hardware_adc hardware_i2c tinyusb_device tinyusb_board)
# Make a UF2 binary
pico_add_extra_outputs(${board})

View File

@ -18,9 +18,12 @@
#define TT_RGB_PIN 28
#define TT_RGB_ORDER GRB
#define TT_AS5600_SCL 27
#define TT_AS5600_SDA 26
#define TT_AS5600_I2C i2c1
/* If you define both Analog and I2C, it will use analog */
#define TT_AS5600_ANALOG 27
//#define TT_AS5600_SCL 27
//#define TT_AS5600_SDA 26
//#define TT_AS5600_I2C i2c1
#else
#endif

View File

@ -253,7 +253,7 @@ static void quit_mode(bool apply)
current_mode = MODE_NONE;
printf("Quit setup %s\n", apply ? "saved." : "discarded.");
}
bool setup_run(uint16_t keys, uint16_t angle)
{
setup_tick_ms = time_us_64() / 1000;
@ -262,9 +262,14 @@ bool setup_run(uint16_t keys, uint16_t angle)
input.just_pressed = keys & ~input.last_keys;
input.just_released = ~keys & input.last_keys;
input.rotate = input.angle - input.last_angle;
if (input.rotate > 128) {
input.rotate -= 256;
} else if (input.rotate < -128) {
input.rotate += 256;
}
if (input.rotate != 0) {
printf("@ %d\n", input.rotate);
if (input.rotate != 0) {
printf("@ %3d %2x\n", input.rotate, input.angle);
mode_defs[current_mode].rotate();
}

View File

@ -9,27 +9,88 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "hardware/i2c.h"
#include "board_defs.h"
#include "config.h"
static uint8_t as5600_addr = 0x36;
static uint16_t angle = 0;
void turntable_init()
{
#ifdef TT_AS5600_ANALOG
adc_init();
adc_gpio_init(TT_AS5600_ANALOG);
adc_select_input(TT_AS5600_ANALOG - 26);
#else
i2c_init(TT_AS5600_I2C, 800 * 1000);
gpio_set_function(TT_AS5600_SCL, GPIO_FUNC_I2C);
gpio_set_function(TT_AS5600_SDA, GPIO_FUNC_I2C);
gpio_pull_up(TT_AS5600_SCL);
gpio_pull_up(TT_AS5600_SDA);
#endif
}
uint32_t max_adc = 3500;
static inline void adjust_max(uint32_t value)
{
if (value > max_adc) {
max_adc += (value - max_adc + 1) / 2;
}
}
static uint16_t read_average(uint16_t size)
{
uint32_t large_cnt = 0;
uint32_t small_cnt = 0;
uint32_t large = 0;
uint32_t small = 0;
uint32_t medium = 0;
for (int i = 0; i < size; i++) {
uint32_t sample = adc_read();
if (sample > 3500) {
large_cnt++;
large += sample;
} else if (sample < 500) {
small_cnt++;
small += sample;
} else {
medium += sample;
}
}
if (large_cnt > 100) {
adjust_max(large / large_cnt);
}
uint32_t all = large + small + medium;
if (large_cnt && small_cnt) {
all += small_cnt * max_adc;
}
return (all / size) % max_adc;
}
void turntable_update()
{
{
#ifdef TT_AS5600_ANALOG
const uint16_t deadzone = 24;
static uint16_t sample = 0;
int new_value = read_average(200);
int delta = abs(new_value - sample);
if ((abs(delta) < deadzone) || (abs(delta) > 4096 - deadzone)) {
return;
}
sample = new_value;
angle = (sample * 4095) / max_adc;
#else
const uint8_t as5600_addr = 0x36;
uint8_t buf[2] = {0x0c, 0x00};
i2c_write_blocking_until(TT_AS5600_I2C, as5600_addr, buf, 1, true,
make_timeout_time_ms(1));
@ -37,6 +98,7 @@ void turntable_update()
make_timeout_time_ms(1));
angle = ((uint16_t)buf[0] & 0x0f) << 8 | buf[1];
#endif
}
uint16_t turntable_read()