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:
parent
cb2461dd5c
commit
93d5eebb74
Binary file not shown.
@ -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
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_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
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/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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user