mirror of
https://github.com/whowechina/iidx_pico.git
synced 2025-02-21 12:49:54 +01:00
Supports TMAG5273 sensor
This commit is contained in:
parent
cb2461dd5c
commit
93d5eebb74
Binary file not shown.
@ -1,34 +1,34 @@
|
|||||||
set(BTSTACK_ROOT ${PICO_SDK_PATH}/lib/btstack)
|
set(BTSTACK_ROOT ${PICO_SDK_PATH}/lib/btstack)
|
||||||
set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
|
set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
|
||||||
|
|
||||||
function(make_firmware board board_def)
|
function(make_firmware board board_def)
|
||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
add_executable(${board}
|
add_executable(${board}
|
||||||
main.c cli.c commands.c buttons.c rgb.c save.c config.c setup.c
|
main.c cli.c commands.c buttons.c rgb.c save.c config.c setup.c
|
||||||
turntable.c tt_rainbow.c tt_blade.c
|
turntable.c as5600.c tmag5273.c tt_rainbow.c tt_blade.c
|
||||||
usb_descriptors.c)
|
usb_descriptors.c)
|
||||||
target_compile_definitions(${board} PUBLIC ${board_def})
|
target_compile_definitions(${board} PUBLIC ${board_def})
|
||||||
pico_enable_stdio_usb(${board} 1)
|
pico_enable_stdio_usb(${board} 1)
|
||||||
pico_enable_stdio_uart(${board} 0)
|
pico_enable_stdio_uart(${board} 0)
|
||||||
|
|
||||||
pico_generate_pio_header(${board} ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
|
pico_generate_pio_header(${board} ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
|
||||||
|
|
||||||
target_compile_options(${board} PRIVATE -Wfatal-errors -O3)
|
target_compile_options(${board} PRIVATE -Wfatal-errors -O3)
|
||||||
target_include_directories(${board} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
target_include_directories(${board} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||||
target_include_directories(${board} PRIVATE
|
target_include_directories(${board} PRIVATE
|
||||||
${BTSTACK_ROOT}/src
|
${BTSTACK_ROOT}/src
|
||||||
${LWIP_ROOT}/src/include)
|
${LWIP_ROOT}/src/include)
|
||||||
|
|
||||||
target_link_libraries(${board} PRIVATE
|
target_link_libraries(${board} PRIVATE
|
||||||
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
|
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
|
||||||
hardware_adc hardware_i2c hardware_watchdog
|
hardware_adc hardware_i2c hardware_watchdog
|
||||||
tinyusb_device tinyusb_board)
|
tinyusb_device tinyusb_board)
|
||||||
|
|
||||||
pico_add_extra_outputs(${board})
|
pico_add_extra_outputs(${board})
|
||||||
|
|
||||||
add_custom_command(TARGET ${board} POST_BUILD
|
add_custom_command(TARGET ${board} POST_BUILD
|
||||||
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
|
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
make_firmware(iidx_pico BOARD_IIDX_PICO)
|
make_firmware(iidx_pico BOARD_IIDX_PICO)
|
||||||
|
|
||||||
|
59
firmware/src/as5600.c
Normal file
59
firmware/src/as5600.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* AS5600 Angular Hall Sensor
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "turntable.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/i2c.h"
|
||||||
|
|
||||||
|
#include "board_defs.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define AS5600_ADDR 0x36
|
||||||
|
|
||||||
|
static i2c_inst_t *as5600_i2c = i2c0;
|
||||||
|
static uint16_t raw_angle = 0;
|
||||||
|
|
||||||
|
void as5600_init(i2c_inst_t *i2c_port)
|
||||||
|
{
|
||||||
|
as5600_i2c = i2c_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool as5600_init_sensor()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool as5600_is_present()
|
||||||
|
{
|
||||||
|
uint8_t buf[1] = {0x0c};
|
||||||
|
int ret = i2c_write_blocking_until(as5600_i2c, AS5600_ADDR, buf, 1, true,
|
||||||
|
make_timeout_time_ms(1));
|
||||||
|
return ret == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int as5600_read_angle()
|
||||||
|
{
|
||||||
|
uint8_t buf[2] = {0x0c, 0x00};
|
||||||
|
int ret = i2c_write_blocking_until(as5600_i2c, AS5600_ADDR, buf, 1, true,
|
||||||
|
make_timeout_time_ms(1));
|
||||||
|
if (ret != 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = i2c_read_blocking_until(as5600_i2c, AS5600_ADDR, buf, 2, false,
|
||||||
|
make_timeout_time_ms(1));
|
||||||
|
if (ret != 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (buf[0] & 0x0f) << 8 | buf[1];
|
||||||
|
}
|
17
firmware/src/as5600.h
Normal file
17
firmware/src/as5600.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* AS5600 Angular Hall Sensor
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AS5600_H
|
||||||
|
#define AS5600_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void as5600_init(i2c_inst_t *i2c_port);
|
||||||
|
bool as5600_init_sensor();
|
||||||
|
bool as5600_is_present();
|
||||||
|
int as5600_read_angle();
|
||||||
|
|
||||||
|
#endif
|
@ -13,14 +13,12 @@
|
|||||||
#define BUTTON_RGB_NUM 11
|
#define BUTTON_RGB_NUM 11
|
||||||
#define BUTTON_RGB_MAP { 6, 0, 5, 1, 4, 2, 3, 7, 8, 9, 10}
|
#define BUTTON_RGB_MAP { 6, 0, 5, 1, 4, 2, 3, 7, 8, 9, 10}
|
||||||
|
|
||||||
|
|
||||||
#define TT_RGB_PIN 28
|
#define TT_RGB_PIN 28
|
||||||
#define TT_RGB_ORDER GRB // or RGB
|
#define TT_RGB_ORDER GRB // or RGB
|
||||||
|
|
||||||
#define TT_AS5600_ANALOG 26
|
#define TT_SENSOR_SCL 27
|
||||||
#define TT_AS5600_SCL 27
|
#define TT_SENSOR_SDA 26
|
||||||
#define TT_AS5600_SDA 26
|
#define TT_SENSOR_I2C i2c1
|
||||||
#define TT_AS5600_I2C i2c1
|
|
||||||
|
|
||||||
// Alternative I2C pins
|
// Alternative I2C pins
|
||||||
//#define TT_AS5600_SCL 21
|
//#define TT_AS5600_SCL 21
|
||||||
|
120
firmware/src/tmag5273.c
Normal file
120
firmware/src/tmag5273.c
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* TMAG5273 Angular Hall Sensor
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hardware/i2c.h"
|
||||||
|
#include "board_defs.h"
|
||||||
|
|
||||||
|
#include "tmag5273.h"
|
||||||
|
|
||||||
|
#define TMAG5273_DEF_ADDR 0x35
|
||||||
|
|
||||||
|
#define IO_TIMEOUT_US 1000
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
i2c_inst_t *port;
|
||||||
|
uint8_t addr;
|
||||||
|
uint16_t cache;
|
||||||
|
bool present;
|
||||||
|
} instances[16] = { { i2c0, TMAG5273_DEF_ADDR } };
|
||||||
|
#define INSTANCE_NUM count_of(instances)
|
||||||
|
|
||||||
|
static int current_instance = 0;
|
||||||
|
#define INSTANCE instances[current_instance]
|
||||||
|
|
||||||
|
#define I2C_PORT INSTANCE.port
|
||||||
|
#define I2C_ADDR INSTANCE.addr
|
||||||
|
|
||||||
|
static void write_reg(uint8_t reg, uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t data[2] = { reg, value };
|
||||||
|
i2c_write_blocking_until(I2C_PORT, I2C_ADDR, data, 2, false,
|
||||||
|
time_us_64() + IO_TIMEOUT_US);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t read_reg(uint8_t reg)
|
||||||
|
{
|
||||||
|
uint8_t value;
|
||||||
|
i2c_write_blocking_until(I2C_PORT, I2C_ADDR, ®, 1, true,
|
||||||
|
time_us_64() + IO_TIMEOUT_US);
|
||||||
|
i2c_read_blocking_until(I2C_PORT, I2C_ADDR, &value, 1, false,
|
||||||
|
time_us_64() + IO_TIMEOUT_US);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_many(uint8_t reg, uint8_t *dst, uint8_t len)
|
||||||
|
{
|
||||||
|
i2c_write_blocking_until(I2C_PORT, I2C_ADDR, ®, 1, true,
|
||||||
|
time_us_64() + IO_TIMEOUT_US);
|
||||||
|
i2c_read_blocking_until(I2C_PORT, I2C_ADDR, dst, len, false,
|
||||||
|
time_us_64() + IO_TIMEOUT_US * len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tmag5273_init(unsigned instance, i2c_inst_t *i2c_port)
|
||||||
|
{
|
||||||
|
if (instance < INSTANCE_NUM) {
|
||||||
|
current_instance = instance;
|
||||||
|
INSTANCE.port = i2c_port;
|
||||||
|
INSTANCE.addr = TMAG5273_DEF_ADDR;
|
||||||
|
INSTANCE.present = tmag5273_change_addr(TMAG5273_DEF_ADDR + 1 + instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tmag5273_use(unsigned instance)
|
||||||
|
{
|
||||||
|
if (instance < INSTANCE_NUM) {
|
||||||
|
current_instance = instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tmag5273_is_present(unsigned instance)
|
||||||
|
{
|
||||||
|
if (instance >= INSTANCE_NUM) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return instances[instance].present;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tmag5273_change_addr(uint8_t i2c_addr)
|
||||||
|
{
|
||||||
|
tmag5273_write_reg(0x0c, (i2c_addr << 1) | 0x01);
|
||||||
|
INSTANCE.addr = i2c_addr;
|
||||||
|
tmag5273_read_reg(0x0c); // Dummy read
|
||||||
|
uint8_t new_addr = tmag5273_read_reg(0x0c) >> 1;
|
||||||
|
return new_addr == i2c_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tmag5273_init_sensor()
|
||||||
|
{
|
||||||
|
tmag5273_write_reg(0x03, 0x01 << 2); // Enable angle calculation
|
||||||
|
tmag5273_write_reg(0x02, 0x03 << 4); // X-Y
|
||||||
|
tmag5273_write_reg(0x00, 0x03 << 2); // 8x average mode
|
||||||
|
tmag5273_write_reg(0x01, 0x02); // Continuous mode
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tmag5273_read_reg(uint8_t addr)
|
||||||
|
{
|
||||||
|
return read_reg(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tmag5273_write_reg(uint8_t addr, uint8_t value)
|
||||||
|
{
|
||||||
|
write_reg(addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tmag5273_read_angle()
|
||||||
|
{
|
||||||
|
uint8_t buf[3] = { 0 };
|
||||||
|
read_many(0x18, buf, sizeof(buf));
|
||||||
|
if (buf[0] & 0x01) {
|
||||||
|
INSTANCE.cache = (buf[1] << 8 | buf[2]) & 0x1fff;
|
||||||
|
}
|
||||||
|
return INSTANCE.cache;
|
||||||
|
}
|
27
firmware/src/tmag5273.h
Normal file
27
firmware/src/tmag5273.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* TMAG5273 Angular Hall Sensor
|
||||||
|
* WHowe <github.com/whowechina>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TMAG5273_H
|
||||||
|
#define TMAG5273_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "hardware/i2c.h"
|
||||||
|
|
||||||
|
void tmag5273_init(unsigned instance, i2c_inst_t *i2c_port);
|
||||||
|
void tmag5273_use(unsigned instance);
|
||||||
|
bool tmag5273_is_present(unsigned instance);
|
||||||
|
bool tmag5273_change_addr(uint8_t i2c_addr);
|
||||||
|
|
||||||
|
bool tmag5273_init_sensor();
|
||||||
|
|
||||||
|
uint8_t tmag5273_read_reg(uint8_t addr);
|
||||||
|
void tmag5273_write_reg(uint8_t addr, uint8_t value);
|
||||||
|
|
||||||
|
uint16_t tmag5273_read_angle();
|
||||||
|
|
||||||
|
#endif
|
@ -15,45 +15,47 @@
|
|||||||
#include "hardware/adc.h"
|
#include "hardware/adc.h"
|
||||||
#include "hardware/i2c.h"
|
#include "hardware/i2c.h"
|
||||||
|
|
||||||
|
#include "as5600.h"
|
||||||
|
#include "tmag5273.h"
|
||||||
|
|
||||||
#include "board_defs.h"
|
#include "board_defs.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static uint16_t angle = 0;
|
static uint16_t raw_angle = 0;
|
||||||
|
static bool use_as5600 = true;
|
||||||
static void init_i2c()
|
|
||||||
{
|
|
||||||
i2c_init(TT_AS5600_I2C, 400 * 1000);
|
|
||||||
gpio_set_function(TT_AS5600_SCL, GPIO_FUNC_I2C);
|
|
||||||
gpio_set_function(TT_AS5600_SDA, GPIO_FUNC_I2C);
|
|
||||||
gpio_set_drive_strength(TT_AS5600_SCL, GPIO_DRIVE_STRENGTH_8MA);
|
|
||||||
gpio_set_drive_strength(TT_AS5600_SDA, GPIO_DRIVE_STRENGTH_8MA);
|
|
||||||
gpio_pull_up(TT_AS5600_SCL);
|
|
||||||
gpio_pull_up(TT_AS5600_SDA);
|
|
||||||
}
|
|
||||||
|
|
||||||
void turntable_init()
|
void turntable_init()
|
||||||
{
|
{
|
||||||
init_i2c();
|
i2c_init(TT_SENSOR_I2C, 400 * 1000);
|
||||||
|
gpio_init(TT_SENSOR_SCL);
|
||||||
|
gpio_init(TT_SENSOR_SDA);
|
||||||
|
gpio_set_function(TT_SENSOR_SCL, GPIO_FUNC_I2C);
|
||||||
|
gpio_set_function(TT_SENSOR_SDA, GPIO_FUNC_I2C);
|
||||||
|
gpio_pull_up(TT_SENSOR_SCL);
|
||||||
|
gpio_pull_up(TT_SENSOR_SDA);
|
||||||
|
|
||||||
|
tmag5273_init(0, TT_SENSOR_I2C);
|
||||||
|
if (tmag5273_is_present(0)) {
|
||||||
|
tmag5273_use(0);
|
||||||
|
tmag5273_init_sensor();
|
||||||
|
use_as5600 = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
as5600_init(TT_SENSOR_I2C);
|
||||||
|
as5600_init_sensor();
|
||||||
|
use_as5600 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_angle()
|
static int read_angle()
|
||||||
{
|
{
|
||||||
const uint8_t as5600_addr = 0x36;
|
if (use_as5600) {
|
||||||
uint8_t buf[2] = {0x0c, 0x00};
|
return as5600_read_angle();
|
||||||
int ret = i2c_write_blocking_until(TT_AS5600_I2C, as5600_addr, buf, 1, true,
|
|
||||||
make_timeout_time_ms(1));
|
|
||||||
if (ret != 1) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i2c_read_blocking_until(TT_AS5600_I2C, as5600_addr, buf, 2, false,
|
return tmag5273_read_angle() * 0x1000 / 360 / 16;
|
||||||
make_timeout_time_ms(1));
|
|
||||||
if (ret != 2) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (buf[0] & 0x0f) << 8 | buf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void turntable_update()
|
void turntable_update()
|
||||||
{
|
{
|
||||||
int candidate = read_angle();
|
int candidate = read_angle();
|
||||||
@ -75,12 +77,12 @@ void turntable_update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
angle = candidate;
|
raw_angle = candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t turntable_raw()
|
uint16_t turntable_raw()
|
||||||
{
|
{
|
||||||
return iidx_cfg->tt_sensor.reversed ? 4095 - angle : angle; // 12bit
|
return iidx_cfg->tt_sensor.reversed ? 4095 - raw_angle : raw_angle; // 12bit
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t turntable_read()
|
uint8_t turntable_read()
|
||||||
@ -96,10 +98,10 @@ uint8_t turntable_read()
|
|||||||
} else if (iidx_cfg->tt_sensor.ppr == 3) {
|
} else if (iidx_cfg->tt_sensor.ppr == 3) {
|
||||||
step = 4096 / 64;
|
step = 4096 / 64;
|
||||||
} else {
|
} else {
|
||||||
return angle >> 4;
|
return raw_angle >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t delta = angle - old_angle;
|
int16_t delta = raw_angle - old_angle;
|
||||||
if (delta == 0) {
|
if (delta == 0) {
|
||||||
return counter;
|
return counter;
|
||||||
} else if (delta > 2048) {
|
} else if (delta > 2048) {
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* IIDX Controller Turntable
|
* IIDX Controller Turntable
|
||||||
* WHowe <github.com/whowechina>
|
* WHowe <github.com/whowechina>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TURNTABLE_H
|
#ifndef TURNTABLE_H
|
||||||
#define TURNTABLE_H
|
#define TURNTABLE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
void turntable_init();
|
void turntable_init();
|
||||||
uint8_t turntable_read();
|
uint8_t turntable_read();
|
||||||
uint16_t turntable_raw();
|
uint16_t turntable_raw();
|
||||||
void turntable_update();
|
void turntable_update();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user