1
0
mirror of https://github.com/whowechina/iidx_pico.git synced 2025-02-20 04:21:01 +01:00

Supports TMAG5273 sensor

This commit is contained in:
whowechina 2024-12-03 14:21:08 +08:00
parent cb2461dd5c
commit 93d5eebb74
9 changed files with 309 additions and 86 deletions

Binary file not shown.

View File

@ -1,34 +1,34 @@
set(BTSTACK_ROOT ${PICO_SDK_PATH}/lib/btstack)
set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c cli.c commands.c buttons.c rgb.c save.c config.c setup.c
turntable.c tt_rainbow.c tt_blade.c
usb_descriptors.c)
target_compile_definitions(${board} PUBLIC ${board_def})
pico_enable_stdio_usb(${board} 1)
pico_enable_stdio_uart(${board} 0)
pico_generate_pio_header(${board} ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
target_compile_options(${board} PRIVATE -Wfatal-errors -O3)
target_include_directories(${board} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(${board} PRIVATE
${BTSTACK_ROOT}/src
${LWIP_ROOT}/src/include)
target_link_libraries(${board} PRIVATE
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
hardware_adc hardware_i2c hardware_watchdog
tinyusb_device tinyusb_board)
pico_add_extra_outputs(${board})
add_custom_command(TARGET ${board} POST_BUILD
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
endfunction()
make_firmware(iidx_pico BOARD_IIDX_PICO)
set(BTSTACK_ROOT ${PICO_SDK_PATH}/lib/btstack)
set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c cli.c commands.c buttons.c rgb.c save.c config.c setup.c
turntable.c as5600.c tmag5273.c tt_rainbow.c tt_blade.c
usb_descriptors.c)
target_compile_definitions(${board} PUBLIC ${board_def})
pico_enable_stdio_usb(${board} 1)
pico_enable_stdio_uart(${board} 0)
pico_generate_pio_header(${board} ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)
target_compile_options(${board} PRIVATE -Wfatal-errors -O3)
target_include_directories(${board} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(${board} PRIVATE
${BTSTACK_ROOT}/src
${LWIP_ROOT}/src/include)
target_link_libraries(${board} PRIVATE
pico_multicore pico_stdlib hardware_pio hardware_pwm hardware_flash
hardware_adc hardware_i2c hardware_watchdog
tinyusb_device tinyusb_board)
pico_add_extra_outputs(${board})
add_custom_command(TARGET ${board} POST_BUILD
COMMAND cp ${board}.uf2 ${CMAKE_CURRENT_LIST_DIR}/..)
endfunction()
make_firmware(iidx_pico BOARD_IIDX_PICO)

59
firmware/src/as5600.c Normal file
View 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
View 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

View File

@ -13,14 +13,12 @@
#define BUTTON_RGB_NUM 11
#define BUTTON_RGB_MAP { 6, 0, 5, 1, 4, 2, 3, 7, 8, 9, 10}
#define TT_RGB_PIN 28
#define TT_RGB_ORDER GRB // or RGB
#define TT_AS5600_ANALOG 26
#define TT_AS5600_SCL 27
#define TT_AS5600_SDA 26
#define TT_AS5600_I2C i2c1
#define TT_SENSOR_SCL 27
#define TT_SENSOR_SDA 26
#define TT_SENSOR_I2C i2c1
// Alternative I2C pins
//#define TT_AS5600_SCL 21

120
firmware/src/tmag5273.c Normal file
View 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, &reg, 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, &reg, 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
View 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

View File

@ -15,45 +15,47 @@
#include "hardware/adc.h"
#include "hardware/i2c.h"
#include "as5600.h"
#include "tmag5273.h"
#include "board_defs.h"
#include "config.h"
static uint16_t angle = 0;
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);
}
static uint16_t raw_angle = 0;
static bool use_as5600 = true;
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()
{
const uint8_t as5600_addr = 0x36;
uint8_t buf[2] = {0x0c, 0x00};
int ret = i2c_write_blocking_until(TT_AS5600_I2C, as5600_addr, buf, 1, true,
make_timeout_time_ms(1));
if (ret != 1) {
return -1;
if (use_as5600) {
return as5600_read_angle();
}
ret = i2c_read_blocking_until(TT_AS5600_I2C, as5600_addr, buf, 2, false,
make_timeout_time_ms(1));
if (ret != 2) {
return -1;
}
return (buf[0] & 0x0f) << 8 | buf[1];
return tmag5273_read_angle() * 0x1000 / 360 / 16;
}
void turntable_update()
{
int candidate = read_angle();
@ -75,12 +77,12 @@ void turntable_update()
}
}
angle = candidate;
raw_angle = candidate;
}
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()
@ -96,10 +98,10 @@ uint8_t turntable_read()
} else if (iidx_cfg->tt_sensor.ppr == 3) {
step = 4096 / 64;
} else {
return angle >> 4;
return raw_angle >> 4;
}
int16_t delta = angle - old_angle;
int16_t delta = raw_angle - old_angle;
if (delta == 0) {
return counter;
} else if (delta > 2048) {

View File

@ -1,17 +1,17 @@
/*
* IIDX Controller Turntable
* WHowe <github.com/whowechina>
*/
#ifndef TURNTABLE_H
#define TURNTABLE_H
#include <stdint.h>
#include <stdbool.h>
void turntable_init();
uint8_t turntable_read();
uint16_t turntable_raw();
void turntable_update();
#endif
/*
* IIDX Controller Turntable
* WHowe <github.com/whowechina>
*/
#ifndef TURNTABLE_H
#define TURNTABLE_H
#include <stdint.h>
#include <stdbool.h>
void turntable_init();
uint8_t turntable_read();
uint16_t turntable_raw();
void turntable_update();
#endif