Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.6.5 #323

Merged
merged 23 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ sphinx:

# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
# python:
# install:
# - requirements: docs/requirements.txt
python:
install:
- requirements: docs/requirements.txt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![Docs Build](https://github.com/yconst/tinymovr/workflows/Tinymovr%20Docs%20Build/badge.svg)
[![Discord](https://img.shields.io/discord/742400176664084535)](https://discord.gg/CzcCaXbU)

[Tinymovr is an affordable motor controller](https://tinymovr.com) for precise control of 3-phase brushless motors. Tinymovr works with up to 38V input voltage, drives motors up to 40A continuous phase current, integrates an absolute angle encoder (MPS MA702) and features rich connectivity.
[Tinymovr is an affordable motor controller](https://tinymovr.com) with integrated encoder and CAN bus for precise control of 3-phase brushless motors (PMSMs).

This repository holds the open source firmware, client library, hardware designs and documentation source.

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = 'furo'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down
6 changes: 5 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
sphinx>=3.2.1
sphinx>=5.2.3
sphinxcontrib-programoutput
sphinx-inline-tabs
sphinx-copybutton
furo
17 changes: 9 additions & 8 deletions firmware/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ all: release
debug: CFLAGS += -DDEBUG -g2 -O1
debug: CPPFLAGS += -DDEBUG -g2 -O1
debug: LDFLAGS += -O1
debug: OBJECTS += $(BUILDDIR)/bootloader_$(REV).o
debug: OBJECTS += $(BUILDDIR)/bootloader-$(REV).o
debug: binary

# Upgrade target
Expand All @@ -114,11 +114,11 @@ upgrade: LDFLAGS += -O3
upgrade: binary

# Release target
release: OBJECTS += $(BUILDDIR)/bootloader_$(REV).o
release: OBJECTS += $(BUILDDIR)/bootloader-$(REV).o
release: upgrade

# Binary target
binary: print_board_rev $(HEX) $(BIN) $(ELF)
binary: print_board_info $(HEX) $(BIN) $(ELF)

# Objcopy to HEX
$(HEX): $(ELF)
Expand All @@ -131,7 +131,7 @@ $(BIN): $(ELF)

# Link
$(ELF): $(OBJECTS)
- $(OBJCOPY) -I binary -O elf32-littlearm -B arm --rename-section .data=.bl_section,alloc,load,readonly,data,contents $(PROJECTDIR)/bootloader/bootloader_$(REV).bin $(BUILDDIR)/bootloader_$(REV).o
- $(OBJCOPY) -I binary -O elf32-littlearm -B arm --rename-section .data=.bl_section,alloc,load,readonly,data,contents $(PROJECTDIR)/bootloader/bootloader-$(REV).bin $(BUILDDIR)/bootloader-$(REV).o
$(LD) $(LDFLAGS) $(OBJECTS) -o $(ELF)
$(SIZE_EX) --format=berkeley $(ELF)

Expand All @@ -151,8 +151,9 @@ clean :
- $(rmdir_cmd) "$(BUILDDIR)"

# Print board revision
.PHONY: print_board_rev
print_board_rev:
@echo "===Building Tinymovr==="
.PHONY: print_board_info
print_board_info:
@echo "===Building Tinymovr Bootloader==="
@echo "Board revision is $(REV)"
@echo "======================="
@echo "Fw version is $(GIT_VERSION)"
@echo "=================================="
Binary file added firmware/bootloader/bootloader-M51.bin
Binary file not shown.
Binary file added firmware/bootloader/bootloader-R32.bin
Binary file not shown.
Binary file added firmware/bootloader/bootloader-R33.bin
Binary file not shown.
Binary file added firmware/bootloader/bootloader-R50.bin
Binary file not shown.
Binary file added firmware/bootloader/bootloader-R51.bin
Binary file not shown.
Binary file added firmware/bootloader/bootloader-R52.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_M51.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_R32.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_R33.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_R50.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_R51.bin
Binary file not shown.
Binary file removed firmware/bootloader/bootloader_R52.bin
Binary file not shown.
6 changes: 5 additions & 1 deletion firmware/src/can/can.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ static CANState state ={0};

extern volatile uint32_t msTicks;

const uint8_t avlos_proto_hash_8 = (uint8_t)(avlos_proto_hash & 0xFF);
const size_t endpoint_count = sizeof(avlos_endpoints) / sizeof(avlos_endpoints[0]);

void CAN_init(void)
{
#if defined(BOARD_REV_R52)
Expand Down Expand Up @@ -135,7 +138,8 @@ void CAN_process_interrupt(void)
{
can_process_extended();

if (sizeof(avlos_endpoints) / sizeof(avlos_endpoints[0]) > can_ep_id)
if ((endpoint_count > can_ep_id) &&
((can_frame_hash == avlos_proto_hash_8) || (can_frame_hash == 0)))
{
uint8_t (*callback)(uint8_t buffer[], uint8_t * buffer_length, Avlos_Command cmd) = avlos_endpoints[can_ep_id];
uint8_t can_msg_buffer[8];
Expand Down
1 change: 0 additions & 1 deletion firmware/src/can/can_endpoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@


uint8_t (*avlos_endpoints[79])(uint8_t * buffer, uint8_t * buffer_len, Avlos_Command cmd) = {&avlos_protocol_hash, &avlos_uid, &avlos_fw_version, &avlos_hw_revision, &avlos_Vbus, &avlos_Ibus, &avlos_power, &avlos_temp, &avlos_calibrated, &avlos_errors, &avlos_save_config, &avlos_erase_config, &avlos_reset, &avlos_enter_dfu, &avlos_scheduler_errors, &avlos_controller_state, &avlos_controller_mode, &avlos_controller_warnings, &avlos_controller_errors, &avlos_controller_position_setpoint, &avlos_controller_position_p_gain, &avlos_controller_velocity_setpoint, &avlos_controller_velocity_limit, &avlos_controller_velocity_p_gain, &avlos_controller_velocity_i_gain, &avlos_controller_velocity_deadband, &avlos_controller_velocity_increment, &avlos_controller_current_Iq_setpoint, &avlos_controller_current_Id_setpoint, &avlos_controller_current_Iq_limit, &avlos_controller_current_Iq_estimate, &avlos_controller_current_bandwidth, &avlos_controller_current_Iq_p_gain, &avlos_controller_current_max_Ibus_regen, &avlos_controller_current_max_Ibrake, &avlos_controller_voltage_Vq_setpoint, &avlos_controller_calibrate, &avlos_controller_idle, &avlos_controller_position_mode, &avlos_controller_velocity_mode, &avlos_controller_current_mode, &avlos_controller_set_pos_vel_setpoints, &avlos_comms_can_rate, &avlos_comms_can_id, &avlos_motor_R, &avlos_motor_L, &avlos_motor_pole_pairs, &avlos_motor_type, &avlos_motor_offset, &avlos_motor_direction, &avlos_motor_calibrated, &avlos_motor_I_cal, &avlos_motor_errors, &avlos_encoder_position_estimate, &avlos_encoder_velocity_estimate, &avlos_encoder_type, &avlos_encoder_bandwidth, &avlos_encoder_calibrated, &avlos_encoder_errors, &avlos_traj_planner_max_accel, &avlos_traj_planner_max_decel, &avlos_traj_planner_max_vel, &avlos_traj_planner_t_accel, &avlos_traj_planner_t_decel, &avlos_traj_planner_t_total, &avlos_traj_planner_move_to, &avlos_traj_planner_move_to_tlimit, &avlos_traj_planner_errors, &avlos_homing_velocity, &avlos_homing_max_homing_t, &avlos_homing_retract_dist, &avlos_homing_warnings, &avlos_homing_stall_detect_velocity, &avlos_homing_stall_detect_delta_pos, &avlos_homing_stall_detect_t, &avlos_homing_home, &avlos_watchdog_enabled, &avlos_watchdog_triggered, &avlos_watchdog_timeout };
uint32_t avlos_proto_hash = 3526126264;

uint32_t _avlos_get_proto_hash(void)
{
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/can/can_endpoints.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ typedef enum
ENCODER_TYPE_HALL = 1
} encoder_type_options;

extern uint32_t avlos_proto_hash;
static const uint32_t avlos_proto_hash = 3526126264;
extern uint8_t (*avlos_endpoints[79])(uint8_t * buffer, uint8_t * buffer_len, Avlos_Command cmd);
extern uint32_t _avlos_get_proto_hash(void);

Expand Down
253 changes: 1 addition & 252 deletions firmware/src/can/can_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ uint8_t data_length;
uint32_t rx_id;
bool rtr;
uint32_t can_ep_id;
uint32_t can_seq_id;
uint32_t can_frame_hash;

// * The function "can_io_config" is part of the Tinymovr-Firmware distribution
// * (https://github.com/yconst/tinymovr-firmware).
Expand Down Expand Up @@ -169,256 +169,5 @@ void can_baud(CAN_BAUD_TYPE baud)
}
}

TM_RAMFUNC void can_process_standard(void)
{
uint32_t buffer = PAC55XX_CAN->RXBUF; // read RX buffer, RX buffer bit order same as TX buffer

data_length = buffer & 0x0F;
rx_id = ((buffer & 0xE00000) >> 21) | ((buffer & 0xFF00) >> 5);

can_ep_id = rx_id & 0x3F;
rtr = ((buffer >> 6) & 0x1) == 0x1;
rx_data[0] = buffer >> 24; // data0
if (data_length > 1u)
{
buffer = PAC55XX_CAN->RXBUF; // buffer contains data1..data4
rx_data[1] = buffer;
rx_data[2] = buffer >> 8;
rx_data[3] = buffer >> 16;
rx_data[4] = buffer >> 24;
if (data_length > 5u)
{
buffer = PAC55XX_CAN->RXBUF; // buffer contains data7..data5
rx_data[5] = buffer;
rx_data[6] = buffer >> 8;
rx_data[7] = buffer >> 16;
}
}
}

// * The function "can_process_extended" is part of the Tinymovr-Firmware distribution
// * (https://github.com/yconst/tinymovr-firmware).
// * Copyright (c) 2022 Ioannis Chatzikonstantinou.
// *
// * 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, version 3.
// *
// * 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. If not, see <http://www.gnu.org/licenses/>.

TM_RAMFUNC void can_process_extended(void)
{
uint32_t buffer = PAC55XX_CAN->RXBUF; // read RX buffer, RX buffer bit order same as TX buffer

data_length = buffer & 0x0F;
rtr = ((buffer >> 6) & 0x1) == 0x1;
rx_id = ((buffer & 0xFF000000) >> 19) | ((buffer & 0x00FF0000) >> 3) | ((buffer & 0x0000FF00) << 13);

buffer = PAC55XX_CAN->RXBUF;

rx_id |= (buffer & 0xFF) >> 3;

ids_from_arbitration(rx_id, &can_ep_id, &can_seq_id);

rx_data[0] = (buffer >> 8) & 0xFF; // data0
rx_data[1] = (buffer >> 16) & 0xFF; // data1
rx_data[2] = (buffer >> 24) & 0xFF; // data2
if (data_length > 3u)
{
buffer = PAC55XX_CAN->RXBUF; // buffer contains data3..data6
rx_data[3] = buffer & 0xFF;
rx_data[4] = (buffer >> 8) & 0xFF;
rx_data[5] = (buffer >> 16) & 0xFF;
rx_data[6] = (buffer >> 24) & 0xFF;
if (data_length > 7u)
{
buffer = PAC55XX_CAN->RXBUF; // buffer contains data7
rx_data[7] = buffer & 0xFF;
}
}
}

TM_RAMFUNC void can_transmit_standard(uint8_t dataLen, uint16_t id, const uint8_t * data)
{
while (PAC55XX_CAN->SR.TBS == 0) {}; // wait for TX buffer free
PAC55XX_CAN->TXBUF = (dataLen << 0) | // DLC - Data Length Code
(0u << 6) | // RTR = 0 Data Frame
(0u << 7) | // FF - Format Frame; 0=Std Frame
((id>>3 & 0xFF) << 8) | // ID 10:3
((id&0x07u) << 21) | // ID 2:0
(data[0] << 24); // Data 0

if (dataLen > 1u)
{
PAC55XX_CAN->TXBUF = (data[1] << 0) | // Data 1
(data[2] << 8) | // Data 2
(data[3] << 16) | // Data 3
(data[4] << 24); // Data 4
}
if (dataLen > 5u)
{
PAC55XX_CAN->TXBUF = (data[5] << 0) | // Data 5
(data[6] << 8) | // Data 6
(data[7] << 16); // Data 7

}

PAC55XX_CAN->CMR.TR = 1; // Request transmit
}

// * The function "can_transmit_extended" is part of the Tinymovr-Firmware distribution
// * (https://github.com/yconst/tinymovr-firmware).
// * Copyright (c) 2022 Ioannis Chatzikonstantinou.
// *
// * 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, version 3.
// *
// * 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. If not, see <http://www.gnu.org/licenses/>.

TM_RAMFUNC void can_transmit_extended(uint8_t dataLen, uint32_t id, const uint8_t * data)
{
while (PAC55XX_CAN->SR.TBS == 0) {}; // wait for TX buffer free
PAC55XX_CAN->TXBUF = (dataLen << 0) | // DLC - Data Length Code
(0u << 6) | // RTR = 0 Data Frame
(1u << 7) | // FF - Format Frame; 1=Ext Frame
((id&0x1FE00000u) >> (21-8)) |
((id&0x001FE000u) << (16-13)) |
((id&0x00001FE0u) << (24-5));

PAC55XX_CAN->TXBUF = ((id & 0x1F) << 3) |
((data[0] & 0xFF) << 8) |
((data[1] & 0xFF) << 16) |
((data[2] & 0xFF) << 24);

if (dataLen > 3u)
{
PAC55XX_CAN->TXBUF = ((data[3] & 0xFF) << 0) | // Data 3
((data[4] & 0xFF) << 8) | // Data 4
((data[5] & 0xFF) << 16) | // Data 5
((data[6] & 0xFF) << 24); // Data 6
}
if (dataLen > 7u)
{
PAC55XX_CAN->TXBUF = ((data[7] & 0xFF) << 0); // Data 7
}

PAC55XX_CAN->CMR.TR = 1; // Request transmit
}

uint16_t CAN_BaudTypeToInt(CAN_BAUD_TYPE type)
{
uint16_t ret = 0u;
switch(type)
{
case CAN_BAUD_50KHz:
ret = 50u;
break;

case CAN_BAUD_100KHz:
ret = 100u;
break;

case CAN_BAUD_125KHz:
ret = 125u;
break;

case CAN_BAUD_200KHz:
ret = 200u;
break;

case CAN_BAUD_250KHz:
ret = 250u;
break;

case CAN_BAUD_400KHz:
ret = 400u;
break;

case CAN_BAUD_500KHz:
ret = 500u;
break;

case CAN_BAUD_800KHz:
ret = 800u;
break;

case CAN_BAUD_1000KHz:
ret = 1000u;
break;

default:
// ret already set
break;
}
return ret;
}

CAN_BAUD_TYPE CAN_IntToBaudType(uint16_t baud)
{
CAN_BAUD_TYPE ret = CAN_BAUD_250KHz;
switch(baud)
{
case 50u:
ret = CAN_BAUD_50KHz;
break;

case 100u:
ret = CAN_BAUD_100KHz;
break;

case 125u:
ret = CAN_BAUD_125KHz;
break;

case 200u:
ret = CAN_BAUD_200KHz;
break;

// 250 handled in default

case 400u:
ret = CAN_BAUD_400KHz;
break;

case 500u:
ret = CAN_BAUD_500KHz;
break;

case 800u:
ret = CAN_BAUD_800KHz;
break;

case 1000u:
ret = CAN_BAUD_1000KHz;
break;

default:
// ret already set
break;
}
return ret;
}

inline void ids_from_arbitration(uint32_t arb_id, uint32_t* ep_id, uint32_t* seq_id)
{
*ep_id = arb_id & CAN_EP_MASK;
*seq_id = (arb_id & CAN_SEQ_MASK) >> CAN_EP_SIZE;
}

inline void arbitration_from_ids(uint32_t* arb_id, uint32_t ep_id, uint32_t seq_id, uint32_t node_id)
{
*arb_id = (ep_id & CAN_EP_MASK) | ((seq_id << CAN_EP_SIZE) & CAN_SEQ_MASK) | ((node_id << (CAN_EP_SIZE + CAN_SEQ_SIZE)) & CAN_DEV_MASK);
}
Loading
Loading