diff --git a/.gitmodules b/.gitmodules index 27d54c3..63fb9fc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,7 @@ path = mdrv_fw/cdnet url = ../cdnet +[submodule "pycdnet"] + path = tools/pycdnet + url = ../pycdnet + diff --git a/mdrv_fw/STM32G431CBUx_FLASH.ld b/mdrv_fw/STM32G431CBUx_FLASH.ld index c590626..5a4bd8f 100644 --- a/mdrv_fw/STM32G431CBUx_FLASH.ld +++ b/mdrv_fw/STM32G431CBUx_FLASH.ld @@ -62,7 +62,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K -FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 102K /* 128 - 24 - 2 = 102 */ +FLASH (rx) : ORIGIN = 0x8006000, LENGTH = 86K /* 128 -24 (bl) -2 (config) -8 (encoder cali) -8 (anticogging cali) = 86 */ } /* Define output sections */ diff --git a/mdrv_fw/usr/app_main.h b/mdrv_fw/usr/app_main.h index 83cb7d0..988f1a4 100644 --- a/mdrv_fw/usr/app_main.h +++ b/mdrv_fw/usr/app_main.h @@ -23,8 +23,10 @@ #define P_3F(x) (int)(x), abs(((x)-(int)(x))*1000) // "%d.%.3d" +#define CALI_ENCODER_TBL 0x0801b800 // 8k, 2bytes x 4096 +#define ANTICOGGING_TBL 0x0801d800 // 8k, 2bytes x 4096 #define APP_CONF_ADDR 0x0801f800 // page 63, the last page -#define APP_CONF_VER 0x0105 +#define APP_CONF_VER 0x0106 #define CURRENT_LOOP_FREQ (170000000 / 4096 / 2) #define DRV_PWM_HALF 2048 @@ -105,6 +107,12 @@ typedef struct { float cali_angle_step; // increase cali_angle_elec bool cali_run; + bool cali_encoder_en; + bool anticogging_en; + float anticogging_max_val[2]; + + uint8_t _reserved[28]; + // end of flash #define _end_save state @@ -144,6 +152,12 @@ typedef struct { int16_t dbg_u; int16_t dbg_v; + float sen_i_sq_avg; + float cal_v_sq_avg; + uint8_t _reserved2[8]; + float sen_speed_avg; + float sen_rpm_avg; + } csa_t; // config status area diff --git a/mdrv_fw/usr/app_motor.c b/mdrv_fw/usr/app_motor.c index 1640a3a..017ac7e 100644 --- a/mdrv_fw/usr/app_motor.c +++ b/mdrv_fw/usr/app_motor.c @@ -282,6 +282,8 @@ static inline void speed_loop_compute(void) csa.sen_speed = s_avg / 5.0f; s_avg = 0; + csa.sen_speed_avg += (csa.sen_speed - csa.sen_speed_avg) * 0.005f; + csa.sen_rpm_avg = csa.sen_speed_avg / 0x10000 * 60; if (csa.state < ST_SPEED) { pid_f_reset(&csa.pid_speed, 0, 0); @@ -451,6 +453,13 @@ void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc) csa.sen_i_sq = -i_alpha * sin_tmp_angle_elec + i_beta * cos_tmp_angle_elec; csa.sen_i_sd = i_alpha * cos_tmp_angle_elec + i_beta * sin_tmp_angle_elec; + if (csa.anticogging_en) { + int8_t *p = (int8_t *)ANTICOGGING_TBL + (csa.sen_encoder >> 4) * 2; + csa.sen_i_sq -= csa.anticogging_max_val[0] * (*p) / 100.0f; + } + float err_i_sq = csa.sen_i_sq - csa.sen_i_sq_avg; + csa.sen_i_sq_avg += err_i_sq * 0.001f; + if (dbg_str) //d_debug_c(", i %5d %5d %5d", ia, ib, ic); d_debug_c(", i %5d %5d", adc1_val, adc2_val); @@ -478,6 +487,14 @@ void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc) #endif csa.cal_v_sq = pid_f_compute_no_d(&csa.pid_i_sq, csa.sen_i_sq); csa.cal_v_sd = pid_f_compute_no_d(&csa.pid_i_sd, csa.sen_i_sd); // target default 0 + + if (csa.anticogging_en) { + int8_t *p = (int8_t *)ANTICOGGING_TBL + (csa.sen_encoder >> 4) * 2; + csa.cal_v_sq += csa.anticogging_max_val[1] * (*(p+1)) / 100.0f; + } + float err_v_sq = csa.cal_v_sq - csa.cal_v_sq_avg; + csa.cal_v_sq_avg += err_v_sq * 0.001f; + if (csa.state == ST_CALI) csa.cal_v_sd = 0; diff --git a/mdrv_fw/usr/config.c b/mdrv_fw/usr/config.c index 5a8b732..54fbbf5 100644 --- a/mdrv_fw/usr/config.c +++ b/mdrv_fw/usr/config.c @@ -219,6 +219,7 @@ int flash_write(uint32_t addr, uint32_t len, const uint8_t *buf) uint8_t *: "[B]", \ int16_t *: "[h]", \ uint32_t *: "[I]", \ + float *: "[f]", \ regr_t: "H,H", \ regr_t *: "{H,H}", \ default: "-")) @@ -323,6 +324,11 @@ void csa_list_show(void) CSA_SHOW(0, cali_run, "0: stopped, write 1 start calibration"); d_info("\n"); debug_flush(true); + CSA_SHOW(0, cali_encoder_en, ""); + CSA_SHOW(0, anticogging_en, ""); + CSA_SHOW(0, anticogging_max_val, ""); + d_info("\n"); debug_flush(true); + CSA_SHOW(0, state, "0: stop, 1: calibrate, 2: cur loop, 3: speed loop, 4: pos loop, 5: t_curve"); //CSA_SHOW(0, err_flag, "not used"); d_info("\n"); debug_flush(true); @@ -364,5 +370,11 @@ void csa_list_show(void) CSA_SHOW(0, dbg_v, ""); d_info("\n"); debug_flush(true); + CSA_SHOW(0, sen_i_sq_avg, ""); + CSA_SHOW(0, cal_v_sq_avg, ""); + CSA_SHOW(0, sen_speed_avg, ""); + CSA_SHOW(0, sen_rpm_avg, ""); + d_info("\n"); debug_flush(true); + d_info("\x1b[92mColor Test...\x1b[0m\n"); } diff --git a/tools/anticogging.py b/tools/anticogging.py new file mode 100755 index 0000000..9f5c145 --- /dev/null +++ b/tools/anticogging.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +# Software License Agreement (MIT License) +# +# Copyright (c) 2024, DUKELEC, Inc. +# All rights reserved. +# +# Author: Duke Fong + +"""CDFOC anticogging tool + +Args: + --dev DEV # specify serial port, default: /dev/ttyACM0 + --baud BAUD # set baudrate, default: 115200 + --target-addr ADDR # default: 80:00:fe + --help | -h # this help message + --verbose | -v # debug level: verbose + --debug | -d # debug level: debug + --info | -i # debug level: info + +Command prompt example: + +$ ./anticogging.py + +""" + +R_tc_pos = 0x01f8 +R_anticogging_en = 0x021a +R_anticogging_max_val = 0x021c +R_state = 0x0240 +R_tc_state = 0x0284 +R_sen_i_sq_avg = 0x029c +R_cal_v_sq_avg = 0x02a0 + +ANTICOGGING_TBL = 0x0801d800 # 8k, 2bytes x 4096 + + +import sys, os +import struct +import _thread +import re +import json +from time import sleep +from argparse import ArgumentParser +from pathlib import Path + +sys.path.append(os.path.join(os.path.dirname(__file__), './pycdnet')) + +from cdnet.utils.log import * +from cdnet.utils.cd_args import CdArgs +from cdnet.dev.cdbus_serial import CDBusSerial +from cdnet.dispatch import * + +args = CdArgs() +local_mac = int(args.get("--local-mac", dft="0x00"), 0) +dev_str = args.get("--dev", dft="ttyACM0") +baud = int(args.get("--baud", dft="115200"), 0) +target_addr = args.get("--target-addr", dft="80:00:fe") + +out_file = args.get("--out-file") +reboot_flag = args.get("--reboot") != None + +sub_size = 128 + +if args.get("--help", "-h") != None: + print(__doc__) + exit() + + +if args.get("--verbose", "-v") != None: + logger_init(logging.VERBOSE) +elif args.get("--debug", "-d") != None: + logger_init(logging.DEBUG) +elif args.get("--info", "-i") != None: + logger_init(logging.INFO) + + +dev = CDBusSerial(dev_str, baud=baud) +CDNetIntf(dev, mac=local_mac) +sock = CDNetSocket(('', 0xcdcd)) +sock_dbg = CDNetSocket(('', 9)) + + +def dbg_echo(): + while True: + rx = sock_dbg.recvfrom() + #print('\x1b[0;37m ' + re.sub(br'[^\x20-\x7e]',br'.', rx[0][5:-1]).decode() + '\x1b[0m') + print('\x1b[0;37m ' + re.sub(br'[^\x20-\x7e]',br'.', rx[0]).decode() + '\x1b[0m') + +_thread.start_new_thread(dbg_echo, ()) + + +def csa_write(offset, dat): + sock.sendto(b'\x20' + struct.pack("= 1: + plt.setp(plt.plot(t, dat[0], 'g.-'), alpha=0.2) # green +if len(dat) >= 2: + plt.setp(plt.plot(t, dat[1], 'b.-'), alpha=0.2) # blue +if len(dat) >= 3: + plt.setp(plt.plot(t, dat[2], 'y.-'), alpha=0.2) # yellow +if len(dat) >= 4: + plt.setp(plt.plot(t, dat[3], 'k.-'), alpha=0.2) # black +if len(dat) >= 5: + plt.setp(plt.plot(t, dat[4], 'r.-'), alpha=0.2) # red +if len(dat) >= 6: + plt.setp(plt.plot(t, dat[5], 'c.-'), alpha=0.2) # cyan +if len(dat) >= 7: + plt.setp(plt.plot(t, dat[6], 'm.-'), alpha=0.2) # purple +# not use: w for white + +plt.tight_layout() +plt.grid() +plt.show() diff --git a/tools/pycdnet b/tools/pycdnet new file mode 160000 index 0000000..4c10f32 --- /dev/null +++ b/tools/pycdnet @@ -0,0 +1 @@ +Subproject commit 4c10f3290ccc123936bffb32c6099d85d80412fb