474 次代碼提交 0e55eec4d8 ... b90ed380f3

作者 SHA1 備註 提交日期
  huhui b90ed380f3 更新encoder错误检测 2 年之前
  huhui f6a80370a3 修改encoder 调试错误的打印和内部变量 2 年之前
  huhui b537ad1447 优化编码器错误检测 2 年之前
  huhui 564f9cd408 优化参数识别逻辑 2 年之前
  huhui fb09b1487b 加入磁链识别 2 年之前
  huhui 7a31d390ec 识别DQ电感加入超时机制 2 年之前
  huhui 4bd2d721e2 加入电机电气参数的离线识别 2 年之前
  huhui dbd2ed2768 FOC log print idc limit 2 年之前
  huhui d7f5f410c5 如果硬件没有母线电流采集,系统的母线电流用软件计算的替代 2 年之前
  huhui c795a0c367 计算母线电流需要对死区进行补偿,如果svpwm已经做了死区补偿,那么母线电流计算就不补偿 2 年之前
  huhui 5f15c9c987 切换到无感模式后,通过CONFIG_SENSORLESS_RAMP_TIME控制限制速度和母线功率的缓慢平滑 2 年之前
  huhui 4fc1018800 相电流波形记录8000个点,然后输出给示波器,确保波形数据详细 2 年之前
  huhui 013294e3d2 1. 编码器Z信号使用timer处理上升沿,可以做数字滤波 2 年之前
  huhui 8ca5e9d862 三相平衡检测,加入时间维度,防止转速太低,检测时间过长 2 年之前
  huhui 901d0c4ffd 1. start stop 指令加入设置挡位信息 2 年之前
  huhui 30a7e82b10 1. 死区补偿暂时关闭,效果不明显 2 年之前
  huhui 07de41d428 加入逆变器死区补偿,采用线性补偿方式,相电流滤波通过dq滤波,再变化到abc 2 年之前
  huhui 27156825ec 使用PI_Controller_RunVel控制限速和速度环,根据文档调整硬件死区时间 2 年之前
  huhui 87f8d921e3 加入三相电流不平衡算法,目前只能通过检测负序分量,比如相线螺丝松动等情况 2 年之前
  huhui 6d7178fdaa 编码器结构体变量改为static类型 2 年之前
  huhui cbcb089f7f 相电流采样系数改为0.303(原来0.32) 2 年之前
  huhui 6c34e6e5b6 PMSM_FOC_GetSpeed 判断无感模式使用不同的速度 2 年之前
  huhui 3683bbe13c z 信号中断,如果发现无法校准需要置位编码器AB错误,切换到无感 2 年之前
  huhui a986a29a9c 硬件欠压快速判断 2 年之前
  huhui 0be2475256 重命名ADC_SAMPLE_TIME to ADC_INSERT_SAMPLE_TIME 2 年之前
  huhui 20b9be4db4 增加err的数量 2 年之前
  huhui e8ef351ce7 编码器z index 校准AB干扰 2 年之前
  huhui 7d8642716f 修改s_motRPMFilted 为 s_motVelocityFiltered 2 年之前
  huhui f13852f23e 无感角度偏差和速度通过plot显示 2 年之前
  huhui a840e91f62 加入s16 的step forward 函数 2 年之前
  huhui 54b2701661 encoder interface滤波系数调整到30 2 年之前
  huhui f6189f5799 1. 编码器Z信号对齐补偿,后期需要优化 2 年之前
  huhui f1fbb06594 默认开启电压相角补偿 2 年之前
  huhui bd2fd8c21b 上报速度,需要判断是否无感,无感是否稳定 2 年之前
  huhui 812ba03d46 刹车灯处理 2 年之前
  huhui 9b896cc94f 使用单独的can指令设置log等级 2 年之前
  huhui 8895b3e1fd 1. 欠压和过流5ms内检测完成 2 年之前
  huhui 4f8cedbfc9 编码器错误检查调试 2 年之前
  huhui d2da18139a 打开编码器错误检测,角度错误后保存runtime现场 2 年之前
  huhui 42307a6b50 错误处理保存和工具读取 2 年之前
  huhui 366b590bfa 编码器监测放到encoder.c中,低速通过pwm的频率检测,中高速通过上一次的cnt和当前cnt的比较来检测 2 年之前
  huhui e16fa66bc6 move simulink modules to other git repo 2 年之前
  huhui 8b7088320b 通过能量回收时间和能量回收负扭矩来调节回收大小和舒适性 2 年之前
  huhui 810e748a1e autohold 刹车2s进入 2 年之前
  huhui 84934ccaa3 EPM 模式单独速度控制参数,支持转把控制前进车速 2 年之前
  huhui d91ed28992 支持定速巡航设置车速 2 年之前
  huhui 53e6bc88da 上报广播7F, foc observer 还是使用编码器的速度 2 年之前
  huhui 55b8c16617 上报给车机的母线电流,如果FOC不在调制,直接给0 2 年之前
  huhui 1daa3e555b 1. 默认关闭log,有45发来的can指令,打开log 2 年之前
  huhui 426331c18c 1. 当相错误的时候,记录mc_error到flash中 3 年之前
  huhui c675a5c77d 编码器校准,for循环前已经有一次了,所以还是要除count+1 3 年之前
  huhui 713520e8e8 解决编码器校准的时候,除数多1的问题 3 年之前
  huhui 165809155c epm ladrc 参数用宏定义 3 年之前
  huhui 552479dcee 空转检测恢复以前的方式 3 年之前
  huhui 64b2726b6c epm 模式空转和骑行同一套参数 3 年之前
  huhui 1e6c717b75 空转检测考虑EPM倒车的情况(负扭矩) 3 年之前
  huhui c1497ca7bd 1. 能量回收负扭矩根据车速,线性减弱 3 年之前
  huhui 0adbbfadce 负扭矩查表后,D轴电流不变,Q轴电流取负。D轴电流不变,Q轴正负,产生的扭矩也是正负,且大小相等 3 年之前
  huhui 8b133a2c0c 1. 锁电机,改为开下管,50% duty 无法锁电机 3 年之前
  huhui 6da89727ea 1. 加速EPM后退的扭矩限制和最大速度限制 3 年之前
  huhui f02386bc3a 开启能量回收的情况下,解决偶发松开转把再拧转把扭矩始终为-1.0的问题 3 年之前
  huhui 1600303020 1. 解决定速巡航飞车问题 3 年之前
  huhui 8a2305aabe 1. 解决打齿和加速响应之间的平衡,主要修改 crosszero_step_towards 函数 3 年之前
  huhui 683c46fc11 处理autohold和打齿 3 年之前
  huhui 26b45a5567 相错误的时候,保存电流侧瞬时电流,电压 3 年之前
  huhui cf80407556 工厂测试,支持相电流采集开启和关闭 3 年之前
  huhui ba5226578d 3相桥测试,只支持互补输出 3 年之前
  huhui 994c222641 部分工厂测试实现 3 年之前
  huhui ef4d3b963a 用户设置的idc limit小于零,不处理,通过这个设置可以读取当前的限流 3 年之前
  huhui 1263c31861 解决限流错误 3 年之前
  huhui 62c5d5be49 用户设置的runtime限流,保存到motor结构体,挡位切换的母线电流不能超过用户的runtime设置 3 年之前
  huhui db54c20bd1 限流等级保存,恢复低等级限流需要转把释放后,避免突然加速 3 年之前
  huhui 12909a95ac 修改A1 5匝的电气参数 3 年之前
  huhui db39d5b06d 母线采集计算系数减小到原来的94% 3 年之前
  huhui 351a9465da 母线过流,设置为最高电流的1.1倍 3 年之前
  huhui 3506687d9b MC105的母线最大放到250A 3 年之前
  huhui 8c75c82259 更新simulink模型 3 年之前
  huhui 6e62faea20 加入A1 5匝的电机支持,最高车速125km/h 3 年之前
  huhui 0099388d31 update at32f413 3 年之前
  huhui 7c36cb7da1 更新simulink模型 3 年之前
  huhui 641a6aed66 标定高温,过流保护 3 年之前
  huhui 262b8280f1 电机和mos高温停机处理 3 年之前
  huhui 62ae51e888 加入母线电流过流检测 3 年之前
  huhui 476fc5e651 2/3用宏定义表示 3 年之前
  huhui 02083718c3 加入A1 5匝电机的磁链,扭矩仿真数据 3 年之前
  huhui 078281785d 空转检测调试 3 年之前
  huhui 1c569316a3 解决turbo挡位不正常的问题 3 年之前
  huhui b200aaa24b update 3 年之前
  huhui d36cc2955f 超前角标定,q轴电流根据调度的s符号定正负 3 年之前
  huhui 0fe44c3d52 motor params去掉不用的back emf和hall table 3 年之前
  huhui 11781c2507 负载识别,空载和带负载速度环参数不一样 3 年之前
  huhui d40c320ea0 A1电机加入5匝的电气参数 3 年之前
  huhui cef0bd05af AT32 设置中断可抢占16个优先级 3 年之前
  huhui d8b7fd7344 更新打印信息 3 年之前
  huhui b0bb565944 在配置设备中断前先配置系统的优先级为16个抢占优先级,1个子优先级 3 年之前
  huhui f8cf5d0e01 MC105 V4 电流采集正确 3 年之前
  huhui 6c0b2bf131 MC105 V3V4的board id改为 2和1 3 年之前
  huhui 4390a1fdcc 更新simulink模型,通过三相电流重构母线电流 3 年之前
  huhui c16ec4ed7b 1. 更新通过pwm和三相电流计算母线电流的方式 3 年之前
  huhui 1d234474cb 无感和encoder切换,未调试 3 年之前
  huhui adb5bc67cf 105 V4的支持 3 年之前
  huhui a2f3f3bd21 加入母线电流的另一种计算方式 3 年之前
  huhui 766ce4f7a4 仿真: 利用相电流通过对开关管时序的分析,重构母线电流 3 年之前
  huhui dd10cb01f2 1. 更新pwm驱动,通过宏定义控制adc触发通过update事件,一个周期两次,暂时不用 3 年之前
  huhui b099b64939 ladrc sensorless observer limit the max vel 3 年之前
  huhui eff46e6644 1. 加入ladrc sensorless 观测器 3 年之前
  huhui 5a28362944 add ladrc sensorless observer 3 年之前
  huhui c8a9e560c0 update smo, 计算公司错误 3 年之前
  huhui 6267beb0be update simulink model for sensorless 3 年之前
  huhui b312d17bcc 105 V3控制器 母线电流最大200A,19KW的功率 3 年之前
  huhui 5474c1f6c6 change pwm_timer to MOS_PWM_TIMER 3 年之前
  huhui 95f6a8c637 update AT32 mcu 3 年之前
  huhui e82c496d78 add adc ins chan len=4 support 3 年之前
  huhui 6f05d9f70b 国民MCU,adc采集,编码器OK 3 年之前
  huhui fe92094061 add N32G45x MCU support 3 年之前
  huhui 51e7b8cf90 at32 adc等16次转换结束后开中断 3 年之前
  huhui c0686b4705 update for gd32f305 3 年之前
  huhui dfcafd7e84 gd32 adc 改为 普通通道双工作模式 3 年之前
  huhui 381929ce3e GD32 改为305 3 年之前
  huhui 27e3cc267a 加入雅特力MCU的支持 3 年之前
  huhui 64dea2f061 bsp架构梳理 3 年之前
  huhui c551246ad4 hall 去掉 3 年之前
  huhui 8fbbf019aa 去掉不使用的timer32 counter 3 年之前
  huhui 4c8bc9e1cb add AT32 driver & cmsis 3 年之前
  huhui 7724b404fb update simulink module 3 年之前
  huhui e29c851f81 update for smo 3 年之前
  huhui 7fb261bd9d 更新FOC_adrc.xls simulink 模型 3 年之前
  huhui 368db640ce timer brk中断中记录当前的重要数据,给诊断使用 3 年之前
  huhui af75b8c0fa smo加入电流电压滞后一个控制器周期的相位补偿 3 年之前
  huhui a869a1dd38 更新滑膜观测器算法,使用pll锁相环 3 年之前
  huhui a10cf6e4d3 update simulink module & smo c code 3 年之前
  huhui 8386a75c19 A1电机的电流环带宽设置为1.6kHz 3 年之前
  huhui 325ed6e0a7 update,解决高速急停相错误,dq查询异常,导致程序异常 3 年之前
  huhui 1c1b096c85 add get chip id for cmd 0xF6 3 年之前
  huhui 79ae59b035 adc 采集for V3版本修正 3 年之前
  huhui 4ce10f30ff 电压上报加上转把5v 3 年之前
  huhui 489c69ee34 mc105 油门5v采集,启动autohold点亮刹车灯 3 年之前
  huhui ec49c1222f V3 update 3 年之前
  huhui a84e688d96 默认减速50ms,lq通过iq查表获取,然后更新iq的pi控制器 3 年之前
  huhui 4d9d2cad18 死区时间计算问题 3 年之前
  huhui f6d3d3a006 update 3 年之前
  huhui b21a56bbc2 加入示波器选择功能 3 年之前
  huhui 8f054393db 死区设置修正 3 年之前
  huhui 94824aa596 1. 启动时间用24bit上报 3 年之前
  huhui 3a52462034 can_report_foc_status 加入挡位上报 3 年之前
  huhui 7a35b1f566 adrc 参数加入配置 3 年之前
  huhui c596c80f1a V3版本电流采样修改 3 年之前
  huhui 920d8ca2cf 电机外特性放到XX_motor_config.c中 3 年之前
  huhui 4ce8f9eaf0 通过挡位配置决定加速时间 3 年之前
  huhui 099d8bbf9a 1. 温度限流可以通过工具设置 3 年之前
  huhui e9dd31a67b 电压圆限制幅度在电流环的时候处理 3 年之前
  huhui b6fadb3f8a 调试信息加入vdq的log 3 年之前
  huhui 7e4ad6c394 A1的电机参数重新测量 3 年之前
  huhui e1682a4cf5 svpwm加入溢出保护 3 年之前
  huhui 8191a204d0 vbus 电流最大200A 3 年之前
  huhui a1a0feeba8 修改扭矩 3 年之前
  huhui 93dc7232f5 重新加入编码器的log 3 年之前
  huhui d571d76f1c 电机标定后,通过电流矢量查找MTPA和弱磁 3 年之前
  huhui efd8248547 real torque control 3 年之前
  huhui 68126d1054 修改autohold的最大扭矩为20N.M,修改芯片为303RC 3 年之前
  huhui adbfc75c91 解决滑膜观测器模型错误 3 年之前
  huhui 0bc21b0f14 A1电机最大退磁电流300A,实际标定3000rpm的时候最大扭矩47N.M, D轴电流-282A 3 年之前
  huhui 6c653fbebd 高温度,欠压配置nv保存处理 3 年之前
  huhui c8e32c4441 A1电机的最大D轴电流修改为-250A 3 年之前
  huhui e20da5d4f7 高温限制扭矩,欠压限制母线电流参数放到nv中 3 年之前
  huhui 12402bff1d 去掉不用的代码 3 年之前
  huhui ae1df0b387 母线的限流,最大值不能超过挡位的限流 3 年之前
  huhui 6fece42d9b 模拟转把使能后,清除转把故障 3 年之前
  huhui cc3059bf09 MCxxx 使用外部晶振 3 年之前
  huhui 40123a36f9 加入v3后,调整adc的代码 3 年之前
  huhui 3b7da82c60 加入硬件版本号 3 年之前
  huhui 7eb0537990 add mc105 v3 support 3 年之前
  huhui 3a5d066d60 1. 电流环带宽减小到1000 3 年之前
  huhui 1e65d1fb12 模拟油门清楚转把故障,开环强制运行和零位置校准忽略转把故障 3 年之前
  huhui 81850ffe06 编码器技术方向调整,不需要交换AB信号 3 年之前
  huhui 586abcb7f5 解决除0问题 3 年之前
  huhui d1d918a7d7 电子刹车使用扭矩方式 3 年之前
  huhui d630787c73 1. 转把扭矩解析按照加减速的逻辑处理,结合当前的实际扭矩 3 年之前
  huhui 4dd4bf8079 更改PMSM_FOC_Get_Real_Torque -> PMSM_FOC_Get_Real_dqVector,DQ轴电流矢量 3 年之前
  huhui 297419c32e 修正adrc的reset,给定输出 3 年之前
  huhui 5cab0e7091 每次进入定速巡航后,需要间隔一定时间才能使能转把加速功能 3 年之前
  huhui be5c550de0 定速巡航考虑加减速后的转把加速 3 年之前
  huhui 30ca66d422 定速巡航模式下,可以加速 3 年之前
  huhui 8c4ef78eaa foc的pid控制器单独定义 3 年之前
  huhui 2812b95e43 加入LADRC控制器,控制速度和限速环路 3 年之前
  huhui d9cac14e3e 更新simulink模块,加入adrc的支持 3 年之前
  huhui 4955e1c3ba 加入电门过压和欠压检测 3 年之前
  huhui 0af4ddfb68 霍尔电流采样用单独的宏控制电流采样系数 3 年之前
  huhui e7e9c5386d 限速还是回退到限制扭矩,如果限制电压,速度环和扭矩模式切换不平滑 3 年之前
  huhui 3db2e106ea kb 改为 kd,不使用饱和系数,改为微分系数 3 年之前
  huhui 90d3d38585 扭矩模式限速通过PI调节器限制DQ的最大输出电压 3 年之前
  huhui 590f4e03a1 电流环带宽放到motor_param.h中定义,A1 motor的带宽2000 3 年之前
  huhui dd1b10aab2 解决零位置校准除数少1的问题 3 年之前
  huhui e48c4f7a20 扭矩查表后的D轴电流需要step给定,防止D轴电流突变 3 年之前
  huhui c9f25e0f5d 工厂测试加入三相驱动设置 3 年之前
  huhui 682a1b1c87 add A1 motor and factory test file 3 年之前
  huhui b96cb29317 上报相电流 3 年之前
  huhui e31c4ce9a4 重新处理温度limit 3 年之前
  huhui d740566645 扭矩和相电流区分开,可以给真实扭矩(需要通过台架标定) 3 年之前
  huhui 89f1fb73a0 挡位切换需要ramp给定 3 年之前
  huhui 810553c18f 加入3相开关接口,gpio模式 3 年之前
  huhui 10faffd07d 保存flash的命令在电机运行过程中不能处理 3 年之前
  huhui eaee8fea62 fix 写SN号错误,中动100码电机,编码器做了零位置校准,软件偏移固定0 3 年之前
  huhui 5c2c80c219 update 3 年之前
  huhui 8897e23ff4 保存扭矩查抄表写flash检查地址溢出 3 年之前
  huhui e419a868f5 上报过滤后的DQ电流 3 年之前
  huhui 51212c16f3 1. 加入扭矩速度查表DQ电流,通过线性插值,先做扭矩插值,再做速度插值 3 年之前
  huhui a854e1e0b1 实现编码器零位置校准功能 3 年之前
  huhui 3a33a7bda0 功率pi,修改kp为1.8,ki为6,每个挡位单独定义转把,转速和扭矩的对应关系 3 年之前
  huhui f6a10a156d 温度补偿低通滤波设置更小的截止频率,母线的滤波器截止频率设置的大一些 3 年之前
  huhui fcdf2d7343 电压采集补偿系统低通系统修改为宏定义控制0.01f 3 年之前
  huhui 7ccc676502 加入foc的观测器融合encoder和smo,进行切换,目前实现了一部分 3 年之前
  huhui 5ed8eb8078 对3.3和5v进行实时校准,温度变化3.3和5v会有明显变化 3 年之前
  huhui 66a0250b9c 编码器和无感都封装到foc_observer.c 中 3 年之前
  huhui cfef077733 转把对应的扭矩需求从电机外特性map中获取最大扭矩 3 年之前
  huhui ee89cbef19 测功机简单外特性获取 3 年之前
  huhui 48af4118d9 加入软件设置油门开度的功能,模拟转把功能 3 年之前
  huhui 1fae21df3b 加入电机外特性map和查询当前转速下的最大扭矩 3 年之前
  huhui 390d180c61 不管是否有母线采样,母线电流软件计算都执行 3 年之前
  huhui 8d0f1184a2 pid get & set log changed 3 年之前
  huhui 1bb634310e 相电流加入自适应滤波,截止频率为当前电频率的4倍 3 年之前
  huhui 8ce40ff0f7 解决设置和查询挡位问题 3 年之前
  huhui 51faf5ecd4 放电母线电流为正,发送母线电流为负 3 年之前
  huhui 0eaca20590 设置和查询挡位信息 3 年之前
  huhui 170bc02e78 母线限流,取母线绝对值,母线电流计算取负号,负放电,正发电 3 年之前
  huhui 6527985719 Foc_Cali_Hall_Phase 做零位置校准 3 年之前
  huhui c3a30f7e38 鲨湾控制器+中动编码器电机需要编码器反向 3 年之前
  huhui 223b02d12d MPS编码器做非线性校准, shark V形电机 3 年之前
  huhui 34cb44e758 MPS编码器做非线性校准 3 年之前
  huhui 508354da7b Foc_Fan_Duty 加一个具体数值的注释 3 年之前
  huhui 8157f21de7 修改滑膜参数,默认限速最大电机转速 3 年之前
  huhui a0e14fdb2c ADC规则组改为55 cycle 3 年之前
  huhui 3d66399914 1. ADC注入通道采样时间修改为28 cycle 3 年之前
  huhui 26a4318a28 母线电流精确到0.1A 3 年之前
  huhui 3ff5f6c657 电压圆之后DQ电压乘以SQRT3_BY_2, svm中不需要在乘SQRT3_BY_2 3 年之前
  huhui c68eebe756 去掉CONFIG_MIN_CURRENT_FOR_EBRK 3 年之前
  huhui c259f1378d 定义CONFIG_ZERO_SPEED_RPM为0速度 3 年之前
  huhui 2d39cabcbd 去掉电机温感固定0度 3 年之前
  huhui 628640a1a2 限制功率变化需要重新设置挡位信息(主要是限制母线电流和相电流) 3 年之前
  huhui d639314f12 上报上位机的数据从float改为S16Q5格式 3 年之前
  huhui 4e533839aa smo计算低通滤波系数用FOC_CTRL_US 3 年之前
  huhui 0e02ee7971 处理前一次角度和当前角度跨2PI或者0 3 年之前
  huhui 33e5850a5e V形电机+公司磁编码器器, 默认250度offset 3 年之前
  huhui a6b136a80c 滑膜观测器使用arctan和pll实现,单独pll效果不好 3 年之前
  huhui 78e8b60d8c 标定返回实际的电流矢量 3 年之前
  huhui 08eddbe5a9 V型电机不做FIR非线性校准,后期编码器做非线性校准 3 年之前
  huhui bf530deede MC100 不需要swap UV,选择V型电机调试 3 年之前
  huhui a5561a6fd0 零位置校准delayms过程中需要喂狗 3 年之前
  huhui 699d90fa5e MT编码器4096个脉冲,AB一起触发4096个,单个A和B1024个脉冲 3 年之前
  huhui 2c595b52df 硬件过采样x4 3 年之前
  huhui e1d6194691 adc2加入是否硬件过采样的处理 3 年之前
  huhui 3f912f7df6 电流传感器adc的电流参数修改为0.32f, adc的没bit可以分辨320mA 3 年之前
  huhui 83184f87d6 加入挡位切换的log信息 3 年之前
  huhui 48915aebed runtime 限制处理优化 3 年之前
  huhui 058098651e 扭矩限速Kp,Ki跟着电机,更新smo 3 年之前
  huhui 0cdab24213 打印FOC最大执行时间 3 年之前
  huhui 22a8ac9722 编码器的占空比0-100 3 年之前
  huhui 67fbe6fc47 远驱编码器最小duty 0 3 年之前
  huhui 17108c555b add ibus offset logout 3 年之前
  huhui df68b399b2 母线最大电压不是额定电压 3 年之前
  huhui 61cba65df7 母线过压检测 3 年之前
  huhui a603356155 母线采集adc offset开机只校准一次 3 年之前
  huhui d1a013acbe 加入软件多次采样,去掉最大,最小取平均 3 年之前
  huhui 747ca05851 速度小于10RPM可以升级重启 3 年之前
  huhui ad8f1fcd0f 蓝鲨MC100电流传感器adc系数校准 3 年之前
  huhui dc56c4e7fd shark_get_seconds 使用32bit的ticks,不要用64位除法,耗CPU资源 3 年之前
  huhui 3fbd6b08fc fix encoder error for mc100 3 年之前
  huhui afff55bf59 smo 拼写错误 3 年之前
  huhui 200dfeb35a 更新编码器处理,pwm duty适当放宽 3 年之前
  huhui 6e2d6ce7a8 远驱控制器加入smo 3 年之前
  huhui 4ee5db284a foc 中执行smo观测器处理 3 年之前
  huhui a1f6f03727 fix motor lock error 3 年之前
  huhui 235a9ff9f0 加入母线电流采集的offset校准 3 年之前
  huhui d0315cac63 加入母线电流的采集 3 年之前
  huhui 117d2213d7 加入滑膜观测器 3 年之前
  huhui d5b331b0dc 风扇错误检测 3 年之前
  huhui c3e0566660 风扇检测 3 年之前
  huhui 46aa3ddfdb 风扇pwm控制 3 年之前
  huhui 5822c0d2af 加入前刹处理,目前只要有一路刹车就认为有刹车信号 3 年之前
  huhui 30d2c26ae8 1. 加入MT编码器支持 3 年之前
  huhui c3b5aa9b44 增加解锁电机的处理 3 年之前
  huhui 0df69e24bd 1. 增加mos2的采集 3 年之前
  huhui acaab45b49 严重错误放到motor.h/.c 中 3 年之前
  huhui 6b32f07b07 update gpio and pin setup 3 年之前
  huhui 5a21802c38 give some times to get the pwm brk error 3 年之前
  huhui 096db65975 1. change old mc100 project to yuanqu 3 年之前
  huhui a78d86fb11 滑膜观测器仿真 3 年之前
  huhui ebf3fe1e6d 高边ics采样,单独用current_ics.c实现 3 年之前
  huhui 4d3ddf15ef 空转起步防止打齿 3 年之前
  huhui 95bccd0942 挡位切换功能 3 年之前
  huhui ae784e7440 加入挡位和96/48模式 3 年之前
  huhui c52214bde4 二段曲线改为过零处理 3 年之前
  huhui 71af1614c1 update 3 年之前
  huhui e8a531db72 高边电流采集修改为在中心点位置 3 年之前
  huhui 1fe625d4b0 关闭过调制 3 年之前
  huhui 265a6e2f0e 48v过调制OK 3 年之前
  huhui d06298f194 Merge remote-tracking branch 'mc/dev' into over_mod 3 年之前
  huhui 9d6a57ae43 encoder clear 不带参数 3 年之前
  huhui 5fb3ebd3c8 过调制处理 3 年之前
  huhui 4e17ebfa28 二段加减速的第一段step和大小通过宏来控制 3 年之前
  huhui d0dbbeedc7 mc_stop 处理需要关闭中断 3 年之前
  huhui 37cca55c56 motor 初始化motor.b_wait_brk_release置为false 3 年之前
  huhui 50051eb091 二段加减油门判断step_val 大于阈值才启动二段模式 3 年之前
  huhui b23c0a4b64 autohold模式下,再次捏刹车退出autohold模式 3 年之前
  huhui 0bf4aac347 更新二段加减速 3 年之前
  huhui 194107ec1e 转把处理 3 年之前
  huhui b9328aa378 1. 处理转把 3 年之前
  huhui ff956e5f73 母线电流的低通滤波系数增加到0.1f,增加灵敏度 3 年之前
  huhui 1d91e6bb1e 硬件保护停机后,关闭foc,使速度能归0 3 年之前
  huhui d67da61f2b 更新Simulink Fir, 加入新电机的非线性校准 3 年之前
  huhui 50c09f42ef update motor.c foc core 3 年之前
  huhui dca516c892 加入新电机的偏心校准参数 3 年之前
  huhui 7004b22d6e 加入电机编号,如果nv的和现有的不相等,重新初始化电机参数 3 年之前
  huhui 8c384d85d1 发送数据前先poll tx尽量清空发送buffer 3 年之前
  huhui 3cb87e60bf 加入新电机参数 3 年之前
  huhui 6170fe9020 加入中动100码新电机 3 年之前
  huhui c50058b210 实现EPM功能 3 年之前
  huhui 7deb2c2887 转把指令处理 3 年之前
  huhui 13c0420f0b autohold 成功后蜂鸣器再滴一下 3 年之前
  huhui 0ebb06aff2 1. 母线电流计算,通过D轴电流给一个修正 3 年之前
  huhui e98549c552 母线电流计算先不加系数 3 年之前
  huhui d8e2382515 update mc100 3 年之前
  huhui a9c4fd1731 设置定速巡航的速度 3 年之前
  huhui a4d957ef10 ebrk—_time 使用CONFIG_EBRK_RAMP_TIME 3 年之前
  huhui d278714b7d 命令从32开始,给老控制器预留 3 年之前
  huhui 6f47d880a3 autohold beep单独定时器 3 年之前
  huhui 93e9075c2d 1. 有能量回收的时候,解决飞车问题 3 年之前
  huhui f068a49411 优化 3 年之前
  huhui d26c99eee2 堵转保护开始计时点Q轴电流大于阈值并且速度小于1km,在3s内不超过0.2圈认为堵转 3 年之前
  huhui c240c7b5be 整理motor.c 3 年之前
  huhui 2d97243a32 速度上报取绝对值 3 年之前
  huhui 12056ca6b5 支持欠压动态设置 3 年之前
  huhui 7fb50cb202 支持CAN老协议 3 年之前
  huhui a41c11604c 1. 长捏3s刹车进入坡起模式 3 年之前
  huhui 0581ebcb9a 坡起和锁电机功能 3 年之前
  huhui e85be2d30c 1. 堵转功能 3 年之前
  huhui 7e691d40fd 超前角标定调试 3 年之前
  huhui 5874f7d711 调整扭矩查找表的结构 3 年之前
  huhui 7bb234d990 foc 执行时间log 3 年之前
  huhui acb1d30663 torque table error log 3 年之前
  huhui f3ea0ae12e dq轴电流分配查表,如果表不存在,使用id=0的控制策略 3 年之前
  huhui 1e8596b420 过温和欠压保护 3 年之前
  huhui 8dd93f56d2 加入电机和mos的温度测量 3 年之前
  huhui 1565a73dfd 电流环饱和后,定速巡航的reset值取实际的电流矢量 3 年之前
  huhui 74c1d356b3 定速巡航,最高速限速 3 年之前
  huhui 14192a94ec 1. 电流环带宽2000hz,否则高速电流环不能稳定,而且计算的母线电流偏小 3 年之前
  huhui 76347900b8 1. 支持鲨湾V形新电机,encoder_off4.h 3 年之前
  huhui bd0e9217c5 加入plot type开启,选择,关闭功能 3 年之前
  huhui 1d8760fa53 加入D轴最大电流的限制 3 年之前
  huhui afc294643b 加入DQ电流MTPA校准命令 3 年之前
  huhui 05b5dd1b99 通过宏定义选择电机 3 年之前
  huhui 29dfe0143a 加入蓝鲨电机的支持,电流环带宽1500 3 年之前
  huhui d189574847 加入电机和MOS温度的adc配置,增加电机和mos过温错误 3 年之前
  huhui 27e8794886 处理EPM模式 3 年之前
  huhui 60d16b48c2 1.堵转处理,单独一个函数 3 年之前
  huhui 0de0fe9dfe FOC core部分代码移动到motor.c中 3 年之前
  huhui 7afefada9d 1. 没有start的时候,需要通过pwm timer的update中断处理速度 3 年之前
  huhui 649adc7bc3 欠压限速,限母线电流 3 年之前
  huhui 5a3500c184 限速,限相电流,慢速给定,默认10s 3 年之前
  huhui 5192687509 加入堵转判断和保护 3 年之前
  huhui 7eea79d70e 母线电压上报不从PMSM FOC中获取,直接获取采样值 3 年之前
  huhui 3caf15c993 加入判断3相是否连接的错误 3 年之前
  huhui 90da7a89bd 1. pwm 停止后,关闭上下桥 3 年之前
  huhui 4df0408556 速度,扭矩限速PI调试 3 年之前
  huhui a17d506f7b update 3 年之前
  huhui f956107125 update 3 年之前
  huhui d0d9ab2240 update 3 年之前
  huhui dd388bc93f 改装电机2,使用encoder_off2.h 3 年之前
  huhui 45392820d3 update uart 3 年之前
  huhui 970c224bcd CAN消息处理 3 年之前
  huhui 3a1cf0a42d 支持bootloader 3 年之前
  huhui b0d7fe4e11 去掉多余的参数 3 年之前
  huhui 0cf5cb2253 加入刹车能量回收 3 年之前
  huhui ee98871c07 start mc需要检查刹车状态 3 年之前
  huhui 9c78d6740d 加入刹车断电功能,可以配置 3 年之前
  huhui 841cbb5e6b 每次开机FOC user 参数只使用nv初始化一次,后面等用户设置 3 年之前
  huhui a849695b9f 加入nv配置PID 3 年之前
  huhui 20028a70e1 修改变量 3 年之前
  huhui e1d53b8df7 母线限流,转把释放速度为0后停止FOC 3 年之前
  huhui 3b651ceb43 1. pwm 模式改为PWM0,高有效 3 年之前
  huhui 64bc09e7da 加入转把电压,母线电压采集,电流环ramp给定稍微慢一些,防止过冲 3 年之前
  huhui 78f47e2d21 限速 3 年之前
  huhui 0b560a2d02 encoder_offset_map 使用s16替代float 3 年之前
  huhui f37ec09064 重构encoder的校准 3 年之前
  huhui 849e704a60 同心校准,通过matlab设计FIR滤波器,采样率500HZ,通过频率0.5HZ,截至频率5Hz 3 年之前
  huhui 4682d70d21 电流传感器调试 3 年之前
  huhui 49fdc1be84 远驱控制器调试 3 年之前
  huhui 0c9da426f4 通过ENCODER_CC_INVERT定义编码器是否和电机的方向相反 3 年之前
  huhui 291119e50c 解决gd32 demo的编译错误 3 年之前
  huhui ac710fb089 过流过压保护,刹车处理 3 年之前
  huhui b72b9255f9 加入电流高边采样 3 年之前
  huhui c5a432105d 去掉单电阻采样 3 年之前
  huhui d075e01f95 update mc100 3 年之前
  huhui 2c254a099e 加入EPM 模式 3 年之前
  huhui 18ae3a1ca3 锁电机功能部分实现 3 年之前
  huhui 71598e2045 部分使用nv_storage 中的参数 3 年之前
  huhui 3282109b96 加入电流刹车模式 3 年之前
  huhui 3c17c68dfd 加入设置和获取最大扭矩的接口 3 年之前
  huhui 3f716304cc add error record & change torque_lut to torque -manager speed & torque 3 年之前
  huhui fae0376699 加入转把处理 3 年之前
  huhui c2c32e2bef ab信号加入4次滤波 3 年之前
  huhui 657c9c9b4c nv storage update 3 年之前
  huhui 6f8a0ecc96 add board_xxx.h 定义板子相关的硬件资源 3 年之前
  huhui 88deb0c5d3 速度环 3 年之前
  huhui 27ae733bd4 速度扭矩环平滑切换 3 年之前
  huhui b3f2092376 as5407P编码器调试 3 年之前
  huhui 58e259f377 SVPWM调制设置1,pwm duty 放置饱和 3 年之前
  huhui 58e162944e 新的电流采样方式 3 年之前
  huhui 0a0565b3a9 扭矩模式和定速巡航相互切换 3 年之前
  huhui 9e86eea4b9 加入扭矩环,扭矩环限速 3 年之前
  huhui 7660f9aafc GD32_DEMO工程加入key的处理 3 年之前
  huhui 7e4785faeb update,uart更新,加入单独的电流控制模式,加入MTPA标定模式 3 年之前
  huhui cafdbb45bc 粗调电流环OK 3 年之前
  huhui 636e110d79 PI controller's I use DT 3 年之前
  huhui 578832b01c 重新计算相电流的采样方式 3 年之前
  huhui bfc1bdbc61 解决hall时间计算错误的问题 3 年之前
  huhui 9644cd344a hall angle/offset detect 3 年之前
  huhui 940a7258f7 开环hall OK,但是后陆续后优化hall跳变 3 年之前
  huhui af28139d43 hall 校准调试 3 年之前
  huhui bb4048ce18 SVM fix OK, fix TWO_BY_SQRT3_Q14 error 3 年之前
  huhui be9ea247f4 debug 3 年之前
  huhui 4cb196470c use sched_timer call foc的部分 3 年之前
  huhui 8228493bc4 add GD32 demo project, vbus sample 3 年之前
  huhui 521a7bd8e5 update for current sample 3 年之前
  huhui 944615208f adc 外部触发使能开始就使能,不在timer update event 中断中更新 3 年之前
  huhui fa5c03b0eb 电流环的给定使用ramp,在一个speed的控制周期内完成给定 3 年之前
  huhui 5a43847b3d foc核心代码手写替代自动生成 3 年之前
  huhui cb1dbf1334 1. 手动编写代码,simulink生成的代码效率低一些 3 年之前
  huhui 430e0276ad update new simulink modle and C code 3 年之前
  huhui 4aea892cc3 更新模型,需要修改的变量导出给C语言使用 4 年之前
  huhui f653605064 add pid config command 4 年之前
  huhui f82189fec5 export 电机极对数,pwm计数等参数,C代码可以直接修改 4 年之前
  huhui 76b9dfe66e 默认限流,限速放到foc_config.h中 4 年之前
  huhui e1a3e95e60 加入直流母线电流的计算和获取 4 年之前
  huhui 686240344f 中断处理放到motor.c中,brake中断统一处理 4 年之前
  huhui b9271c2731 加入e_ctrl.c 控制加速,电子刹车,能量回收级别 4 年之前
  huhui 75d71536d8 电流电压改为s16Fix5类型 4 年之前
  huhui 5066ef532e 1. 速度改为s32En4 4 年之前
  huhui 0051a9a900 update foc libs 4 年之前
  huhui 9cad4d49db 扭矩模式下限速,通过PI控制器实现,参数主要从速度环拿过来微调 4 年之前
  huhui 85586c7d68 1. 调制架构,加入电流分配模块 4 年之前
  huhui f7fef159e4 扭矩模式,直接给FOC电流,加入刹车能量回收 4 年之前
  huhui a2e209ba97 1. 加入MTPA和弱磁控制 4 年之前
  huhui 9f81816b15 1. 测试弱磁效果 4 年之前
  huhui 903e4c01ba 更新模型,使用一个全局的1ms定时器,不通过delay模块实现,效率低 4 年之前
  huhui 511a241d54 通过采样点的判断,使用什么样的触发方式 4 年之前
  huhui 643f7467d6 模型拿掉电流采样部分,这部分放到手写部分中 4 年之前
  huhui dd4dfae3b7 update model & code 4 年之前
  huhui 86fca0a7d7 update gitignore 4 年之前
  huhui 9477536a7f update for simulink code and Uv projects 4 年之前
  huhui 2fe00cb8dd 增加转子位置的精度,增加hall校准功能 4 年之前
  huhui df8901c4fc update module 4 年之前
  huhui 69eb6b71f2 加入GUI测试 4 年之前
  huhui 56863cef8d 扭矩模式下支持限速 4 年之前
  huhui 61c0929eab update simulink add torque&speed mode control 4 年之前
  huhui 6bb11ce1fa update and Simulink can run speed&current loop 4 年之前
  huhui d8d5b78264 速度波动跟踪OK 4 年之前
  huhui ca2e400d52 add close loop for speed & current 4 年之前
  huhui c8519ff1e4 update simlink model 4 年之前
  huhui ee14387b97 add gd32 demo && add motor dir 4 年之前
  huhui c4bf855ae8 fix foc_clear 4 年之前
  huhui 46170b36bb add hall_sensor.* one copy 4 年之前
  huhui 9431490e92 update fsm 4 年之前
  huhui b081243ea8 update three shunts current sample 4 年之前
  huhui 96a8e29749 update single shunt 4 年之前
  huhui 32889a9a62 uart独立工作,logger使用can输出 4 年之前
  huhui 3417c7504f update adc driver 4 年之前
  huhui b30532af1d update,函数名词修改 4 年之前
  huhui 5db3f61713 update 4 年之前
  huhui 7025f45e28 adc sample time use macro 4 年之前
  huhui 76d1b57398 update phase current sample 4 年之前
  huhui 470249c329 整理phase_current_sample 4 年之前
  huhui d5c48ff1d4 code update 4 年之前
  huhui f441182f15 update hall code 4 年之前
共有 100 個文件被更改,包括 11903 次插入1228 次删除
  1. 1 0
      .gitignore
  2. 206 22
      Applications/app/app.c
  3. 121 0
      Applications/app/factory.c
  4. 8 0
      Applications/app/factory.h
  5. 78 0
      Applications/app/key_process.c
  6. 528 27
      Applications/app/nv_storage.c
  7. 130 12
      Applications/app/nv_storage.h
  8. 0 196
      Applications/bsp/adc.c
  9. 0 160
      Applications/bsp/adc.h
  10. 471 0
      Applications/bsp/at32/adc.c
  11. 78 0
      Applications/bsp/at32/adc.h
  12. 353 0
      Applications/bsp/at32/board_at_mc100_v1.h
  13. 391 0
      Applications/bsp/at32/board_at_mc105_v3.h
  14. 92 0
      Applications/bsp/at32/bsp.c
  15. 35 0
      Applications/bsp/at32/bsp.h
  16. 255 0
      Applications/bsp/at32/can.c
  17. 3 2
      Applications/bsp/at32/can.h
  18. 152 0
      Applications/bsp/at32/enc_intf.c
  19. 27 0
      Applications/bsp/at32/enc_intf.h
  20. 58 0
      Applications/bsp/at32/fan_pwm.c
  21. 23 0
      Applications/bsp/at32/fan_pwm.h
  22. 218 0
      Applications/bsp/at32/fmc_flash.c
  23. 25 0
      Applications/bsp/at32/fmc_flash.h
  24. 191 0
      Applications/bsp/at32/gpio.c
  25. 36 0
      Applications/bsp/at32/gpio.h
  26. 191 0
      Applications/bsp/at32/mc_irqs.c
  27. 257 0
      Applications/bsp/at32/pwm.c
  28. 105 0
      Applications/bsp/at32/pwm.h
  29. 25 0
      Applications/bsp/at32/sched_timer.c
  30. 8 0
      Applications/bsp/at32/sched_timer.h
  31. 478 0
      Applications/bsp/at32/uart.c
  32. 53 0
      Applications/bsp/at32/uart.h
  33. 30 55
      Applications/bsp/bsp.h
  34. 52 0
      Applications/bsp/bsp_driver.h
  35. 75 0
      Applications/bsp/delay.c
  36. 21 0
      Applications/bsp/delay.h
  37. 0 73
      Applications/bsp/dma.c
  38. 0 20
      Applications/bsp/dma.h
  39. 0 88
      Applications/bsp/eeprom.c
  40. 0 10
      Applications/bsp/eeprom.h
  41. 0 140
      Applications/bsp/fmc_flash.c
  42. 0 14
      Applications/bsp/fmc_flash.h
  43. 645 0
      Applications/bsp/gd32/adc.c
  44. 196 0
      Applications/bsp/gd32/adc.h
  45. 176 0
      Applications/bsp/gd32/board_gd32demo.h
  46. 374 0
      Applications/bsp/gd32/board_mc100_v1.h
  47. 436 0
      Applications/bsp/gd32/board_mc105_v3.h
  48. 257 0
      Applications/bsp/gd32/board_yuanqu.h
  49. 33 35
      Applications/bsp/gd32/bsp.c
  50. 41 0
      Applications/bsp/gd32/bsp.h
  51. 91 72
      Applications/bsp/gd32/can.c
  52. 76 0
      Applications/bsp/gd32/can.h
  53. 232 0
      Applications/bsp/gd32/enc_intf.c
  54. 29 0
      Applications/bsp/gd32/enc_intf.h
  55. 83 0
      Applications/bsp/gd32/fan_pwm.c
  56. 23 0
      Applications/bsp/gd32/fan_pwm.h
  57. 223 0
      Applications/bsp/gd32/fmc_flash.c
  58. 24 0
      Applications/bsp/gd32/fmc_flash.h
  59. 0 8
      Applications/bsp/gd32/gd32_bkp.c
  60. 1 1
      Applications/bsp/gd32/gd32_bkp.h
  61. 11 6
      Applications/bsp/gd32/gd32_rtc.c
  62. 0 0
      Applications/bsp/gd32/gd32_rtc.h
  63. 278 0
      Applications/bsp/gd32/gpio.c
  64. 43 0
      Applications/bsp/gd32/gpio.h
  65. 2 1
      Applications/bsp/gd32/i2c.c
  66. 0 0
      Applications/bsp/gd32/i2c.h
  67. 65 28
      Applications/bsp/gd32/mc_irqs.c
  68. 310 0
      Applications/bsp/gd32/pwm.c
  69. 101 0
      Applications/bsp/gd32/pwm.h
  70. 35 0
      Applications/bsp/gd32/sched_timer.c
  71. 8 0
      Applications/bsp/gd32/sched_timer.h
  72. 74 85
      Applications/bsp/gd32/uart.c
  73. 2 2
      Applications/bsp/gd32/uart.h
  74. 0 13
      Applications/bsp/gpio.c
  75. 0 64
      Applications/bsp/gpio.h
  76. 0 58
      Applications/bsp/mc_hall_gpio.c
  77. 0 36
      Applications/bsp/mc_hall_gpio.h
  78. 399 0
      Applications/bsp/n32/adc.c
  79. 131 0
      Applications/bsp/n32/adc.h
  80. 380 0
      Applications/bsp/n32/board_n32_mc105_v3.h
  81. 93 0
      Applications/bsp/n32/bsp.c
  82. 41 0
      Applications/bsp/n32/bsp.h
  83. 129 0
      Applications/bsp/n32/bsp_wrapper.h
  84. 240 0
      Applications/bsp/n32/can.c
  85. 76 0
      Applications/bsp/n32/can.h
  86. 158 0
      Applications/bsp/n32/enc_intf.c
  87. 27 0
      Applications/bsp/n32/enc_intf.h
  88. 87 0
      Applications/bsp/n32/fan_pwm.c
  89. 23 0
      Applications/bsp/n32/fan_pwm.h
  90. 210 0
      Applications/bsp/n32/fmc_flash.c
  91. 25 0
      Applications/bsp/n32/fmc_flash.h
  92. 162 0
      Applications/bsp/n32/gpio.c
  93. 28 0
      Applications/bsp/n32/gpio.h
  94. 199 0
      Applications/bsp/n32/mc_irqs.c
  95. 242 0
      Applications/bsp/n32/pwm.c
  96. 101 0
      Applications/bsp/n32/pwm.h
  97. 34 0
      Applications/bsp/n32/sched_timer.c
  98. 8 0
      Applications/bsp/n32/sched_timer.h
  99. 413 0
      Applications/bsp/n32/uart.c
  100. 53 0
      Applications/bsp/n32/uart.h

+ 1 - 0
.gitignore

@@ -1,5 +1,6 @@
 .vs
 slprj
+MotorController_FOC_sfun.mexw64
 output
 Objects
 Output

+ 206 - 22
Applications/app/app.c

@@ -1,38 +1,222 @@
+#include "bsp/bsp_driver.h"
 #include "app/app.h"
-#include "bsp/bsp.h"
-#include "os/timer.h"
-#include "os/co_task.h"
+#include "os/os_task.h"
 #include "libs/logger.h"
 #include "libs/utils.h"
+#include "foc/motor/motor.h"
+#include "foc/motor/current.h"
+#include "foc/core/foc_observer.h"
+#include "foc/core/ladrc_observer.h"
+#include "foc/samples.h"
 #include "prot/can_foc_msg.h"
 #include "prot/can_message.h"
-#include "foc/foc_api.h"
-#include "bsp/timer_count32.h"
+#include "libs/time_measure.h"
+#include "app/nv_storage.h"
+#include "foc/commands.h"
+#include "foc/core/thro_torque.h"
+#include "foc/core/F_Calc.h"
+#include "foc/motor/motor_param.h"
+#include "foc/motor/mot_params_ind.h"
+#include "foc/limit.h"
+#include "foc/mc_error.h"
 
-static void _app_low_task(void *args);
+
+#ifdef CONFIG_DQ_STEP_RESPONSE
+extern float target_d;
+extern float target_q;
+#endif
+static u32 _app_low_task(void *args);
+static u32 _app_report_task(void *args);
+static u32 _app_plot_task(void *args);
+//static u32 _app_trq_test_task(void *args);
+extern void PMSM_FOC_LogDebug(void);
+extern void mc_err_code_log(void);
+extern void encoder_log(void);
+extern void sample_log(void);
+extern void thro_torque_log(void);
+extern void eCtrl_debug_log(void);
+extern bool can_is_connect_pc(void);
 extern measure_time_t g_meas_hall;
 extern measure_time_t g_meas_foc;
+extern measure_time_t g_meas_MCTask;
+#ifdef JTAG_DEBUG
+int jtag_cmd = 0;
+int jtag_data = 0;
+int jtag_plot = 0;
+void fetch_jtag_cmd(void) {
+	foc_cmd_body_t foc_cmd;
+
+	if (jtag_cmd == 1 || jtag_cmd == 2) {
+		jtag_plot = 2;
+		foc_cmd.cmd = Foc_Start_Motor;
+		foc_cmd.data = (void *)os_alloc(4);
+		encode_u8(foc_cmd.data, jtag_cmd);
+		foc_send_command(&foc_cmd);
+		jtag_cmd = 0;
+	}else if (jtag_cmd == 3) {
+		
+		float vq = (float)jtag_data/10.0f;
+		PMSM_FOC_SetOpenVdq(0, (vq));
+		jtag_cmd = 0;
+	}else if (jtag_cmd == 4) {
+		jtag_plot = 1;
+		foc_cmd.cmd = Foc_Cali_Hall_Phase;
+		foc_cmd.data = (void *)os_alloc(4);;
+		encode_s16(foc_cmd.data, jtag_data);
+		foc_send_command(&foc_cmd);
+		jtag_cmd = 0;
+	}else if (jtag_cmd == 5) {
+		PMSM_FOC_Set_Torque((float)jtag_data/10.0f);
+		jtag_cmd = 0;
+	}else if (jtag_cmd == 6) {
+		PMSM_FOC_EnableCruise(true);
+	}else if (jtag_cmd == 7) {
+		PMSM_FOC_EnableCruise(false);
+	}else if (jtag_cmd == 8) {
+		//mc_current_sensor_calibrate((float)jtag_data/10.0f);
+		jtag_cmd = 0;
+	}else if (jtag_cmd == 9) {
+		mc_encoder_zero_calibrate(jtag_data);
+		jtag_cmd = 0;
+	}
+	jtag_cmd = 0;
+}
+#else
+void fetch_jtag_cmd(void){
+}
+#endif
+
+#if 0
+static s16 test_rpm = 0000;
+static float test_trq = 0;
+static float test_id = 0;
+static float test_iq = 0;
+static u32 _app_trq_test_task(void *args) {
+	DQ_t dq;
+	motor_mpta_fw_lookup(test_rpm, test_trq, &dq);
+	test_id = dq.d;
+	test_iq = dq.q;
+	sys_debug("lookup: %d, %f, %f, %f\n", test_rpm, test_trq, test_id, test_iq);
+	test_rpm = 8000;
+	test_trq += 5.0f;
+	return 500;
+}
+#endif
 void app_start(void){
-	set_log_level(MOD_SYSTEM, L_debug);
+	set_log_level(MOD_SYSTEM, L_disable);
 	can_message_init();
-	foc_init();
-	co_task_create(_app_low_task, NULL, 512);
-	co_task_schedule();
+	nv_storage_init();
+	mc_err_block_init();
+	mc_init();
+#ifdef GD32_FOC_DEMO	
+	extern void key_init(void);
+	key_init();
+#endif
+	shark_task_create(_app_low_task, NULL);
+	shark_task_create(_app_report_task, NULL);
+	shark_task_create(_app_plot_task, NULL);
+	//shark_task_create(_app_trq_test_task, NULL);
+	sys_debug("mc start\n");
+	shark_task_run();
 }
 
-static void _can_report_info(void) {
-	can_report_speed(0x45, foc_get_speed());
-	current_samp_t *s = foc_get_current_sample();
-	can_report_phase_current(0x45, F2I(s->Ia * 1000), F2I(s->Ib * 1000), F2I(s->Ic * 1000));
-}
+static u32 _app_report_task(void *p) {
+	static u32 loop = 0;
 
-static void _app_low_task(void *args) {
-	while(1) {
-		wdog_reload();
-		_can_report_info();
-		sys_debug("foc exec time %d, intval %d\n", g_meas_foc.exec_time, g_meas_foc.intval_time);
-		sys_debug("hall exec time %d, intval %d\n", g_meas_hall.exec_time, g_meas_hall.intval_time);
-		co_task_delay(500);
+	can_report_ext_status(0x43);
+	can_mcast_foc_status2();
+	if (!can_is_connect_pc()) {
+		return 200;
+	}
+	can_report_power(0x45);
+	can_report_dq_current(0x45);
+	can_report_foc_status(0x45);
+	can_report_phase_voltage(0x45);
+	can_report_mpta_values(0x45);
+	can_report_phase_current(0x45);
+	if (mot_params_rs_ested()) {
+		can_report_motparam(mot_params_get_est_rs(), R_TYPE);
+	}
+	if (mot_params_ld_ested()) {
+		can_report_motparam(mot_params_get_est_ld(), L_TYPE_D);
+	}
+	if (mot_params_lq_ested()) {
+		can_report_motparam(mot_params_get_est_lq(), L_TYPE_Q);
+	}
+	if (mot_params_flux_ested()) {
+		can_report_motparam(mot_params_get_est_flux(), FLUX_TYPE);
+	}
+
+	if (++loop % 10 == 0) {
+		//sys_debug("rst 0x%x\n", get_mcu_reset_source());
+		sys_debug("Slow: %d - %d\n", g_meas_MCTask.intval_time, g_meas_MCTask.exec_time);
+		sys_debug("Fast: %d - %d, err: %d-%d-%d\n", g_meas_foc.intval_time, g_meas_foc.exec_time, g_meas_foc.intval_hi_err, g_meas_foc.intval_low_err, g_meas_foc.exec_max_error_time);
+		sys_debug("FOC time err %d %d\n", g_meas_foc.intval_time_h_error, g_meas_foc.intval_time_l_error);
+		//sys_debug("acc vol %d, bid %d\n", get_acc_vol(), gpio_board_id());
+		//sys_debug("throttle %f\n", get_throttle_float());
+		//sys_debug("ADC Vref %f, %f\n", get_adc_vref(), adc_5vref_compesion());
+		//sys_debug("dead time %d\n", get_deadtime());
+		//thro_torque_log();
+		//sys_debug("_>%f, %f, %f\n", ladrc_observer_get()->ld, ladrc_observer_get()->lq, ladrc_observer_get()->poles);
+		encoder_log();
+		//motor_debug();
+		//sample_log();
+		PMSM_FOC_LogDebug();
+		//F_debug();
+		//eCtrl_debug_log();
+		//sys_debug("enc err %d, %d\n", foc_observer_enc_errcount(), foc_observer_sensorless_stable());
+		//mc_err_code_log();
+		sys_debug("=====\n");
+	}
+	return 200;
+}
+int plot_type = 0;
+static void plot_smo_angle(void) {
+#if 1
+	float smo_angle = foc_observer_sensorless_angle();
+	float delta = smo_angle - PMSM_FOC_Get()->in.s_motAngle;
+	float s, c;
+	arm_sin_cos_f32(delta, &s, &c);
+	delta = fast_atan2(s, c)/PI*180.0f;
+	can_plot3(PMSM_FOC_Get()->in.s_motAngle, smo_angle, delta);
+#else
+	can_plot2((s16)(foc_observer_sensorless_diff() * 100.0f), (s16)(foc_observer_sensorless_ration() * 100.0f));
+#endif
+}
+static u32 _app_plot_task(void * args) {
+	if (plot_type == 1) {
+		can_plot2((s16)foc_observer_sensorless_speed(), (s16)PMSM_FOC_GetSpeed());
+		//can_plot3((s16)PMSM_FOC_GetSpeed() + 1000, (s16)PMSM_FOC_GetSpeed(), (s16)PMSM_FOC_GetSpeed() - 1000);
+	}else if (plot_type == 2) {
+		can_plot2(eCtrl_get_FinalTorque(), PMSM_FOC_Get()->in.s_targetTorque);
+	}else if (plot_type == 3) {
+		plot_smo_angle();
+	}else if (plot_type == 4) {
+		can_plot2((s16)PMSM_FOC_Get()->out.s_RealIdq.d, (s16)PMSM_FOC_Get()->out.s_RealIdq.q);
+	}else if (plot_type == 5) {
+		can_plot2((s16)PMSM_FOC_Get()->idq_ctl[0].s_Cp, (s16)PMSM_FOC_Get()->idq_ctl[1].s_Cp);
+	}else if (plot_type == 6) {
+		//can_plot2((s16)(PMSM_FOC_Get()->in.s_iABC[0]), (s16)(PMSM_FOC_Get()->in.s_iABC[1]));
+	}else if (plot_type == 7) {
+		#ifdef CONFIG_DQ_STEP_RESPONSE
+		can_plot2((s16)(target_d*10.0f), (s16)(PMSM_FOC_Get()->out.s_RealIdq.d * 10.0f));
+		#endif
+	}else if (plot_type == 8) {
+		#ifdef CONFIG_DQ_STEP_RESPONSE
+		can_plot2((s16)(target_q*10.0f), (s16)(PMSM_FOC_Get()->out.s_RealIdq.q * 10.0f));
+		#endif
+	}else if (plot_type == 9) {
+		can_plot3((s16)F_get_air(), (s16)F_get_accl(), (s16)F_get_Te());
+	}
+	
+	return 20;
+}
+static u32 _app_low_task(void *args) {
+	wdog_reload();
+	if (!PMSM_FOC_Is_Start()) {
+		mc_err_block_save();
 	}
+	fetch_jtag_cmd();
+	return 1;
 }
 

+ 121 - 0
Applications/app/factory.c

@@ -0,0 +1,121 @@
+#include "factory.h"
+#include "bsp/bsp_driver.h"
+#include "prot/can_message.h"
+#include "prot/can_foc_msg.h"
+#include "foc/samples.h"
+#include "foc/motor/current.h"
+#include "libs/utils.h"
+#include "libs/logger.h"
+#include "os/os_task.h"
+
+static u8 factory_mode = 0;
+
+static void stop_pwm_adc(void);
+
+static bool start_pwm_adc(void) {
+	pwm_turn_on_low_side();
+	delay_ms(10);
+	phase_current_offset_calibrate();
+	pwm_start();
+	delay_us(10); //wait for ebrake error
+	adc_start_convert();
+	phase_current_calibrate_wait();
+	if (phase_curr_offset_check()) {
+		stop_pwm_adc();
+		return false;
+	}
+	return true;
+}
+
+static void stop_pwm_adc(void) {
+	u32 mask = cpu_enter_critical();
+	adc_stop_convert();
+	pwm_stop();
+	pwm_up_enable(true);
+	cpu_exit_critical(mask);
+}
+
+void can_process_factory_message(can_message_t *can_message){
+	uint8_t response[32];
+	uint8_t rsplen;
+	encoder_can_key(response, can_message->key);
+	response[2] = 0;
+	rsplen = 3;
+	switch(can_message->key) {
+		case BUILD_CMD_KEY(0xE0):
+			factory_mode = decode_u8(can_message->data);
+			break;
+		case BUILD_CMD_KEY(0xE1):
+		{
+			if (factory_mode == 0) {
+				response[2] = 1;
+				break;
+			}
+			u8 item = decode_u8(can_message->data);
+			if (item == 1) { //3相驱动测试
+				u8 mask = decode_u8((u8 *)can_message->data + 1);
+				pwm_3phase_sides(false, mask);
+			}else if (item == 2) {//获取所有电压的采集值
+				can_response_vols(can_message->src, can_message->key);
+				return;
+			}else if (item == 3) { //读取gpio状态
+				encode_u16(response + 3, GPIOA_VALUE);
+				encode_u16(response + 5, GPIOB_VALUE);
+				encode_u16(response + 7, GPIOC_VALUE);
+				encode_u16(response + 9, GPIOD_VALUE);
+				encode_u16(response + 11, GPIOE_VALUE);
+				rsplen += 10;
+			}else if (item == 4) { // u phase detect
+				int count = 20;
+				s16 uvw[3] = {0, 0, 0};
+				s16 uvw_total[3] = {0, 0, 0};
+				if (can_message->len < 2) {
+					response[2] = 2; //长度错误
+					break;
+				}
+				u8 detect = decode_u8((u8 *)can_message->data + 1);
+				gpio_phase_u_detect(detect?true:false);
+				while(count-- > 0) {
+					delay_us(100);
+					sample_uvw_phases_raw(uvw);
+					uvw_total[0] += uvw[0];
+					uvw_total[1] += uvw[1];
+					uvw_total[2] += uvw[2];
+				}
+				encode_u16(response + 3, uvw_total[0]/20);
+				encode_u16(response + 5, uvw_total[1]/20);
+				encode_u16(response + 7, uvw_total[2]/20);
+				gpio_phase_u_detect(false);
+				rsplen += 6;
+			}else if (item == 5) { //phase current test
+				u8 start = decode_u8((u8 *)can_message->data + 1);
+				if (start) {
+					pwm_3phase_sides(true, 0); //use pwm output, disable timer break in
+					if (!start_pwm_adc()) {
+						response[2] = 1;
+						break;
+					}
+				}else {
+					stop_pwm_adc();
+					pwm_3phase_init();
+				}
+			}
+			break;
+		}
+		default:
+			rsplen = 0;
+			break;
+	}
+	if (rsplen > 0) {
+		can_send_response(can_message->src, response, rsplen);
+	}
+}
+
+u8 factory_get_mode(void) {
+	return factory_mode;
+}
+
+bool factory_is_running(void) {
+	return (factory_mode == 0);
+}
+

+ 8 - 0
Applications/app/factory.h

@@ -0,0 +1,8 @@
+#ifndef _FACTORY_H__
+#define _FACTORY_H__
+#include "prot/can_message.h"
+
+void can_process_factory_message(can_message_t *can_message);
+bool factory_is_running(void);
+
+#endif /* _FACTORY_H__ */

+ 78 - 0
Applications/app/key_process.c

@@ -0,0 +1,78 @@
+#include "os/os_task.h"
+#include "bsp/bsp_driver.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+#include "libs/utils.h"
+#include "foc/commands.h"
+#include "foc/core/PMSM_FOC_Core.h"
+
+#define KEY_START 0
+#define KEY_STOP  1
+#define KEY_FUNC  2
+
+static u8 key_value[3];
+static float foc_current = 0.0f;
+static u8 ctrl_mode = CTRL_MODE_OPEN;
+static float target_speed = 2000;
+static u32 key_task(void *p) {
+	foc_cmd_body_t foc_cmd;
+	u8 cmd_data[16];
+	foc_cmd.data = cmd_data;
+	int value = gpio_startkey_value();
+	if (value != key_value[KEY_START]) {
+		if (value) {
+			foc_cmd.cmd = Foc_Start_Motor;
+			if (PMSM_FOC_Is_Start()) {
+				PMSM_FOC_Set_Torque(foc_current);
+				PMSM_FOC_Set_Speed(0.0f);
+			}else {
+				cmd_data[0] = Foc_Start;
+				foc_send_command(&foc_cmd);
+				
+			}
+		}
+		key_value[KEY_START] = value;
+	}
+
+	value = gpio_stopkey_value();
+	if (value != key_value[KEY_STOP]) {
+		if (value) {
+			PMSM_FOC_SetCtrlMode(CTRL_MODE_SPD);
+			//PMSM_FOC_SpeedLimit(100);
+			//PMSM_FOC_AutoHold(true);
+		}
+		key_value[KEY_STOP] = value;
+	}
+
+	value = gpio_funckey_value();
+	if (value != key_value[KEY_FUNC]) {
+		if (value) {
+			if (ctrl_mode == CTRL_MODE_TRQ) {
+				ctrl_mode = CTRL_MODE_SPD;
+				PMSM_FOC_SetCtrlMode(ctrl_mode);
+			}else if(ctrl_mode == CTRL_MODE_SPD){
+				//ctrl_mode = CTRL_MODE_TRQ;
+				//PMSM_FOC_EnableCruise(false);
+				PMSM_FOC_SpeedLimit(10000);
+				target_speed += 1000;
+				PMSM_FOC_Set_Speed(target_speed);
+				
+			}else {
+				//ctrl_mode = CTRL_MODE_TRQ;
+			}
+			
+			//PMSM_FOC_SpeedLimit(max_speed);
+			//max_speed += 1000;
+		}
+		key_value[KEY_FUNC] = value;
+	}
+	return 0;
+}
+
+void key_init(void) {
+	key_value[KEY_START] = gpio_startkey_value();
+	key_value[KEY_STOP] = gpio_stopkey_value();
+	key_value[KEY_FUNC] = gpio_funckey_value();
+
+	shark_task_create(key_task, NULL);
+}

+ 528 - 27
Applications/app/nv_storage.c

@@ -1,46 +1,547 @@
 #include "app/nv_storage.h"
-#include "bsp/fmc_flash.h"
+#include "bsp/bsp_driver.h"
 #include "libs/crc16.h"
+#include "libs/logger.h"
+#include "foc/motor/motor_param.h"
+#include "foc/foc_config.h"
 
-static void mc_config_default(void);
+#define motorParam_idx_0 (sn_page_index + 1)
+#define motorParam_idx_1 (motorParam_idx_0 + 1)
+#define focParam_idx_0 (motorParam_idx_1 + 1)
+#define focParam_idx_1 (focParam_idx_0 + 1)
 
-static mc_config_t g_config;
+#define trq_Tbl_size (4)
+#define trq_Tbl_idx0 (focParam_idx_1 + 1)
+#define trq_Tbl_idx1 (trq_Tbl_idx0 + trq_Tbl_size)
 
-void config_set_hall_offset(s16 offset) {
-	g_config.hall_offset = offset;
+#define gear_config_idx_0 (trq_Tbl_idx1 + trq_Tbl_size)
+#define gear_config_idx_1 (gear_config_idx_0 + 1)
+
+#define sn_idx_back       (gear_config_idx_1 + 1)
+
+#define limiter_cfg_idx_0 (sn_idx_back + 1)
+#define limiter_cfg_idx_1 (limiter_cfg_idx_0 + 1)
+
+#define mc_runtime_red_idx (limiter_cfg_idx_1 + 1)
+#define mc_crit_err_idx (mc_runtime_red_idx + 1)
+
+static motor_params_t m_params;
+static foc_params_t   foc_params;
+static mc_gear_config_t gear_config;
+static mc_limit_t limiter;
+#define NV_MAGIC 0x5AA5
+
+motor_params_t *nv_get_motor_params(void) {
+	return &m_params;
+}
+foc_params_t *nv_get_foc_params(void) {
+	return &foc_params;
+}
+
+mc_gear_config_t *nv_get_gear_configs(void) {
+	return &gear_config;
+}
+
+mc_limit_t *nv_get_limter(void) {
+	return &limiter;
 }
 
-mc_config_t *mc_config_get(void) {
-	return &g_config;
+void nv_save_hall_table(s32 *hall_table) {
+//	memcpy((char *)m_params.hall_table, (char *)hall_table, sizeof(m_params.hall_table));
+	nv_save_motor_params();
 }
 
-void store_config(void) {
-	u16 crc = crc16_get((u8 *)&g_config, sizeof(g_config) - 2);
-	g_config.crc16 = crc;
-	fmc_write_data(0, (u8 *)&g_config, sizeof(g_config));
-	fmc_write_data(1, (u8 *)&g_config, sizeof(g_config));
+void nv_save_angle_offset(float offset) {
+	m_params.offset = offset;
+	nv_save_motor_params();
 }
 
-void restore_config(void) {
-	fmc_read_data(0, (u8 *)&g_config, sizeof(g_config));
-	u16 crc0 = crc16_get((u8 *)&g_config, sizeof(g_config) - 2);
-	if (crc0 != g_config.crc16) {
-		fmc_read_data(1, (u8 *)&g_config, sizeof(g_config));
-		crc0 = crc16_get((u8 *)&g_config, sizeof(g_config) - 2);
-		if (crc0 != g_config.crc16) {
-			mc_config_default();
+
+static void nv_default_motor_params(void) {
+	m_params.mot_nr = MOTOR_NR;
+	m_params.poles = MOTOR_POLES;
+	m_params.r = MOTOR_R;
+	m_params.ld = MOTOR_Ld;
+	m_params.lq = MOTOR_Lq;
+#ifdef MOTOR_Flux
+	m_params.flux_linkage = MOTOR_Flux;
+#else
+	m_params.flux_linkage = 0;
+#endif
+	m_params.offset = MOTOR_ENC_OFFSET;
+	m_params.est_pll_band = 200;
+	m_params.epm_pll_band = 400;
+	m_params.pos_lock_pll_band = 500;
+	m_params.velocity_weight = 190;
+	m_params.velocity_C = 145;
+	m_params.gear_ratio = 6250;//6.25:1
+}
+
+static void nv_default_limter(void) {
+	limiter.motor[0].enter_pointer = 120;
+	limiter.motor[0].exit_pointer = 110;
+	limiter.motor[0].limit_value = 0;
+	limiter.motor[1].enter_pointer = 110;
+	limiter.motor[1].exit_pointer = 97;
+	limiter.motor[1].limit_value = 50;
+	limiter.motor[2].enter_pointer = 97;
+	limiter.motor[2].exit_pointer = 85;
+	limiter.motor[2].limit_value = 80;
+
+	limiter.mos[0].enter_pointer = 110;
+	limiter.mos[0].exit_pointer = 100;
+	limiter.mos[0].limit_value = 0;
+	limiter.mos[1].enter_pointer = 100;
+	limiter.mos[1].exit_pointer = 90;
+	limiter.mos[1].limit_value = 60;
+	limiter.mos[2].enter_pointer = 90;
+	limiter.mos[2].exit_pointer = 80;
+	limiter.mos[2].limit_value = 80;
+
+	limiter.vbus.enter_pointer = 76;
+	limiter.vbus.exit_pointer = 80;
+	limiter.vbus.limit_value = 20;
+}
+
+
+static void nv_default_foc_params(void) {
+	foc_params.s_maxDCVol = CONFIG_MAX_DC_VOL;
+	foc_params.s_minDCVol = CONFIG_MIN_DC_VOL;
+	foc_params.s_PhaseCurrLim = CONFIG_DEFAULT_PHASE_CURR_LIM;
+	foc_params.s_maxRPM = CONFIG_DEFAULT_RPM_LIM;
+	foc_params.s_maxEpmRPM = CONFIG_DEFAULT_EPM_RPM;
+	foc_params.s_maxEpmTorqueLim = CONFIG_DEFAULT_EPM_PHASE_CURR;
+	foc_params.s_maxTorque = CONFIG_MAX_MOTOR_TORQUE;
+	foc_params.s_TorqueBrkLim = CONFIG_DEFAULT_EBRK_TORQUE;
+	foc_params.n_currentBand = CONFIG_CURRENT_BANDWITH;
+	foc_params.n_brkShutPower = CONFIG_BRK_SHUT_POWER_ENABLE;
+	foc_params.s_LimitiDC = CONFIG_DEFAULT_IDC_LIM;
+	foc_params.s_iDCeBrkLim = CONFIG_DEFAULT_EBRK_IDC_LIM;
+	foc_params.n_startThroVol = CONFIG_THROTTLE_START_VALUE;
+	foc_params.n_endThroVol = CONFIG_THROTTLE_END_VALUE;
+	foc_params.n_autoHold = CONFIG_AUTOHOLD_ENABLE;
+	foc_params.n_dec_time = CONFIG_DEC_TIME;
+	foc_params.n_ebrk_time = CONFIG_EBRK_RAMP_TIME;
+	foc_params.n_FwEnable  = CONFIG_DEFAULT_FW_ENABLE;
+	foc_params.f_minThroVol = CONFIG_THROTTLE_MIN_VALUE;
+	foc_params.f_maxThroVol = CONFIG_THROTTLE_MAX_VALUE;
+
+	foc_params.s_maxEpmRPMBck = CONFIG_DEFAULT_EPM_BK_RPM;
+	foc_params.s_maxEpmTorqueLimBck = CONFIG_DEFAULT_EPM_BK_PHASE_CURR;
+
+	foc_params.pid_conf[PID_D_id].kp = (foc_params.n_currentBand * MOTOR_Ld);
+	foc_params.pid_conf[PID_D_id].ki = (MOTOR_R/MOTOR_Ld);
+	foc_params.pid_conf[PID_D_id].kd = 0;
+	
+	foc_params.pid_conf[PID_Q_id].kp = (foc_params.n_currentBand * MOTOR_Lq);
+	foc_params.pid_conf[PID_Q_id].ki = (MOTOR_R/MOTOR_Lq);
+	foc_params.pid_conf[PID_Q_id].kd = 0;
+
+	foc_params.pid_conf[PID_TRQ_id].kp = PI_VEL_LIM_KP;
+	foc_params.pid_conf[PID_TRQ_id].ki = PI_VEL_LIM_KI;
+	foc_params.pid_conf[PID_TRQ_id].kd = PI_VEL_LIM_KD;
+
+	foc_params.pid_conf[PID_Spd_id].kp = PI_VEL_KP;
+	foc_params.pid_conf[PID_Spd_id].ki = PI_VEL_KI;
+	foc_params.pid_conf[PID_Spd_id].kd = PI_VEL_KD;
+
+	foc_params.pid_conf[PID_Pow_id].kp = 5.0f;
+	foc_params.pid_conf[PID_Pow_id].ki = 15.0f;
+	foc_params.pid_conf[PID_Pow_id].kd = 0;
+
+	foc_params.pid_conf[PID_Lock_id].kp = (0.01f);
+	foc_params.pid_conf[PID_Lock_id].ki = (0.20f);
+	foc_params.pid_conf[PID_Lock_id].kd = 0;
+#ifdef CONFIG_SPEED_LADRC
+	foc_params.f_adrc_vel_lim_Wo = CONFIG_LADRC_Wo;
+	foc_params.f_adrc_vel_lim_Wcv = CONFIG_LADRC_Wcv;
+	foc_params.f_adrc_vel_lim_B0 = CONFIG_LADRC_B0;
+	foc_params.f_adrc_vel_Wo = CONFIG_LADRC_Wo;
+	foc_params.f_adrc_vel_Wcv = CONFIG_LADRC_Wcv;
+	foc_params.f_adrc_vel_B0 = CONFIG_LADRC_B0;
+#endif
+}
+
+static void nv_default_gear_config(void) {
+	for (int i = 0; i < CONFIG_MAX_GEAR_NUM; i++) {
+		gear_config.gears_48[i].n_max_speed = 4000;
+		gear_config.gears_48[i].n_max_trq = CONFIG_MAX_MOTOR_TORQUE/2;
+		gear_config.gears_48[i].n_max_idc = 60;
+		gear_config.gears_48[i].n_zero_accl = 500;
+		gear_config.gears_48[i].n_accl_time = 10;
+
+		gear_config.gears_96[i].n_max_speed = 8000;
+		gear_config.gears_96[i].n_max_trq = CONFIG_MAX_MOTOR_TORQUE;
+		gear_config.gears_96[i].n_max_idc = 100;
+		gear_config.gears_96[i].n_zero_accl = 500;
+		gear_config.gears_96[i].n_accl_time = 10;
+
+		for (int j = 0; j < GEAR_SPEED_TRQ_NUM; j++) {
+			gear_config.gears_48[i].n_torque[j] = 60+j;
+			gear_config.gears_96[i].n_torque[j] = 80+j;
+		}
+	}
+
+}
+
+
+void nv_write_crit_errblock(u8 *data, int len) {
+	fmc_write_data(mc_crit_err_idx, data, len);
+}
+
+void nv_read_crit_errblock(u8 *data, int len) {
+	fmc_read_data(mc_crit_err_idx, data, len);
+}
+
+void nv_write_runtime_block(u8 *data, int len) {
+	fmc_write_data(mc_runtime_red_idx, data, len);
+}
+
+void nv_read_runtime_block(u8 *data, int len) {
+	fmc_read_data(mc_runtime_red_idx, data, len);
+}
+
+void nv_save_motor_params(void) {
+	u16 crc = crc16_get((u8 *)&m_params, sizeof(m_params) - 2);
+	m_params.crc16 = crc;
+	fmc_write_data(motorParam_idx_0, (u8 *)&m_params, sizeof(m_params));
+	fmc_write_data(motorParam_idx_1, (u8 *)&m_params, sizeof(m_params));
+}
+void nv_read_motor_params(void) {
+	fmc_read_data(motorParam_idx_0, (u8 *)&m_params, sizeof(m_params));
+	u16 crc0 = crc16_get((u8 *)&m_params, sizeof(m_params) - 2);
+	if (crc0 != m_params.crc16) {
+		sys_debug("mp 0 error\n");
+		fmc_read_data(motorParam_idx_1, (u8 *)&m_params, sizeof(m_params));
+		crc0 = crc16_get((u8 *)&m_params, sizeof(m_params) - 2);
+		if (crc0 != m_params.crc16) {
+			nv_default_motor_params();
+			nv_save_motor_params();
+			return;
+		}
+		fmc_write_data(motorParam_idx_0, (u8 *)&m_params, sizeof(m_params));
+	}else {
+		fmc_read_data(motorParam_idx_1, (u8 *)&m_params, sizeof(m_params));
+		crc0 = crc16_get((u8 *)&m_params, sizeof(m_params) - 2);
+		if (crc0 != m_params.crc16) {
+			sys_debug("mp 1 error\n");
+			fmc_read_data(motorParam_idx_0, (u8 *)&m_params, sizeof(m_params));
+			fmc_write_data(motorParam_idx_1, (u8 *)&m_params, sizeof(m_params));
+		}
+	}
+}
+
+bool nv_set_limit_config(u8 *config, int len) {
+	int config_len = sizeof(nv_limter_t) * (2 * TEMP_LIMITER_NUM + 1);
+	if (len < config_len) {
+		return false;
+	}
+	memcpy(&limiter.motor[0], config, len);
+	sys_debug("lim %d %d %d\n", limiter.motor[0].enter_pointer, limiter.motor[0].exit_pointer, limiter.motor[0].limit_value);
+	nv_save_limit_config();
+	return true;
+}
+
+void* nv_get_limit_config(int *len) {
+	if (len) {
+		*len = sizeof(nv_limter_t) * (2 * TEMP_LIMITER_NUM + 1);
+	}
+	return &limiter.motor[0];
+}
+
+void nv_save_limit_config(void) {
+	limiter.magic = NV_MAGIC;
+	u16 crc = crc16_get((u8 *)&limiter, sizeof(limiter) - 2);
+	limiter.crc16 = crc;
+	fmc_write_data(limiter_cfg_idx_0, (u8 *)&limiter, sizeof(limiter));
+	fmc_write_data(limiter_cfg_idx_1, (u8 *)&limiter, sizeof(limiter));
+}
+
+void nv_read_limit_config(void) {
+	fmc_read_data(limiter_cfg_idx_0, (u8 *)&limiter, sizeof(limiter));
+	u16 crc16 = crc16_get((u8 *)&limiter, sizeof(limiter) - 2);
+	if (limiter.magic != NV_MAGIC || limiter.crc16 != crc16) {
+		sys_debug("lim 0 error\n");
+		fmc_read_data(limiter_cfg_idx_1, (u8 *)&limiter, sizeof(limiter));
+		crc16 = crc16_get((u8 *)&limiter, sizeof(limiter) - 2);
+		if (limiter.magic == NV_MAGIC && limiter.crc16 == crc16) {
+			fmc_write_data(limiter_cfg_idx_0, (u8 *)&limiter, sizeof(limiter));
 			return;
+		}else {
+			sys_debug("lim 1 error\n");
+			nv_default_limter();
+			nv_save_limit_config();
 		}
-		fmc_write_data(0, (u8 *)&g_config, sizeof(g_config));
 	}else {
-		fmc_write_data(1, (u8 *)&g_config, sizeof(g_config));
+		fmc_read_data(limiter_cfg_idx_1, (u8 *)&limiter, sizeof(limiter));
+		crc16 = crc16_get((u8 *)&limiter, sizeof(limiter) - 2);
+		if (limiter.magic != NV_MAGIC || limiter.crc16 != crc16) {
+			sys_debug("lim 1 error\n");
+			fmc_read_data(limiter_cfg_idx_0, (u8 *)&limiter, sizeof(limiter));
+			fmc_write_data(limiter_cfg_idx_1, (u8 *)&limiter, sizeof(limiter));
+		}
 	}
 }
 
-static void mc_config_default(void) {
-	g_config.hall_offset = 0;
-	for (int i = 0; i < 3; i++) {
-		g_config.phase_op[i].op_i_k = 1;
-		g_config.phase_op[i].op_i_offset = 0;;
+void nv_save_foc_params(void) {
+	u16 crc = crc16_get((u8 *)&foc_params, sizeof(foc_params) - 2);
+	foc_params.crc16 = crc;
+	fmc_write_data(focParam_idx_0, (u8 *)&foc_params, sizeof(foc_params));
+	fmc_write_data(focParam_idx_1, (u8 *)&foc_params, sizeof(foc_params));
+}
+
+void nv_read_foc_params(void) {
+	fmc_read_data(focParam_idx_0, (u8 *)&foc_params, sizeof(foc_params));
+	u16 crc0 = crc16_get((u8 *)&foc_params, sizeof(foc_params) - 2);
+	if (crc0 != foc_params.crc16) {
+		sys_debug("fp 0 error\n");
+		fmc_read_data(focParam_idx_1, (u8 *)&foc_params, sizeof(foc_params));
+		crc0 = crc16_get((u8 *)&foc_params, sizeof(foc_params) - 2);
+		if (crc0 != foc_params.crc16) {
+			nv_default_foc_params();
+			nv_save_foc_params();
+			return;
+		}
+		fmc_write_data(focParam_idx_0, (u8 *)&foc_params, sizeof(foc_params));
+	}else {
+		fmc_read_data(focParam_idx_1, (u8 *)&foc_params, sizeof(foc_params));
+		crc0 = crc16_get((u8 *)&foc_params, sizeof(foc_params) - 2);
+		if (crc0 != foc_params.crc16) {
+			sys_debug("fp 1 error\n");
+			fmc_read_data(focParam_idx_0, (u8 *)&foc_params, sizeof(foc_params));
+			fmc_write_data(focParam_idx_1, (u8 *)&foc_params, sizeof(foc_params));
+		}
 	}
+	sys_debug("maxTorque=%f\n", foc_params.s_maxTorque);
 }
+
+void nv_save_gear_configs(void) {
+	gear_config.magic = NV_MAGIC;
+	u16 crc = crc16_get((u8 *)&gear_config, sizeof(gear_config) - 2);
+	gear_config.crc16 = crc;
+	fmc_write_data(gear_config_idx_0, (u8 *)&gear_config, sizeof(gear_config));
+	fmc_write_data(gear_config_idx_1, (u8 *)&gear_config, sizeof(gear_config));
+}
+
+void nv_read_gear_configs(void) {
+	fmc_read_data(gear_config_idx_0, (u8 *)&gear_config, sizeof(gear_config));
+	u16 crc0 = crc16_get((u8 *)&gear_config, sizeof(gear_config) - 2);
+	if (crc0 != gear_config.crc16) {
+		sys_debug("gear 0 error\n");
+		fmc_read_data(gear_config_idx_1, (u8 *)&gear_config, sizeof(gear_config));
+		crc0 = crc16_get((u8 *)&gear_config, sizeof(gear_config) - 2);
+		if (crc0 != gear_config.crc16) {
+			sys_debug("default gear\n");
+			nv_default_gear_config();
+			nv_save_gear_configs();
+			return;
+		}
+		fmc_write_data(gear_config_idx_0, (u8 *)&gear_config, sizeof(gear_config));
+	}else {
+		fmc_read_data(gear_config_idx_1, (u8 *)&gear_config, sizeof(gear_config));
+		crc0 = crc16_get((u8 *)&gear_config, sizeof(gear_config) - 2);
+		if (crc0 != gear_config.crc16) {
+			sys_debug("gear 1 error\n");
+			fmc_read_data(gear_config_idx_0, (u8 *)&gear_config, sizeof(gear_config));
+			fmc_write_data(gear_config_idx_1, (u8 *)&gear_config, sizeof(gear_config));
+		}
+	}
+}
+
+#if 0
+bool nv_set_gear_config(u8 mode4896, u8 gear, u16 rpm, u16 torque, u16 idc, u16 acc) {
+	mc_gear_t *gear_cfg;
+	if (gear >= CONFIG_MAX_GEAR_NUM) {
+		return false;
+	}
+
+	if (mode4896 == 0) { //48vmode
+		gear_cfg = &gear_config.gears_48[gear];
+	}else {
+		gear_cfg = &gear_config.gears_96[gear];
+	}
+	gear_cfg->u_maxRPM = rpm;
+	gear_cfg->u_maxTorque = torque;
+	gear_cfg->u_maxIdc = idc;
+	gear_cfg->u_accTime = acc;
+
+	nv_save_gear_configs();
+	return true;
+}
+
+bool nv_get_gear_config(u8 mode4896, u8 gear, u16 *rpm, u16 *torque, u16 *idc, u16 *acc) {
+	mc_gear_t *gear_cfg;
+	if (gear >= CONFIG_MAX_GEAR_NUM) {
+		return false;
+	}
+
+	if (mode4896 == 0) { //48vmode
+		gear_cfg = &gear_config.gears_48[gear];
+	}else {
+		gear_cfg = &gear_config.gears_96[gear];
+	}
+	*rpm = gear_cfg->u_maxRPM;
+	*torque = gear_cfg->u_maxTorque;
+	*idc = gear_cfg->u_maxIdc;
+	*acc = gear_cfg->u_accTime;
+
+	return true;
+}
+#endif
+
+
+bool nv_set_gear_config(u8 mode96, u8 *config, int len) {
+	int config_len = sizeof(mc_gear_t) * CONFIG_MAX_GEAR_NUM;
+	if (len < config_len) {
+		return false;
+	}
+	if (mode96) {
+		memcpy(&gear_config.gears_96[0], config, len);
+	}else {
+		memcpy(&gear_config.gears_48[0], config, len);
+	}
+	for (int i = 0; i < CONFIG_MAX_GEAR_NUM; i++) {
+		if (gear_config.gears_48[i].n_max_speed > CONFIG_MAX_MOT_RPM) {
+			gear_config.gears_48[i].n_max_speed = CONFIG_MAX_MOT_RPM;
+		}
+
+		if (gear_config.gears_48[i].n_max_trq > CONFIG_MAX_TORQUE) {
+			gear_config.gears_48[i].n_max_trq = CONFIG_MAX_TORQUE;
+		}
+
+		if (gear_config.gears_48[i].n_max_idc > CONFIG_MAX_VBUS_CURRENT) {
+			gear_config.gears_48[i].n_max_idc = CONFIG_MAX_VBUS_CURRENT;
+		}
+		if (gear_config.gears_48[i].n_zero_accl == 0) {
+			gear_config.gears_48[i].n_zero_accl = 100;
+		}
+		if (gear_config.gears_48[i].n_accl_time == 0) {
+			gear_config.gears_48[i].n_accl_time = 1;
+		}
+
+		if (gear_config.gears_96[i].n_max_speed > CONFIG_MAX_MOT_RPM) {
+			gear_config.gears_96[i].n_max_speed = CONFIG_MAX_MOT_RPM;
+		}
+
+		if (gear_config.gears_96[i].n_max_trq > CONFIG_MAX_TORQUE) {
+			gear_config.gears_96[i].n_max_trq = CONFIG_MAX_TORQUE;
+		}
+
+		if (gear_config.gears_96[i].n_max_idc > CONFIG_MAX_VBUS_CURRENT) {
+			gear_config.gears_96[i].n_max_idc = CONFIG_MAX_VBUS_CURRENT;
+		}
+		if (gear_config.gears_96[i].n_zero_accl == 0) {
+			gear_config.gears_96[i].n_zero_accl = 100;
+		}
+		if (gear_config.gears_96[i].n_accl_time == 0) {
+			gear_config.gears_96[i].n_accl_time = 1;
+		}
+		for (int j = 0; j < GEAR_SPEED_TRQ_NUM; j++) {
+			if (gear_config.gears_48[i].n_torque[j] > 100) {
+				gear_config.gears_48[i].n_torque[j] = 100;
+			}
+
+			if (gear_config.gears_96[i].n_torque[j] > 100) {
+				gear_config.gears_96[i].n_torque[j] = 100;
+			}
+		}
+	}
+
+	nv_save_gear_configs();
+	return true;
+}
+
+void* nv_get_gear_config(u8 mode96, int *len) {
+	if (len) {
+		*len = sizeof(mc_gear_t) * CONFIG_MAX_GEAR_NUM;
+	}
+	sys_debug("gear0 %d %d\n", mode96, gear_config.gears_96[0].n_max_speed);
+	if (mode96) {
+		return &gear_config.gears_96[0];
+	}else {
+		return &gear_config.gears_48[0];
+	}
+}
+
+
+void nv_set_pid(u8 id, pid_conf_t *pid) {
+	foc_params.pid_conf[id] = *pid;
+	nv_save_foc_params();
+}
+
+void nv_get_pid(u8 id, pid_conf_t *pid) {
+	*pid = foc_params.pid_conf[id];
+}
+
+void nv_set_hwbrake_mode(u8 mode) {
+	foc_params.n_brkShutPower = mode;
+}
+
+void nv_set_throttle_vol(float min, float max) {
+	foc_params.n_startThroVol = min;
+	foc_params.n_endThroVol = max;
+}
+
+
+int nv_write_sn(u8 *data, int len) {
+	mc_sn_t sn;
+	memset(&sn, 0, sizeof(sn));
+	len = min(32, len);
+	memcpy(sn.sn, data, len);
+	sn.len = len;
+	sn.crc = crc16_get(data, len);
+	fmc_write_data(sn_page_index, (u8 *)&sn, sizeof(sn));
+	fmc_write_data(sn_idx_back, (u8 *)&sn, sizeof(sn));
+	return len;
+}
+int nv_read_sn(u8 *data, int len) {
+	mc_sn_t *sn;
+	memset(&sn, 0, sizeof(sn));
+	len = min(ARRAY_SIZE(sn->sn), len);
+	
+	sn = (mc_sn_t *)fmc_get_addr(sn_page_index);
+	u16 crc16 = crc16_get(sn->sn, min(32, sn->len));
+	if (crc16 == sn->crc) {
+		memcpy(data, sn->sn, len);
+		return len;
+	}
+	sn = (mc_sn_t *)fmc_get_addr(sn_idx_back);
+	crc16 = crc16_get(sn->sn, min(32, sn->len));
+	if (crc16 == sn->crc) {
+		memcpy(data, sn->sn, len);
+		return len;
+	}
+	return 0;
+}
+
+void nv_storage_init(void) {
+	nv_read_motor_params();
+	nv_read_foc_params();
+	nv_read_gear_configs();
+	nv_read_limit_config();
+	sys_debug("encoder_off = %f\n", m_params.offset);
+	if (m_params.mot_nr != MOTOR_NR) {
+		nv_default_motor_params();
+		nv_default_foc_params();
+		nv_save_foc_params();
+		nv_save_motor_params();
+		nv_default_gear_config();
+		nv_save_gear_configs();
+		nv_default_limter();
+		nv_save_limit_config();
+		sys_debug("change motor %x\n", m_params.mot_nr);
+	}
+#if CONFIG_MOT_TYPE==MOTOR_BLUESHARK_NEW1
+	m_params.offset = 0.0f; //编码器做了零位置校准
+#endif
+#if CONFIG_MOT_TYPE==MOTOR_BLUESHARK_ZD_100
+	m_params.offset = 0.0f; //编码器做了零位置校准
+	m_params.est_pll_band = 200;
+	m_params.flux_linkage = MOTOR_Flux;
+#endif
+#if CONFIG_MOT_TYPE==MOTOR_BLUESHARK_A1
+	m_params.offset = 0.0f; //编码器做了零位置校准
+#endif
+	sys_debug("%f -- %f, flux: %f, %d\n", foc_params.n_currentBand, m_params.ld, m_params.flux_linkage, sizeof(m_params));
+}
+

+ 130 - 12
Applications/app/nv_storage.h

@@ -1,25 +1,143 @@
 #ifndef _NV_Storage_H__
 #define _NV_Storage_H__
-#include "os/os_type.h"
-
+#include "os/os_types.h"
+#include "foc/core/PMSM_FOC_Core.h"
+#include "foc/commands.h"
 #pragma  pack (push,1)
 
 typedef struct {
-	int op_i_k; /* 斜率 */
-	int op_i_offset; /* 截距 */
-}op_cali_t;
+	float s_PhaseCurrLim;
+	float s_maxDCVol;
+	float s_minDCVol;
+	float s_maxRPM;
+	float s_maxEpmRPM;
+	float s_maxEpmTorqueLim;
+	float s_maxTorque;
+	float s_TorqueBrkLim;
+	float s_iDCeBrkLim;
+	float s_LimitiDC;
+	float n_currentBand; //电流环带宽
+	float n_startThroVol;
+	float n_endThroVol;
+	u8    n_brkShutPower;
+	u8    n_autoHold;
+	u32   n_dec_time;
+	u32   n_ebrk_time;
+	u8    n_FwEnable;
+	pid_conf_t pid_conf[PID_Max_id];
+	float f_minThroVol;
+	float f_maxThroVol;
+
+	float f_adrc_vel_lim_Wo;
+	float f_adrc_vel_lim_Wcv;
+	float f_adrc_vel_lim_B0;
+
+	float f_adrc_vel_Wo;
+	float f_adrc_vel_Wcv;
+	float f_adrc_vel_B0;
+
+	float s_maxEpmRPMBck;
+	float s_maxEpmTorqueLimBck;
+
+	u8    res[256 - 157 - 24 - 8];
+	u16   crc16;
+}foc_params_t;
+
+typedef struct {
+	u8 mot_nr;
+	u8 poles;
+	float r;
+	float ld;
+	float lq;
+	float flux_linkage;
+	float offset;
+	float est_pll_band; //normal工作模式下的pll带宽
+	float pos_lock_pll_band; //电机锁定模式下的pll带宽
+	float epm_pll_band;
+	s16   velocity_weight;//车重, kg
+	s16   velocity_C; //车轮周长, cm
+	s16   gear_ratio; //传动比
+	u8    res[128 - 36 - 6];
+	u16   crc16;
+}motor_params_t;
+
+typedef struct {
+	s16 enter_pointer;
+	s16 exit_pointer;
+	s16 limit_value;
+}nv_limter_t;
 
+#define TEMP_LIMITER_NUM 3
 typedef struct {
-	s16 hall_offset; /* hall 和A相之间的电角度偏移量 */
-	op_cali_t phase_op[3]; /* 三相电流采集的校准系数 */
+	u16  magic;
+	nv_limter_t motor[TEMP_LIMITER_NUM];
+	nv_limter_t mos[TEMP_LIMITER_NUM];
+	nv_limter_t vbus;
+	u8    res[128 - 46];
 	u16 crc16;
-}mc_config_t;
+}mc_limit_t;
+
+#define GEAR_SPEED_TRQ_NUM 10
+typedef struct {
+	u16 n_max_speed; //最大速度, rpm
+	u16 n_max_trq;   //最大扭矩
+	u16 n_max_idc;   //最大母线电流
+	u16 n_zero_accl; //零速启动扭矩给定时间,防止翘头
+	u16 n_accl_time; //加速的扭矩斜坡时间
+	u8  n_torque[GEAR_SPEED_TRQ_NUM]; //1000, 2000, 3000... RPM 最大给定扭矩的百分比(最大扭矩的百分比)
+}mc_gear_t;
+
+#define CONFIG_MAX_GEAR_NUM 4
+typedef struct {
+	mc_gear_t gears_48[CONFIG_MAX_GEAR_NUM];
+	mc_gear_t gears_96[CONFIG_MAX_GEAR_NUM];
+	u16  	  magic;
+	u16       crc16;
+}mc_gear_config_t;
+
 #pragma pack(pop)
 
-mc_config_t *mc_config_get(void);
-void config_set_hall_offset(s16 offset);
-void store_config(void);
-void restore_config(void);
+typedef struct {
+	u8 sn[32];
+	u16 len;
+	u16 crc;
+}mc_sn_t;
+
+typedef struct {
+	u8 index;
+	u16 crc;
+	u16 len;
+	u32 err_mask;
+	u8 data[0]; //just a tag, no memeory alloc
+}mc_err_red_t;
+
+void nv_storage_init(void);
+motor_params_t *nv_get_motor_params(void);
+foc_params_t *nv_get_foc_params(void);
+mc_gear_config_t *nv_get_gear_configs(void);
+mc_limit_t *nv_get_limter(void);
+void nv_save_angle_offset(float offset);
+void nv_save_motor_params(void);
+void nv_read_motor_params(void);
+void nv_save_foc_params(void);
+void nv_read_foc_params(void);
+void nv_save_hall_table(s32 *hall_table);
+void nv_set_pid(u8 id, pid_conf_t *pid);
+void nv_get_pid(u8 id, pid_conf_t *pid);
+void nv_set_hwbrake_mode(u8 mode);
+void nv_set_throttle_vol(float min, float max);
+int nv_write_sn(u8 *data, int len);
+int nv_read_sn(u8 *data, int len);
+bool nv_set_limit_config(u8 *config, int len);
+void nv_save_limit_config(void);
+void* nv_get_limit_config(int *len);
+bool nv_set_gear_config(u8 mode96, u8 *config, int len);
+void nv_save_gear_configs(void);
+void* nv_get_gear_config(u8 mode96, int *len);
+void nv_write_crit_errblock(u8 *data, int len);
+void nv_read_crit_errblock(u8 *data, int len);
+void nv_write_runtime_block(u8 *data, int len);
+void nv_read_runtime_block(u8 *data, int len);
 
 #endif /* _NV_Storage_H__ */
 

+ 0 - 196
Applications/bsp/adc.c

@@ -1,196 +0,0 @@
-#include "bsp/adc.h"
-#include "libs/utils.h"
-#include "os/co_task.h"
-static void _gpio_init(void);
-static void _adc0_init(void);
-static void _adc0_insert_chan_init(void);
-static void _adc0_regular_chan_init(void);
-static void _adc1_init(void);
-static void _adc1_insert_chan_init(void);
-static void _adc1_regular_chan_init(void);
-/*
-ADC0 inserted 采集母线电流
-ADC1 inserted 采集三相电流
-每次同时发送母线电流和响应的相电流,通过母线电流给相电流采集的MOS内阻校准
-可以理解为FOC工作在三电阻采样模式下,只是需要不停的校准MOS的内阻
-*/
-void adc_init(void){
-	/* init adc input gpio */
-	_gpio_init();
-    /* config ADC clock */
-    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4); //APB2 clk 120M, adc clk 30M
-
-	_adc0_init();
-
-	_adc1_init();
-
-	adc_config_trigger(ADC_TRIGGER_PHASE);
-
-	nvic_irq_enable(ADC0_1_IRQn, ADC_IRQ_PRIORITY, 0);
-}
-
-static void _gpio_init(void) {
-	rcu_periph_clock_enable(RCU_GPIOA);
-	rcu_periph_clock_enable(RCU_GPIOB);
-	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
-	gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_1);
-}
-
-static void _adc0_init(void) {
-	u32 adc_dev = ADC0;
-    /* enable ADC1 clock */
-    rcu_periph_clock_enable(RCU_ADC0);
-    /* ADC mode config,adc0 master, adc1 slave */
-    adc_mode_config(ADC_DAUL_INSERTED_PARALLEL);
-    /* ADC special function config */
-    adc_special_function_config(adc_dev, ADC_SCAN_MODE, ENABLE);
-    adc_special_function_config(adc_dev, ADC_CONTINUOUS_MODE, DISABLE);  
-    /* ADC data alignment config */
-    adc_data_alignment_config(adc_dev, ADC_DATAALIGN_RIGHT);
-	/* init insert chans*/
-	_adc0_insert_chan_init();
-	/* init regular chans*/
-	_adc0_regular_chan_init();
-	adc_interrupt_disable(adc_dev, ADC_INT_EOIC);
-	adc_interrupt_disable(adc_dev, ADC_INT_EOC);
-	adc_interrupt_disable(adc_dev, ADC_INT_WDE);	
-    /* enable ADC interface */
-    adc_enable(adc_dev);
-    delay_ms(1);
-    /* ADC calibration and reset calibration */
-    adc_calibration_enable(adc_dev);
-}
-
-static void _adc1_init(void) {
-	u32 adc_dev = ADC1;
-    /* enable ADC1 clock */
-    rcu_periph_clock_enable(RCU_ADC1);
-    /* ADC mode config,adc0 master, adc1 slave */
-    adc_mode_config(ADC_DAUL_INSERTED_PARALLEL); 
-    /* ADC special function config */
-    adc_special_function_config(adc_dev, ADC_SCAN_MODE, ENABLE);
-    adc_special_function_config(adc_dev, ADC_CONTINUOUS_MODE, DISABLE);  
-    /* ADC data alignment config */
-    adc_data_alignment_config(adc_dev, ADC_DATAALIGN_RIGHT);
-	/* init insert chans*/
-	_adc1_insert_chan_init();
-	/* init regular chans*/
-	_adc1_regular_chan_init();
-	adc_interrupt_disable(adc_dev, ADC_INT_EOIC);
-	adc_interrupt_disable(adc_dev, ADC_INT_EOC);
-	adc_interrupt_disable(adc_dev, ADC_INT_WDE);
-    /* enable ADC interface */
-    adc_enable(adc_dev);
-    delay_ms(1);
-    /* ADC calibration and reset calibration */
-    adc_calibration_enable(adc_dev);
-
-}
-
-/* ADC0 insert chan sample phase I(use two chan, selected by foc) */
-static void _adc0_insert_chan_init(void) {
-	u32 adc_dev = ADC0;
-	//adc_discontinuous_mode_config(adc_dev, ADC_INSERTED_CHANNEL, 0);	
-    /* ADC channel length config */
-    adc_channel_length_config(adc_dev, ADC_INSERTED_CHANNEL, 1);
-    /* ADC inserted channel ran config, use ISQ2,ISQ3 */
-	adc_update_insert_sample_rank(adc_dev, U_PHASE_I_CHAN);
-	/* config inserted channel sample time */
-	adc_update_insert_sample_time(adc_dev, U_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-	adc_update_insert_sample_time(adc_dev, V_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-	adc_update_insert_sample_time(adc_dev, W_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-    /* ADC trigger config */
-    adc_external_trigger_source_config(adc_dev, ADC_INSERTED_CHANNEL, ADC0_1_EXTTRIG_INSERTED_T0_CH3); 
-	/* ADC external trigger enable */
-    adc_external_trigger_config(adc_dev, ADC_INSERTED_CHANNEL, ENABLE);	
-}
-
-/* ADC1 insert chan sample vbus I */
-static void _adc1_insert_chan_init(void) {
-	u32 adc_dev = ADC1;
-	//adc_discontinuous_mode_config(adc_dev, ADC_INSERTED_CHANNEL, 0);
-    /* ADC channel length config */
-    adc_channel_length_config(adc_dev, ADC_INSERTED_CHANNEL, 1);
-    /* ADC inserted channel config */
-	adc_update_insert_sample_rank(adc_dev, V_PHASE_I_CHAN);
-	/* config inserted channel sample time */
-	adc_update_insert_sample_time(adc_dev, U_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-	adc_update_insert_sample_time(adc_dev, V_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-	adc_update_insert_sample_time(adc_dev, W_PHASE_I_CHAN, ADC_SAMPLETIME_7POINT5);
-
-    /* ADC trigger config, slave must config to software trigger */
-    adc_external_trigger_source_config(adc_dev, ADC_INSERTED_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
-	/* ADC external trigger enable */
-    adc_external_trigger_config(adc_dev, ADC_INSERTED_CHANNEL, ENABLE);
-}
-
-static void _adc0_regular_chan_init(void) {
-	adc_discontinuous_mode_config(ADC0, ADC_REGULAR_CHANNEL, 1); //每次转化一个
-	/* ADC channel length config */
-	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
-	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
-	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); 
-	adc_regular_channel_config(ADC0, 0, MOTOR_TEMP_CHAN, ADC_SAMPLETIME_55POINT5);
-	//adc_regular_channel_config(ADC0, 1, HANDLERBAR_CHAN, ADC_SAMPLETIME_55POINT5);
-	//adc_regular_channel_config(ADC0, 2, VBUS_V_CHAN, ADC_SAMPLETIME_55POINT5);
-}
-
-static void _adc1_regular_chan_init(void) {
-	adc_discontinuous_mode_config(ADC1, ADC_REGULAR_CHANNEL, 1); //每次转化一个
-	/* ADC channel length config */
-	adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 1);
-	adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
-	adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
-	adc_regular_channel_config(ADC1, 0, W_PHASE_V_CHAN, ADC_SAMPLETIME_55POINT5);
-	//adc_regular_channel_config(ADC1, 1, V_PHASE_V_CHAN, ADC_SAMPLETIME_55POINT5);
-	//adc_regular_channel_config(ADC1, 2, U_PHASE_V_CHAN, ADC_SAMPLETIME_55POINT5);
-}
-
-void adc_start_insert_convert(void) {
-    /* clear the ADC flag */
-    adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
-    adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);
-    adc_interrupt_flag_clear(ADC1, ADC_INT_FLAG_EOC);
-    adc_interrupt_flag_clear(ADC1, ADC_INT_FLAG_EOIC);	
-    /* enable ADC interrupt */
-    adc_interrupt_enable(ADC0, ADC_INT_EOIC);
-	adc_interrupt_enable(ADC1, ADC_INT_EOIC);
-}
-
-s32 adc_sample_regular_channel(int channel, int times) {
-	u32 adc_device = ADC0;
-	if (channel >= W_PHASE_V_CHAN && channel <= U_PHASE_V_CHAN) {
-		adc_device = ADC1;
-	}
-	int value = 0;
-	int count = 0;
-	int min = 0xFFFFF;
-	int max = -0xFFFFF;
-	u64 start_time;
-	adc_regular_channel_config(adc_device, 0, channel, ADC_SAMPLETIME_55POINT5);
-	while(count < times){
-restart:		
-		start_time = co_task_sys64_ticks();
-		adc_software_trigger_enable(adc_device, ADC_REGULAR_CHANNEL);
-    	while(SET != adc_flag_get(adc_device, ADC_FLAG_EOC)){
-			if (co_task_sys64_ticks() - start_time >= 2){
-				goto restart;
-			}
-		};
-    	int one = adc_regular_data_read(adc_device);
-		adc_flag_clear(adc_device, ADC_FLAG_EOC);		
-		value += (one & 0xFFF);
-		count ++;
-		if (one > max){
-			max = one;
-		}
-		if (one < min) {
-			min = one;
-		}
-	}
-	if (times <= 2) {
-		return value/times;
-	}
-	return (value - min - max)/(times-2);	
-}
-

+ 0 - 160
Applications/bsp/adc.h

@@ -1,160 +0,0 @@
-#ifndef _ADC_H__
-#define _ADC_H__
-#include "bsp/bsp.h"
-#include "os/os_type.h"
-
-/*
-inserted ADC 由timer0 ch3触发,
-注意:adc所有外部触发都是下降沿触发 
-*/
-#define MOTOR_TEMP_CHAN ADC_CHANNEL_0
-#define HANDLERBAR_CHAN ADC_CHANNEL_1 //转把信号
-#define VBUS_V_CHAN 	ADC_CHANNEL_2
-#define W_PHASE_V_CHAN  ADC_CHANNEL_3
-#define V_PHASE_V_CHAN  ADC_CHANNEL_4
-#define U_PHASE_V_CHAN  ADC_CHANNEL_5
-#define W_PHASE_I_CHAN  ADC_CHANNEL_6
-#define V_PHASE_I_CHAN  ADC_CHANNEL_7
-#define U_PHASE_I_CHAN  ADC_CHANNEL_8
-#define VBUS_I_CHAN     ADC_CHANNEL_9
-#define ISQ2_OFFSET 10
-#define ISO3_OFFSET 15
-#define IL_OFFSET   20
-
-//#define ADC_RANK_CHANNEL(c1, c2, l) ((c1)<<ISQ2_OFFSET | (c2)<<ISO3_OFFSET | (l)<<IL_OFFSET)
-#define ADC_RANK_CHANNEL(c)  ((c)<<ISO3_OFFSET | (0)<<IL_OFFSET) 
-#define ADC_CALI_RANK_CHANEL(c)  ((c)<<ISO3_OFFSET | (0)<<IL_OFFSET) 
-static u32 adc0_rank_channels[6] = {
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
-};
-static u32 adc1_rank_channels[6] = {
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),
-	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),
-};
-
-static u32 adc0_cali_rank_channels[3] = {
-	ADC_CALI_RANK_CHANEL(U_PHASE_I_CHAN),
-	ADC_CALI_RANK_CHANEL(V_PHASE_I_CHAN),
-	ADC_CALI_RANK_CHANEL(W_PHASE_I_CHAN),
-};
-static u32 adc1_cali_rank_channels[3] = {
-	ADC_CALI_RANK_CHANEL(VBUS_I_CHAN),
-	ADC_CALI_RANK_CHANEL(VBUS_I_CHAN),
-	ADC_CALI_RANK_CHANEL(VBUS_I_CHAN),
-};
-
-#define PHASE_I_ADC ADC0
-static u32 volatile * adc_phase_reg1[6] = {
-	&ADC_IDATA0(ADC0),
-	&ADC_IDATA0(ADC1),
-	&ADC_IDATA0(ADC0),
-	&ADC_IDATA0(ADC1),
-	&ADC_IDATA0(ADC0),
-	&ADC_IDATA0(ADC1),
-};
-static u32 volatile * adc_phase_reg2[6] = {
-	&ADC_IDATA0(ADC1),
-	&ADC_IDATA0(ADC0),
-	&ADC_IDATA0(ADC1),
-	&ADC_IDATA0(ADC0),
-	&ADC_IDATA0(ADC1),
-	&ADC_IDATA0(ADC0),
-};
-
-static void __inline adc_phase_current_read(u8 sector, u32 *v1, u32 *v2) {
-	*v1 = (*adc_phase_reg1[sector]) << 4;
-	*v2 = (*adc_phase_reg2[sector]) << 4;
-}
-
-static void __inline adc_cali_current_read(u32 *v1, u32 *v2) {
-	*v1 = ADC_IDATA0(ADC0);
-	*v2 = ADC_IDATA0(ADC1);
-}
-
-
-static void __inline adc_phase_inserted_config(u8 sector) {
-	ADC_ISQ(ADC0) = adc0_rank_channels[sector];
-	ADC_ISQ(ADC1) = adc1_rank_channels[sector];
-}
-
-
-static void __inline adc_cali_inserted_config(u8 invert) {
-	ADC_ISQ(ADC0) = adc0_cali_rank_channels[invert];
-	ADC_ISQ(ADC1) = adc1_cali_rank_channels[invert];
-}
-
-#define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_CH3
-#define ADC_TRIGGER_VBUS ADC0_1_EXTTRIG_INSERTED_T1_CH0
-
-
-static void __inline adc_config_trigger(u32 trigger) {
-	ADC_CTL1(ADC0) &= ~((uint32_t)ADC_CTL1_ETSIC);
-	ADC_CTL1(ADC0) |= (uint32_t)trigger;
-
-	ADC_CTL1(ADC1) &= ~((uint32_t)ADC_CTL1_ETSIC);
-	ADC_CTL1(ADC1) |= (uint32_t)trigger;
-}
-
-static bool __inline adc_is_trigged_vbus(void) {
-	if ((ADC_CTL1(ADC1) & ADC_TRIGGER_VBUS) == ADC_TRIGGER_VBUS) {
-		return true;
-	}
-	return false;
-}
-
-/* insert len fixed to 2(IL=1), ISQ2 >> ISQ3*/
-static __inline__ void adc_update_insert_sample_rank(u32 adc, u8 channel) {
-    ADC_ISQ(adc) = ADC_RANK_CHANNEL(channel);
-}
-
-static __inline__ void adc_update_insert_sample_time(u32 adc, uint8_t adc_channel , uint32_t sample_time)
-{
-    uint32_t sampt;
-    /* ADC sampling time config */  
-    if(adc_channel < 10U){
-        sampt = ADC_SAMPT1(adc);
-        sampt &= ~((u32)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
-        sampt |= (u32) sample_time << (3U*adc_channel);
-        ADC_SAMPT1(adc) = sampt;
-    }else if(adc_channel < 18U){
-        sampt = ADC_SAMPT0(adc);
-        sampt &= ~((u32)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
-        sampt |= ((u32)sample_time << (3U*(adc_channel-10U)));
-        ADC_SAMPT0(adc) = sampt;
-    }
-}
-
-static __inline__ bool adc_eoic_interrupt(void)
-{
-	if (ADC_STAT(ADC0) & ADC_STAT_EOIC){
-		return true;
-	}
-	if (ADC_STAT(ADC1) & ADC_STAT_EOIC){
-		return true;
-	}
-	return false;
-}
-
-static __inline__ void adc_clear_eoic_flags(void) {
-	ADC_STAT(ADC0) &= ~((u32) ADC_STAT_EOIC);
-	ADC_STAT(ADC1) &= ~((u32) ADC_STAT_EOIC);
-}
-
-
-static __inline__ void adc_insert_continue_mode(u32 adc_periph) {
-	ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISIC ));
-}
-void adc_init(void);
-s32 adc_sample_regular_channel(int chan, int times);
-void adc_start_insert_convert(void);
-
-#endif /* _ADC_H__ */

+ 471 - 0
Applications/bsp/at32/adc.c

@@ -0,0 +1,471 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+#include "math/fast_math.h"
+
+
+#ifdef CONFIG_BOARD_MCXXX
+#if (CONFIG_HW_VERSION==2)
+#define ADC01_NUM (8)
+#define ADC2_NUM 4
+
+#define MOS_TEMP_BUFF_IDX 0
+#define VREF5v_BUFF_IDX 1
+#define VBUS_I_BUFF_IDX 2
+#define U_VOL_BUFF_IDX 3
+#define V_VOL_BUFF_IDX 4
+#define W_VOL_BUFF_IDX 5
+#define VREF_BUFF_IDX 7
+
+#define VBUS_V_BUFF_IDX 8
+#define ACC_V_BUFF_IDX 9
+#define THROTTLE_BUFF_IDX 10
+#define MOTOR_TEMP_BUFF_IDX 11
+
+#elif (CONFIG_HW_VERSION==3)
+#define ADC1_NUM 9
+#define ADC2_NUM 9
+
+#define MOS_TEMP_BUFF_IDX 0
+#define VBUS_V_BUFF_IDX 1
+
+#define MOTOR_TEMP_BUFF_IDX 2
+#define ACC_V_BUFF_IDX 3
+
+#define THROTTLE_BUFF_IDX 4
+#define VBUS_I_BUFF_IDX 5
+
+#define THROTTLE2_BUFF_IDX 6
+#define V_VOL_BUFF_IDX 7
+
+//zero chan            8
+#define W_VOL_BUFF_IDX 9
+
+#define VREF_BUFF_IDX   10
+//zero chan             11
+
+#define THROTTLE2_5V_BUFF_IDX 12
+#define THROTTLE_5V_BUFF_IDX 13
+
+#define U_VOL_BUFF_IDX 14
+//zero chan            15
+
+//zero chan            16
+#define VREF5v_BUFF_IDX 17
+
+#endif
+#endif
+#define REG_CHAN_NUM (ADC1_NUM + ADC2_NUM)
+u16 adc_buffer[REG_CHAN_NUM];
+float vref_adc = 1408.0f;
+float vref_5v_adc = 3095.0f;
+
+static void analog_gpio_init(gpio_type *gpiox, u32 pin) {
+	gpio_init_type gpio_init_struct = {0};
+	/* gpio configuration */
+	gpio_default_para_init(&gpio_init_struct);
+	gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
+	gpio_init_struct.gpio_pins = pin;
+	gpio_init(gpiox, &gpio_init_struct);
+}
+
+static void adc01_dma_init(void)
+{
+    dma_init_type dma_init_struct;
+	/* dma clock configuration */
+	crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
+
+	/* dma configuration */
+	dma_reset(DMA1_CHANNEL1);
+	dma_default_para_init(&dma_init_struct);
+	dma_init_struct.buffer_size = REG_CHAN_NUM/2;
+	dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
+	dma_init_struct.memory_base_addr = (uint32_t)adc_buffer;
+	dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;
+	dma_init_struct.memory_inc_enable = TRUE;
+	dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt);
+	dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
+	dma_init_struct.peripheral_inc_enable = FALSE;
+	dma_init_struct.priority = DMA_PRIORITY_HIGH;
+	dma_init_struct.loop_mode_enable = TRUE;
+	dma_init(DMA1_CHANNEL1, &dma_init_struct);
+	
+	dma_channel_enable(DMA1_CHANNEL1, TRUE);
+
+}
+
+
+static void adc0_init(void){
+	adc_base_config_type adc_base_struct;
+	
+	/* adc clock configuration */
+	crm_adc_clock_div_set(CRM_ADC_DIV_8);								  /* PCLK2 Max. CLK = 100M Hz, ADC_CLK = 100/4 = 25M Hz */
+	crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
+	crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
+
+	adc_reset(ADC1);
+	adc_reset(ADC2);
+	
+	adc_base_struct.sequence_mode = TRUE;
+	adc_base_struct.repeat_mode = TRUE;
+	adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
+	adc_base_struct.ordinary_channel_length = ADC1_NUM;
+	adc_base_config(ADC1, &adc_base_struct);
+	adc_base_config(ADC2, &adc_base_struct);
+	
+	/* ordinary channel configuration */
+	adc_ordinary_channel_set(ADC1, MOS_TEMP_ADC_CHAN, 1, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, MOTOR_TEMP_ADC_CHAN, 2, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, THROTTLE_CHAN, 3, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, THROTTLE2_CHAN, 4, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, ZERO_ADC_CHAN, 5, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_channel_set(ADC1, ADC_CHANNEL_17, 6, ADC_REGCHAN_SAMPLE_TIME); //mcu内部vref
+	adc_ordinary_channel_set(ADC1, THROTTLE2_5V_CHAN, 7, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, U_VOL_ADC_CHAN, 8, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC1, ZERO_ADC_CHAN, 9, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
+
+	adc_ordinary_channel_set(ADC2, VBUS_V_CHAN, 1, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ACC_V_CHAN, 2, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, VBUS_I_CHAN, 3, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, V_VOL_ADC_CHAN, 4, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, W_VOL_ADC_CHAN, 5, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ZERO_ADC_CHAN, 6, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_channel_set(ADC2, THROTTLE_5V_CHAN, 7, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ZERO_ADC_CHAN, 8, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_channel_set(ADC2, DC5V_ADC_CHAN, 9, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_conversion_trigger_set(ADC2, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
+
+
+	adc_preempt_channel_length_set(ADC1, 3);
+	adc_preempt_channel_set(ADC1, V_PHASE_I_CHAN, 1, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC1, V_PHASE_I_CHAN, 2, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC1, V_PHASE_I_CHAN, 3, ADC_INSERT_SAMPLE_TIME);
+	//adc_preempt_channel_set(ADC1, V_PHASE_I_CHAN, 4, ADC_INSERT_SAMPLE_TIME);
+	/* adc prempt trigger source */
+	adc_preempt_conversion_trigger_set(ADC1, ADC12_PREEMPT_TRIG_TMR1CH4, TRUE);
+
+	adc_preempt_channel_length_set(ADC2, 3);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 1, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 2, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 3, ADC_INSERT_SAMPLE_TIME);
+	//adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 4, ADC_INSERT_SAMPLE_TIME);
+	/* adc prempt trigger source */
+	adc_preempt_conversion_trigger_set(ADC2, ADC12_PREEMPT_TRIG_TMR1CH4, TRUE);
+
+	/* select adc mster-slave mode */
+	adc_combine_mode_select(ADC_ORDINARY_SMLT_PREEMPT_SMLT_MODE);
+
+	adc_tempersensor_vintrv_enable(TRUE);
+
+	adc_dma_mode_enable(ADC1, TRUE);
+	adc_dma_mode_enable(ADC2, TRUE);
+
+	/* ADC enable and calibration */
+	adc_enable(ADC1, TRUE);
+	adc_calibration_init(ADC1);
+	while(adc_calibration_init_status_get(ADC1));
+	adc_calibration_start(ADC1);
+	while(adc_calibration_status_get(ADC1));
+
+	adc_enable(ADC2, TRUE);
+	adc_calibration_init(ADC2);
+	while(adc_calibration_init_status_get(ADC2));
+	adc_calibration_start(ADC2);
+	while(adc_calibration_status_get(ADC2));
+
+	nvic_irq_enable(ADC1_2_IRQn, ADC_IRQ_PRIORITY, 0);
+
+	adc_disable_ext_trigger();
+
+	adc_current_sample_config(0);
+	
+	adc_ordinary_software_trigger_enable(ADC1, TRUE);
+}
+
+static void adc1_init(void){
+
+#if 0
+	adc_base_config_type adc_base_struct;
+	
+	/* adc clock configuration */
+	crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
+
+	adc_reset(ADC2);
+	adc_base_struct.sequence_mode = TRUE;
+	adc_base_struct.repeat_mode = TRUE;
+	adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
+	adc_base_struct.ordinary_channel_length = ADC2_NUM;
+	adc_base_config(ADC2, &adc_base_struct);
+
+	/* ordinary channel configuration */
+	adc_ordinary_channel_set(ADC2, VBUS_V_CHAN, 1, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ACC_V_CHAN, 2, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, VBUS_I_CHAN, 3, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, V_VOL_ADC_CHAN, 4, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, W_VOL_ADC_CHAN, 5, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ZERO_ADC_CHAN, 6, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_channel_set(ADC2, THROTTLE_5V_CHAN, 7, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_channel_set(ADC2, ZERO_ADC_CHAN, 8, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_ordinary_channel_set(ADC2, DC5V_ADC_CHAN, 9, ADC_REGCHAN_SAMPLE_TIME);
+	adc_ordinary_conversion_trigger_set(ADC2, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);
+
+	adc_preempt_channel_length_set(ADC2, 3);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 1, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 2, ADC_INSERT_SAMPLE_TIME);
+	adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 3, ADC_INSERT_SAMPLE_TIME);
+	//adc_preempt_channel_set(ADC2, W_PHASE_I_CHAN, 4, ADC_INSERT_SAMPLE_TIME);
+	/* adc prempt trigger source */
+	adc_preempt_conversion_trigger_set(ADC2, ADC12_PREEMPT_TRIG_TMR1CH4, TRUE);
+
+	adc_dma_mode_enable(ADC2, TRUE);
+	/* ADC enable and calibration */
+	adc_enable(ADC2, TRUE);
+	adc_calibration_init(ADC2);
+	while(adc_calibration_init_status_get(ADC2));
+	adc_calibration_start(ADC2);
+	while(adc_calibration_status_get(ADC2));
+#endif
+}
+
+
+static void adc_gpio_init(void) {
+
+	/* configure ADC pin, current sampling -- ADC_IN1(PA1) ADC_IN12(PC2) ADC_IN13(PC3) */
+#ifdef U_PHASE_ADC_GROUP
+	crm_periph_clock_enable(U_PHASE_ADC_RCU, TRUE);
+	analog_gpio_init(U_PHASE_ADC_GROUP, U_PHASE_ADC_PIN);
+#endif
+#ifdef V_PHASE_ADC_GROUP
+	crm_periph_clock_enable(V_PHASE_ADC_RCU, TRUE);
+	analog_gpio_init(V_PHASE_ADC_GROUP, V_PHASE_ADC_PIN);
+#endif
+#ifdef W_PHASE_ADC_GROUP
+	crm_periph_clock_enable(W_PHASE_ADC_RCU, TRUE);
+	analog_gpio_init(W_PHASE_ADC_GROUP, W_PHASE_ADC_PIN);
+#endif
+
+#ifdef VBUS_V_ADC_GROUP
+	crm_periph_clock_enable(VBUS_V_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(VBUS_V_ADC_GROUP, VBUS_V_ADC_PIN);
+#endif
+
+#ifdef VBUS_I_ADC_GROUP
+	crm_periph_clock_enable(VBUS_I_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(VBUS_I_ADC_GROUP, VBUS_I_ADC_PIN);
+#endif
+
+
+#ifdef ACC_V_ADC_GROUP
+	crm_periph_clock_enable(ACC_V_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(ACC_V_ADC_GROUP, ACC_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_V_ADC_GROUP
+	crm_periph_clock_enable(THROTTLE_V_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(THROTTLE_V_ADC_GROUP, THROTTLE_V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_V_ADC_GROUP
+	crm_periph_clock_enable(THROTTLE2_V_ADC_RCU, TRUE);
+	analog_gpio_init(THROTTLE2_V_ADC_GROUP, THROTTLE2_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_5V_ADC_GROUP
+	crm_periph_clock_enable(THROTTLE_5V_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(THROTTLE_5V_ADC_GROUP, THROTTLE_5V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_5V_ADC_GROUP
+	crm_periph_clock_enable(THROTTLE2_5V_ADC_RCU, TRUE);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	analog_gpio_init(THROTTLE2_5V_ADC_GROUP, THROTTLE2_5V_ADC_PIN);
+#endif
+
+#ifdef U_VOL_ADC_GROUP
+	crm_periph_clock_enable(U_VOL_ADC_RCU, TRUE);
+	analog_gpio_init(U_VOL_ADC_GROUP,  U_VOL_ADC_PIN);
+#endif
+#ifdef V_VOL_ADC_GROUP
+	crm_periph_clock_enable(V_VOL_ADC_RCU, TRUE);
+	analog_gpio_init(V_VOL_ADC_GROUP, V_VOL_ADC_PIN);
+#endif
+#ifdef W_VOL_ADC_GROUP
+	crm_periph_clock_enable(W_VOL_ADC_RCU, TRUE);
+	analog_gpio_init(W_VOL_ADC_GROUP, W_VOL_ADC_PIN);
+#endif
+#ifdef MOS_TEMP_ADC_GROUP
+	crm_periph_clock_enable(MOS_TEMP_ADC_RCU, TRUE);
+	analog_gpio_init(MOS_TEMP_ADC_GROUP, MOS_TEMP_ADC_PIN);
+#endif
+#ifdef MOS_TEMP1_ADC_GROUP
+	crm_periph_clock_enable(MOS_TEMP1_ADC_RCU, TRUE);
+	analog_gpio_init(MOS_TEMP1_ADC_GROUP, MOS_TEMP1_ADC_PIN);
+#endif
+
+#ifdef MOTOR_TEMP_ADC_GROUP
+	crm_periph_clock_enable(MOTOR_TEMP_ADC_RCU, TRUE);
+	analog_gpio_init(MOTOR_TEMP_ADC_GROUP, MOTOR_TEMP_ADC_PIN);
+#endif
+
+#ifdef ZERO_ADC_GROUP
+	crm_periph_clock_enable(ZERO_ADC_RCU, TRUE);
+	analog_gpio_init(ZERO_ADC_GROUP, ZERO_ADC_PIN);
+#endif
+
+}
+
+void adc_init(void) {
+	adc_gpio_init();
+	adc01_dma_init();
+	adc0_init();
+	adc1_init();
+}
+
+void adc_set_vref_calc(float v) {
+	vref_adc = v;
+}
+
+void adc_set_5vref_calc(float v) {
+	vref_5v_adc = v;
+}
+
+#define VREF_COMP_LFP_CEOF (0.0001F)
+static float vref_compestion_filter = 1.0f;
+#define VREF_3V3_COMPESTION() (vref_adc/(float)adc_buffer[VREF_BUFF_IDX])
+void adc_3v3ref_filter(void) {
+	float value = VREF_3V3_COMPESTION();
+	LowPass_Filter(vref_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_vref_compesion(void) {
+	return vref_compestion_filter;
+}
+
+static float vref_5v_compestion_filter = 1.0f;
+#define VREF_5V_COMPESTION() (vref_5v_adc/(float)adc_buffer[VREF5v_BUFF_IDX])
+void adc_5vref_filter(void) {
+	float value = VREF_5V_COMPESTION();
+	LowPass_Filter(vref_5v_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_5vref_compesion(void) {
+	return vref_5v_compestion_filter;
+}
+
+void adc_vref_filter(void) {
+	adc_3v3ref_filter();
+	adc_5vref_filter();
+}
+
+u16 adc_get_vbus(void) {
+	return (float)adc_buffer[VBUS_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+}
+
+u16 adc_get_acc(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[ACC_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_vbus();
+#endif
+}
+
+u16 adc_get_ibus(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[VBUS_I_BUFF_IDX] * VREF_5V_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_throttle(void) {
+	return adc_buffer[THROTTLE_BUFF_IDX] * VREF_3V3_COMPESTION();
+}
+
+u16 adc_get_throttle2(void) {
+#ifdef THROTTLE2_BUFF_IDX
+	return adc_buffer[THROTTLE2_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_throttle();
+#endif
+}
+
+u16 adc_get_thro_5v(void) {
+#ifdef THROTTLE_5V_BUFF_IDX
+	return adc_buffer[THROTTLE_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_thro2_5v(void) {
+#ifdef THROTTLE2_5V_BUFF_IDX
+	return adc_buffer[THROTTLE2_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+void adc_get_uvw_phaseV(u16 *uvw) {
+	uvw[0] = adc_buffer[U_VOL_BUFF_IDX];
+	uvw[1] = adc_buffer[V_VOL_BUFF_IDX];
+	uvw[2] = adc_buffer[W_VOL_BUFF_IDX];
+}
+
+u16 adc_get_mos_temp(void) {
+	return adc_buffer[MOS_TEMP_BUFF_IDX];
+}
+
+u16 adc_get_motor_temp(void) {
+	return adc_buffer[MOTOR_TEMP_BUFF_IDX];
+}
+
+u16 adc_get_vref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_5v_ref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF5v_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+void adc_start_convert(void) {
+	int drop = 16;
+    /* clear the ADC flag */
+    adc_flag_clear(ADC1, ADC_PCCE_FLAG);
+    adc_flag_clear(ADC2, ADC_PCCE_FLAG);
+
+	adc_enable_ext_trigger();
+	while(drop-- > 0) {
+		while (adc_flag_get(ADC1, ADC_PCCE_FLAG) == RESET);
+		adc_flag_clear(ADC1, ADC_PCCE_FLAG);
+	}
+    /* enable ADC interrupt */
+
+	adc_interrupt_enable(ADC1, ADC_PCCE_INT, TRUE);
+
+	adc_update_ext_trigger(ADC_TRIGGER_PHASE);
+}
+
+void adc_stop_convert(void) {
+	adc_disable_ext_trigger();
+    /* disable ADC interrupt */
+
+	adc_interrupt_enable(ADC1, ADC_PCCE_INT, FALSE);
+
+    /* clear the ADC flag */
+    adc_flag_clear(ADC1, ADC_PCCE_FLAG);
+	adc_flag_clear(ADC2, ADC_PCCE_FLAG);
+}
+

+ 78 - 0
Applications/bsp/at32/adc.h

@@ -0,0 +1,78 @@
+#ifndef _ADC_H__
+#define _ADC_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+float adc_vref_compesion(void);
+float adc_5vref_compesion(void);
+
+/*
+inserted ADC 由timer0 ch3触发,
+注意:adc所有外部触发都是下降沿触发 
+*/
+#define ISQ0_OFFSET 0
+#define ISQ1_OFFSET 5
+#define ISQ2_OFFSET 10
+#define ISQ3_OFFSET 15
+#define IL_OFFSET   20
+
+#define ADC_REGCHAN_SAMPLE_TIME ADC_SAMPLETIME_239_5
+#define ADC_INSERT_SAMPLE_TIME ADC_SAMPLETIME_28_5
+#define ADC_TRIGGER_PHASE ADC12_PREEMPT_TRIG_TMR1CH4
+
+#define PHASE_AB 0
+#define PHASE_AC 1
+#define PHASE_BC 2
+
+
+static void __inline adc_phase_current_read(u8 phases, s32 *v1, s32 *v2) {
+	*v1 = (s32)((float)((ADC1->pdt2_bit.pdt2 + ADC1->pdt3_bit.pdt3)/2.0f) * adc_5vref_compesion());
+	*v2 = (s32)((float)((ADC2->pdt2_bit.pdt2 + ADC2->pdt3_bit.pdt3)/2.0f) * adc_5vref_compesion());
+}
+
+
+static void __inline adc_current_sample_config(u8 phases) {
+	//ADC1->psq_bit.psn4 = V_PHASE_I_CHAN;
+	//ADC2->psq_bit.psn4 = W_PHASE_I_CHAN;
+}
+
+static void __inline adc_disable_ext_trigger(void) {   
+	//ADC1->ctrl2_bit.pcten = FALSE;
+	//ADC2->ctrl2_bit.pcten = FALSE;
+}
+
+static void __inline adc_enable_ext_trigger(void) {	
+	//ADC1->ctrl2_bit.pcten = TRUE;
+	//ADC2->ctrl2_bit.pcten = TRUE;
+}
+
+static __inline__ void adc_clear_irq_flags(void) {
+    /* clear the ADC flag */
+    adc_flag_clear(ADC1, ADC_PCCE_FLAG);
+	adc_flag_clear(ADC2, ADC_PCCE_FLAG);
+}
+
+
+#define adc_update_ext_trigger(trigger) \
+	adc_preempt_conversion_trigger_set(ADC1, trigger, TRUE)
+
+void adc_init(void);
+void adc_start_convert(void);
+void adc_stop_convert(void);
+u16 adc_get_vbus(void);
+u16 adc_get_acc(void);
+u16 adc_get_throttle(void);
+void adc_get_uvw_phaseV(u16 *uvw);
+u16 adc_get_mos_temp(void);
+u16 adc_get_motor_temp(void);
+u16 adc_get_ibus(void);
+u16 adc_get_vref(void);
+void adc_set_vref_calc(float v);
+void adc_vref_filter(void);
+u16 adc_get_5v_ref(void);
+void adc_set_5vref_calc(float v);
+u16 adc_get_throttle2(void);
+u16 adc_get_thro_5v(void);
+u16 adc_get_thro2_5v(void);
+
+#endif /* _ADC_H__ */

+ 353 - 0
Applications/bsp/at32/board_at_mc100_v1.h

@@ -0,0 +1,353 @@
+#ifndef _BOARD_MC_V1_H__
+#define _BOARD_MC_V1_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_MOS_MAX_VOL 145.0F
+#define CONFIG_MAX_DC_VOL 110.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (36.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 200.0f
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   500.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       CONFIG_MAX_PHASE_CURR
+#define CONFIG_MAX_LOCK_TORQUE  20
+
+//#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+
+#define CONFIG_CURR_LP_WC (600.0F)
+
+#define CONFIG_CURR_LP_CEOF (CONFIG_CURR_LP_WC*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (60.0F)
+
+#define CONFIG_SMO_OBSERVER 1
+#define CONFIG_SPEED_LADRC  1
+
+#define SCHED_TIMER TIMER5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIMER5_IRQn
+#define SCHED_TIMER_IRQHandler TIMER5_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define HW_DEAD_TIME_NS  200u
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 300u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4095.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER TIMER0
+#define PWM_MODE TIMER_OC_MODE_PWM0
+
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_BRAKE_GROUP 	GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PIN_12
+#define PWM_BRAKE_RCU 	RCU_GPIOB
+#define PWM_BRAKE_MODE 	GPIO_MODE_IN_FLOATING
+
+#define HALL_SENSOR_CEOF 0.32F
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  ADC_CHANNEL_5
+#define W_PHASE_I_CHAN  ADC_CHANNEL_6
+
+#define V_PHASE_ADC_GROUP 	GPIOA
+#define V_PHASE_ADC_PIN 	GPIO_PIN_5
+#define V_PHASE_ADC_RCU 	RCU_GPIOA
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOA
+#define W_PHASE_ADC_PIN 	GPIO_PIN_6
+#define W_PHASE_ADC_RCU 	RCU_GPIOA
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define ADC_TO_CURR_ceof1  (HALL_SENSOR_CEOF)
+#define ADC_TO_CURR_ceof2  (HALL_SENSOR_CEOF)
+
+#define CONFIG_PWM_UV_SWAP 1
+
+//#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL8
+//#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_3B
+//#define CONFIG_SW_MUTISAMPLE 1
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 		ADC_CHANNEL_3  //adc012
+#define VBUS_V_ADC_GROUP 	GPIOA
+#define VBUS_V_ADC_PIN 		GPIO_PIN_3
+#define VBUS_V_ADC_RCU 		RCU_GPIOA
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define ACC_V_CHAN 		ADC_CHANNEL_2    //adc012
+#define ACC_V_ADC_GROUP 	GPIOA
+#define ACC_V_ADC_PIN 		GPIO_PIN_2
+#define ACC_V_ADC_RCU 		RCU_GPIOA
+#define ACC_V_ADC_MODE 	GPIO_MODE_AIN
+#define ACC_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define VBUS_I_CHAN 		ADC_CHANNEL_4
+#define VBUS_I_ADC_GROUP 	GPIOA
+#define VBUS_I_ADC_PIN 		GPIO_PIN_4
+#define VBUS_I_ADC_RCU 		RCU_GPIOA
+#define VBUS_I_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_I_CEOF         (HALL_SENSOR_CEOF)
+
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN    ADC_CHANNEL_14
+#define MOS_TEMP_ADC_GROUP 	 GPIOC
+#define MOS_TEMP_ADC_PIN 	 GPIO_PIN_4
+#define MOS_TEMP_ADC_RCU 	 RCU_GPIOC
+#define MOS_TEMP_ADC_MODE 	 GPIO_MODE_AIN
+
+#define MOS_TEMP1_ADC_CHAN   ADC_CHANNEL_15
+#define MOS_TEMP1_ADC_GROUP  GPIOC
+#define MOS_TEMP1_ADC_PIN 	 GPIO_PIN_5
+#define MOS_TEMP1_ADC_RCU 	 RCU_GPIOC
+#define MOS_TEMP1_ADC_MODE 	 GPIO_MODE_AIN
+#define MOS_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     ADC_CHANNEL_0 //adc012
+#define MOTOR_TEMP_ADC_GROUP 	GPIOA
+#define MOTOR_TEMP_ADC_PIN 	GPIO_PIN_0
+#define MOTOR_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOTOR_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOTOR_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+//#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把电压采集 */
+#define THROTTLE_CHAN           ADC_CHANNEL_1 //转把信号 adc012
+#define THROTTLE_V_ADC_GROUP 	GPIOA
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_1
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+#define THROTTLE_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     ADC_CHANNEL_9
+#define U_VOL_ADC_GROUP 	GPIOB
+#define U_VOL_ADC_PIN 	GPIO_PIN_1
+#define U_VOL_ADC_RCU 	RCU_GPIOB
+#define U_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_VOL_ADC_CHAN     ADC_CHANNEL_8
+#define V_VOL_ADC_GROUP 	GPIOB
+#define V_VOL_ADC_PIN 	GPIO_PIN_0
+#define V_VOL_ADC_RCU 	RCU_GPIOB
+#define V_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_VOL_ADC_CHAN     ADC_CHANNEL_7
+#define W_VOL_ADC_GROUP 	GPIOA
+#define W_VOL_ADC_PIN 	GPIO_PIN_7
+#define W_VOL_ADC_RCU 	RCU_GPIOA
+#define W_VOL_ADC_MODE 	GPIO_MODE_AIN
+#define UVW_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 刹车手把输入 */
+#define GPIO_BRAKE_IN_GROUP 	GPIOB
+#define GPIO_BRAKE_IN_PIN 	GPIO_PIN_3
+#define GPIO_BRAKE_IN_RCU 	RCU_GPIOB
+#define GPIO_BRAKE_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE_IRQ  EXTI3_IRQn
+#define GPIO_BRAKE_EXTI EXTI_3
+#define GPIO_BRAKE_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define GPIO_BRAKE_EXIT_SRC_PIN GPIO_PIN_SOURCE_3
+
+/* 前刹 */
+#define GPIO_BRAKE1_IN_GROUP 	GPIOD
+#define GPIO_BRAKE1_IN_PIN 	GPIO_PIN_2
+#define GPIO_BRAKE1_IN_RCU 	RCU_GPIOD
+#define GPIO_BRAKE1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE1_IRQ  EXTI2_IRQn
+#define GPIO_BRAKE1_EXTI EXTI_2
+#define GPIO_BRAKE1_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOD
+#define GPIO_BRAKE1_EXIT_SRC_PIN GPIO_PIN_SOURCE_2
+#define GPIO_BREAK_MODE GPIO_LOW_BRK_MODE      
+
+/* 锁电机线,  使用查询模式 */
+#define GPIO_MLOCK_IN_GROUP GPIOC
+#define GPIO_MLOCK_IN_PIN GPIO_PIN_13
+#define GPIO_MLOCK_IN_RCU RCU_GPIOC
+#define GPIO_MLOCK_IN_MODE 	GPIO_MODE_IN_FLOATING
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 	GPIOB
+#define GPIO_UDEC_OUT_PIN 	GPIO_PIN_9
+#define GPIO_UDEC_OUT_RCU 	RCU_GPIOB
+#define GPIO_UDEC_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 风扇 PWM */
+#define GPIO_FAN_OUT_GROUP 	GPIOC
+#define GPIO_FAN_OUT_PIN 	GPIO_PIN_8
+#define GPIO_FAN_OUT_RCU 	RCU_GPIOC
+#define GPIO_FAN_OUT_MODE 	GPIO_MODE_AF_PP
+#define FAN_PWM_TIMER TIMER7
+#define FAN_PWM_CHAN  TIMER_CH_2
+#define FAN_TIMER_RCU  RCU_TIMER7
+
+/* 风扇1检测 */
+#define GPIO_FAN1_IN_GROUP 	GPIOC
+#define GPIO_FAN1_IN_PIN 	GPIO_PIN_10
+#define GPIO_FAN1_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN1_IRQ  EXTI10_15_IRQn
+#define GPIO_FAN1_EXTI EXTI_10
+#define GPIO_FAN1_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN1_EXIT_SRC_PIN GPIO_PIN_SOURCE_10
+
+/* 风扇2检测 */
+#define GPIO_FAN2_IN_GROUP 	GPIOC
+#define GPIO_FAN2_IN_PIN 	GPIO_PIN_11
+#define GPIO_FAN2_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN2_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN2_IRQ  EXTI10_15_IRQn
+#define GPIO_FAN2_EXTI EXTI_11
+#define GPIO_FAN2_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN2_EXIT_SRC_PIN GPIO_PIN_SOURCE_11
+
+/* CAN 定义 */
+#define CAN_TX_GROUP GPIOA
+#define CAN_TX_PIN   GPIO_PIN_12
+#define CAN_RX_GROUP GPIOA
+#define CAN_RX_PIN   GPIO_PIN_11
+#define CAN_PIN_RCU  RCU_GPIOA
+
+
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MT
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOB
+#define ENC_A_PIN GPIO_PIN_4
+#define ENC_A_RCU RCU_GPIOB
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOB
+#define ENC_B_PIN GPIO_PIN_5
+#define ENC_B_RCU RCU_GPIOB
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define TIMER2_PB4_PB5_REMAP GPIO_TIMER2_PARTIAL_REMAP
+
+#define ENC_PWM_GROUP GPIOA
+#define ENC_PWM_PIN GPIO_PIN_15
+#define ENC_PWM_RCU RCU_GPIOA
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+#define TIMER1_PA15_REMAP GPIO_TIMER1_PARTIAL_REMAP0
+
+#define ENC_I_GROUP GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_8
+#define ENC_I_RCU RCU_GPIOB
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI5_9_IRQn
+#define ENC_I_EXTI EXTI_8
+#define ENC_I_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE_8
+
+#define ENC_TIMER TIMER2  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER2
+#define ENC_TIMER_IRQ TIMER2_IRQn
+#define ENC_TIMER_IRQHandler TIMER2_IRQHandler
+
+#define ENC_PWM_TIMER TIMER1    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER1
+#define ENC_PWM_TIMER_IRQ TIMER1_IRQn
+#define ENC_PWM_TIMER_CHAN  TIMER_CH_0
+#define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_PWM_IRQHandler TIMER1_IRQHandler
+
+#define ENC_MAX_interpolation 1.0F
+
+#define ENC_FILTER_NR          15
+#ifdef CONFIG_PWM_UV_SWAP
+#define ENCODER_CC_INVERT 1
+#endif
+/* 编码器参数      */
+#define ENC_MAX_RES  4096.0f
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+#define ENC_PWM_Min_P 0.0f//(1.0f/(131.0f + 1.0f))
+#define ENC_PWM_Max_P  1.0f
+
+#if ENCODER_TYPE==ENCODER_MPS
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+#elif ENCODER_TYPE==ENCODER_MT
+/*min. 994 hz*/
+#define ENC_PWM_MAX_RES    4119.0F
+#define ENC_PWM_INIT_WIDTH 16.0F //PWM 起始宽度
+#define ENC_PWM_END_WIDTH   8.0F
+//#define ENC_PWM_Min_P      (ENC_PWM_INIT_WIDTH/(ENC_PWM_MAX_RES + 1.0f))
+//#define ENC_PWM_Max_P      ((ENC_PWM_MAX_RES-ENC_PWM_END_WIDTH)/(ENC_PWM_MAX_RES - 1.0f))
+#define PWM_Duty(d, t) ((d)/(t))
+#define ENC_Duty(d, t) ((PWM_Duty(d, t)*ENC_PWM_MAX_RES - ENC_PWM_INIT_WIDTH)/(ENC_PWM_MAX_RES - ENC_PWM_END_WIDTH - ENC_PWM_INIT_WIDTH))
+#else
+#error "Postion sensor ERROR"
+
+#endif
+#define DEBUG_PORT_UART2
+
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_A1
+
+#if (CONFIG_MOT_TYPE==MOTOR_BLUESHARK_A1)
+#define CONFIG_FORCE_96V_MODE 1
+#endif
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V1_H__ */
+

+ 391 - 0
Applications/bsp/at32/board_at_mc105_v3.h

@@ -0,0 +1,391 @@
+#ifndef _BOARD_MC_V3_H__
+#define _BOARD_MC_V3_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_MOS_MAX_VOL 145.0F
+#define CONFIG_MAX_DC_VOL 110.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (36.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 200.0f
+#define CONFIG_MAX_CHRG_CURRENT (-100.0f)
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   500.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       CONFIG_MAX_PHASE_CURR
+#define CONFIG_MAX_LOCK_TORQUE  20
+#define CONFIG_MAX_ACTIVE_EMF   5000.0F
+
+//#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+
+#define CONFIG_CURR_LP_WC (600.0F)
+
+#define CONFIG_CURR_LP_CEOF (CONFIG_CURR_LP_WC*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (60.0F)
+
+#define CONFIG_LADRC_OBSERVER
+#define CONFIG_SPEED_LADRC  
+//#define CONFIG_FORCE_96V_MODE
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+#define CONFIG_SENSORLESS_TS (FOC_CTRL_US/2.0f)
+#else
+#define CONFIG_SENSORLESS_TS FOC_CTRL_US
+#endif
+
+//#define CONFIG_FORCE_96V_MODE 1
+
+#define SCHED_TIMER TMR5
+#define SCHED_TIMER_RCU CRM_TMR5_PERIPH_CLOCK
+#define SCHED_TIMER_IRQ TMR5_GLOBAL_IRQn
+#define SCHED_TIMER_IRQHandler TMR5_GLOBAL_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define HW_DEAD_TIME_NS  200u
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 300u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4095.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER 		TMR1
+#define PWM_MODE 		TMR_OUTPUT_CONTROL_PWM_MODE_A
+#define PWM_CRM_CLK     CRM_TMR1_PERIPH_CLOCK
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PINS_8
+#define PWM_U_P_RCU 	CRM_GPIOA_PERIPH_CLOCK
+#define PWM_U_P_MODE 	GPIO_MODE_MUX
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PINS_13
+#define PWM_U_N_RCU 	CRM_GPIOB_PERIPH_CLOCK
+#define PWM_U_N_MODE 	GPIO_MODE_MUX
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PINS_9
+#define PWM_V_P_RCU 	CRM_GPIOA_PERIPH_CLOCK
+#define PWM_V_P_MODE 	GPIO_MODE_MUX
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PINS_14
+#define PWM_V_N_RCU 	CRM_GPIOB_PERIPH_CLOCK
+#define PWM_V_N_MODE 	GPIO_MODE_MUX
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PINS_10
+#define PWM_W_P_RCU 	CRM_GPIOA_PERIPH_CLOCK
+#define PWM_W_P_MODE 	GPIO_MODE_MUX
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PINS_15
+#define PWM_W_N_RCU 	CRM_GPIOB_PERIPH_CLOCK
+#define PWM_W_N_MODE 	GPIO_MODE_MUX
+
+#define PWM_BRAKE_GROUP GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PINS_12
+#define PWM_BRAKE_RCU 	CRM_GPIOB_PERIPH_CLOCK
+#define PWM_BRAKE_MODE 	GPIO_MODE_INPUT
+
+#define HALL_SENSOR_CEOF 0.32F
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  			ADC_CHANNEL_14
+#define W_PHASE_I_CHAN  			ADC_CHANNEL_10
+
+#define V_PHASE_ADC_GROUP 			GPIOC
+#define V_PHASE_ADC_PIN 			GPIO_PINS_4
+#define V_PHASE_ADC_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define V_PHASE_ADC_MODE 			GPIO_MODE_ANALOG
+
+#define W_PHASE_ADC_GROUP 			GPIOC
+#define W_PHASE_ADC_PIN 			GPIO_PINS_0
+#define W_PHASE_ADC_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define W_PHASE_ADC_MODE 			GPIO_MODE_ANALOG
+
+#define ADC_TO_CURR_ceof1  			(HALL_SENSOR_CEOF)
+#define ADC_TO_CURR_ceof2 			(HALL_SENSOR_CEOF)
+
+#define CONFIG_PWM_UV_SWAP 		   	1
+
+//#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL8
+//#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_3B
+//#define CONFIG_SW_MUTISAMPLE 1
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 				ADC_CHANNEL_12  //adc012
+#define VBUS_V_ADC_GROUP 			GPIOC
+#define VBUS_V_ADC_PIN 				GPIO_PINS_2
+#define VBUS_V_ADC_RCU 				CRM_GPIOC_PERIPH_CLOCK
+#define VBUS_V_ADC_MODE 			GPIO_MODE_ANALOG
+#define VBUS_VOL_CEOF 				(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define ACC_V_CHAN 					ADC_CHANNEL_11    //adc012
+#define ACC_V_ADC_GROUP 			GPIOC
+#define ACC_V_ADC_PIN 				GPIO_PINS_1
+#define ACC_V_ADC_RCU 				CRM_GPIOC_PERIPH_CLOCK
+#define ACC_V_ADC_MODE 				GPIO_MODE_ANALOG
+#define ACC_VOL_CEOF 				(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define VBUS_I_CHAN 				ADC_CHANNEL_0 //adc012
+#define VBUS_I_ADC_GROUP 			GPIOA
+#define VBUS_I_ADC_PIN 				GPIO_PINS_0
+#define VBUS_I_ADC_RCU 				CRM_GPIOA_PERIPH_CLOCK
+#define VBUS_I_ADC_MODE 			GPIO_MODE_ANALOG
+#define VBUS_I_CEOF         		(HALL_SENSOR_CEOF)
+#define VBUS_I_POSITIVE     		1
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN    		ADC_CHANNEL_8
+#define MOS_TEMP_ADC_GROUP 	 		GPIOB
+#define MOS_TEMP_ADC_PIN 	 		GPIO_PINS_0
+#define MOS_TEMP_ADC_RCU 	 		CRM_GPIOB_PERIPH_CLOCK
+#define MOS_TEMP_ADC_MODE 	 		GPIO_MODE_ANALOG
+#define MOS_TEMP_R(adc) 			((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     	ADC_CHANNEL_5
+#define MOTOR_TEMP_ADC_GROUP 		GPIOA
+#define MOTOR_TEMP_ADC_PIN 			GPIO_PINS_5
+#define MOTOR_TEMP_ADC_RCU 			CRM_GPIOA_PERIPH_CLOCK
+#define MOTOR_TEMP_ADC_MODE 		GPIO_MODE_ANALOG
+#define MOTOR_TEMP_R(adc) 			((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+//#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把信号电压采集 */
+#define THROTTLE_CHAN           	ADC_CHANNEL_4
+#define THROTTLE_V_ADC_GROUP 		GPIOA
+#define THROTTLE_V_ADC_PIN 			GPIO_PINS_4
+#define THROTTLE_V_ADC_RCU 			CRM_GPIOA_PERIPH_CLOCK
+#define THROTTLE_V_ADC_MODE 		GPIO_MODE_ANALOG
+#define THROTTLE_VOL_CEOF 			(ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* 第二路转把信号电压采集 */
+#define THROTTLE2_CHAN           	ADC_CHANNEL_7
+#define THROTTLE2_V_ADC_GROUP 		GPIOA
+#define THROTTLE2_V_ADC_PIN 		GPIO_PINS_7
+#define THROTTLE2_V_ADC_RCU 		CRM_GPIOA_PERIPH_CLOCK
+#define THROTTLE2_V_ADC_MODE 		GPIO_MODE_ANALOG
+
+/* 转把供电5V电压采集 */
+#define THROTTLE_5V_CHAN            ADC_CHANNEL_6
+#define THROTTLE_5V_ADC_GROUP 		GPIOA
+#define THROTTLE_5V_ADC_PIN 		GPIO_PINS_6
+#define THROTTLE_5V_ADC_RCU 		CRM_GPIOA_PERIPH_CLOCK
+#define THROTTLE_5V_ADC_MODE 		GPIO_MODE_ANALOG
+
+/* 第二路供电5V电压采集 */
+#define THROTTLE2_5V_CHAN           ADC_CHANNEL_9
+#define THROTTLE2_5V_ADC_GROUP 		GPIOB
+#define THROTTLE2_5V_ADC_PIN 		GPIO_PINS_1
+#define THROTTLE2_5V_ADC_RCU 		CRM_GPIOB_PERIPH_CLOCK
+#define THROTTLE2_5V_ADC_MODE 		GPIO_MODE_ANALOG
+
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     			ADC_CHANNEL_15
+#define U_VOL_ADC_GROUP 			GPIOC
+#define U_VOL_ADC_PIN 				GPIO_PINS_5
+#define U_VOL_ADC_RCU 				CRM_GPIOC_PERIPH_CLOCK
+#define U_VOL_ADC_MODE 				GPIO_MODE_ANALOG
+
+#define V_VOL_ADC_CHAN     			ADC_CHANNEL_1 //adc012
+#define V_VOL_ADC_GROUP 			GPIOA
+#define V_VOL_ADC_PIN 				GPIO_PINS_1
+#define V_VOL_ADC_RCU 				CRM_GPIOA_PERIPH_CLOCK
+#define V_VOL_ADC_MODE 				GPIO_MODE_ANALOG
+
+#define W_VOL_ADC_CHAN     			ADC_CHANNEL_2 //adc012
+#define W_VOL_ADC_GROUP 			GPIOA
+#define W_VOL_ADC_PIN 				GPIO_PINS_2
+#define W_VOL_ADC_RCU 				CRM_GPIOA_PERIPH_CLOCK
+#define W_VOL_ADC_MODE 				GPIO_MODE_ANALOG
+#define UVW_VOL_CEOF 				(ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 模拟5v电压采集 */
+#define DC5V_ADC_CHAN     			ADC_CHANNEL_3 //adc012
+#define DC5V_ADC_GROUP 				GPIOA
+#define DC5V_ADC_PIN 				GPIO_PINS_3
+#define DC5V_ADC_RCU 				CRM_GPIOA_PERIPH_CLOCK
+#define DC5V_ADC_MODE 				GPIO_MODE_ANALOG
+
+/* 0v电压采集,主要是用来给上一次的采集放电 */
+#define ZERO_ADC_CHAN    			ADC_CHANNEL_13 //adc012
+#define ZERO_ADC_GROUP 				GPIOC
+#define ZERO_ADC_PIN 				GPIO_PINS_3
+#define ZERO_ADC_RCU 				CRM_GPIOC_PERIPH_CLOCK
+#define ZERO_ADC_MODE 				GPIO_MODE_ANALOG
+
+/* 刹车手把输入 */
+#define GPIO_BREAK_MODE 			GPIO_LOW_BRK_MODE
+#define GPIO_BRAKE_IN_GROUP 		GPIOB
+#define GPIO_BRAKE_IN_PIN 			GPIO_PINS_3
+#define GPIO_BRAKE_IN_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define GPIO_BRAKE_IN_MODE 			GPIO_MODE_INPUT
+#define GPIO_BRAKE_IRQ  			EXINT3_IRQn
+#define GPIO_BRAKE_EXTI 			EXINT_LINE_3
+#define GPIO_BRAKE_EXIT_SRC_GROUP	GPIO_PORT_SOURCE_GPIOB
+#define GPIO_BRAKE_EXIT_SRC_PIN 	GPIO_PINS_SOURCE3
+#define GPIO_BRAKE_PIN_REMAP 		SWJTAG_CONF_010
+
+/* 锁电机线,  使用查询模式 */
+#define GPIO_MLOCK_IN_GROUP 		GPIOC
+#define GPIO_MLOCK_IN_PIN 			GPIO_PINS_13
+#define GPIO_MLOCK_IN_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define GPIO_MLOCK_IN_MODE 			GPIO_MODE_INPUT
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 		GPIOB
+#define GPIO_UDEC_OUT_PIN 			GPIO_PINS_7
+#define GPIO_UDEC_OUT_RCU 			CRM_GPIOB_PERIPH_CLOCK
+#define GPIO_UDEC_OUT_MODE 			GPIO_MODE_OUTPUT
+
+/* 风扇 PWM */
+#define GPIO_FAN_OUT_GROUP 			GPIOC
+#define GPIO_FAN_OUT_PIN 			GPIO_PINS_8
+#define GPIO_FAN_OUT_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define GPIO_FAN_OUT_MODE 			GPIO_MODE_MUX
+#define FAN_PWM_TIMER 				TMR8
+#define FAN_PWM_CHAN  				TMR_SELECT_CHANNEL_3
+#define FAN_TIMER_RCU  				CRM_TMR8_PERIPH_CLOCK
+
+/* 风扇1检测 */
+#define GPIO_FAN1_IN_GROUP 			GPIOC
+#define GPIO_FAN1_IN_PIN 			GPIO_PINS_11
+#define GPIO_FAN1_IN_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define GPIO_FAN1_IN_MODE 			GPIO_MODE_INPUT
+#define GPIO_FAN1_IRQ  				EXINT15_10_IRQn
+#define GPIO_FAN1_EXTI 				EXINT_LINE_11
+#define GPIO_FAN1_EXIT_SRC_GROUP 	GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN1_EXIT_SRC_PIN 		GPIO_PINS_SOURCE11
+
+/* LED 灯控制 */
+#define GPIO_LED_OUT_GROUP 			GPIOC
+#define GPIO_LED_OUT_PIN 			GPIO_PINS_14
+#define GPIO_LED_OUT_RCU 			CRM_GPIOC_PERIPH_CLOCK
+#define GPIO_LED_OUT_MODE 			GPIO_MODE_OUTPUT
+
+/* 刹车灯控制,能量回收的时候需要电量刹车灯 */
+#define GPIO_BRAKE_LIGHT_OUT_GROUP 	GPIOD
+#define GPIO_BRAKE_LIGHT_OUT_PIN 	GPIO_PINS_2
+#define GPIO_BRAKE_LIGHT_OUT_RCU 	CRM_GPIOD_PERIPH_CLOCK
+#define GPIO_BRAKE_LIGHT_OUT_MODE 	GPIO_MODE_OUTPUT
+
+/* CAN 定义 */
+#define CAN_TX_GROUP GPIOB
+#define CAN_TX_PIN   GPIO_PINS_9
+#define CAN_RX_GROUP GPIOB
+#define CAN_RX_PIN   GPIO_PINS_8
+#define CAN_PIN_RCU  CRM_GPIOB_PERIPH_CLOCK
+#define CAN_REMAP    CAN_MUX_10
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MT
+
+/* 编码器 */
+#define ENC_A_GROUP 	GPIOB
+#define ENC_A_PIN 		GPIO_PINS_4
+#define ENC_A_RCU 		CRM_GPIOB_PERIPH_CLOCK
+#define ENC_A_MODE 		GPIO_MODE_INPUT
+
+#define ENC_B_GROUP 	GPIOB
+#define ENC_B_PIN 		GPIO_PINS_5
+#define ENC_B_RCU 		CRM_GPIOB_PERIPH_CLOCK
+#define ENC_B_MODE 		GPIO_MODE_INPUT
+#define TIMER2_PB4_PB5_REMAP TMR3_MUX_10
+
+#define ENC_PWM_GROUP 	GPIOA
+#define ENC_PWM_PIN 	GPIO_PINS_15
+#define ENC_PWM_RCU 	CRM_GPIOA_PERIPH_CLOCK
+#define ENC_PWM_MODE	GPIO_MODE_MUX
+#define TIMER1_PA15_REMAP TMR2_MUX_01
+
+#define ENC_I_GROUP 			GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN 				GPIO_PINS_6
+#define ENC_I_RCU 				CRM_GPIOB_PERIPH_CLOCK
+#define ENC_I_MODE 				GPIO_MODE_INPUT
+#define ENC_I_IRQ  				EXINT9_5_IRQn
+#define ENC_I_EXTI 				EXINT_LINE_6
+#define ENC_I_EXIT_SRC_GROUP 	GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN 		GPIO_PINS_SOURCE6
+
+#define ENC_TIMER 				TMR3  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU 			CRM_TMR3_PERIPH_CLOCK
+#define ENC_TIMER_IRQ 			TMR3_GLOBAL_IRQn
+#define ENC_TIMER_IRQHandler 	TMR3_GLOBAL_IRQHandler
+
+#define ENC_PWM_TIMER 			TMR2    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU 		CRM_TMR2_PERIPH_CLOCK
+#define ENC_PWM_TIMER_IRQ 		TMR2_GLOBAL_IRQn
+#define ENC_PWM_TIMER_CHAN  	TMR_SELECT_CHANNEL_1
+#define ENC_PWM_TIMER_IRQ_CH 	TMR_C1_INT
+#define ENC_PWM_TIMER_INT_FLG 	TMR_C1_FLAG
+#define ENC_PWM_IRQHandler 		TMR2_GLOBAL_IRQHandler
+
+/* board id, 0x01=>v3, 0x02=>v4 */
+#define BOOT_PIN_0_GROUP GPIOC 
+#define BOOT_PIN_0_PIN   GPIO_PINS_6
+#define BOOT_PIN_1_GROUP GPIOC 
+#define BOOT_PIN_1_PIN   GPIO_PINS_7
+
+#define BOARD_105_VERSION_3 2
+#define BOARD_105_VERSION_4 1
+
+
+#define ENC_MAX_interpolation 1.0F
+
+#define ENC_FILTER_NR          15
+#ifdef CONFIG_PWM_UV_SWAP
+#define ENCODER_CC_INVERT 1
+#endif
+/* 编码器参数      */
+#define ENC_MAX_RES  4096.0f
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+#define ENC_PWM_Min_P 0.0f//(1.0f/(131.0f + 1.0f))
+#define ENC_PWM_Max_P  1.0f
+
+#if ENCODER_TYPE==ENCODER_MPS
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+#elif ENCODER_TYPE==ENCODER_MT
+/*min. 994 hz*/
+#define ENC_PWM_MAX_RES    4119.0F
+#define ENC_PWM_INIT_WIDTH 16.0F //PWM 起始宽度
+#define ENC_PWM_END_WIDTH   8.0F
+//#define ENC_PWM_Min_P      (ENC_PWM_INIT_WIDTH/(ENC_PWM_MAX_RES + 1.0f))
+//#define ENC_PWM_Max_P      ((ENC_PWM_MAX_RES-ENC_PWM_END_WIDTH)/(ENC_PWM_MAX_RES - 1.0f))
+#define PWM_Duty(d, t) ((d)/(t))
+#define ENC_Duty(d, t) ((PWM_Duty(d, t)*ENC_PWM_MAX_RES - ENC_PWM_INIT_WIDTH)/(ENC_PWM_MAX_RES - ENC_PWM_END_WIDTH - ENC_PWM_INIT_WIDTH))
+#else
+#error "Postion sensor ERROR"
+
+#endif
+#define DEBUG_PORT_UART2
+
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_ZD_100
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V3_H__ */
+
+

+ 92 - 0
Applications/bsp/at32/bsp.c

@@ -0,0 +1,92 @@
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+#include "libs/logger.h"
+#include "os/os_types.h"
+#include "version.h"
+
+extern void system_clock_config(void);
+static void wdog_enable(void);
+
+void bsp_init(void){
+	system_clock_config();
+	wdog_enable();
+	debug_periph_mode_set(DEBUG_TMR1_PAUSE, TRUE);
+	nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+	systick_open();
+	task_ticks_enable();
+	gpio_pin_init();
+	shark_uart_init(SHARK_UART0);
+}
+
+
+void system_reboot(void){
+	NVIC_SystemReset();
+}
+
+void systick_close(void)
+{
+	SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;
+}
+
+void systick_open(void)
+{
+	systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
+	SysTick_Config(system_core_clock / 1000);
+	NVIC_SetPriority(SysTick_IRQn, 0x00U);
+}
+
+u8 mcu_chip_id(u8 *buff)
+{
+	u32 values[] = { REG32(0x1FFFF7E8), REG32(0x1FFFF7EC), REG32(0x1FFFF7F0), REG32(0x1FFFF7E0) };
+	memcpy(buff, values, sizeof(values));
+	return sizeof(values);
+}
+
+u32 get_mcu_reset_source(void)
+{
+	uint32_t reset_source = CRM->ctrlsts;
+	CRM->ctrlsts_bit.rstfc = TRUE;
+	return reset_source;
+}
+
+void wdog_reload(void){
+#if CONFIG_DEBUG == 0
+    wdt_counter_reload();
+#endif    
+}
+
+static void wdog_enable(void)
+{
+#if CONFIG_DEBUG == 0  
+	/* disable register write protection */
+	 wdt_register_write_enable(TRUE);
+	
+	 /* set the wdt divider value */
+	 wdt_divider_set(WDT_CLK_DIV_64);
+	
+	 /* set reload value
+	
+	  timeout = reload_value * (divider / lick_freq )	 (s)
+	
+	  lick_freq    = 40000 Hz
+	  divider	   = 4
+	  reload_value = 30000
+	
+	  timeout = 3000 * (64 / 40000 ) = 4.8s = 4800ms
+	 */
+	 wdt_reload_value_set(3000 - 1);
+	
+	 /* reload wdt counter */
+	 wdt_counter_reload();
+	 
+	 /* enable wdt */
+	 wdt_enable();
+#endif
+}
+
+int wdog_set_timeout(int wdog_time)
+{  
+	return 0;
+}
+
+

+ 35 - 0
Applications/bsp/at32/bsp.h

@@ -0,0 +1,35 @@
+#ifndef __BSP_AT32_H__
+#define __BSP_AT32_H__
+#if defined AT32F413RCT7
+#include "at32f413.h"
+#endif
+#define BIT(x)        ((uint32_t)((uint32_t)0x01U<<(x)))
+
+#define SYSTEM_CLOCK (200000000u) //system clk 200M Hz
+#define TIM_CLOCK (SYSTEM_CLOCK) /*SystemClock_Config��TIM1��clk��sys PLL �������̶�2����PLLƵ��*/
+#define TIM_CLOCK_MHz (200u)
+#define ADC_CLOCK (25000000u)
+#define ADC_CLOCK_MHz (30u)
+#define NS_PER_TCLK (5u) /* (1/200000000 * 1000000000) */
+#define NS_2_TCLK(ns) (((ns)/NS_PER_TCLK) + 1u) //ns תΪpwmʹ�õ��Ǹ�TIM��clk count
+#define FOC_PWM_FS (16000u)
+#define FOC_PWM_period (TIM_CLOCK/FOC_PWM_FS)
+#define FOC_PWM_Half_Period (FOC_PWM_period/2)
+
+#define FOC_CTRL_US (1.0f/(float)FOC_PWM_FS)
+
+#define ADC_TRIG_CONV_LATENCY_CYCLES 12.5f
+#define ADC_SAMPLING_CYCLES 13.5f
+
+#if defined (MC100_HW_V1)
+#include "bsp/at32/board_mc100_v1.h"
+#define CONFIG_BOARD_MCXXX
+#define CONFIG_BOARD_NAME "MC100AT"
+#define CONFIG_HW_VERSION 2
+#elif defined (MC105_HW_V3)
+#include "bsp/at32/board_at_mc105_v3.h"
+#define CONFIG_BOARD_MCXXX
+#define CONFIG_BOARD_NAME "MC105AT"
+#define CONFIG_HW_VERSION 3
+#endif
+#endif /* __BSP_AT32_H__ */

+ 255 - 0
Applications/bsp/at32/can.c

@@ -0,0 +1,255 @@
+#include <stdio.h>
+#include "os/queue.h"
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "libs/circle_buffer.h"
+
+#define CAN_RX_MESSAGE_RX_ID 1
+#define CAN_SEND_QUEUE_SIZE 32
+#define RX_ID_OFFSET 16
+#define CAN_SEND_OK 0
+#define CAN_SEND_ERROR -1
+#define CAN_SEND_WAIT_TIMEOUT -2
+
+
+#define TX_NUM 64
+#define RX_NUM 64
+static c_buffer_t g_tx_circle;
+static c_buffer_t g_rx_circle;
+static uint8_t _g_tx_buffer[sizeof(can_tx_message_type) * TX_NUM + 1];
+static uint8_t _g_rx_buffer[sizeof(can_rx_message_type) * RX_NUM + 1];
+
+static int shark_send_can0_data(can_tx_message_type *P_message);
+static uint8_t can_get_mailbox(uint32_t can_periph);
+/* this function can be overide by app, which need recv the can frame */
+__weak void handle_can_frame(can_id_t id, uint8_t *data, int len){
+
+}
+
+void can_rx_poll(void){
+	can_rx_message_type message;
+	if (circle_get_data(&g_rx_circle, (uint8_t *)&message, sizeof(message)) != sizeof(message)) {
+		return;
+	}	
+	can_id_t can_id;
+	can_id.id = message.extended_id;
+	handle_can_frame(can_id, message.data, message.dlc); 
+	return ;
+}
+
+void can_tx_poll(void){
+	can_tx_message_type can_tr_m;
+	if (CAN1->ests_bit.bof){
+		shark_can0_reset();
+	}
+	while (can_get_mailbox((u32)CAN1) != CAN_TX_STATUS_NO_EMPTY) {
+		if (circle_get_data(&g_tx_circle, (uint8_t * )&can_tr_m, sizeof(can_tr_m)) != sizeof(can_tr_m)) {
+			break;
+		}
+		can_message_transmit(CAN1,&can_tr_m);
+	}
+}
+
+static u32 _can_poll_task(void *args) {
+	can_rx_poll();
+	can_tx_poll();
+	return 0;
+}
+
+static __inline__ void can_fifo_recv(can_rx_fifo_num_type fifo){
+	can_rx_message_type Rxmessage;
+
+	can_message_receive(CAN1, fifo, &Rxmessage);
+
+	circle_put_data(&g_rx_circle, (uint8_t *)&Rxmessage,  sizeof(Rxmessage));
+
+}
+
+void USBFS_L_CAN1_RX0_IRQHandler(void)
+{
+	can_fifo_recv(CAN_RX_FIFO0);
+}
+
+void CAN0_RX1_IRQHandler(void)
+{
+	can_fifo_recv(CAN_RX_FIFO1);
+}
+
+static void shark_can0_txrx_pin_config(void){
+	gpio_init_type gpio_init_struct;
+    /* enable can clock */
+    crm_periph_clock_enable(CAN_PIN_RCU, TRUE);
+
+#ifdef CAN_REMAP
+	gpio_pin_remap_config(CAN_REMAP,TRUE);
+#endif
+	
+	gpio_default_para_init(&gpio_init_struct);
+	
+	/* can tx pin */
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+	gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+	gpio_init_struct.gpio_pins = CAN_TX_PIN;
+	gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+	gpio_init(CAN_TX_GROUP, &gpio_init_struct);
+	
+	/* can rx pin */
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
+	gpio_init_struct.gpio_pins = CAN_RX_PIN;
+	gpio_init_struct.gpio_pull = GPIO_PULL_UP;
+	gpio_init(CAN_RX_GROUP, &gpio_init_struct);
+}
+
+
+static void shark_can0_config(void)
+{
+	can_base_type can_base_struct;
+	can_baudrate_type can_baudrate_struct;
+	can_filter_init_type can_filter_init_struct;
+	
+	crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);
+	/* can base init */
+	can_default_para_init(&can_base_struct);
+	can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
+	can_base_struct.ttc_enable = FALSE;
+	can_base_struct.aebo_enable = TRUE;
+	can_base_struct.aed_enable = TRUE;
+	can_base_struct.prsf_enable = FALSE;
+	can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
+	can_base_struct.mmssr_selection = CAN_SENDING_BY_REQUEST;
+	can_base_init(CAN1, &can_base_struct);
+
+	//CAN0_SPEED==250 //250k bps
+	/* can baudrate, set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
+	can_baudrate_struct.baudrate_div = 40;
+	can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ;
+	can_baudrate_struct.bts1_size = CAN_BTS1_5TQ;
+	can_baudrate_struct.bts2_size = CAN_BTS2_4TQ;
+	can_baudrate_set(CAN1, &can_baudrate_struct);
+
+	/* can filter 0 config */
+	can_filter_init_struct.filter_activate_enable = TRUE;
+	can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
+	can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
+	can_filter_init_struct.filter_number = 0;
+	can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
+	can_filter_init_struct.filter_id_high = (((CAN_MY_ADDRESS << 3) >> 16) & 0xFFFF);	/* extended identifier is 29 bit */
+	can_filter_init_struct.filter_id_low = ((CAN_MY_ADDRESS << 3) & 0xFFFF) | 0x04;
+	can_filter_init_struct.filter_mask_high = ((CAN_FILTER_DEST_MASK << 3) >> 16) & 0xFFFF; /* extended identifier is 29 bit */
+	can_filter_init_struct.filter_mask_low = ((CAN_FILTER_DEST_MASK << 3) & 0xFFFF) | 0x04;
+	can_filter_init(CAN1, &can_filter_init_struct);
+
+//  	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);  
+  	nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn,CAN_IRQ_PRIORITY,0);	
+    /* enable can receive FIFO0 not empty interrupt */
+    can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
+}
+
+
+static int shark_send_can0_data(can_tx_message_type *P_message){
+	can_tx_poll();
+	if (circle_put_data(&g_tx_circle, (u8 *)P_message, sizeof(can_tx_message_type))){
+		return CAN_SEND_OK;
+	}
+	return CAN_SEND_ERROR;
+}
+
+
+static uint8_t can_get_mailbox(uint32_t can_periph)
+{
+    uint8_t transmit_mailbox = CAN_TX_MAILBOX0;
+    can_type* can_x = CAN1;
+	
+	/* select one empty transmit mailbox */
+	if(can_x->tsts_bit.tm0ef)
+	{
+	  transmit_mailbox = CAN_TX_MAILBOX0;
+	}
+	else if(can_x->tsts_bit.tm1ef)
+	{
+	  transmit_mailbox = CAN_TX_MAILBOX1;
+	}
+	else if(can_x->tsts_bit.tm2ef)
+	{
+	  transmit_mailbox = CAN_TX_MAILBOX2;
+	}
+	else
+	{
+	  transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
+	}
+
+    /* return no mailbox empty */
+    if(CAN_TX_STATUS_NO_EMPTY == transmit_mailbox){
+        return CAN_TX_STATUS_NO_EMPTY;
+    }
+	return transmit_mailbox;
+}
+
+
+int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
+	can_tx_message_type trasnmit_msg;
+	can_id_t can_frame_id;
+	u32 total_frames = ((len + 7) >> 3);
+	int send_len = len;
+	u32 frame_id = 1;
+	can_frame_id.id = can_id;
+	can_frame_id.total = total_frames;
+
+	while(send_len > 0){
+		can_frame_id.idx = frame_id;
+
+		trasnmit_msg.standard_id	= 0;
+		trasnmit_msg.extended_id	= can_frame_id.id;				
+		trasnmit_msg.frame_type	= CAN_TFT_DATA;
+		trasnmit_msg.id_type	= CAN_ID_EXTENDED;
+		trasnmit_msg.dlc = min(CAN_DATA_SIZE,send_len);
+		memcpy((char *)trasnmit_msg.data, (char *)buff + (len - send_len), trasnmit_msg.dlc);
+		send_len -= trasnmit_msg.dlc;
+		frame_id ++;
+		if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
+			return CAN_SEND_ERROR;
+		}
+	}
+
+	return CAN_SEND_OK;
+
+}
+
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len){
+	can_tx_message_type trasnmit_msg;
+	
+	trasnmit_msg.standard_id	= 0;
+	trasnmit_msg.extended_id	= can_id;				
+	trasnmit_msg.frame_type	= CAN_TFT_DATA;
+	trasnmit_msg.id_type	= CAN_ID_EXTENDED;
+	trasnmit_msg.dlc = min(CAN_DLC_LENGTH,len);
+	memcpy((char *)trasnmit_msg.data, (char *)buff, trasnmit_msg.dlc);
+
+	if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
+		return CAN_SEND_ERROR;
+	}
+	return CAN_SEND_OK;
+}
+
+
+void shark_can0_reset(void){
+	shark_can0_txrx_pin_config();
+	shark_can0_config();
+}
+
+void shark_can0_deinit(void){
+	can_reset(CAN1);
+	crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, FALSE);
+}
+
+void shark_can0_init(void){
+	circle_buffer_init(&g_tx_circle, _g_tx_buffer, sizeof(_g_tx_buffer));
+	circle_buffer_init(&g_rx_circle, _g_rx_buffer, sizeof(_g_rx_buffer));
+
+	shark_task_create(_can_poll_task, NULL);
+	shark_can0_txrx_pin_config();
+	shark_can0_config();
+}
+

+ 3 - 2
Applications/bsp/can.h → Applications/bsp/at32/can.h

@@ -1,7 +1,7 @@
 #ifndef _Shark_Can0_h__
 #define _Shark_Can0_h__
 #include <stdio.h>
-#include "os/os_type.h"
+#include "os/os_types.h"
 #include "config.h"
 //CAN DLC lenght
 #define   CAN_DLC_LENGTH     8
@@ -66,10 +66,11 @@ static __inline__ void encoder_can_key(uint8_t *buff, uint16_t key) {
 
 int shark_can0_send_message(uint32_t can_id, const void*buff, int len);
 void shark_can0_route_message(uint32_t can_id, const void *buff, int len);
-
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len);
 void shark_can0_init(void);
 void shark_can0_reset(void);
 void shark_can0_deinit(void);
+void can_rx_poll(void);
 
 #endif /* _Shark_Can0_h__ */
 

+ 152 - 0
Applications/bsp/at32/enc_intf.c

@@ -0,0 +1,152 @@
+#include "bsp/bsp_driver.h"
+#include "libs/logger.h"
+
+static void enc_gpio_init(gpio_type *gpiox, gpio_mode_type mode, u32 pin) {
+	gpio_init_type gpio_init_struct = {0};
+	gpio_default_para_init(&gpio_init_struct);
+	gpio_init_struct.gpio_mode = mode;
+	gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
+	gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	
+	/* High-side, Phase A,B,C Config */
+	gpio_init_struct.gpio_pins = pin;
+	gpio_init(gpiox, &gpio_init_struct);
+}
+
+
+static void _io_init(void) {
+	crm_periph_clock_enable(ENC_A_RCU, TRUE);
+	crm_periph_clock_enable(ENC_B_RCU, TRUE);
+	crm_periph_clock_enable(ENC_PWM_RCU, TRUE);
+	crm_periph_clock_enable(ENC_I_RCU, TRUE);
+#ifdef TIMER2_PB4_PB5_REMAP
+	gpio_pin_remap_config(TIMER2_PB4_PB5_REMAP, TRUE);
+#endif
+#ifdef TIMER1_PA15_REMAP
+	gpio_pin_remap_config(TIMER1_PA15_REMAP, TRUE);
+#endif
+	enc_gpio_init(ENC_A_GROUP, ENC_A_MODE, ENC_A_PIN);
+	enc_gpio_init(ENC_B_GROUP, ENC_B_MODE, ENC_B_PIN);
+	enc_gpio_init(ENC_PWM_GROUP, ENC_PWM_MODE, ENC_PWM_PIN);
+	enc_gpio_init(ENC_I_GROUP, ENC_I_MODE, ENC_I_PIN);
+}
+
+static void _io_init_irq(void) {
+	exint_init_type exint_init_struct;
+
+	gpio_exint_line_config(ENC_I_EXIT_SRC_GROUP, ENC_I_EXIT_SRC_PIN);
+	
+	exint_default_para_init(&exint_init_struct);
+	exint_init_struct.line_enable = TRUE;
+	exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
+	exint_init_struct.line_select = ENC_I_EXTI;
+	exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
+	exint_init(&exint_init_struct);
+
+	nvic_irq_enable(ENC_I_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0U);
+}
+
+void enc_intf_init(u32 rate) {
+	_io_init();
+	enc_intf_pwm_counter();
+	enc_intf_quadrature_init(rate);
+	_io_init_irq();
+}
+
+void enc_intf_quadrature_init(u32 rate) {
+
+	tmr_type* timer = ENC_TIMER;
+
+	crm_periph_clock_enable(ENC_TIMER_RCU, TRUE);
+	tmr_reset(timer);
+
+	tmr_base_init(timer, rate -1 , 0);
+	tmr_cnt_dir_set(timer, TMR_COUNT_UP);
+	tmr_input_channel_filter_set(timer, TMR_SELECT_CHANNEL_1, ENC_FILTER_NR);
+	tmr_input_channel_filter_set(timer, TMR_SELECT_CHANNEL_2, ENC_FILTER_NR);
+	/* config encoder mode */
+	tmr_encoder_mode_config(timer, TMR_ENCODER_MODE_C, TMR_INPUT_FALLING_EDGE, TMR_INPUT_RISING_EDGE);
+	
+	/* enable tmr2 */
+	tmr_counter_enable(timer, TRUE);
+}
+
+void enc_intf_pwm_counter(void) {
+	tmr_input_config_type tmr_ic_init_structure;
+
+	tmr_type * timer = ENC_PWM_TIMER;
+
+	crm_periph_clock_enable(ENC_PWM_TIMER_RCU, TRUE);
+	tmr_reset(timer);
+
+	tmr_input_default_para_init(&tmr_ic_init_structure);
+	tmr_ic_init_structure.input_filter_value = ENC_FILTER_NR;
+	tmr_ic_init_structure.input_channel_select = ENC_PWM_TIMER_CHAN;
+	tmr_ic_init_structure.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT;
+	tmr_ic_init_structure.input_polarity_select = TMR_INPUT_RISING_EDGE;
+	
+	tmr_pwm_input_config(timer, &tmr_ic_init_structure, TMR_CHANNEL_INPUT_DIV_1);
+	
+	/* select the tmr3 input trigger: c2df2 */
+	tmr_trigger_input_select(timer, TMR_SUB_INPUT_SEL_C1DF1);
+	
+	/* select the sub mode: reset mode */
+	tmr_sub_mode_select(timer, TMR_SUB_RESET_MODE);
+	
+	/* enable the sub sync mode */
+	tmr_sub_sync_mode_set(timer, TRUE);
+	
+	/* tmr enable counter */
+	tmr_counter_enable(timer, TRUE);
+	
+	/* enable the c2 interrupt request */
+	tmr_interrupt_enable(timer, ENC_PWM_TIMER_IRQ_CH, TRUE);
+
+	nvic_irq_enable(ENC_PWM_TIMER_IRQ, ENC_PWM_IRQ_PRIORITY, 0);
+
+}
+
+__weak void ENC_TIMER_Overflow(void) {
+
+}
+
+void ENC_TIMER_IRQHandler(void) {
+	if (SET == tmr_flag_get(ENC_TIMER, TMR_OVF_FLAG)) {
+		tmr_flag_clear(ENC_TIMER, TMR_OVF_FLAG);
+		ENC_TIMER_Overflow();
+	}
+}
+
+
+__weak void ENC_ABI_IRQHandler(void) {
+
+}
+
+void ABI_I_IRQHandler(void) {
+	ENC_ABI_IRQHandler();
+}
+
+__weak void ENC_PWM_Duty_Handler(float t, float d) {
+
+}
+
+static float pwm_freq = 0.0f;
+void ENC_PWM_IRQHandler(void) {
+    if(SET == tmr_flag_get(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG)){
+        /* clear channel 0 interrupt bit */
+        tmr_flag_clear(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG);
+        /* read channel 0 capture value */
+        u32 ic0value = tmr_channel_value_get(ENC_PWM_TIMER, TMR_SELECT_CHANNEL_1) + 1;
+		u32 ic1value = tmr_channel_value_get(ENC_PWM_TIMER, TMR_SELECT_CHANNEL_2) + 1;
+		float p_calc = ENC_PWM_Calc_P(ic0value);
+		float d_calc = ENC_PWM_Calc_P(ic1value);
+		ENC_PWM_Duty_Handler(p_calc, d_calc);
+		pwm_freq = (float)PWM_TIME_CLK/((float)ic0value);
+    }
+}
+
+float enc_get_pwm_freq(void) {
+	return pwm_freq;
+}
+

+ 27 - 0
Applications/bsp/at32/enc_intf.h

@@ -0,0 +1,27 @@
+#ifndef _ENC_INTF_H__
+#define _ENC_INTF_H__
+#include "os/os_types.h"
+#include "bsp/bsp.h"
+
+#define PWM_TIME_CLK 10000000U
+
+
+#define ENC_DIR_UP 1
+#define ENC_DIR_DOWN 2
+
+#define ENC_PWM_Calc_P(t) ((float)t / (float)PWM_TIME_CLK)
+
+#define ENC_COUNT (ENC_TIMER->cval)
+
+#define ENC_Direction() (((ENC_TIMER->ctrl1) & (0x10))?ENC_DIR_DOWN:ENC_DIR_UP)
+
+#define ENC_OverFlow() (((ENC_TIMER->ists) & TMR_OVF_FLAG)?true:false)
+#define ENC_ClearUpFlags() ((ENC_TIMER->ists) = (~(uint32_t)TMR_OVF_FLAG))
+
+void enc_intf_quadrature_init(u32 rate);
+void enc_intf_pwm_counter(void);
+void enc_intf_init(u32 rate);
+float enc_get_pwm_freq(void);
+
+#endif /*_ENC_INTF_H__*/
+

+ 58 - 0
Applications/bsp/at32/fan_pwm.c

@@ -0,0 +1,58 @@
+#include "fan_pwm.h"
+
+void fan_pwm_init(void){
+	tmr_output_config_type tmr_oc_init_structure;
+
+	/* compute the div value */
+	u16 div_value = (uint16_t)(system_core_clock / 1000000) - 1;
+	
+	/* tmr3 time base configuration */
+	tmr_base_init(FAN_PWM_TIMER, FAN_MAX_DUTY_COUNT, div_value);
+	tmr_cnt_dir_set(FAN_PWM_TIMER, TMR_COUNT_UP);
+	tmr_clock_source_div_set(FAN_PWM_TIMER, TMR_CLOCK_DIV1);
+
+	tmr_output_default_para_init(&tmr_oc_init_structure);
+	tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
+	tmr_oc_init_structure.oc_idle_state = FALSE;
+	tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
+	tmr_oc_init_structure.oc_output_state = TRUE;
+	tmr_output_channel_config(FAN_PWM_TIMER, FAN_PWM_CHAN, &tmr_oc_init_structure);
+	tmr_channel_value_set(FAN_PWM_TIMER, FAN_PWM_CHAN, FAN_MAX_DUTY_COUNT-1);
+	tmr_output_channel_buffer_enable(FAN_PWM_TIMER, FAN_PWM_CHAN, TRUE);
+
+	tmr_period_buffer_enable(FAN_PWM_TIMER, TRUE);
+
+	tmr_output_enable(FAN_PWM_TIMER, FALSE);
+	
+	/* tmr enable counter */
+	tmr_counter_enable(FAN_PWM_TIMER, TRUE);
+}
+
+
+void fan_stop(void) {
+	tmr_counter_enable(FAN_PWM_TIMER, FALSE);
+}
+
+void fan_set_duty(u8 duty) {
+	if (duty > 100) {
+		duty = 100;
+	}else if (duty > 0 && duty < 30) {
+		duty = 30;
+	}
+	u32 count = (float)duty * (float)FAN_MAX_DUTY_COUNT / 100.0f;
+	tmr_channel_value_set(FAN_PWM_TIMER,FAN_PWM_CHAN, count);
+	if (count == 0) {
+		tmr_output_enable(FAN_PWM_TIMER,FALSE);
+	}else {
+		tmr_output_enable(FAN_PWM_TIMER,TRUE);
+	}
+}
+
+
+bool fan_pwm_is_running(void) {
+	if (FAN_PWM_TIMER->ctrl1_bit.tmren == TRUE) {
+		return true;
+	}
+	return false;
+}
+

+ 23 - 0
Applications/bsp/at32/fan_pwm.h

@@ -0,0 +1,23 @@
+#ifndef _FAN_PWM_H__
+#define _FAN_PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define PWM_FREQ_HZ    200
+#define FAN_DUTY_COUNT (1000000/200)
+#define FAN_MAX_DUTY_COUNT (FAN_DUTY_COUNT/2)
+
+#ifdef CONFIG_BOARD_MCXXX
+void fan_pwm_init(void);
+void fan_stop(void);
+void fan_set_duty(u8 duty); //duty 0-100
+bool fan_pwm_is_running(void);
+#else
+static void fan_pwm_init(void) {}
+static void fan_stop(void) {}
+static void fan_set_duty(u8 duty) {}
+bool fan_pwm_is_running(void){return false;}
+
+#endif
+#endif /* _FAN_PWM_H__ */
+

+ 218 - 0
Applications/bsp/at32/fmc_flash.c

@@ -0,0 +1,218 @@
+#include "bsp/bsp_driver.h"
+
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#define FMC_FLAG_PGERR  FMC_FLAG_BANK0_PGERR
+#define FMC_FLAG_PGAERR  FMC_FLAG_BANK0_PGERR
+#define FMC_FLAG_WPERR  FMC_FLAG_BANK0_WPERR
+#define FMC_FLAG_END  FMC_FLAG_BANK0_END
+#endif
+
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_addr(uint32_t addr, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len);
+
+static uint32_t _sn_addr(void);
+static uint32_t _data_addr(int index);
+static uint32_t _maigc_addr(void);
+
+static uint32_t _nv_tbl_write_addr = 0;
+
+static u8 _nv_tbl_write_cache[4];
+static u8 _nv_tbl_write_remain;
+
+void fmc_write_sn(uint8_t *sn, int len){
+	_fmc_erase_write_data(_sn_addr(), sn, len);
+}
+
+void fmc_read_sn(uint8_t *sn, int len){
+	_fmc_read_data(_sn_addr(), sn, len);
+}
+
+void fmc_write_data(int index, uint8_t *data, int len){
+	_fmc_erase_write_data(_data_addr(index), data, len);
+}
+
+void fmc_read_data(int index, uint8_t *data, int len){
+	_fmc_read_data(_data_addr(index), data, len);
+}
+
+static __inline__ void _fmc_flag_clear(void) {
+	flash_flag_clear(FLASH_OBF_FLAG | FLASH_ODF_FLAG | FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
+}
+
+
+void fmc_write_magic(uint32_t magic){
+	uint32_t address = _maigc_addr();
+	uint32_t length, checksum, value;
+
+	value = REG32(address + 8);
+	if (magic == value) {
+		return;
+	}
+
+	length = REG32(address);
+	checksum = REG32(address + 4);
+
+	flash_unlock();
+
+	if (value != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		flash_sector_erase(address);
+
+		_fmc_flag_clear();
+		flash_word_program(address, length);
+
+		_fmc_flag_clear();
+		flash_word_program(address + 4, checksum);
+	}
+
+	if (magic != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		flash_word_program(address + 8, magic);
+	}
+
+	flash_lock();
+}
+
+uint32_t fmc_read_magic(void){
+	uint32_t magic = 0x5555aaaa;
+	_fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
+	return magic;
+}
+
+//if flash is lager than 256k, we just use the 256k
+static uint32_t __inline__ _flash_capatity(void){
+	uint32_t capacity;
+	capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	if (capacity > (256 * 1024)){
+		capacity =  256 * 1024;
+	}
+	return capacity;
+}
+
+static uint32_t _sn_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
+}
+
+static uint32_t _data_addr(int index){
+	return 0x08000000 + (_flash_capatity() - one_page_size * index);
+}
+
+static uint32_t _maigc_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
+}
+
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
+	int i = 0;
+	for (i = 0; i < len; i++){
+		data[i] = REG8(addr + i);
+	}
+}
+
+uint32_t fmc_get_addr(int page) {
+	return 0x08000000 + (_flash_capatity() - one_page_size * page);
+}
+
+void fmc_erase_trq_table(int addr, int len){
+	_fmc_erase_addr(addr, len);
+	_nv_tbl_write_addr = 0;
+}
+void fmc_write_trq_table(int addr, uint8_t *data, int len){
+	_fmc_write_data(addr + _nv_tbl_write_addr, data, len);
+	_nv_tbl_write_addr += len;
+}
+
+void fmc_write_trq_table_begin(int addr)
+{
+	_nv_tbl_write_addr = addr;
+	_nv_tbl_write_remain = 0;
+}
+
+static void fmc_write_trq_table_flush(void)
+{
+	u32 value = *(u32 *) _nv_tbl_write_cache;
+
+	if ((_nv_tbl_write_addr % one_page_size) == 0) {
+		_fmc_flag_clear();
+		flash_sector_erase(_nv_tbl_write_addr);
+	}
+
+	_fmc_flag_clear();
+	flash_word_program(_nv_tbl_write_addr, value);
+
+	_nv_tbl_write_addr += _nv_tbl_write_remain;
+	_nv_tbl_write_remain = 0;
+}
+
+void fmc_write_trq_table_continue(const u8 *data, int len)
+{
+	const u8 *data_end;
+
+	flash_unlock();
+
+	for (data_end = data + len; data < data_end; data++) {
+		if (_nv_tbl_write_remain >= sizeof(_nv_tbl_write_cache)) {
+			fmc_write_trq_table_flush();
+		}
+
+		_nv_tbl_write_cache[_nv_tbl_write_remain] = *data;
+		_nv_tbl_write_remain++;
+	}
+
+	flash_lock();
+}
+
+void fmc_write_trq_table_end(void)
+{
+	if (_nv_tbl_write_remain > 0) {
+		flash_unlock();
+		fmc_write_trq_table_flush();
+		flash_lock();
+	}
+}
+
+extern void wdog_reload(void);
+static void _fmc_erase_addr(uint32_t addr, int len){
+	flash_unlock();
+	uint32_t pages = len/one_page_size + (((len % one_page_size) > 0)?1:0);
+	for (int i = 0; i < pages; i++){
+		_fmc_flag_clear();
+		flash_sector_erase(addr + i * one_page_size);
+		wdog_reload();
+	}
+	flash_lock();
+}
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
+	flash_unlock();
+	int total_words = len / 4;
+	uint32_t *p_u32_data = (uint32_t *)data;
+	int i;
+	for (i = 0; i < total_words; i++){
+		_fmc_flag_clear();
+		flash_word_program(addr, p_u32_data[i]);
+		data += 4;
+		addr += 4;
+	}
+
+	int remain_len = len - total_words * 4;
+	if (remain_len > 0){
+		uint32_t words = 0;
+		for (int i = 0; i < remain_len; i++){
+			words |= data[i] << (8*i);
+		}
+		_fmc_flag_clear();
+		flash_word_program(addr, words);
+	}
+	flash_lock();
+}
+
+
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len){
+	_fmc_erase_addr(addr, len);
+	_fmc_write_data(addr, data, len);
+}
+

+ 25 - 0
Applications/bsp/at32/fmc_flash.h

@@ -0,0 +1,25 @@
+#ifndef _FMC_FLASH_H__
+#define _FMC_FLASH_H__
+#include <stdint.h>
+
+#define one_page_size 2048
+
+#define data_bk_page_index 4
+#define data_page_index 3
+#define sn_page_index 2
+#define magic_page_index 1 //must is the last page in 256K eara
+
+void fmc_write_sn(uint8_t *sn, int len);
+void fmc_read_sn(uint8_t *sn, int len);
+
+void fmc_write_data(int index, uint8_t *data, int len);
+void fmc_read_data(int index, uint8_t *data, int len);
+void fmc_write_magic(uint32_t magic);
+uint32_t fmc_read_magic(void);
+uint32_t fmc_get_addr(int page);
+void fmc_write_trq_table_begin(int addr);
+void fmc_write_trq_table_continue(const u8 *data, int len);
+void fmc_write_trq_table_end(void);
+
+#endif /* _FMC_FLASH_H__ */
+

+ 191 - 0
Applications/bsp/at32/gpio.c

@@ -0,0 +1,191 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+
+/*
+* gpio.c
+* all pins used as gpio(in/out/irq) must be init&accessed here
+*/
+
+void gpio_pin_init(void){
+	crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
+	crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
+	crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
+	crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE);
+	crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
+}
+
+
+void gpio_beep(u32 ms) {
+}
+
+void at32_gpio_init(gpio_type *gpiox, gpio_mode_type mode, gpio_output_type otype, gpio_pull_type pull, u32 pin) {
+	gpio_init_type gpio_init_struct = {0};
+	gpio_default_para_init(&gpio_init_struct);
+	gpio_init_struct.gpio_mode = mode;
+	gpio_init_struct.gpio_out_type = otype;
+	gpio_init_struct.gpio_pull = pull;
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	
+	/* High-side, Phase A,B,C Config */
+	gpio_init_struct.gpio_pins = pin;
+	gpio_init(gpiox, &gpio_init_struct);
+}
+
+
+void gpio_mc_brk_init(void) {
+#ifdef GPIO_BRAKE_IN_GROUP
+	crm_periph_clock_enable(GPIO_BRAKE_IN_RCU, TRUE);
+#ifdef GPIO_BRAKE_PIN_REMAP
+	gpio_pin_remap_config(GPIO_BRAKE_PIN_REMAP, TRUE);
+#endif
+	at32_gpio_init(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_BRAKE_IN_PIN);
+
+	exint_init_type exint_init_struct;
+
+	gpio_exint_line_config(GPIO_BRAKE_EXIT_SRC_GROUP, GPIO_BRAKE_EXIT_SRC_PIN);
+	
+	exint_default_para_init(&exint_init_struct);
+	exint_init_struct.line_enable = TRUE;
+	exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
+	exint_init_struct.line_select = GPIO_BRAKE_EXTI;
+	exint_init_struct.line_polarity = EXINT_TRIGGER_BOTH_EDGE;
+	exint_init(&exint_init_struct);
+	exint_flag_clear(GPIO_BRAKE_EXTI);
+	nvic_irq_enable(GPIO_BRAKE_IRQ, EBREAK_IRQ_PRIORITY, 0U);
+#endif
+}
+
+void gpio_mlock_init(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	crm_periph_clock_enable(GPIO_MLOCK_IN_RCU, TRUE);
+	at32_gpio_init(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_MLOCK_IN_PIN);
+#endif
+}
+
+void gpio_fan_det_init(void) {
+#ifdef GPIO_FAN1_IN_GROUP
+	crm_periph_clock_enable(GPIO_FAN1_IN_RCU, TRUE);
+	at32_gpio_init(GPIO_FAN1_IN_GROUP, GPIO_FAN1_IN_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_FAN1_IN_PIN);
+	exint_init_type exint_init_struct;
+
+	gpio_exint_line_config(GPIO_FAN1_EXIT_SRC_GROUP, GPIO_FAN1_EXIT_SRC_PIN);
+	
+	exint_default_para_init(&exint_init_struct);
+	exint_init_struct.line_enable = TRUE;
+	exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
+	exint_init_struct.line_select = GPIO_FAN1_EXTI;
+	exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
+	exint_init(&exint_init_struct);
+	exint_flag_clear(GPIO_FAN1_EXTI);	
+	nvic_irq_enable(GPIO_FAN1_IRQ, ENC_OTHER_IRQ_PRIORITY, 0U);
+#endif
+}
+
+void gpio_phase_u_detect(bool enable) {
+#ifdef GPIO_UDEC_OUT_GROUP
+	if (enable) {
+		at32_gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_DISABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_DISABLE, ENABLE);
+	#endif
+		gpio_bits_write(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_PIN, TRUE);
+	}else {
+		at32_gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_MODE_INPUT, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_ENABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_ENABLE, ENABLE);
+	#endif
+	}
+#endif
+}
+
+
+void gpio_led_init(void) {
+#ifdef GPIO_LED_OUT_GROUP
+	crm_periph_clock_enable(GPIO_LED_OUT_RCU, TRUE);
+	at32_gpio_init(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_LED_OUT_PIN);
+	gpio_bits_reset(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_PIN);
+#endif
+}
+
+void gpio_brk_light_init(void) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	crm_periph_clock_enable(GPIO_BRAKE_LIGHT_OUT_RCU, TRUE);
+	at32_gpio_init(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_MODE, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_BRAKE_LIGHT_OUT_PIN);
+	gpio_bits_reset(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN);
+#endif
+}
+
+void gpio_board_id_init(void) {
+#ifdef BOOT_PIN_0_GROUP
+	at32_gpio_init(BOOT_PIN_0_GROUP, GPIO_MODE_INPUT, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, BOOT_PIN_0_PIN);
+	at32_gpio_init(BOOT_PIN_1_GROUP, GPIO_MODE_INPUT, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, BOOT_PIN_1_PIN);
+#endif
+}
+
+u8  gpio_hw_board_id(void) {
+	u8 id = BOARD_105_VERSION_4;
+#ifdef BOOT_PIN_0_GROUP
+	u8 b0 = gpio_input_data_bit_read(BOOT_PIN_0_GROUP, BOOT_PIN_0_PIN);
+	u8 b1 = gpio_input_data_bit_read(BOOT_PIN_1_GROUP, BOOT_PIN_1_PIN);
+	id = ((b1 << 1) | b0);
+#endif
+	return id;
+}
+
+static u8 _board_id = BOARD_105_VERSION_4;
+void mc_gpio_init(void) {
+	gpio_mlock_init();
+	gpio_mc_brk_init();
+	gpio_fan_det_init();
+	gpio_led_init();
+	gpio_brk_light_init();
+	gpio_board_id_init();
+	int count = 10;
+	do {
+		delay_ms(5);
+		_board_id = gpio_hw_board_id();
+		if (_board_id == BOARD_105_VERSION_3 || _board_id == BOARD_105_VERSION_4) {
+			break;
+		}
+	}while(count-- > 0);
+}
+
+u8  gpio_board_id(void) {
+	return _board_id;
+}
+
+void gpio_led_enable(bool enable) {
+#ifdef GPIO_LED_OUT_GROUP
+	gpio_bits_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?TRUE:FALSE);
+#endif
+}
+
+void gpio_brk_light_enable(bool enable) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	gpio_bits_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?TRUE:FALSE);
+#endif
+}
+
+
+bool mc_get_gpio_brake(void) {
+	return gpio_input_data_bit_read(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_PIN) == SET;
+}
+
+bool mc_get_gpio_brake1(void) {
+#ifdef GPIO_BRAKE1_IN_GROUP
+	return gpio_input_data_bit_read(GPIO_BRAKE1_IN_GROUP, GPIO_BRAKE1_IN_PIN) == SET;
+#else
+	return mc_get_gpio_brake();
+#endif
+}
+
+
+bool gpio_motor_locked(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	return gpio_input_data_bit_read(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_PIN) == RESET;
+#else
+	return false;
+#endif
+}
+

+ 36 - 0
Applications/bsp/at32/gpio.h

@@ -0,0 +1,36 @@
+
+
+#ifndef _GPIO_PIN_H__
+#define _GPIO_PIN_H__
+
+#include "bsp.h"
+#include "os/os_types.h"
+typedef struct {
+	uint32_t group;
+	uint32_t pin;
+	uint32_t mode;
+	uint32_t speed;
+	int init_value; //-1 input, 0 L, 1 H
+}gpio_pin_config_t;
+
+void gpio_pin_init(void);
+bool gpio_get_brake(void) ;
+void gpio_ir2136_enable(bool enable);
+void gpio_led1_enable(bool enable);
+void gpio_led2_enable(bool enable);
+void gpio_led3_enable(bool enable);
+int gpio_startkey_value(void);
+int gpio_stopkey_value(void);
+int gpio_funckey_value(void);
+void gpio_beep(u32 ms);
+void gpio_phase_u_detect(bool enable);
+void mc_brk_gpio_init(void);
+bool mc_get_gpio_brake(void);
+void mc_gpio_init(void);
+bool gpio_motor_locked(void);
+bool mc_get_gpio_brake1(void);
+void gpio_led_enable(bool enable);
+void gpio_brk_light_enable(bool enable);
+u8  gpio_board_id(void);
+
+#endif /* _GPIO_PIN_H__ */

+ 191 - 0
Applications/bsp/at32/mc_irqs.c

@@ -0,0 +1,191 @@
+#include <stdbool.h>
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+/*!
+    \brief      this function handles NMI exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void NMI_Handler(void)
+{
+}
+
+/*!
+    \brief      this function handles HardFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void HardFault_Handler(void){
+	while(1) {
+	}
+}
+
+/*!
+    \brief      this function handles MemManage exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void MemManage_Handler(void)
+{
+    /* if Memory Manage exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles BusFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void BusFault_Handler(void)
+{
+    /* if Bus Fault exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles UsageFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void UsageFault_Handler(void)
+{
+    /* if Usage Fault exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles DebugMon exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void DebugMon_Handler(void)
+{
+}
+
+
+__weak void MC_Brake_IRQHandler(void) {
+
+}
+__weak void MC_Protect_IRQHandler(void) {
+
+}
+__weak void TIMER_UP_IRQHandler(void) {
+
+}
+
+__weak void ADC_IRQHandler(void) {
+
+}
+
+__weak void HALL_IRQHandler(void) {
+
+}
+
+__weak void ABI_I_IRQHandler(void) {
+
+}
+
+__weak void Fan_IRQHandler(int idx) {
+
+}
+
+void ADC1_2_IRQHandler(void)
+{
+	ADC_IRQHandler();
+	adc_clear_irq_flags();
+}
+
+void TMR1_OVF_TMR10_IRQHandler(void) {
+	if (tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_FLAG)) {
+		tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+		TIMER_UP_IRQHandler();
+	}
+}
+
+void TMR1_BRK_TMR9_IRQHandler(void) {
+	if (tmr_flag_get(MOS_PWM_TIMER, TMR_BRK_FLAG)) {
+		tmr_flag_clear(MOS_PWM_TIMER, TMR_BRK_FLAG);
+		MC_Protect_IRQHandler();
+	}
+}
+
+void EXINT0_IRQHandler(void)
+{
+	if(RESET != exint_flag_get(EXINT_LINE_0)){
+		exint_flag_clear(EXINT_LINE_0);
+	}	
+}
+
+void EXINT2_IRQHandler(void)
+{
+	if(RESET != exint_flag_get(EXINT_LINE_2)){
+		exint_flag_clear(EXINT_LINE_2);
+		MC_Brake_IRQHandler();
+	}	
+}
+
+
+void EXINT3_IRQHandler(void)
+{
+	if(RESET != exint_flag_get(EXINT_LINE_3)){
+		exint_flag_clear(EXINT_LINE_3);
+	}
+}
+
+void EXINT4_IRQHandler(void)
+{
+	if(RESET != exint_flag_get(EXINT_LINE_4)){
+		exint_flag_clear(EXINT_LINE_4);
+		//MC_Brake_IRQHandler();
+	}	
+}
+
+void EXINT9_5_IRQHandler(void){
+	if(RESET != exint_flag_get(EXINT_LINE_5)){
+		exint_flag_clear(EXINT_LINE_5);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_6)){
+		exint_flag_clear(EXINT_LINE_6);
+		ABI_I_IRQHandler();
+	}	
+	if(RESET != exint_flag_get(EXINT_LINE_7)){
+		exint_flag_clear(EXINT_LINE_7);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_8)){
+		exint_flag_clear(EXINT_LINE_8);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_9)){
+		exint_flag_clear(EXINT_LINE_9);
+	}	
+}
+
+void EXINT15_10_IRQHandler(void){
+	if(RESET != exint_flag_get(EXINT_LINE_10)){
+		exint_flag_clear(EXINT_LINE_10);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_11)){
+		exint_flag_clear(EXINT_LINE_11);
+		Fan_IRQHandler(0);
+	}	
+	if(RESET != exint_flag_get(EXINT_LINE_12)){
+		exint_flag_clear(EXINT_LINE_12);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_13)){
+		exint_flag_clear((EXINT_LINE_13));
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_14)){
+		exint_flag_clear(EXINT_LINE_14);
+	}
+	if(RESET != exint_flag_get(EXINT_LINE_15)){
+		exint_flag_clear(EXINT_LINE_15);
+	}	
+}

+ 257 - 0
Applications/bsp/at32/pwm.c

@@ -0,0 +1,257 @@
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+/*
+以下主要是在某一相电路无法采集的时候,需要对这相的pwm挖坑处理
+timer 分配:
+timer0 -> ch0-2 互补pwm
+        ch4 event, update event 触发DMA(ch3,4)实现CCR的自更新
+timer1 -> 触发ADC采样,GD32不支持多channel 或方式触发输出,通过timer1的 ch0 compara 配置 TRGO触发ADC,但是需要在一个PWM周期内触发2次(单电阻)
+timer0 master --> timer1 slave/master 确保timer0,1同步开始,同频同相位
+
+DMA 分配:
+DMA0 ch4 -> timer0 update event
+    ch3 -> timer0 chan3 CC event
+
+    ch1 -> timer1 update event,需要更新CCR
+*/
+
+static void _init_pwm_timer(bool);
+static void _pwm_gpio_config(void);
+#ifndef PWM_BRAKE_GROUP
+static void _gpio_brakein_irq_enable(void);
+#endif
+
+static void pwm_gpio_init(gpio_type *gpiox, gpio_mode_type mode, gpio_output_type otype, gpio_pull_type pull, u32 pin) {
+	gpio_init_type gpio_init_struct = {0};
+	gpio_default_para_init(&gpio_init_struct);
+	gpio_init_struct.gpio_mode = mode;
+	gpio_init_struct.gpio_out_type = otype;
+	gpio_init_struct.gpio_pull = pull;
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	
+	/* High-side, Phase A,B,C Config */
+	gpio_init_struct.gpio_pins = pin;
+	gpio_init(gpiox, &gpio_init_struct);
+}
+
+void pwm_3phase_init(void){
+	_pwm_gpio_config();
+    _init_pwm_timer(false);
+}
+
+void pwm_3phase_sides(bool hon, bool lon) {
+	if (hon && lon) {
+		return;
+	}
+	tmr_reset(MOS_PWM_TIMER);
+	crm_periph_clock_enable(PWM_CRM_CLK, TRUE);
+    pwm_gpio_init(PWM_U_P_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE, PWM_U_P_PIN);
+    pwm_gpio_init(PWM_V_P_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE,PWM_V_P_PIN);
+    pwm_gpio_init(PWM_W_P_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE,PWM_W_P_PIN);
+
+    pwm_gpio_init(PWM_U_N_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE,PWM_U_N_PIN);
+    pwm_gpio_init(PWM_V_N_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE,PWM_V_N_PIN);
+    pwm_gpio_init(PWM_W_N_GROUP,GPIO_MODE_OUTPUT,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE,PWM_W_N_PIN);
+
+	sys_debug("pwm_3phase_sides\n");
+	/* 开上桥或者下桥之前先关闭下桥或者上桥 */
+	if (hon) {
+		_pwm_gpio_config();
+		_init_pwm_timer(false);
+		delay_us(10);
+		pwm_start();
+		pwm_update_duty(FOC_PWM_Half_Period-200, FOC_PWM_Half_Period-200, FOC_PWM_Half_Period-200);
+	}else if (lon) {
+		gpio_bits_write(PWM_U_P_GROUP, PWM_U_P_PIN, FALSE);
+		gpio_bits_write(PWM_V_P_GROUP, PWM_V_P_PIN, FALSE);
+		gpio_bits_write(PWM_W_P_GROUP, PWM_W_P_PIN, FALSE);
+
+		delay_us(10);
+		gpio_bits_write(PWM_U_N_GROUP, PWM_U_N_PIN, TRUE);
+		gpio_bits_write(PWM_V_N_GROUP, PWM_V_N_PIN, TRUE);
+		gpio_bits_write(PWM_W_N_GROUP, PWM_W_N_PIN, TRUE);
+	}else {
+#if 0		
+		gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, RESET);
+		gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, RESET);
+		gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, RESET);
+
+		gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, RESET);
+		gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, RESET);
+		gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, RESET);
+#else
+		pwm_3phase_init();
+#endif
+	}
+}
+
+static void _pwm_gpio_config(void)
+{
+    crm_periph_clock_enable(PWM_U_P_RCU, TRUE);
+    crm_periph_clock_enable(PWM_V_P_RCU, TRUE);
+	crm_periph_clock_enable(PWM_W_P_RCU, TRUE);
+    crm_periph_clock_enable(PWM_U_N_RCU, TRUE);
+    crm_periph_clock_enable(PWM_V_N_RCU, TRUE);
+	crm_periph_clock_enable(PWM_W_N_RCU, TRUE);	
+
+    /*configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/
+    pwm_gpio_init(PWM_U_P_GROUP,PWM_U_P_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_DOWN,PWM_U_P_PIN);
+    pwm_gpio_init(PWM_V_P_GROUP,PWM_V_P_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_DOWN,PWM_V_P_PIN);
+    pwm_gpio_init(PWM_W_P_GROUP,PWM_W_P_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_DOWN,PWM_W_P_PIN);
+
+    /*configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/
+    pwm_gpio_init(PWM_U_N_GROUP,PWM_U_N_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_UP,PWM_U_N_PIN);
+    pwm_gpio_init(PWM_V_N_GROUP,PWM_V_N_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_UP,PWM_V_N_PIN);
+    pwm_gpio_init(PWM_W_N_GROUP,PWM_W_N_MODE,GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_UP,PWM_W_N_PIN);
+
+	/*configure BRAKE IN*/
+#ifdef PWM_BRAKE_GROUP
+    /* TIMER0 BKIN */
+	crm_periph_clock_enable(PWM_BRAKE_RCU, TRUE);
+    pwm_gpio_init(PWM_BRAKE_GROUP, PWM_BRAKE_MODE, GPIO_OUTPUT_PUSH_PULL,GPIO_PULL_NONE, PWM_BRAKE_PIN);
+#endif
+}
+
+static u8 _dead_time(u16 t) {
+	if (t < 128) {
+		return (u8 )t;
+	}else if (t <= (64 + 63) * 2) { //11 1111
+		return ((((u8)2<<6) + (t-64)/2));
+	}else if (t <= (32 + 31) * 8) {
+		return (((u8)3 << 6) + (t - 32)/8);
+	}else {
+		if ((t-32)/16 > 63) {
+			return 0xFF;
+		}
+		return (((u8)7<<3) + (t - 32)/16);
+	}
+}
+
+static void _init_pwm_timer(bool enable_brk) {
+	tmr_output_config_type tmr_output_struct;
+	tmr_brkdt_config_type tmr_brkdt_config_struct;
+
+	tmr_reset(MOS_PWM_TIMER);
+	crm_periph_clock_enable(PWM_CRM_CLK, TRUE);
+	tmr_repetition_counter_set(MOS_PWM_TIMER, 1); 		 /* the pwm cycle isr in underflow (high-side pwm on) */
+	tmr_base_init(MOS_PWM_TIMER, FOC_PWM_Half_Period, 0);
+	tmr_cnt_dir_set(MOS_PWM_TIMER, TMR_COUNT_TWO_WAY_1);	/* output compare interrupt flags are set only count-down */
+	/* set dead time clock */
+	tmr_clock_source_div_set(MOS_PWM_TIMER, TMR_CLOCK_DIV1);
+
+	/* channel 1,2,3,1C,2C,3C configuration in output mode */
+	tmr_channel_value_set(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_1, FOC_PWM_Half_Period/2);
+	tmr_channel_value_set(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_2, FOC_PWM_Half_Period/2);
+	tmr_channel_value_set(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_3, FOC_PWM_Half_Period/2);
+
+	tmr_output_default_para_init(&tmr_output_struct);
+	tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
+	tmr_output_struct.oc_output_state = TRUE;
+	tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
+	tmr_output_struct.oc_idle_state = FALSE;
+	tmr_output_struct.occ_output_state = TRUE;
+	tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
+	tmr_output_struct.occ_idle_state = FALSE;
+	
+	/* channel 1, 2, 3 */
+	tmr_output_channel_config(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
+	tmr_output_channel_config(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
+	tmr_output_channel_config(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
+	
+	tmr_output_channel_buffer_enable(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_1, TRUE);
+	tmr_output_channel_buffer_enable(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_2, TRUE);
+	tmr_output_channel_buffer_enable(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_3, TRUE);
+
+	tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
+	tmr_output_channel_config(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
+	tmr_channel_value_set(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_4, FOC_PWM_Half_Period-1);
+	tmr_output_channel_buffer_enable(MOS_PWM_TIMER, TMR_SELECT_CHANNEL_4, TRUE);
+#ifdef PWM_BRAKE_GROUP
+	/* automatic output enable, break, dead time and lock configuration */
+	tmr_brkdt_default_para_init(&tmr_brkdt_config_struct);
+	tmr_brkdt_config_struct.brk_enable = enable_brk?TRUE:FALSE;
+	tmr_brkdt_config_struct.auto_output_enable = FALSE;
+	tmr_brkdt_config_struct.deadtime = _dead_time(NS_2_TCLK(PWM_DEAD_TIME_NS));
+	tmr_brkdt_config_struct.fcsodis_state = TRUE;
+	tmr_brkdt_config_struct.fcsoen_state = FALSE;
+	tmr_brkdt_config_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW;
+	tmr_brkdt_config_struct.wp_level = TMR_WP_OFF;
+	tmr_brkdt_config(MOS_PWM_TIMER, &tmr_brkdt_config_struct);
+#endif
+	tmr_primary_mode_select(MOS_PWM_TIMER, TMR_PRIMARY_SEL_OVERFLOW);
+
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG | TMR_BRK_FLAG | TMR_C4_INT);
+	tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, TRUE);
+	tmr_interrupt_enable(MOS_PWM_TIMER, TMR_BRK_INT, TRUE);
+
+	/* disable single pulse mode */
+	tmr_one_cycle_mode_enable(MOS_PWM_TIMER, FALSE);
+
+	/* pwm timer output enable */
+	tmr_output_enable(MOS_PWM_TIMER, FALSE);
+
+	nvic_irq_enable(TMR1_BRK_TMR9_IRQn, EBREAK_IRQ_PRIORITY, 0);
+	nvic_irq_enable(TMR1_OVF_TMR10_IRQn, TIMER_UP_IRQ_PRIORITY, 0);
+
+	/* enable pwm timer */
+	tmr_counter_enable(MOS_PWM_TIMER, TRUE);
+}
+
+
+void pwm_start(void){
+	pwm_update_duty(FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	/* wait for a new PWM period to flush last HF task */
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+
+	tmr_event_sw_trigger(MOS_PWM_TIMER, TMR_OVERFLOW_SWTRIG);
+	while ( tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_FLAG) == RESET ){}
+	/* Clear Update Flag */
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+
+	tmr_output_enable(MOS_PWM_TIMER, TRUE);
+}
+
+void pwm_stop(void){
+	tmr_output_enable(MOS_PWM_TIMER, FALSE);
+
+	tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, FALSE);
+	/* wait for a new PWM period to flush last HF task */
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+	while ( tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_FLAG) == RESET ){}
+	/* Clear Update Flag */
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+}
+
+void pwm_enable_output(bool enable) {
+	if (enable) {
+		tmr_output_enable(MOS_PWM_TIMER,TRUE);
+	}else {
+		tmr_output_enable(MOS_PWM_TIMER,FALSE);
+	}
+}
+
+/*open low side of the mosfet*/
+void pwm_turn_on_low_side(void)
+{
+	pwm_update_duty(0, 0, 0);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_FLAG);
+	tmr_event_sw_trigger(MOS_PWM_TIMER, TMR_OVERFLOW_SWTRIG);
+  	while ( tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_FLAG) == RESET ){}
+  	/* Main PWM Output Enable */
+  	tmr_output_enable(MOS_PWM_TIMER,TRUE);
+}
+
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector) {
+	if (samp1 < FOC_PWM_Half_Period) {
+		update_adc_trigger(samp1);
+		pwm_change_t3_mode(TMR_OUTPUT_CONTROL_PWM_MODE_B);
+	}else {
+		update_adc_trigger(samp2);
+		pwm_change_t3_mode(TMR_OUTPUT_CONTROL_PWM_MODE_A);
+	}
+	adc_current_sample_config(sector);
+}

+ 105 - 0
Applications/bsp/at32/pwm.h

@@ -0,0 +1,105 @@
+#ifndef _PWM_H__
+#define _PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define TIMER_CHCTL2_CH0EN               BIT(0)              /*!< channel 0 capture/compare function enable */
+#define TIMER_CHCTL2_CH0P                BIT(1)              /*!< channel 0 capture/compare function polarity */
+#define TIMER_CHCTL2_CH0NEN              BIT(2)              /*!< channel 0 complementary output enable */
+#define TIMER_CHCTL2_CH0NP               BIT(3)              /*!< channel 0 complementary output polarity */
+#define TIMER_CHCTL2_CH1EN               BIT(4)              /*!< channel 1 capture/compare function enable  */
+#define TIMER_CHCTL2_CH1P                BIT(5)              /*!< channel 1 capture/compare function polarity */
+#define TIMER_CHCTL2_CH1NEN              BIT(6)              /*!< channel 1 complementary output enable */
+#define TIMER_CHCTL2_CH1NP               BIT(7)              /*!< channel 1 complementary output polarity */
+#define TIMER_CHCTL2_CH2EN               BIT(8)              /*!< channel 2 capture/compare function enable  */
+#define TIMER_CHCTL2_CH2P                BIT(9)              /*!< channel 2 capture/compare function polarity */
+#define TIMER_CHCTL2_CH2NEN              BIT(10)             /*!< channel 2 complementary output enable */
+#define TIMER_CHCTL2_CH2NP               BIT(11)             /*!< channel 2 complementary output polarity */
+
+
+#define TIMxCCER_MASK_CH012        ((uint16_t)  (TIMER_CHCTL2_CH0EN|TIMER_CHCTL2_CH0NEN|\
+                                                 TIMER_CHCTL2_CH1EN|TIMER_CHCTL2_CH1NEN|\
+                                                 TIMER_CHCTL2_CH2EN|TIMER_CHCTL2_CH2NEN))
+#define TIMxCCER_MASK_CP           ((uint16_t) TIMER_CHCTL2_CH0NP | TIMER_CHCTL2_CH1NP |TIMER_CHCTL2_CH2NP)
+#define pwm_enable_channel() {MOS_PWM_TIMER->cctrl |= TIMxCCER_MASK_CH012;}
+#define pwm_disable_channel() {MOS_PWM_TIMER->cctrl &= ~TIMxCCER_MASK_CH012;}
+
+
+#define ch0_update_duty(duty) 	MOS_PWM_TIMER->c1dt = (uint32_t)duty
+#define ch1_update_duty(duty) 	MOS_PWM_TIMER->c2dt = (uint32_t)duty
+#define ch2_update_duty(duty) 	MOS_PWM_TIMER->c3dt = (uint32_t)duty
+#define update_adc_trigger(time) MOS_PWM_TIMER->c4dt = (uint32_t)time
+
+#ifdef CONFIG_PWM_UV_SWAP
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyC);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyA);\
+	}while(0)
+
+#else
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyA);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyC);\
+	}while(0)
+
+#endif
+
+#define pwm_update_2smaples(samp1, sampl2) \
+	do { \
+		MOS_PWM_TIMER->c4dt = (uint32_t)samp1; \
+	}while(0)
+
+
+#define pwm_clear_updata() \
+	tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT);
+
+#define pwm_wait_and_clear_updata() \
+	do { \
+		while ( tmr_flag_get(MOS_PWM_TIMER, TMR_OVF_INT) == RESET ); \
+		timer_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
+	}while(0)
+
+#define pwm_change_t3_mode(m) \
+	do { \
+		if (MOS_PWM_TIMER->cm2_output_bit.c4octrl != m) { \
+			MOS_PWM_TIMER->cm2_output_bit.c4octrl = m; \
+		} \
+	}while(0)
+
+#define pwm_brake_enable(n) \
+	do { \
+		if (n) { \
+			nvic_irq_enable(TMR1_BRK_TMR9_IRQn, EBREAK_IRQ_PRIORITY, 0); \
+		}else { \
+			nvic_irq_disable(TMR1_BRK_TMR9_IRQn); \
+		} \
+	}while(0)
+
+#define pwm_up_enable(n) \
+	do { \
+		if (n) { \
+			tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
+			tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, TRUE); \
+		}else { \
+			tmr_flag_clear(MOS_PWM_TIMER, TMR_OVF_INT); \
+			tmr_interrupt_enable(MOS_PWM_TIMER, TMR_OVF_INT, FALSE); \
+		} \
+	}while(0)
+
+#define get_deadtime() (MOS_PWM_TIMER->brk_bit.dtc)
+#define PWM_Direction_Down() true
+
+void pwm_3phase_init(void);
+void pwm_3phase_sides(bool hon, bool lon);
+void pwm_start(void);
+void pwm_stop(void);
+void pwm_turn_on_low_side(void);
+void pwm_enable_output(bool enable);
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector);
+
+#endif  /*_PWM_H__*/
+

+ 25 - 0
Applications/bsp/at32/sched_timer.c

@@ -0,0 +1,25 @@
+#include "bsp/bsp_driver.h"
+
+void sched_timer_enable(u32 us) {
+
+    crm_periph_clock_enable(SCHED_TIMER_RCU, TRUE);
+
+    tmr_reset(SCHED_TIMER);
+
+	tmr_base_init(SCHED_TIMER, us-1, TIM_CLOCK_MHz-1);
+	tmr_cnt_dir_set(SCHED_TIMER, TMR_COUNT_UP);
+	tmr_clock_source_div_set(SCHED_TIMER, TMR_CLOCK_DIV1);
+	tmr_counter_value_set(SCHED_TIMER, 0);
+
+	tmr_flag_clear(SCHED_TIMER, TMR_OVF_FLAG);
+	tmr_interrupt_enable(SCHED_TIMER, TMR_OVF_INT, TRUE);
+	nvic_irq_enable(SCHED_TIMER_IRQ, SCHED_TIMER_IRQ_PRIORITY, 0);
+	tmr_counter_enable(SCHED_TIMER, TRUE);
+}
+__weak void Sched_MC_mTask(void) {}
+void SCHED_TIMER_IRQHandler(void) {
+	if(SET == tmr_flag_get(SCHED_TIMER, TMR_OVF_FLAG)) {
+		tmr_flag_clear(SCHED_TIMER, TMR_OVF_FLAG);
+		Sched_MC_mTask();
+	}
+}

+ 8 - 0
Applications/bsp/at32/sched_timer.h

@@ -0,0 +1,8 @@
+#ifndef _Sched_Timer_H__
+#define _Sched_Timer_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+void sched_timer_enable(u32 us);
+
+#endif /* _Sched_Timer_H__ */

+ 478 - 0
Applications/bsp/at32/uart.c

@@ -0,0 +1,478 @@
+#include "uart.h"
+#include "os/os_task.h"
+#include "libs/crc16.h"
+#include "libs/logger.h"
+#include "libs/utils.h"
+
+#define SHARK_UART_BAUDRATE				230400
+
+#ifdef DEBUG_PORT_UART1
+#define SHARK_UART0_com					USART1
+#define SHARK_UART0_tx_port				GPIOA
+#define SHARK_UART0_tx_pin				GPIO_PIN_2
+#define SHARK_UART0_rx_port				GPIOA
+#define SHARK_UART0_rx_pin				GPIO_PIN_3
+#define SHARK_UART0_irq					USART1_IRQn
+#define SHARK_UART0_clk					RCU_USART1
+#define SHARK_UART0_tx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_rx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_tx_dma				DMA0
+#define SHARK_UART0_tx_dma_ch			DMA_CH6
+#define SHARK_UART0_tx_dma_clk			RCU_DMA0
+#define SHARK_UART0_rx_dma				DMA0
+#define SHARK_UART0_rx_dma_ch			DMA_CH5
+#define SHARK_UART0_rx_dma_clk			RCU_DMA0
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel6_IRQn
+#define UART_DMA_IRQHandler             DMA0_Channel6_IRQHandler
+#else
+#define SHARK_UART0_com					USART3
+#define SHARK_UART0_tx_port				GPIOB
+#define SHARK_UART0_tx_pin				GPIO_PINS_10
+#define SHARK_UART0_rx_port				GPIOB
+#define SHARK_UART0_rx_pin				GPIO_PINS_11
+#define SHARK_UART0_irq					USART3_IRQn
+#define SHARK_UART0_clk					CRM_USART3_PERIPH_CLOCK
+#define SHARK_UART0_tx_gpio_clk			CRM_GPIOB_PERIPH_CLOCK
+#define SHARK_UART0_rx_gpio_clk			CRM_GPIOB_PERIPH_CLOCK
+#define SHARK_UART0_tx_dma				DMA1
+#define SHARK_UART0_tx_dma_ch			DMA1_CHANNEL2
+#define SHARK_UART0_tx_dma_clk			CRM_DMA1_PERIPH_CLOCK
+#define SHARK_UART0_rx_dma				DMA1
+#define SHARK_UART0_rx_dma_ch			DMA1_CHANNEL3
+#define SHARK_UART0_rx_dma_clk			CRM_DMA1_PERIPH_CLOCK
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel3_IRQn
+#define UART_DMA_IRQHandler             DMA1_Channel3_IRQHandler
+#endif
+
+// ================================================================================
+#define ENABLE_RX_DMA 1
+static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
+static u8 shark_uart0_rx_cache[SHARK_UART_RX_MEM_SIZE];
+
+static shark_uart_t _shark_uart[1];
+///static bool uart_no_data = false;
+#if ENABLE_RX_DMA==1
+#define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - SHARK_UART0_rx_dma_ch->dtcnt)
+#else
+#define update_dma_w_pos(uart){}
+#endif
+
+// ================================================================================
+static usart_type *_uart_index(usart_type* com){
+	return SHARK_UART0;
+}
+static bool shark_uart_on_rx_frame(shark_uart_t *uart)
+{
+	u16 crc0 = decode_u16(uart->rx_frame + uart->rx_length);
+	u16 crc1 = crc16_get(uart->rx_frame, uart->rx_length);
+
+	if (crc0 != crc1) {
+		return false;
+	}
+	//protocol_recv_frame(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
+	return true;
+}
+
+static void shark_uart_rx(shark_uart_t *uart){
+	while(1) {
+		u8 data = 0;
+		update_dma_w_pos(uart);
+		if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
+			return;
+		}
+		switch(data){
+			case CH_START:
+				uart->rx_length = 0;
+				uart->escape = false;
+				uart->start = true;
+				break;
+			case CH_END:
+				if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){
+					uart->rx_length -= 2; //skip crc
+					shark_uart_on_rx_frame(uart);
+				}
+				uart->rx_length = 0xFFFF;
+				uart->start = false;
+				break;
+			case CH_ESC:
+				uart->escape = true;
+				break;
+			default:
+				if (uart->escape) {
+					uart->escape = false;
+					switch (data) {
+						case CH_ESC_START:
+							data = CH_START;
+							break;
+
+						case CH_ESC_END:
+							data = CH_END;
+							break;
+
+						case CH_ESC_ESC:
+							data = CH_ESC;
+							break;
+
+						default:
+							data = 0xFF;
+					}
+				}
+
+				if (uart->rx_length < sizeof(uart->rx_frame)) {
+					uart->rx_frame[uart->rx_length] = data;
+					uart->rx_length++;
+				} else {
+					uart->rx_length = 0xFFFF;
+				}			
+		}
+	}
+}
+
+#define DMA_CHCTL(dma, dma_ch) ((dma_channel_type *)dma_ch)->ctrl
+#define DMA_CHMADDR(dma, dma_ch) ((dma_channel_type *)dma_ch)->maddr
+
+#define DMA_CHXCTL_CHEN        BIT(0)                  /*!< channel enable */
+
+static void shark_uart_dma_tx(shark_uart_t *uart)
+{
+	u32 value = DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch);
+
+	if (value & DMA_CHXCTL_CHEN) {
+		if (SET != dma_flag_get(DMA1_FDT1_FLAG)) {
+			return;
+		}
+		dma_flag_clear(DMA1_FDT1_FLAG);
+		byte_queue_skip(&uart->tx_queue, uart->tx_length);
+		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value & (~DMA_CHXCTL_CHEN);
+	}
+
+	uart->tx_length = byte_queue_peek(&uart->tx_queue);
+	if (uart->tx_length > 0) {
+		dma_data_number_set(uart->tx_dma_ch,  uart->tx_length);
+		DMA_CHMADDR(SHARK_UART0_tx_dma, uart->tx_dma_ch) = (u32) byte_queue_head(&uart->tx_queue);
+		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value | DMA_CHXCTL_CHEN;
+	}
+}
+
+
+
+static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
+{
+	while (size > 0) {
+		u16 length = byte_queue_write(&uart->tx_queue, buff, size);
+
+		if (length == size) {
+			shark_uart_dma_tx(uart);
+			break;
+		}
+
+		shark_uart_dma_tx(uart);
+		buff += length;
+		size -= length;
+	}
+}
+
+static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
+{
+	byte_queue_write(&uart->tx_queue, &value, 1);
+}
+
+
+void shark_uart_write_log(char *buffer){
+	int len = strlen(buffer);
+	shark_uart_t *uart = (_shark_uart+SHARK_UART0);
+	if (len > byte_queue_get_free(&uart->tx_queue)){
+		return;
+	}
+	byte_queue_write(&uart->tx_queue, (const u8 *)buffer, len);
+	shark_uart_dma_tx(uart);
+}
+
+static void shark_uart_tx_dma_init(shark_uart_t *uart){
+	dma_init_type dma_init_struct;
+	crm_periph_clock_enable(SHARK_UART0_tx_dma_clk, TRUE);
+	
+	dma_reset(uart->tx_dma_ch);
+	dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
+	dma_init_struct.memory_inc_enable = TRUE;
+	dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
+	dma_init_struct.peripheral_base_addr = (u32) &(((usart_type *)uart->uart_com)->dt);
+	dma_init_struct.peripheral_inc_enable = FALSE;
+	dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
+	dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
+	dma_init_struct.loop_mode_enable = FALSE;
+	dma_init(uart->tx_dma_ch, &dma_init_struct);
+	/* config flexible dma for usart2 tx */
+	//dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_UART2_TX);
+
+	usart_dma_transmitter_enable(uart->uart_com, TRUE);
+}
+
+#if ENABLE_RX_DMA==1
+static void shark_uart_rx_dma_init(shark_uart_t *uart){
+	dma_init_type dma_init_struct;
+	crm_periph_clock_enable(SHARK_UART0_rx_dma_clk, TRUE);
+	/* dma1 channel2 for usart2 rx configuration */
+	dma_reset(uart->rx_dma_ch);
+	dma_default_para_init(&dma_init_struct);
+	dma_init_struct.buffer_size = SHARK_UART_RX_MEM_SIZE;
+	dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
+	dma_init_struct.memory_base_addr = (uint32_t)shark_uart0_rx_cache;
+	dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
+	dma_init_struct.memory_inc_enable = TRUE;
+	dma_init_struct.peripheral_base_addr = (u32) &(((usart_type *)uart->uart_com)->dt);
+	dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
+	dma_init_struct.peripheral_inc_enable = FALSE;
+	dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
+	dma_init_struct.loop_mode_enable = FALSE;
+	dma_init(uart->rx_dma_ch, &dma_init_struct);	
+	/* config flexible dma for usart2 rx */
+	//dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_UART2_RX);
+
+	usart_dma_receiver_enable(uart->uart_com, TRUE);
+}
+#endif
+static void shark_uart_pin_init(shark_uart_t *uart){
+	crm_periph_clock_enable(SHARK_UART0_rx_gpio_clk, TRUE);
+	crm_periph_clock_enable(SHARK_UART0_tx_gpio_clk, TRUE);
+
+	gpio_init_type gpio_init_struct;
+	gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+	gpio_init_struct.gpio_out_type	= GPIO_OUTPUT_PUSH_PULL;
+	gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
+	gpio_init_struct.gpio_pins = SHARK_UART0_tx_pin;
+	gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+	gpio_init(SHARK_UART0_tx_port, &gpio_init_struct);
+	
+	/* configure the usart2 rx pin */
+	gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
+	gpio_init_struct.gpio_pins = SHARK_UART0_rx_pin;
+	gpio_init_struct.gpio_pull = GPIO_PULL_UP;
+	gpio_init(SHARK_UART0_rx_port, &gpio_init_struct);
+}
+
+static void shark_uart_pin_deinit(shark_uart_t *uart){
+	if (_uart_index(uart->uart_com) == SHARK_UART0) {
+		gpio_init_type gpio_init_struct;
+		gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+		gpio_init_struct.gpio_out_type	= GPIO_OUTPUT_PUSH_PULL;
+		gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
+		gpio_init_struct.gpio_pins = SHARK_UART0_tx_pin;
+		gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+		gpio_init(SHARK_UART0_tx_port, &gpio_init_struct);
+	
+		gpio_init_struct.gpio_pins = SHARK_UART0_rx_pin;
+		gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
+		gpio_init(SHARK_UART0_rx_port, &gpio_init_struct);
+	}
+}
+
+
+static void shark_uart_device_init(shark_uart_t *uart){
+	crm_periph_clock_enable(SHARK_UART0_clk, TRUE);
+	usart_reset(uart->uart_com);
+	/* configure usart2 param */
+	usart_init(uart->uart_com, SHARK_UART_BAUDRATE, USART_DATA_8BITS, USART_STOP_1_BIT);
+	usart_transmitter_enable(uart->uart_com, TRUE);
+	usart_receiver_enable(uart->uart_com, TRUE);
+	usart_enable(uart->uart_com, TRUE);
+}
+
+static u32 shark_uart_task(void *args)
+{
+	shark_uart_t *uart = (shark_uart_t *)args;
+	if(uart->uart_com != 0) {
+		shark_uart_rx(uart);
+		shark_uart_dma_tx(uart);
+	}
+	return 0;
+}
+
+
+void shark_uart_flush(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (uart->uart_com != 0) {
+		while(!byte_queue_empty(&uart->tx_queue)) {
+			shark_uart_dma_tx(uart);
+		}
+	}	
+}
+
+
+#if 0
+void DMA_Channel1_2_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+
+void DMA_Channel3_4_IRQHandler(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART1;
+	if (dma_interrupt_flag_get(uart->tx_dma_ch, DMA_INT_FLAG_FTF) != RESET){
+		shark_uart_dma_tx(uart);
+		dma_interrupt_flag_clear(uart->tx_dma_ch, DMA_INT_FLAG_FTF);
+	}
+}
+#endif
+
+static u8 *tx_cache_addr(uart_enum_t uart_no){
+	return shark_uart0_tx_cache;
+}
+
+static u8 *rx_cache_addr(uart_enum_t uart_no){
+	return shark_uart0_rx_cache;
+}
+
+
+void shark_uart_deinit(uart_enum_t uart_no){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	if (uart->uart_com != 0) {
+		usart_enable(uart->uart_com, FALSE);
+		usart_reset(uart->uart_com);
+		crm_periph_clock_enable(SHARK_UART0_clk, FALSE);
+		dma_channel_enable(uart->rx_dma_ch, FALSE);
+		dma_channel_enable(uart->tx_dma_ch, FALSE);
+		crm_periph_clock_enable(SHARK_UART0_tx_dma_clk, FALSE);
+		crm_periph_clock_enable(SHARK_UART0_rx_dma_clk, FALSE);
+		shark_uart_pin_deinit(uart);
+	}
+#if ENABLE_RX_DMA==0
+	nvic_irq_disable(SHARK_UART0_irq);	
+#endif
+}
+
+
+bool shark_uart_timeout(void){
+#if UART_NUM==2	
+	return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
+#else
+	return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
+#endif
+}
+void shark_uart_init(uart_enum_t uart_no)
+{
+	shark_uart_t *uart = _shark_uart + uart_no;
+	uart->escape = false;
+	uart->rx_length = 0;
+	uart->tx_length = 0;
+	uart->uart_com = SHARK_UART0_com;
+
+	circle_buffer_init(&uart->rx_queue, rx_cache_addr(uart_no), SHARK_UART_RX_MEM_SIZE);
+	byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
+
+	uart->rx_dma_ch = SHARK_UART0_rx_dma_ch;
+	uart->tx_dma_ch = SHARK_UART0_tx_dma_ch;
+
+	shark_uart_pin_init(uart);
+	shark_uart_device_init(uart);
+#if ENABLE_RX_DMA==1
+	shark_uart_rx_dma_init(uart);
+#endif
+	shark_uart_tx_dma_init(uart);
+	usart_enable(uart->uart_com, TRUE);
+
+	shark_task_create(shark_uart_task, uart);
+#if ENABLE_RX_DMA==0
+	nvic_irq_enable(SHARK_UART0_irq, UART_IRQ_PRIORITY, 0);
+#endif
+	uart->uart_no_data = false;
+}
+
+#if ENABLE_RX_DMA==0
+void USART3_IRQHandler(void){
+	if(usart_flag_get(USART0, USART_FLAG_RBNE) == SET){
+		shark_uart_t *uart = _shark_uart + SHARK_UART0;
+		u8 c = usart_data_receive(USART0);
+		circle_put_one_data(&uart->rx_queue, c);
+	}
+}
+#endif
+
+
+void UART_DMA_IRQHandler(void) {
+	
+}
+
+static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
+{
+	switch (value) {
+	case CH_START:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_START;
+		break;
+
+	case CH_END:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_END;
+		break;
+
+	case CH_ESC:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_ESC;
+		break;
+	}
+
+	shark_uart_write_byte(uart, value);
+}
+
+static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
+{
+	const u8 *buff_end;
+
+	for (buff_end = buff + length; buff < buff_end; buff++) {
+		shark_uart_write_byte_esc(uart, *buff);
+	}
+}
+
+static void shark_uart_tx_start(shark_uart_t *uart)
+{
+	shark_uart_write_byte(uart, CH_START);
+	uart->tx_crc16 = 0;
+}
+
+static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
+{
+	shark_uart_write_esc(uart, (const u8 *) buff, length);
+	uart->tx_crc16 = crc16_update(uart->tx_crc16, (const u8 *) buff, length);
+}
+
+static void shark_uart_tx_end(shark_uart_t *uart)
+{
+	shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
+	shark_uart_write_byte(uart, CH_END);
+}
+
+void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+	shark_uart_tx_end(uart);
+	shark_uart_dma_tx(uart);
+}
+
+void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_end(uart_enum_t uart_no){
+	shark_uart_tx_end(_shark_uart + uart_no);
+}
+
+void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
+	shark_uart_write(_shark_uart + uart_no, buff, size);
+}
+
+int fputc(int c, FILE *fp){
+	shark_uart_write_byte(_shark_uart+SHARK_UART0, (u8)c);
+	return 1;
+}
+

+ 53 - 0
Applications/bsp/at32/uart.h

@@ -0,0 +1,53 @@
+#pragma once
+#include "bsp/bsp.h"
+#include "os/os_task.h"
+#include "libs/byte_queue.h"
+#include "libs/circle_buffer.h"
+
+#define CH_START						0xF5
+#define CH_END							0xF6
+#define CH_ESC							0xF7
+#define CH_ESC_START					0x05
+#define CH_ESC_END						0x06
+#define CH_ESC_ESC						0x07
+
+#define SHARK_UART_TX_MEM_SIZE			(2 * 1024)
+#define SHARK_UART_RX_MEM_SIZE			512
+#define RX_FRAME_MAX_LEN 260
+#define RX_OLD_FRAME_MAX_LEN 256
+
+typedef enum {
+	SHARK_UART0 = 0,
+	SHARK_UART1,
+	SHARK_UART2,
+	SHARK_UART3,
+	SHARK_UART4,
+	SHARK_UART_COUNT
+} uart_enum_t;
+
+typedef struct {
+	byte_queue_t tx_queue;
+	c_buffer_t rx_queue;
+	dma_channel_type * rx_dma_ch;
+	dma_channel_type * tx_dma_ch;
+	uint16_t tx_length;
+	uint16_t tx_crc16;
+	usart_type *uart_com;//uart device
+	uint8_t rx_frame[RX_FRAME_MAX_LEN];
+	uint16_t rx_length;
+	bool escape;
+	bool start;
+	bool uart_no_data;
+}shark_uart_t;
+
+void shark_uart_init(uart_enum_t uart_no);
+void shark_uart_deinit(uart_enum_t uart_no);
+void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_end(uart_enum_t uart_no);
+void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size);
+void shark_uart_flush(void);
+bool shark_uart_timeout(void);
+void shark_uart_log(void);
+

+ 30 - 55
Applications/bsp/bsp.h

@@ -1,65 +1,40 @@
 #ifndef __BSP_H__
 #define __BSP_H__
-#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
-#include "gd32f30x.h"
-#elif defined GD32E10x
-#include "gd32e10x.h"
-#endif
-#include "bsp/gpio.h"
-#include "bsp/gd32_bkp.h"
-#include "bsp/gd32_rtc.h"
-#include "bsp/can.h"
-#include "bsp/i2c.h"
-#include "bsp/fmc_flash.h"
-#include "bsp/can.h"
-
-
-#define ADC_REFERENCE_VOLTAGE  3300.0f
-
-
-#define SYSTEM_CLOCK (120000000L) //system clk 120M Hz
-#define TIM_CLOCK (SYSTEM_CLOCK) /*SystemClock_Config��TIM1��clk��sys PLL �������̶�2����PLLƵ��*/
-#define TIM_CLOCK_MHz (120)
-#define ADC_CLOCK (30000000L)
-#define ADC_CLOCK_MHz (30)
-#define NS_PER_TCLK (8) /* (1/120000000 * 1000000000) */
-#define NS_2_TCLK(ns) ((ns/NS_PER_TCLK) + 1) //ns תΪpwmʹ�õ��Ǹ�TIM��clk count
-#define FOC_PWM_FS (30 * 1000)
-#define FOC_PWM_period (TIM_CLOCK/FOC_PWM_FS)
-#define FOC_PWM_Half_Period (FOC_PWM_period/2)
-
-#define ADC_TRIG_CONV_LATENCY_CYCLES 12.5f
-#define ADC_SAMPLING_CYCLES 7.5f
-
 
-#define HW_DEAD_TIME_NS  1200
-#define HW_RISE_TIME_NS  50
-#define HW_NOISE_TIME_NS 50
-#define TDead NS_2_TCLK(HW_DEAD_TIME_NS/2)/* ����ʱ�� */ 
-#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
-#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
-#define TADC   ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TIMER_UP_IRQ_PRIORITY 2
+#define ADC_IRQ_PRIORITY 1
+#define HALL_IRQ_PRIORITY 2
+#define SCHED_TIMER_IRQ_PRIORITY 3
+#define EBREAK_IRQ_PRIORITY 2
+#define CAN_IRQ_PRIORITY       6 
+#define RTC_IRQ_PRIORITY       7 
+#define UART_IRQ_PRIORITY      6 
+#define ENC_TIMER_IRQ_PRIORITY 2
+#define ENC_PWM_IRQ_PRIORITY 2
+#define ENC_I_EXIT_IRQ_PRIORITY 0
+#define ENC_OTHER_IRQ_PRIORITY 8
 
-#define START_RAMP_DURATION (1000)//ms
-#define SPEED_SAMPLE_INVAL (100) //ת�Ѳɼ��ļ��,ms
-#define SPEED_RAMP_DURATION SPEED_SAMPLE_INVAL //�����ٶȵ�б��ʱ�䣬�ٶ�ƽ���������½�
+#define THREE_SHUNTS_SAMPLE 1
+#define ONE_SHUNT_SAMPLE 2
 
-#define MAX_VBUS_VOLTAGE 48.0f
-#define MAX_CURRENT      50.0F
+#define GPIO_HIGH_BRK_MODE 1
+#define GPIO_LOW_BRK_MODE 2
 
-#define pwm_timer TIMER0
-#define adc_timer TIMER0
-#define aux_timer TIMER0
+#define ENCODER_MPS 1
+#define ENCODER_MT  2
 
-#define USER_ITMER_BRAKE 0
 
-#define TIMER_UP_IRQ_PRIORITY 0
-#define ADC_IRQ_PRIORITY 1
-#define HALL_IRQ_PRIORITY 2
-
-void bsp_init(void);
-void wdog_reload(void);
-void system_reboot(void);
-int wdog_set_timeout(int wdog_time);
+#define MOTOR_BLUESHARK_NEW1  1//蓝鲨大功率电机,双I形
+#define MOTOR_BLUESHARK_NEW2  2//蓝鲨大功率电机,V形
+#define MOTOR_BLUESHARK_OLD   3//目前量产的电机
+#define MOTOR_BLUESHARK_ZD_100  4//中动100码编码器电机样品
+#define MOTOR_BLUESHARK_A1      5
 
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "bsp/gd32/bsp.h"
+#elif defined AT32F413RCT7
+#include "bsp/at32/bsp.h"
+#elif defined N32G45X
+#include "bsp/n32/bsp.h"
+#endif
 #endif /* __BSP_H__ */

+ 52 - 0
Applications/bsp/bsp_driver.h

@@ -0,0 +1,52 @@
+#ifndef __BSP_DRIVER_H__
+#define __BSP_DRIVER_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#include "bsp/gd32/gpio.h"
+#include "bsp/gd32/gd32_bkp.h"
+#include "bsp/gd32/gd32_rtc.h"
+#include "bsp/gd32/can.h"
+#include "bsp/gd32/i2c.h"
+#include "bsp/gd32/fmc_flash.h"
+#include "bsp/gd32/can.h"
+#include "bsp/gd32/pwm.h"
+#include "bsp/gd32/adc.h"
+#include "bsp/gd32/fan_pwm.h"
+#include "bsp/gd32/enc_intf.h"
+#include "bsp/gd32/sched_timer.h"
+#include "bsp/gd32/uart.h"
+#elif defined AT32F413RCT7
+#include "at32f413.h"
+#include "bsp/at32/gpio.h"
+#include "bsp/at32/can.h"
+#include "bsp/at32/fmc_flash.h"
+#include "bsp/at32/can.h"
+#include "bsp/at32/pwm.h"
+#include "bsp/at32/adc.h"
+#include "bsp/at32/fan_pwm.h"
+#include "bsp/at32/enc_intf.h"
+#include "bsp/at32/sched_timer.h"
+#include "bsp/at32/uart.h"
+#elif defined N32G45X
+#include "n32g45x.h"
+#include "bsp/n32/gpio.h"
+#include "bsp/n32/can.h"
+#include "bsp/n32/fmc_flash.h"
+#include "bsp/n32/can.h"
+#include "bsp/n32/pwm.h"
+#include "bsp/n32/adc.h"
+#include "bsp/n32/fan_pwm.h"
+#include "bsp/n32/enc_intf.h"
+#include "bsp/n32/sched_timer.h"
+#include "bsp/n32/uart.h"
+#endif
+#include "bsp/delay.h"
+
+void bsp_init(void);
+void wdog_reload(void);
+void system_reboot(void);
+int wdog_set_timeout(int wdog_time);
+void systick_open(void);
+u8 mcu_chip_id(u8 *buff);
+u32 get_mcu_reset_source(void);
+#endif /* __BSP_DRIVER_H__ */

+ 75 - 0
Applications/bsp/delay.c

@@ -0,0 +1,75 @@
+#include "bsp/bsp.h"
+#include "bsp/delay.h"
+#include "os/os_types.h"
+
+void task_ticks_enable(void)
+{
+	CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+}
+
+uint32_t task_ticks_abs(void)
+{
+	return DWT->CYCCNT;
+}
+
+uint32_t task_ticks_rel(uint32_t start)
+{
+	uint32_t ticks = DWT->CYCCNT;
+
+	if (ticks >= start) {
+		return ticks - start;
+	}
+
+	return 0xFFFFFFFF - start + ticks + 1;
+}
+
+void task_ticks_delay(uint32_t ticks)
+{
+	uint32_t start;
+
+	start = task_ticks_abs();
+	while (task_ticks_rel(start) < ticks);
+}
+
+void task_udelay(uint32_t delay)
+{
+	task_ticks_delay(delay * (SystemCoreClock / 1000000));
+}
+
+
+uint32_t task_get_usecond(void) {
+	return task_ticks_abs() / (SYSTEM_CLOCK / 1000000);
+}
+
+uint32_t task_get_delta_us(uint32_t us) {
+	u32 count = us * (SYSTEM_CLOCK / 1000000);
+	return task_delta_ticks(count) / (SYSTEM_CLOCK / 1000000);
+}
+
+
+uint32_t task_delta_ticks(u32 count) {
+	u32 now = task_ticks_abs();
+	u32 delta = now - count;
+	if (now < count) { //wrap
+		delta = 0xFFFFFFFF - count + now + 1;
+	}
+	return (delta);
+}
+
+void delay_us(uint16_t cnt)
+{
+	task_udelay(cnt);
+}
+
+/*!
+    \brief      delay a time in milliseconds
+    \param[in]  count: count in milliseconds
+    \param[out] none
+    \retval     none
+*/
+void delay_ms(uint32_t count)
+{
+	task_udelay(1000 * count);
+}
+

+ 21 - 0
Applications/bsp/delay.h

@@ -0,0 +1,21 @@
+#ifndef __DELAY_H
+#define __DELAY_H 			   
+
+extern uint32_t utc_seconds;
+
+
+void task_ticks_enable(void);
+uint32_t task_ticks_abs(void);
+uint32_t task_ticks_rel(uint32_t start);
+uint32_t task_delta_ticks(uint32_t count);
+void systick_close(void);
+void delay_ms(uint32_t count);
+void delay_us(uint16_t cnt);
+void task_udelay(uint32_t delay);
+uint32_t task_get_usecond(void);
+uint32_t task_get_delta_us(uint32_t us);
+
+#endif
+
+
+

+ 0 - 73
Applications/bsp/dma.c

@@ -1,73 +0,0 @@
-#include "bsp/dma.h"
-
-u16 pwm_timer_dma_buf[2];
-u16 adc_timer_dma_buf[3];
-static void pwm_timer_dma_init(void);
-static void adc_timer_dma_init(void);
-
-void dma0_init(void){
-	pwm_timer_dma_buf[0] = FOC_PWM_Half_Period;
-	pwm_timer_dma_buf[1] = FOC_PWM_Half_Period;
-
-	adc_timer_dma_buf[0] = FOC_PWM_Half_Period;
-	adc_timer_dma_buf[1] = FOC_PWM_period - 1;
-	adc_timer_dma_buf[0] = FOC_PWM_Half_Period;
-
-	pwm_timer_dma_init();
-	adc_timer_dma_init();
-}
-
-static void pwm_timer_dma_init(void){
-    dma_parameter_struct dma_init_struct;
-
-    /* enable DMA clock */
-    rcu_periph_clock_enable(PWM_TIMER_CC3_DMA_CLK);
-
-    /* initialize DMA channel */
-    dma_deinit(PWM_TIMER_CC3_DMA_DEV,PWM_TIMER_CC3_DMA_CHAN);
-
-    /* DMA channel5 initialize */
-    dma_init_struct.periph_addr = (uint32_t)TIMER_CH0CV(pwm_timer);//changed by foc later
-    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
-    dma_init_struct.memory_addr = (uint32_t)pwm_timer_dma_buf;
-    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
-    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
-    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
-    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
-    dma_init_struct.number = 2;
-    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
-    dma_init(PWM_TIMER_CC3_DMA_DEV,PWM_TIMER_CC3_DMA_CHAN,&dma_init_struct);
-    
-    dma_circulation_enable(PWM_TIMER_CC3_DMA_DEV,PWM_TIMER_CC3_DMA_CHAN);
-
-    /* enable DMA channel */
-    dma_channel_enable(PWM_TIMER_CC3_DMA_DEV,PWM_TIMER_CC3_DMA_CHAN);
-}
-
-static void adc_timer_dma_init(void){
-    dma_parameter_struct dma_init_struct;
-
-    /* enable DMA clock */
-    rcu_periph_clock_enable(ADC_TIMER_CC0_DMA_CLK);
-
-    /* initialize DMA channel */
-    dma_deinit(ADC_TIMER_CC0_DMA_DEV,ADC_TIMER_CC0_DMA_CHAN);
-
-    /* DMA channel5 initialize */
-    dma_init_struct.periph_addr = (uint32_t)TIMER_CH0CV(adc_timer);
-    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
-    dma_init_struct.memory_addr = (uint32_t)adc_timer_dma_buf;
-    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
-    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
-    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
-    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
-    dma_init_struct.number = 3;
-    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
-    dma_init(ADC_TIMER_CC0_DMA_DEV,ADC_TIMER_CC0_DMA_CHAN,&dma_init_struct);
-    
-    dma_circulation_enable(ADC_TIMER_CC0_DMA_DEV,ADC_TIMER_CC0_DMA_CHAN);
-
-    /* enable DMA channel */
-    dma_channel_enable(ADC_TIMER_CC0_DMA_DEV,ADC_TIMER_CC0_DMA_CHAN);
-}
-

+ 0 - 20
Applications/bsp/dma.h

@@ -1,20 +0,0 @@
-#ifndef _DMA_H__
-#define _DMA_H__
-#include "bsp/bsp.h"
-#include "os/os_type.h"
-
-#define PWM_TIMER_CC3_DMA_DEV DMA0
-#define PWM_TIMER_CC3_DMA_CLK RCU_DMA0
-#define PWM_TIMER_CC3_DMA_CHAN DMA_CH3
-
-#define ADC_TIMER_CC0_DMA_DEV DMA0
-#define ADC_TIMER_CC0_DMA_CLK RCU_DMA0
-#define ADC_TIMER_CC0_DMA_CHAN DMA_CH5
-
-extern u16 pwm_timer_dma_buf[2];
-extern u16 adc_timer_dma_buf[3];
-
-void dma0_init(void);
-
-#endif /*_DMA_H__ */
-

+ 0 - 88
Applications/bsp/eeprom.c

@@ -1,88 +0,0 @@
-#include "bsp/i2c.h"
-#include "eeprom.h"
-
-#define I2C_ADDR 0XA4
-#define PAGE_SIZE 16
-
-static int eeprom_write_page(u16 addr,u8 *data,u8 len);
-
-int eeprom_write_bytes(u16 addr, u8 *data, int len){
-	U16 remain_len = len;
-	while(remain_len > 0){
-		U16 w_len = (remain_len > PAGE_SIZE)?PAGE_SIZE:remain_len;
-		if (eeprom_write_page(addr, data, w_len) < 0){
-			return -1;
-		}
-		addr+= w_len;
-		data += w_len;
-		remain_len -= w_len;
-	}
-	return 0;
-}
-int eeprom_read_bytes(u16 addr, u8 *data, int len){
-	uint8_t device_addr = I2C_ADDR | ((addr >>8) << 1);
-	int try_count = 100;
-	while(0 >= shark_i2c_read_nbytes(0, device_addr, (uint8_t)(addr&0xFF), data, len)){
-		if (try_count-- <= 0){
-			return -1;
-		}
-	};
-	return 0;
-}
-
-/* use page write to improve write time */
-static int eeprom_write_page(u16 addr,u8 *data,u8 len){
-	uint8_t device_addr = I2C_ADDR | ((addr >>8) << 1);
-	int try_count = 100;
-	while(0 >= shark_i2c_write_nbytes(0, device_addr, (uint8_t)(addr&0xFF), data, len)){
-		if (try_count-- <= 0){
-			return -1;
-		}
-
-	};
-	return 0;
-}
-
-#if 0
-
-#define ADDR_START 	(2<<7)
-
-static U8 buffr[128];
-static int index = 0;
-static int _AT24CXX_test(void)
-{
-	int i=0;
-	char wdata = 0x5A;
-	if (index % 2 == 1){
-		wdata = 0xA5;
-	}
-	for(i=0;i<128;i++)
-	{
-		buffr[i] = wdata;
-	}
-	
-	eeprom_write_bytes(ADDR_START,buffr,128);
-	
-	memset(buffr,0,128);
-	
-	eeprom_read_bytes(ADDR_START,buffr,128);
-	
-	for(i=0;i<128;i++)
-	{
-		if (buffr[i] != wdata){
-			return -1;
-		}
-	}
-	return 0;
-}
-
-
-void AT24CXX_test(void){
-	while(_AT24CXX_test() == 0){
-		index++;
-	};
-}
-
-#endif
-
-

+ 0 - 10
Applications/bsp/eeprom.h

@@ -1,10 +0,0 @@
-#ifndef _EEPROM_H__
-#define _EEPROM_H__
-
-#include "libs/os.h"
-
-int eeprom_write_bytes(u16 addr, u8 *data, int len);
-int eeprom_read_bytes(u16 addr, u8 *data, int len);
-
-#endif /* _EEPROM_H__ */
-

+ 0 - 140
Applications/bsp/fmc_flash.c

@@ -1,140 +0,0 @@
-#include "bsp.h"
-
-#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
-#define FMC_FLAG_PGERR  FMC_FLAG_BANK0_PGERR
-#define FMC_FLAG_PGAERR  FMC_FLAG_BANK0_PGERR
-#define FMC_FLAG_WPERR  FMC_FLAG_BANK0_WPERR
-#define FMC_FLAG_END  FMC_FLAG_BANK0_END
-#endif
-
-#define one_page_size 2048
-#define sn_page_index 4
-#define data_bk_page_index 3
-#define data_page_index 2
-#define magic_page_index 1 //must is the last page in 256K eara
-static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
-static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
-static uint32_t _sn_addr(void);
-static uint32_t _data_addr(int index);
-static uint32_t _maigc_addr(void);
-
-void fmc_write_sn(uint8_t *sn, int len){
-	_fmc_write_data(_sn_addr(), sn, len);
-}
-
-void fmc_read_sn(uint8_t *sn, int len){
-	_fmc_read_data(_sn_addr(), sn, len);
-}
-
-void fmc_write_data(int index, uint8_t *data, int len){
-	_fmc_write_data(_data_addr(index), data, len);
-}
-
-void fmc_read_data(int index, uint8_t *data, int len){
-	_fmc_read_data(_data_addr(index), data, len);
-}
-
-static __inline__ void _fmc_flag_clear(void) {
-	fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-}
-
-void fmc_write_magic(uint32_t magic){
-	uint32_t address = _maigc_addr();
-	uint32_t length, checksum, value;
-
-	value = REG32(address + 8);
-	if (magic == value) {
-		return;
-	}
-
-	length = REG32(address);
-	checksum = REG32(address + 4);
-
-	fmc_unlock();
-
-	if (value != 0xFFFFFFFF) {
-		_fmc_flag_clear();
-		fmc_page_erase(address);
-
-		_fmc_flag_clear();
-		fmc_word_program(address, length);
-
-		_fmc_flag_clear();
-		fmc_word_program(address + 4, checksum);
-	}
-
-	if (magic != 0xFFFFFFFF) {
-		_fmc_flag_clear();
-		fmc_word_program(address + 8, magic);
-	}
-
-	fmc_lock();
-}
-
-uint32_t fmc_read_magic(void){
-	uint32_t magic = 0x5555aaaa;
-	_fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
-	return magic;
-}
-
-//if flash is lager than 256k, we just use the 256k
-static uint32_t __inline__ _flash_capatity(void){
-	uint32_t capacity;
-	capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
-	if (capacity > (256 * 1024)){
-		capacity =  256 * 1024;
-	}
-	return capacity;
-}
-
-static uint32_t _sn_addr(void){
-	return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
-}
-
-static uint32_t _data_addr(int index){
-	return 0x08000000 + (_flash_capatity() - one_page_size * (data_page_index + index));
-}
-
-static uint32_t _maigc_addr(void){
-	return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
-}
-
-static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
-	int i = 0;
-	for (i = 0; i < len; i++){
-		data[i] = REG8(addr + i);
-	}
-}
-
-static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
-	fmc_unlock();
-	fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-	fmc_page_erase(addr);
-	int total_words = len>>2;
-	uint32_t *p_u32_data = (uint32_t *)data;
-	int i;
-	for (i = 0; i < total_words; i++){
-		fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-		fmc_word_program(addr + i * 4, p_u32_data[i]);
-	}
-	data += i * 4;
-	addr += i * 4;
-	total_words = len - total_words * 4;
-	if (total_words > 0){
-		if (total_words == 1){
-			uint16_t half = *data;
-			fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-			fmc_halfword_program(addr, half);
-		}else if (total_words == 2){
-			uint16_t half = *((uint16_t *)data);
-			fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-			fmc_halfword_program(addr, half);
-		}else {
-			uint32_t words = *((uint32_t *)data);
-			fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
-			fmc_word_program(addr, words);
-		}
-	}
-	fmc_lock();
-}
-

+ 0 - 14
Applications/bsp/fmc_flash.h

@@ -1,14 +0,0 @@
-#ifndef _FMC_FLASH_H__
-#define _FMC_FLASH_H__
-#include <stdint.h>
-
-void fmc_write_sn(uint8_t *sn, int len);
-void fmc_read_sn(uint8_t *sn, int len);
-
-void fmc_write_data(int index, uint8_t *data, int len);
-void fmc_read_data(int index, uint8_t *data, int len);
-void fmc_write_magic(uint32_t magic);
-uint32_t fmc_read_magic(void);
-
-#endif /* _FMC_FLASH_H__ */
-

+ 645 - 0
Applications/bsp/gd32/adc.c

@@ -0,0 +1,645 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+#include "math/fast_math.h"
+
+
+#ifndef CONFIG_BOARD_MCXXX
+#define ADC01_NUM 7
+#define ADC2_NUM 0
+
+#define VBUS_V_BUFF_IDX 0
+#define THROTTLE_BUFF_IDX 1
+#define U_VOL_BUFF_IDX 2
+#define V_VOL_BUFF_IDX 3
+#define W_VOL_BUFF_IDX 4
+#define MOS_TEMP_BUFF_IDX 5
+#define MOTOR_TEMP_BUFF_IDX 6
+#define REG_CHAN_NUM (ADC01_NUM + ADC2_NUM)
+#define ADC_DUAL_MODE ADC_DAUL_INSERTED_PARALLEL
+#elif (CONFIG_HW_VERSION==2)
+#define ADC01_NUM (8)
+#define ADC2_NUM 4
+
+#define MOS_TEMP_BUFF_IDX 0
+#define VREF5v_BUFF_IDX 1
+#define VBUS_I_BUFF_IDX 2
+#define U_VOL_BUFF_IDX 3
+#define V_VOL_BUFF_IDX 4
+#define W_VOL_BUFF_IDX 5
+#define VREF_BUFF_IDX 7
+
+#define VBUS_V_BUFF_IDX 8
+#define ACC_V_BUFF_IDX 9
+#define THROTTLE_BUFF_IDX 10
+#define MOTOR_TEMP_BUFF_IDX 11
+#define REG_CHAN_NUM (ADC01_NUM + ADC2_NUM)
+#define ADC_DUAL_MODE ADC_DAUL_INSERTED_PARALLEL
+#elif (CONFIG_HW_VERSION==3)
+#define ADC01_NUM (9)
+
+#define MOS_TEMP_BUFF_IDX 0
+#define VBUS_V_BUFF_IDX 1
+
+#define MOTOR_TEMP_BUFF_IDX 2
+#define ACC_V_BUFF_IDX 3
+
+#define THROTTLE_BUFF_IDX 4
+#define VBUS_I_BUFF_IDX 5
+
+#define THROTTLE2_BUFF_IDX 6
+#define V_VOL_BUFF_IDX 7
+
+//zero chan            8
+#define W_VOL_BUFF_IDX 9
+
+#define VREF_BUFF_IDX   10
+//zero chan             11
+
+#define THROTTLE2_5V_BUFF_IDX 12
+#define THROTTLE_5V_BUFF_IDX 13
+
+#define U_VOL_BUFF_IDX 14
+//zero chan            15
+
+//zero chan            16
+#define VREF5v_BUFF_IDX 17
+#define REG_CHAN_NUM (ADC01_NUM + ADC01_NUM)
+#define ADC_DUAL_MODE ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL
+
+#endif
+
+s16 adc_buffer[REG_CHAN_NUM];
+float vref_adc = 1408.0f;
+float vref_5v_adc = 2047.0f;
+
+#define VREF_ADC_DATA 1509.0F //1498, 1.21/3.3*4095
+
+#if (CONFIG_HW_VERSION==3)
+static void adc01_dma_init(void)
+{
+    dma_parameter_struct dma_init_struct;
+    rcu_periph_clock_enable(RCU_DMA0);
+
+    dma_deinit(DMA0, DMA_CH0);
+    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
+    dma_init_struct.memory_addr  = (uint32_t)adc_buffer;
+    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
+    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_32BIT;
+    dma_init_struct.number       = REG_CHAN_NUM/2;
+    dma_init_struct.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
+    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
+    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_32BIT;
+    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
+    dma_init(DMA0, DMA_CH0, &dma_init_struct);
+    dma_circulation_enable(DMA0, DMA_CH0);
+    dma_memory_to_memory_disable(DMA0, DMA_CH0);
+
+    dma_channel_enable(DMA0, DMA_CH0);
+}
+#else
+static void adc01_dma_init(void)
+{
+    dma_parameter_struct dma_init_struct;
+    rcu_periph_clock_enable(RCU_DMA0);
+
+    dma_deinit(DMA0, DMA_CH0);
+    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
+    dma_init_struct.memory_addr  = (uint32_t)adc_buffer;
+    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
+    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
+    dma_init_struct.number       = REG_CHAN_NUM;
+    dma_init_struct.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
+    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
+    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
+    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
+    dma_init(DMA0, DMA_CH0, &dma_init_struct);
+    dma_circulation_enable(DMA0, DMA_CH0);
+    dma_memory_to_memory_disable(DMA0, DMA_CH0);
+
+    dma_channel_enable(DMA0, DMA_CH0);
+}
+#endif
+
+#if (CONFIG_HW_VERSION==3)
+static void adc01_init(void) {
+    /* config ADC clock */
+    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4); //APB2 clk 120M, adc clk 30M
+	rcu_periph_clock_enable(RCU_ADC0);
+	rcu_periph_clock_enable(RCU_ADC1);
+	adc_deinit(ADC0);
+	adc_deinit(ADC1);
+
+	/* config work mode */
+    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
+    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
+    adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE);
+    adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
+
+    /* configure ADC data alignment */
+    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
+	adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
+
+	/* configure ADC regular channel */
+	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, ADC01_NUM);
+	adc_regular_channel_config(ADC0, 0, MOS_TEMP_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 1, MOTOR_TEMP_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 2, THROTTLE_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 3, THROTTLE2_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 4, ZERO_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_regular_channel_config(ADC0, 5, ADC_CHANNEL_17, ADC_REGCHAN_SAMPLE_TIME); //mcu内部vref
+	adc_regular_channel_config(ADC0, 6, THROTTLE2_5V_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 7, U_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 8, ZERO_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_tempsensor_vrefint_enable();
+
+	adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, ADC01_NUM);
+	adc_regular_channel_config(ADC1, 0, VBUS_V_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 1, ACC_V_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 2, VBUS_I_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 3, V_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 4, W_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 5, ZERO_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_regular_channel_config(ADC1, 6, THROTTLE_5V_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC1, 7, ZERO_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME); //insert zero vol
+	adc_regular_channel_config(ADC1, 8, DC5V_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_buffer[VREF_BUFF_IDX] = VREF_ADC_DATA; //1.21/3.3*4095
+
+    /* configure ADC regular channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
+	adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
+    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
+	adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
+
+	/* configure ADC inserted channel length */
+	adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, INJ_CHAN_NUM);
+#if 1
+	adc_inserted_channel_config(ADC0, 0, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#if (INJ_CHAN_NUM==4)
+	adc_inserted_channel_config(ADC0, 1, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_inserted_channel_config(ADC0, 2, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_inserted_channel_config(ADC0, 3, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#else
+	adc_update_insert_sample_time(ADC0, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_update_insert_sample_time(ADC0, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+	adc_channel_length_config(ADC1, ADC_INSERTED_CHANNEL, INJ_CHAN_NUM);
+#if 1
+	adc_inserted_channel_config(ADC1, 0, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#if (INJ_CHAN_NUM==4)
+	adc_inserted_channel_config(ADC1, 1, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_inserted_channel_config(ADC1, 2, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_inserted_channel_config(ADC1, 3, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#else
+	adc_update_insert_sample_time(ADC1, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+	adc_update_insert_sample_time(ADC1, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+	adc_mode_config(ADC_DUAL_MODE);
+
+    /* configure ADC inserted channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC_TRIGGER_PHASE);
+    /* ADC external trigger enable */
+    adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
+    /* ADC1 external trigger disable */
+	adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC_TRIGGER_NONE);
+    adc_external_trigger_config(ADC1, ADC_INSERTED_CHANNEL, ENABLE);
+
+    /* enable ADC interface */
+    adc_enable(ADC0);
+	delay_ms(1);
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC0);
+    adc_enable(ADC1);
+	delay_ms(1);
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC1);
+
+	adc_dma_mode_enable(ADC0);
+
+	adc_disable_ext_trigger();
+
+	nvic_irq_enable(ADC0_1_IRQn, ADC_IRQ_PRIORITY, 0);
+
+	//start regular channels
+	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
+}
+#else
+static void adc0_init(void){
+    /* config ADC clock */
+    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4); //APB2 clk 120M, adc clk 30M
+
+	rcu_periph_clock_enable(RCU_ADC0);
+
+	adc_deinit(ADC0);
+
+	adc_mode_config(ADC_DUAL_MODE);
+
+    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);
+    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
+
+    /* configure ADC data alignment */
+    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
+	
+    /* configure ADC inserted channel length */
+    adc_channel_length_config(ADC0, ADC_INSERTED_CHANNEL, 1);
+
+    //adc_inserted_channel_config(ADC0, 0, U_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#ifdef U_PHASE_I_CHAN
+	adc_update_insert_sample_time(ADC0, U_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#ifdef V_PHASE_I_CHAN	
+	adc_update_insert_sample_time(ADC0, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#ifdef W_PHASE_I_CHAN	
+	adc_update_insert_sample_time(ADC0, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+
+#ifdef CONFIG_HW_MUTISAMPLE
+	adc_oversample_mode_config(ADC0, ADC_OVERSAMPLING_ALL_CONVERT, CONFIG_HW_MUTISAMPLE_SHIFT, CONFIG_HW_MUTISAMPLE);
+	adc_oversample_mode_enable(ADC0);
+#endif
+    /* configure ADC inserted channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC_TRIGGER_PHASE);
+
+    /* ADC external trigger enable */
+    adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);
+
+    /* configure ADC regular channel */
+    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, ADC01_NUM);
+#ifndef CONFIG_BOARD_MCXXX
+    adc_regular_channel_config(ADC0, 0, VBUS_V_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+    adc_regular_channel_config(ADC0, 1, THROTTLE_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 2, U_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 3, V_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 4, W_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 5, MOS_TEMP_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 6, MOTOR_TEMP_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+#elif (CONFIG_HW_VERSION==2)
+	adc_regular_channel_config(ADC0, 0, MOS_TEMP_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 1, MOS_TEMP1_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 2, VBUS_I_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 3, U_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 4, V_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 5, W_VOL_ADC_CHAN, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 6, ADC_CHANNEL_10, ADC_REGCHAN_SAMPLE_TIME);
+	adc_regular_channel_config(ADC0, 7, ADC_CHANNEL_17, ADC_REGCHAN_SAMPLE_TIME);
+	adc_tempsensor_vrefint_enable();
+	adc_buffer[VREF_BUFF_IDX] = VREF_ADC_DATA; //1.21/3.3*4095
+#endif
+    /* configure ADC regular channel trigger */
+    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
+    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
+
+	adc_dma_mode_enable(ADC0);
+
+    /* enable ADC interface */
+    adc_enable(ADC0);
+
+	delay_ms(1);
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC0);
+
+	nvic_irq_enable(ADC0_1_IRQn, ADC_IRQ_PRIORITY, 0);
+
+	adc_disable_ext_trigger();
+}
+
+static void adc1_init(void){
+
+	rcu_periph_clock_enable(RCU_ADC1);
+	adc_deinit(ADC1);
+
+	adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, ENABLE);
+	adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
+
+    /* configure ADC data alignment */
+    adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
+	
+    /* configure ADC inserted channel length */
+    adc_channel_length_config(ADC1, ADC_INSERTED_CHANNEL, 1);
+
+    /* configure ADC inserted channel */
+#ifdef U_PHASE_I_CHAN
+	adc_update_insert_sample_time(ADC1, U_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#ifdef V_PHASE_I_CHAN	
+	adc_update_insert_sample_time(ADC1, V_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+#ifdef W_PHASE_I_CHAN	
+	adc_update_insert_sample_time(ADC1, W_PHASE_I_CHAN, ADC_INSERT_SAMPLE_TIME);
+#endif
+
+#ifdef CONFIG_HW_MUTISAMPLE
+	adc_oversample_mode_config(ADC1, ADC_OVERSAMPLING_ALL_CONVERT, CONFIG_HW_MUTISAMPLE_SHIFT, CONFIG_HW_MUTISAMPLE);
+	adc_oversample_mode_enable(ADC1);
+#endif
+
+    /* ADC external trigger enable */
+	adc_external_trigger_source_config(ADC1, ADC_INSERTED_CHANNEL, ADC_TRIGGER_NONE);
+    adc_external_trigger_config(ADC1, ADC_INSERTED_CHANNEL, ENABLE);
+
+    /* enable ADC interface */
+    adc_enable(ADC1);
+	delay_ms(1);
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC1);	
+}
+
+#endif
+
+static void adc_gpio_init(void) {
+
+	rcu_periph_clock_enable(RCU_AF);
+		/* configure ADC pin, current sampling -- ADC_IN1(PA1) ADC_IN12(PC2) ADC_IN13(PC3) */
+#ifdef U_PHASE_ADC_GROUP
+		rcu_periph_clock_enable(U_PHASE_ADC_RCU);
+		gpio_init(U_PHASE_ADC_GROUP, U_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, U_PHASE_ADC_PIN);
+#endif
+#ifdef V_PHASE_ADC_GROUP
+		rcu_periph_clock_enable(V_PHASE_ADC_RCU);
+		gpio_init(V_PHASE_ADC_GROUP, V_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, V_PHASE_ADC_PIN);
+#endif
+#ifdef W_PHASE_ADC_GROUP
+		rcu_periph_clock_enable(W_PHASE_ADC_RCU);
+		gpio_init(W_PHASE_ADC_GROUP, W_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, W_PHASE_ADC_PIN);
+#endif
+
+#ifdef VBUS_V_ADC_GROUP
+	rcu_periph_clock_enable(VBUS_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(VBUS_V_ADC_GROUP, VBUS_V_ADC_MODE, GPIO_OSPEED_50MHZ, VBUS_V_ADC_PIN);
+#endif
+
+#ifdef VBUS_I_ADC_GROUP
+	rcu_periph_clock_enable(VBUS_I_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(VBUS_I_ADC_GROUP, VBUS_I_ADC_MODE, GPIO_OSPEED_50MHZ, VBUS_I_ADC_PIN);
+#endif
+
+
+#ifdef ACC_V_ADC_GROUP
+	rcu_periph_clock_enable(ACC_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(ACC_V_ADC_GROUP, ACC_V_ADC_MODE, GPIO_OSPEED_50MHZ, ACC_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_V_ADC_GROUP
+	rcu_periph_clock_enable(THROTTLE_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE_V_ADC_GROUP, THROTTLE_V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE_V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_V_ADC_GROUP
+	rcu_periph_clock_enable(THROTTLE2_V_ADC_RCU);
+	gpio_init(THROTTLE2_V_ADC_GROUP, THROTTLE2_V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE2_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_5V_ADC_GROUP
+	rcu_periph_clock_enable(THROTTLE_5V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE_5V_ADC_GROUP, THROTTLE_5V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE_5V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_5V_ADC_GROUP
+	rcu_periph_clock_enable(THROTTLE2_5V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE2_5V_ADC_GROUP, THROTTLE2_5V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE2_5V_ADC_PIN);
+#endif
+
+#ifdef U_VOL_ADC_GROUP
+	rcu_periph_clock_enable(U_VOL_ADC_RCU);
+	gpio_init(U_VOL_ADC_GROUP, U_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, U_VOL_ADC_PIN);
+#endif
+#ifdef V_VOL_ADC_GROUP
+	rcu_periph_clock_enable(V_VOL_ADC_RCU);
+	gpio_init(V_VOL_ADC_GROUP, V_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, V_VOL_ADC_PIN);
+#endif
+#ifdef W_VOL_ADC_GROUP
+	rcu_periph_clock_enable(W_VOL_ADC_RCU);
+	gpio_init(W_VOL_ADC_GROUP, W_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, W_VOL_ADC_PIN);
+#endif
+#ifdef MOS_TEMP_ADC_GROUP
+	rcu_periph_clock_enable(MOS_TEMP_ADC_RCU);
+	gpio_init(MOS_TEMP_ADC_GROUP, MOS_TEMP_ADC_MODE, GPIO_OSPEED_50MHZ, MOS_TEMP_ADC_PIN);
+#endif
+#ifdef MOS_TEMP1_ADC_GROUP
+	rcu_periph_clock_enable(MOS_TEMP1_ADC_RCU);
+	gpio_init(MOS_TEMP1_ADC_GROUP, MOS_TEMP1_ADC_MODE, GPIO_OSPEED_50MHZ, MOS_TEMP1_ADC_PIN);
+#endif
+
+#ifdef MOTOR_TEMP_ADC_GROUP
+	rcu_periph_clock_enable(MOTOR_TEMP_ADC_RCU);
+	gpio_init(MOTOR_TEMP_ADC_GROUP, MOTOR_TEMP_ADC_MODE, GPIO_OSPEED_50MHZ, MOTOR_TEMP_ADC_PIN);
+#endif
+
+#ifdef ZERO_ADC_GROUP
+	rcu_periph_clock_enable(ZERO_ADC_RCU);
+	gpio_init(ZERO_ADC_GROUP, ZERO_ADC_MODE, GPIO_OSPEED_50MHZ, ZERO_ADC_PIN);
+#endif
+
+}
+
+void adc_init(void) {
+	adc_gpio_init();
+	adc01_dma_init();
+#if (CONFIG_HW_VERSION==3)
+	adc01_init();
+#else
+	adc0_init();
+	adc1_init();
+#endif
+	adc_current_sample_config(0);
+}
+
+void adc_set_vref_calc(float v) {
+	vref_adc = v;
+}
+
+void adc_set_5vref_calc(float v) {
+	vref_5v_adc = v;
+}
+
+#define VREF_COMP_LFP_CEOF (0.0001F)
+static float vref_compestion_filter = 1.0f;
+#define VREF_3V3_COMPESTION() (vref_adc/(float)adc_buffer[VREF_BUFF_IDX])
+void adc_3v3ref_filter(void) {
+	float value = VREF_3V3_COMPESTION();
+	LowPass_Filter(vref_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_vref_compesion(void) {
+	return vref_compestion_filter;
+}
+
+static float vref_5v_compestion_filter = 1.0f;
+#define VREF_5V_COMPESTION() (vref_5v_adc/(float)adc_buffer[VREF5v_BUFF_IDX])
+void adc_5vref_filter(void) {
+	float value = VREF_5V_COMPESTION();
+	LowPass_Filter(vref_5v_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_5vref_compesion(void) {
+	return vref_5v_compestion_filter;
+}
+
+void adc_vref_filter(void) {
+	adc_3v3ref_filter();
+	adc_5vref_filter();
+}
+
+u16 adc_get_vbus(void) {
+	return (float)adc_buffer[VBUS_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+}
+
+u16 adc_get_acc(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[ACC_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_vbus();
+#endif
+}
+
+u16 adc_get_ibus(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[VBUS_I_BUFF_IDX] * VREF_5V_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_throttle(void) {
+	if (gpio_board_id() == BOARD_105_VERSION_3) {
+		return adc_buffer[THROTTLE_BUFF_IDX] * VREF_3V3_COMPESTION();
+	}else {
+		return adc_buffer[MOTOR_TEMP_BUFF_IDX];
+	}
+}
+
+u16 adc_get_throttle2(void) {
+#ifdef THROTTLE2_BUFF_IDX
+	return adc_buffer[THROTTLE2_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_throttle();
+#endif
+}
+
+u16 adc_get_thro_5v(void) {
+#ifdef THROTTLE_5V_BUFF_IDX
+	return adc_buffer[THROTTLE_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_thro2_5v(void) {
+#ifdef THROTTLE2_5V_BUFF_IDX
+	return adc_buffer[THROTTLE2_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+void adc_get_uvw_phaseV(u16 *uvw) {
+	uvw[0] = adc_buffer[U_VOL_BUFF_IDX];
+	uvw[1] = adc_buffer[V_VOL_BUFF_IDX];
+	uvw[2] = adc_buffer[W_VOL_BUFF_IDX];
+}
+
+u16 adc_get_mos_temp(void) {
+	return adc_buffer[MOS_TEMP_BUFF_IDX];
+}
+
+u16 adc_get_motor_temp(void) {
+	if (gpio_board_id() == BOARD_105_VERSION_3) {
+		return adc_buffer[MOTOR_TEMP_BUFF_IDX];
+	}else {
+		return adc_buffer[THROTTLE_BUFF_IDX];
+	}
+}
+
+u16 adc_get_vref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_5v_ref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF5v_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+void adc_start_convert(void) {
+	int drop = 16;
+    /* clear the ADC flag */
+    adc_flag_clear(ADC0, ADC_FLAG_EOIC);
+    adc_flag_clear(ADC1, ADC_FLAG_EOIC);
+
+	adc_enable_ext_trigger();
+	while(drop-- > 0) {
+		while (adc_flag_get(ADC0, ADC_FLAG_EOIC) == RESET);
+		adc_flag_clear(ADC0, ADC_FLAG_EOIC);
+	}
+    /* enable ADC interrupt */
+
+	adc_interrupt_enable(ADC0, ADC_INT_EOIC);
+
+	adc_update_ext_trigger(ADC_TRIGGER_PHASE);
+}
+
+void adc_stop_convert(void) {
+	adc_disable_ext_trigger();
+    /* disable ADC interrupt */
+
+	adc_interrupt_disable(ADC0, ADC_INT_EOIC);
+
+    /* clear the ADC flag */
+    adc_flag_clear(ADC0, ADC_FLAG_EOIC);
+	adc_flag_clear(ADC1, ADC_FLAG_EOIC);
+}
+
+
+s32 adc_sample_regular_channel(int channel, int times) {
+#ifndef REG_CHAN_DMA
+	u32 adc_device = ADC0;
+	int value = 0;
+	int count = 0;
+	int min = 0xFFFFF;
+	int max = -0xFFFFF;
+	u64 start_time;
+	adc_channel_length_config(adc_device, ADC_REGULAR_CHANNEL, 1);
+	adc_regular_channel_config(adc_device, 0, channel, ADC_REGCHAN_SAMPLE_TIME);
+	while(count < times){
+restart:		
+		start_time = shark_get_mseconds();
+		adc_software_trigger_enable(adc_device, ADC_REGULAR_CHANNEL);
+    	while(SET != adc_flag_get(adc_device, ADC_FLAG_EOC)){
+			if (shark_get_mseconds() - start_time >= 2){
+				goto restart;
+			}
+		};
+    	int one = adc_regular_data_read(adc_device);
+		adc_flag_clear(adc_device, ADC_FLAG_EOC);		
+		value += (one & 0xFFF);
+		count ++;
+		if (one > max){
+			max = one;
+		}
+		if (one < min) {
+			min = one;
+		}
+	}
+	if (times <= 2) {
+		return value/times;
+	}
+	return (value - min - max)/(times-2);
+#else
+	return 0;
+#endif
+}
+

+ 196 - 0
Applications/bsp/gd32/adc.h

@@ -0,0 +1,196 @@
+#ifndef _ADC_H__
+#define _ADC_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+float adc_vref_compesion(void);
+float adc_5vref_compesion(void);
+
+/*
+inserted ADC 由timer0 ch3触发,
+注意:adc所有外部触发都是下降沿触发 
+*/
+#define ISQ0_OFFSET 0
+#define ISQ1_OFFSET 5
+#define ISQ2_OFFSET 10
+#define ISQ3_OFFSET 15
+#define IL_OFFSET   20
+
+#define ADC_INSERT_SAMPLE_TIME ADC_SAMPLETIME_13POINT5
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+#define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_TRGO
+#else
+#define ADC_TRIGGER_PHASE ADC0_1_EXTTRIG_INSERTED_T0_CH3
+#endif
+#define ADC_TRIGGER_PHASE2 ADC0_1_EXTTRIG_INSERTED_T1_CH0
+#define ADC_TRIGGER_NONE  ADC0_1_2_EXTTRIG_INSERTED_NONE
+#define ADC_TRIGGER_VBUS ADC0_1_EXTTRIG_INSERTED_T1_CH0
+
+#define PHASE_AB 0
+#define PHASE_AC 1
+#define PHASE_BC 2
+
+#define ADC_RANK_CHANNEL(c)  ((c)<<ISQ3_OFFSET | (0)<<IL_OFFSET) 
+#define ADC_INS_RANK_4_CHANS(c1,c2,c3,c4) (((c1)<<ISQ0_OFFSET) | ((c2)<<ISQ1_OFFSET) | ((c3)<<ISQ2_OFFSET) | ((c4)<<ISQ3_OFFSET) | ((3)<<IL_OFFSET))
+#define INJ_CHAN_NUM 1
+
+#ifndef HIGH_SIDE_CURRENT_SENSOR
+static u32 adc0_rank_channels[3] = {
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//0, A, AB	
+	ADC_RANK_CHANNEL(U_PHASE_I_CHAN),//1, A, AC
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//2, B, BC
+
+};
+static u32 adc1_rank_channels[3] = {
+	ADC_RANK_CHANNEL(V_PHASE_I_CHAN),//0, B
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//1, C
+	ADC_RANK_CHANNEL(W_PHASE_I_CHAN),//2, C
+};
+
+
+static u32 volatile * adc_phase_reg1[3] = {
+	&ADC_IDATA0(ADC0),//0, A
+	&ADC_IDATA0(ADC0),//1, A
+	&ADC_IDATA0(ADC0),//2, B
+};
+static u32 volatile * adc_phase_reg2[3] = {
+	&ADC_IDATA0(ADC1),//0, B
+	&ADC_IDATA0(ADC1),//1, C
+	&ADC_IDATA0(ADC1),//2, C
+};
+#endif
+
+#define v_calc(sum, v, min, max) \
+	do { \
+		if (v > max) { \
+			max = v; \
+		} \
+		if (v < min) { \
+			min = v; \
+		}\
+		sum += v; \
+	}while(0);
+
+static void __inline adc_phase_current_read(u8 phases, s32 *pv1, s32 *pv2) {
+#ifdef HIGH_SIDE_CURRENT_SENSOR
+#if (INJ_CHAN_NUM==4)
+	u16 min, max;
+	u16 sum = 0;
+	u16 v1 = ADC_IDATA0(ADC0);
+	u16 v2 = ADC_IDATA1(ADC1);
+	u16 v3 = ADC_IDATA2(ADC0);
+	u16 v4 = ADC_IDATA3(ADC1);
+	min = max = v1;
+	sum += v1;
+	v_calc(sum, v2, min, max);
+	v_calc(sum, v3, min, max);
+	v_calc(sum, v4, min, max);
+	*pv1 = (s32) ((sum-min-max)/2.0f * adc_5vref_compesion());
+
+	sum = 0;
+	v1 = ADC_IDATA0(ADC1);
+	v2 = ADC_IDATA1(ADC0);
+	v3 = ADC_IDATA2(ADC1);
+	v4 = ADC_IDATA3(ADC0);
+	min = max = v1;
+	sum += v1;
+	v_calc(sum, v2, min, max);
+	v_calc(sum, v3, min, max);
+	v_calc(sum, v4, min, max);
+	*pv2 = (s32) ((sum-min-max)/2.0f * adc_5vref_compesion());
+
+#else
+	*pv1 = (s32)((float)ADC_IDATA0(ADC0) * adc_5vref_compesion());
+	*pv2 = (s32)((float)ADC_IDATA0(ADC1) * adc_5vref_compesion());
+#endif
+#else
+	*pv1 = (s32)(*adc_phase_reg1[phases]) ;
+	*pv2 = (s32)(*adc_phase_reg2[phases]) ;
+#endif
+}
+
+
+static void __inline adc_current_sample_config(u8 phases) {
+#ifdef HIGH_SIDE_CURRENT_SENSOR
+#if (INJ_CHAN_NUM==4)
+	//ADC_ISQ(ADC0) = ADC_INS_RANK_4_CHANS(V_PHASE_I_CHAN, W_PHASE_I_CHAN, V_PHASE_I_CHAN, W_PHASE_I_CHAN);
+	//ADC_ISQ(ADC1) = ADC_INS_RANK_4_CHANS(W_PHASE_I_CHAN, V_PHASE_I_CHAN, W_PHASE_I_CHAN, V_PHASE_I_CHAN);
+#else
+	ADC_ISQ(ADC0) = ADC_RANK_CHANNEL(V_PHASE_I_CHAN);
+	ADC_ISQ(ADC1) = ADC_RANK_CHANNEL(W_PHASE_I_CHAN);
+#endif
+#else
+	ADC_ISQ(ADC0) = adc0_rank_channels[phases];
+	ADC_ISQ(ADC1) = adc1_rank_channels[phases];
+#endif
+}
+
+static void __inline adc_disable_ext_trigger(void) {   
+	ADC_CTL1(ADC0) &= ~ADC_CTL1_ETEIC;
+}
+
+static void __inline adc_enable_ext_trigger(void) {	
+	ADC_CTL1(ADC0) |= ADC_CTL1_ETEIC;
+}
+
+/* insert len fixed to 2(IL=1), ISQ2 >> ISQ3*/
+static __inline__ void adc_update_insert_sample_rank(u32 adc, u8 channel) {
+    ADC_ISQ(adc) = ADC_RANK_CHANNEL(channel);
+}
+
+static __inline__ void adc_update_insert_sample_time(u32 adc, uint8_t adc_channel , uint32_t sample_time)
+{
+    uint32_t sampt;
+    /* ADC sampling time config */  
+    if(adc_channel < 10U){
+        sampt = ADC_SAMPT1(adc);
+        sampt &= ~((u32)(ADC_SAMPTX_SPTN << (3U*adc_channel)));
+        sampt |= (u32) sample_time << (3U*adc_channel);
+        ADC_SAMPT1(adc) = sampt;
+    }else if(adc_channel < 18U){
+        sampt = ADC_SAMPT0(adc);
+        sampt &= ~((u32)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U))));
+        sampt |= ((u32)sample_time << (3U*(adc_channel-10U)));
+        ADC_SAMPT0(adc) = sampt;
+    }
+}
+
+static __inline__ bool adc_eoic_interrupt(void)
+{
+	if (ADC_STAT(ADC0) & ADC_STAT_EOIC){
+		return true;
+	}
+	return false;
+}
+
+static __inline__ void adc_clear_irq_flags(void) {
+	ADC_STAT(ADC0) &= ~((u32) ADC_INT_FLAG_EOIC);
+	ADC_STAT(ADC1) &= ~((u32) ADC_INT_FLAG_EOIC);
+}
+
+
+static __inline void adc_update_ext_trigger(u32 trigger) {
+	adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, trigger);
+}
+
+void adc_init(void);
+s32 adc_sample_regular_channel(int chan, int times);
+void adc_start_convert(void);
+void adc_stop_convert(void);
+u16 adc_get_vbus(void);
+u16 adc_get_acc(void);
+u16 adc_get_throttle(void);
+void adc_get_uvw_phaseV(u16 *uvw);
+u16 adc_get_mos_temp(void);
+u16 adc_get_motor_temp(void);
+u16 adc_get_ibus(void);
+u16 adc_get_vref(void);
+void adc_set_vref_calc(float v);
+void adc_vref_filter(void);
+u16 adc_get_5v_ref(void);
+void adc_set_5vref_calc(float v);
+u16 adc_get_throttle2(void);
+u16 adc_get_thro_5v(void);
+u16 adc_get_thro2_5v(void);
+
+#endif /* _ADC_H__ */

+ 176 - 0
Applications/bsp/gd32/board_gd32demo.h

@@ -0,0 +1,176 @@
+#ifndef _BOARD_GD32DEMO_H__
+#define _BOARD_GD32DEMO_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_RATED_DC_VOL (16)   /* 母线最大电压 V*/
+
+
+#define SCHED_TIMER TIMER5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIMER5_IRQn
+#define SCHED_TIMER_IRQHandler TIMER5_IRQHandler
+
+/* mos 参数,电流采集需要 */
+#define MOSDEV_DLY      550U
+#define MOSDRV_DT_NS     400U
+#define HW_DEAD_TIME_NS  (MOSDEV_DLY+MOSDRV_DT_NS)
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 500u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+
+/* MOS 驱动 */
+#define MOS_PWM_TIMER TIMER0
+#define PWM_MODE TIMER_OC_MODE_PWM0
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+/* 三电阻采样 */
+#define SHUNT_NUM 			THREE_SHUNTS_SAMPLE
+#define U_PHASE_I_CHAN  	ADC_CHANNEL_1
+#define V_PHASE_I_CHAN  	ADC_CHANNEL_12
+#define W_PHASE_I_CHAN  	ADC_CHANNEL_13
+
+#define U_PHASE_ADC_GROUP 	GPIOA
+#define U_PHASE_ADC_PIN 	GPIO_PIN_1
+#define U_PHASE_ADC_RCU 	RCU_GPIOA
+#define U_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_PHASE_ADC_GROUP 	GPIOC
+#define V_PHASE_ADC_PIN 	GPIO_PIN_2
+#define V_PHASE_ADC_RCU 	RCU_GPIOC
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOC
+#define W_PHASE_ADC_PIN 	GPIO_PIN_3
+#define W_PHASE_ADC_RCU 	RCU_GPIOC
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+/* 温度,母线,油门等采集*/
+#define MOTOR_TEMP_CHAN 	ADC_CHANNEL_11
+
+#define VBUS_V_CHAN 		ADC_CHANNEL_0
+#define VBUS_V_ADC_GROUP 	GPIOA
+#define VBUS_V_ADC_PIN 		GPIO_PIN_0
+#define VBUS_V_ADC_RCU 		RCU_GPIOA
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+
+#define THROTTLE_CHAN   		ADC_CHANNEL_10
+#define THROTTLE_V_ADC_GROUP 	GPIOC
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_0
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOC
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+
+/* 是否有目前电流采集 */
+#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* ADC 的电压系数 */
+#define ADC_TO_CURR_ceof (0.008f)
+#define VBUS_VOL_CEOF (ADC_REFERENCE_VOLTAGE*16/4096.0f)
+#define THROTTLE_VOL_CEOF (ADC_REFERENCE_VOLTAGE/4096.0f * 2.0f)
+
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_CC_INVERT //编码器方向和电机反向
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOA
+#define ENC_A_PIN GPIO_PIN_6
+#define ENC_A_RCU RCU_GPIOA
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOA
+#define ENC_B_PIN GPIO_PIN_7
+#define ENC_B_RCU RCU_GPIOA
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_PWM_GROUP GPIOB
+#define ENC_PWM_PIN GPIO_PIN_6
+#define ENC_PWM_RCU RCU_GPIOB
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_I_GROUP GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_0
+#define ENC_I_RCU RCU_GPIOB
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI0_IRQn
+#define ENC_I_EXTI EXTI_0
+#define ENC_I_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE_0
+
+#define ENC_TIMER TIMER2  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER2
+#define ENC_TIMER_IRQ TIMER2_IRQn
+#define ENC_TIMER_IRQHandler TIMER2_IRQHandler
+
+#define ENC_PWM_TIMER TIMER3    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER3
+#define ENC_PWM_TIMER_IRQ TIMER3_IRQn
+#define ENC_PWM_TIMER_CHAN  TIMER_CH_0
+#define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_PWM_IRQHandler TIMER3_IRQHandler
+
+#define ENC_MAX_interpolation 1.0f
+#define ENC_FILTER_NR          4
+
+/* 编码器参数      */
+#define ENC_MAX_RES  4096
+/*min. 490 Hz, max 603 Hz*/
+#define ENC_PWM_Max_P (1.0f/490.0f)
+#define ENC_PWM_Min_P (1.0f/603.0f)
+
+#define ENC_PWM_MAX_RES 4119.0F
+#define ENC_PWM_INIT_WIDTH 12.0F //PWM 起始宽度
+#define ENC_PWM_ERROR_WIDTH 4.0f //PWM 指示错误的宽度
+#define ENC_PWM_END_WIDTH   0.0F
+#define ENC_PWM_Error_P (ENC_PWM_INIT_WIDTH/ENC_PWM_MAX_RES)
+#define ENC_PWM_MIN_duty ((ENC_PWM_INIT_WIDTH + ENC_PWM_ERROR_WIDTH + ENC_PWM_END_WIDTH)/ENC_PWM_MAX_RES)
+
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_PWM_MAX_RES - (ENC_PWM_INIT_WIDTH + ENC_PWM_ERROR_WIDTH + ENC_PWM_END_WIDTH)) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+
+#define ENC_Duty(d, t) ((d)/(t))
+
+#define MOTOR_3505
+
+#endif /*_BOARD_GD32DEMO_H__ */
+

+ 374 - 0
Applications/bsp/gd32/board_mc100_v1.h

@@ -0,0 +1,374 @@
+#ifndef _BOARD_MC_V1_H__
+#define _BOARD_MC_V1_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_MOS_MAX_VOL 145.0F
+#define CONFIG_MAX_DC_VOL 110.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (36.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 200.0f
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   500.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       CONFIG_MAX_PHASE_CURR
+#define CONFIG_MAX_LOCK_TORQUE  20
+
+//#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+
+#define CONFIG_CURR_LP_WC (600.0F)
+
+#define CONFIG_CURR_LP_CEOF (CONFIG_CURR_LP_WC*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (60.0F)
+
+#define CONFIG_SMO_OBSERVER 1
+#define CONFIG_SPEED_LADRC  1
+
+#define SCHED_TIMER TIMER5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIMER5_IRQn
+#define SCHED_TIMER_IRQHandler TIMER5_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define HW_DEAD_TIME_NS  200u
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 300u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4095.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER TIMER0
+#define PWM_MODE TIMER_OC_MODE_PWM0
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_BRAKE_GROUP 	GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PIN_12
+#define PWM_BRAKE_RCU 	RCU_GPIOB
+#define PWM_BRAKE_MODE 	GPIO_MODE_IN_FLOATING
+
+#ifdef GD32F30X_CL
+#define PWM_BRK_IRQ TIMER0_BRK_TIMER8_IRQn
+#define PWM_UP_IRQ  TIMER0_UP_TIMER9_IRQn
+#define PWM_UP_IRQHandler   TIMER0_UP_TIMER9_IRQHandler
+#define PWM_BRK_IRQHandler  TIMER0_BRK_TIMER8_IRQHandler
+
+#else
+#define PWM_BRK_IRQ TIMER0_BRK_IRQn
+#define PWM_UP_IRQ  TIMER0_UP_IRQn
+#define PWM_UP_IRQHandler   TIMER0_UP_IRQHandler
+#define PWM_BRK_IRQHandler  TIMER0_BRK_IRQHandler
+#endif
+
+
+#define HALL_SENSOR_CEOF 0.32F
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  ADC_CHANNEL_5
+#define W_PHASE_I_CHAN  ADC_CHANNEL_6
+
+#define V_PHASE_ADC_GROUP 	GPIOA
+#define V_PHASE_ADC_PIN 	GPIO_PIN_5
+#define V_PHASE_ADC_RCU 	RCU_GPIOA
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOA
+#define W_PHASE_ADC_PIN 	GPIO_PIN_6
+#define W_PHASE_ADC_RCU 	RCU_GPIOA
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define ADC_TO_CURR_ceof1  (HALL_SENSOR_CEOF)
+#define ADC_TO_CURR_ceof2  (HALL_SENSOR_CEOF)
+
+#define CONFIG_PWM_UV_SWAP 1
+
+//#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL8
+//#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_3B
+//#define CONFIG_SW_MUTISAMPLE 1
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 		ADC_CHANNEL_3  //adc012
+#define VBUS_V_ADC_GROUP 	GPIOA
+#define VBUS_V_ADC_PIN 		GPIO_PIN_3
+#define VBUS_V_ADC_RCU 		RCU_GPIOA
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define ACC_V_CHAN 		ADC_CHANNEL_2    //adc012
+#define ACC_V_ADC_GROUP 	GPIOA
+#define ACC_V_ADC_PIN 		GPIO_PIN_2
+#define ACC_V_ADC_RCU 		RCU_GPIOA
+#define ACC_V_ADC_MODE 	GPIO_MODE_AIN
+#define ACC_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define VBUS_I_CHAN 		ADC_CHANNEL_4
+#define VBUS_I_ADC_GROUP 	GPIOA
+#define VBUS_I_ADC_PIN 		GPIO_PIN_4
+#define VBUS_I_ADC_RCU 		RCU_GPIOA
+#define VBUS_I_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_I_CEOF         (HALL_SENSOR_CEOF)
+
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN    ADC_CHANNEL_14
+#define MOS_TEMP_ADC_GROUP 	 GPIOC
+#define MOS_TEMP_ADC_PIN 	 GPIO_PIN_4
+#define MOS_TEMP_ADC_RCU 	 RCU_GPIOC
+#define MOS_TEMP_ADC_MODE 	 GPIO_MODE_AIN
+
+#define MOS_TEMP1_ADC_CHAN   ADC_CHANNEL_15
+#define MOS_TEMP1_ADC_GROUP  GPIOC
+#define MOS_TEMP1_ADC_PIN 	 GPIO_PIN_5
+#define MOS_TEMP1_ADC_RCU 	 RCU_GPIOC
+#define MOS_TEMP1_ADC_MODE 	 GPIO_MODE_AIN
+#define MOS_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     ADC_CHANNEL_0 //adc012
+#define MOTOR_TEMP_ADC_GROUP 	GPIOA
+#define MOTOR_TEMP_ADC_PIN 	GPIO_PIN_0
+#define MOTOR_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOTOR_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOTOR_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+//#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把电压采集 */
+#define THROTTLE_CHAN           ADC_CHANNEL_1 //转把信号 adc012
+#define THROTTLE_V_ADC_GROUP 	GPIOA
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_1
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+#define THROTTLE_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     ADC_CHANNEL_9
+#define U_VOL_ADC_GROUP 	GPIOB
+#define U_VOL_ADC_PIN 	GPIO_PIN_1
+#define U_VOL_ADC_RCU 	RCU_GPIOB
+#define U_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_VOL_ADC_CHAN     ADC_CHANNEL_8
+#define V_VOL_ADC_GROUP 	GPIOB
+#define V_VOL_ADC_PIN 	GPIO_PIN_0
+#define V_VOL_ADC_RCU 	RCU_GPIOB
+#define V_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_VOL_ADC_CHAN     ADC_CHANNEL_7
+#define W_VOL_ADC_GROUP 	GPIOA
+#define W_VOL_ADC_PIN 	GPIO_PIN_7
+#define W_VOL_ADC_RCU 	RCU_GPIOA
+#define W_VOL_ADC_MODE 	GPIO_MODE_AIN
+#define UVW_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 刹车手把输入 */
+#define GPIO_BRAKE_IN_GROUP 	GPIOB
+#define GPIO_BRAKE_IN_PIN 	GPIO_PIN_3
+#define GPIO_BRAKE_IN_RCU 	RCU_GPIOB
+#define GPIO_BRAKE_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE_IRQ  EXTI3_IRQn
+#define GPIO_BRAKE_EXTI EXTI_3
+#define GPIO_BRAKE_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define GPIO_BRAKE_EXIT_SRC_PIN GPIO_PIN_SOURCE_3
+
+/* 前刹 */
+#define GPIO_BRAKE1_IN_GROUP 	GPIOD
+#define GPIO_BRAKE1_IN_PIN 	GPIO_PIN_2
+#define GPIO_BRAKE1_IN_RCU 	RCU_GPIOD
+#define GPIO_BRAKE1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE1_IRQ  EXTI2_IRQn
+#define GPIO_BRAKE1_EXTI EXTI_2
+#define GPIO_BRAKE1_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOD
+#define GPIO_BRAKE1_EXIT_SRC_PIN GPIO_PIN_SOURCE_2
+#define GPIO_BREAK_MODE GPIO_LOW_BRK_MODE      
+
+/* 锁电机线,  使用查询模式 */
+#define GPIO_MLOCK_IN_GROUP GPIOC
+#define GPIO_MLOCK_IN_PIN GPIO_PIN_13
+#define GPIO_MLOCK_IN_RCU RCU_GPIOC
+#define GPIO_MLOCK_IN_MODE 	GPIO_MODE_IN_FLOATING
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 	GPIOB
+#define GPIO_UDEC_OUT_PIN 	GPIO_PIN_9
+#define GPIO_UDEC_OUT_RCU 	RCU_GPIOB
+#define GPIO_UDEC_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 风扇 PWM */
+#define GPIO_FAN_OUT_GROUP 	GPIOC
+#define GPIO_FAN_OUT_PIN 	GPIO_PIN_8
+#define GPIO_FAN_OUT_RCU 	RCU_GPIOC
+#define GPIO_FAN_OUT_MODE 	GPIO_MODE_AF_PP
+#define FAN_PWM_TIMER TIMER7
+#define FAN_PWM_CHAN  TIMER_CH_2
+#define FAN_TIMER_RCU  RCU_TIMER7
+
+/* 风扇1检测 */
+#define GPIO_FAN1_IN_GROUP 	GPIOC
+#define GPIO_FAN1_IN_PIN 	GPIO_PIN_10
+#define GPIO_FAN1_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN1_IRQ  EXTI10_15_IRQn
+#define GPIO_FAN1_EXTI EXTI_10
+#define GPIO_FAN1_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN1_EXIT_SRC_PIN GPIO_PIN_SOURCE_10
+
+/* 风扇2检测 */
+#define GPIO_FAN2_IN_GROUP 	GPIOC
+#define GPIO_FAN2_IN_PIN 	GPIO_PIN_11
+#define GPIO_FAN2_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN2_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN2_IRQ  EXTI10_15_IRQn
+#define GPIO_FAN2_EXTI EXTI_11
+#define GPIO_FAN2_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN2_EXIT_SRC_PIN GPIO_PIN_SOURCE_11
+
+/* CAN 定义 */
+#define CAN_TX_GROUP GPIOA
+#define CAN_TX_PIN   GPIO_PIN_12
+#define CAN_RX_GROUP GPIOA
+#define CAN_RX_PIN   GPIO_PIN_11
+#define CAN_PIN_RCU  RCU_GPIOA
+#ifdef GD32F30X_CL
+#define CAN_REMAP    GPIO_CAN0_PARTIAL_REMAP
+#define CAN_IRQ0     CAN0_RX0_IRQn
+#define CAN_RX0_IRQHandler  CAN0_RX0_IRQHandler
+#else
+#define CAN_REMAP    GPIO_CAN_PARTIAL_REMAP
+#define CAN_IRQ0     USBD_LP_CAN0_RX0_IRQn
+#define CAN_RX0_IRQHandler  USBD_LP_CAN0_RX0_IRQHandler
+#endif
+
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MT
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOB
+#define ENC_A_PIN GPIO_PIN_4
+#define ENC_A_RCU RCU_GPIOB
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOB
+#define ENC_B_PIN GPIO_PIN_5
+#define ENC_B_RCU RCU_GPIOB
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define TIMER2_PB4_PB5_REMAP GPIO_TIMER2_PARTIAL_REMAP
+
+#define ENC_PWM_GROUP GPIOA
+#define ENC_PWM_PIN GPIO_PIN_15
+#define ENC_PWM_RCU RCU_GPIOA
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+#define TIMER1_PA15_REMAP GPIO_TIMER1_PARTIAL_REMAP0
+
+#define ENC_I_GROUP GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_8
+#define ENC_I_RCU RCU_GPIOB
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI5_9_IRQn
+#define ENC_I_EXTI EXTI_8
+#define ENC_I_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE_8
+
+#define ENC_TIMER TIMER2  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER2
+#define ENC_TIMER_IRQ TIMER2_IRQn
+#define ENC_TIMER_IRQHandler TIMER2_IRQHandler
+
+#define ENC_PWM_TIMER TIMER1    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER1
+#define ENC_PWM_TIMER_IRQ TIMER1_IRQn
+#define ENC_PWM_TIMER_CHAN  TIMER_CH_0
+#define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_PWM_IRQHandler TIMER1_IRQHandler
+
+#define ENC_MAX_interpolation 1.0F
+
+#define ENC_FILTER_NR          15
+#ifdef CONFIG_PWM_UV_SWAP
+#define ENCODER_CC_INVERT 1
+#endif
+/* 编码器参数      */
+#define ENC_MAX_RES  4096.0f
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+#define ENC_PWM_Min_P 0.0f//(1.0f/(131.0f + 1.0f))
+#define ENC_PWM_Max_P  1.0f
+
+#if ENCODER_TYPE==ENCODER_MPS
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+#elif ENCODER_TYPE==ENCODER_MT
+/*min. 994 hz*/
+#define ENC_PWM_MAX_RES    4119.0F
+#define ENC_PWM_INIT_WIDTH 16.0F //PWM 起始宽度
+#define ENC_PWM_END_WIDTH   8.0F
+//#define ENC_PWM_Min_P      (ENC_PWM_INIT_WIDTH/(ENC_PWM_MAX_RES + 1.0f))
+//#define ENC_PWM_Max_P      ((ENC_PWM_MAX_RES-ENC_PWM_END_WIDTH)/(ENC_PWM_MAX_RES - 1.0f))
+#define PWM_Duty(d, t) ((d)/(t))
+#define ENC_Duty(d, t) ((PWM_Duty(d, t)*ENC_PWM_MAX_RES - ENC_PWM_INIT_WIDTH)/(ENC_PWM_MAX_RES - ENC_PWM_END_WIDTH - ENC_PWM_INIT_WIDTH))
+#else
+#error "Postion sensor ERROR"
+
+#endif
+#define DEBUG_PORT_UART2
+
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_A1
+
+#if (CONFIG_MOT_TYPE==MOTOR_BLUESHARK_A1)
+#define CONFIG_FORCE_96V_MODE 1
+#endif
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V1_H__ */
+

+ 436 - 0
Applications/bsp/gd32/board_mc105_v3.h

@@ -0,0 +1,436 @@
+#ifndef _BOARD_MC_V3_H__
+#define _BOARD_MC_V3_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_MOS_MAX_VOL 125.0F
+#define CONFIG_MAX_DC_VOL 110.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (60.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 250.0f
+#define CONFIG_MAX_CHRG_CURRENT (-100.0f)
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   500.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       CONFIG_MAX_PHASE_CURR
+#define CONFIG_MAX_LOCK_TORQUE  100
+#define CONFIG_MAX_ACTIVE_EMF   5000.0F
+//#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+
+#define CONFIG_CURR_LP_WC (600.0F)
+
+#define CONFIG_CURR_LP_CEOF (CONFIG_CURR_LP_WC*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (60.0F)
+
+//#define CONFIG_SENSORLESS_TOW_SAMPLES
+//#define CONFIG_SMO_OBSERVER 
+#define CONFIG_LADRC_OBSERVER
+//#define CONFIG_SPEED_LADRC  
+#define CONFIG_FORCE_96V_MODE
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+#define CONFIG_SENSORLESS_TS (FOC_CTRL_US/2.0f)
+#else
+#define CONFIG_SENSORLESS_TS FOC_CTRL_US
+#endif
+
+#define SCHED_TIMER TIMER5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIMER5_IRQn
+#define SCHED_TIMER_IRQHandler TIMER5_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define PWM_TOFF_DELAY_MAX 240u
+#define PWM_TON_DELAY_MIN 200u
+#define HW_DEAD_TIME_NS  210u
+#define HW_RISE_TIME_NS  150u
+#define HW_NOISE_TIME_NS 300u
+
+#define CONFIG_HW_DeadTime NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS + (PWM_TOFF_DELAY_MAX - PWM_TON_DELAY_MIN))/* ����ʱ�� */
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+//#define CONFIG_START_LINE_DTC_CURRENT 5.0F /* 死区补偿开始电流,取决于电流噪声 */
+//#define COMFIG_END_LINE_DTC_CURRENT   15.0F
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4095.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER TIMER0
+#define PWM_MODE TIMER_OC_MODE_PWM0
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_BRAKE_GROUP 	GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PIN_12
+#define PWM_BRAKE_RCU 	RCU_GPIOB
+#define PWM_BRAKE_MODE 	GPIO_MODE_IN_FLOATING
+
+#ifdef GD32F30X_CL
+#define PWM_BRK_IRQ TIMER0_BRK_TIMER8_IRQn
+#define PWM_UP_IRQ  TIMER0_UP_TIMER9_IRQn
+#define PWM_UP_IRQHandler   TIMER0_UP_TIMER9_IRQHandler
+#define PWM_BRK_IRQHandler  TIMER0_BRK_TIMER8_IRQHandler
+
+#else
+#define PWM_BRK_IRQ TIMER0_BRK_IRQn
+#define PWM_UP_IRQ  TIMER0_UP_IRQn
+#define PWM_UP_IRQHandler   TIMER0_UP_IRQHandler
+#define PWM_BRK_IRQHandler  TIMER0_BRK_IRQHandler
+#endif
+
+
+#define HALL_SENSOR_CEOF 0.303F
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  ADC_CHANNEL_14
+#define W_PHASE_I_CHAN  ADC_CHANNEL_10
+
+#define V_PHASE_ADC_GROUP 	GPIOC
+#define V_PHASE_ADC_PIN 	GPIO_PIN_4
+#define V_PHASE_ADC_RCU 	RCU_GPIOC
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOC
+#define W_PHASE_ADC_PIN 	GPIO_PIN_0
+#define W_PHASE_ADC_RCU 	RCU_GPIOC
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define ADC_TO_CURR_ceof1  (HALL_SENSOR_CEOF)
+#define ADC_TO_CURR_ceof2  (HALL_SENSOR_CEOF)
+
+#define CONFIG_PWM_UV_SWAP 1
+
+//#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL8
+//#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_3B
+//#define CONFIG_SW_MUTISAMPLE 1
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 		ADC_CHANNEL_12  //adc012
+#define VBUS_V_ADC_GROUP 	GPIOC
+#define VBUS_V_ADC_PIN 		GPIO_PIN_2
+#define VBUS_V_ADC_RCU 		RCU_GPIOC
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define ACC_V_CHAN 			ADC_CHANNEL_11    //adc012
+#define ACC_V_ADC_GROUP 	GPIOC
+#define ACC_V_ADC_PIN 		GPIO_PIN_1
+#define ACC_V_ADC_RCU 		RCU_GPIOC
+#define ACC_V_ADC_MODE 		GPIO_MODE_AIN
+#define ACC_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define VBUS_I_CHAN 		ADC_CHANNEL_0 //adc012
+#define VBUS_I_ADC_GROUP 	GPIOA
+#define VBUS_I_ADC_PIN 		GPIO_PIN_0
+#define VBUS_I_ADC_RCU 		RCU_GPIOA
+#define VBUS_I_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_I_CEOF         (0.303f)
+#define VBUS_I_POSITIVE     1
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN    ADC_CHANNEL_8
+#define MOS_TEMP_ADC_GROUP 	 GPIOB
+#define MOS_TEMP_ADC_PIN 	 GPIO_PIN_0
+#define MOS_TEMP_ADC_RCU 	 RCU_GPIOB
+#define MOS_TEMP_ADC_MODE 	 GPIO_MODE_AIN
+#define MOS_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     ADC_CHANNEL_5
+#define MOTOR_TEMP_ADC_GROUP 	GPIOA
+#define MOTOR_TEMP_ADC_PIN 	GPIO_PIN_5
+#define MOTOR_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOTOR_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOTOR_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+//#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把信号电压采集 */
+#define THROTTLE_CHAN           ADC_CHANNEL_4
+#define THROTTLE_V_ADC_GROUP 	GPIOA
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_4
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+#define THROTTLE_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* 第二路转把信号电压采集 */
+#define THROTTLE2_CHAN           	ADC_CHANNEL_7
+#define THROTTLE2_V_ADC_GROUP 		GPIOA
+#define THROTTLE2_V_ADC_PIN 		GPIO_PIN_7
+#define THROTTLE2_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE2_V_ADC_MODE 		GPIO_MODE_AIN
+
+/* 转把供电5V电压采集 */
+#define THROTTLE_5V_CHAN           ADC_CHANNEL_6
+#define THROTTLE_5V_ADC_GROUP 	GPIOA
+#define THROTTLE_5V_ADC_PIN 		GPIO_PIN_6
+#define THROTTLE_5V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_5V_ADC_MODE 	GPIO_MODE_AIN
+
+/* 第二路供电5V电压采集 */
+#define THROTTLE2_5V_CHAN           	ADC_CHANNEL_9
+#define THROTTLE2_5V_ADC_GROUP 		GPIOB
+#define THROTTLE2_5V_ADC_PIN 		GPIO_PIN_1
+#define THROTTLE2_5V_ADC_RCU 		RCU_GPIOB
+#define THROTTLE2_5V_ADC_MODE 		GPIO_MODE_AIN
+
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     ADC_CHANNEL_15
+#define U_VOL_ADC_GROUP 	GPIOC
+#define U_VOL_ADC_PIN 	GPIO_PIN_5
+#define U_VOL_ADC_RCU 	RCU_GPIOC
+#define U_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_VOL_ADC_CHAN     ADC_CHANNEL_1 //adc012
+#define V_VOL_ADC_GROUP 	GPIOA
+#define V_VOL_ADC_PIN 	GPIO_PIN_1
+#define V_VOL_ADC_RCU 	RCU_GPIOA
+#define V_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_VOL_ADC_CHAN     ADC_CHANNEL_2 //adc012
+#define W_VOL_ADC_GROUP 	GPIOA
+#define W_VOL_ADC_PIN 	GPIO_PIN_2
+#define W_VOL_ADC_RCU 	RCU_GPIOA
+#define W_VOL_ADC_MODE 	GPIO_MODE_AIN
+#define UVW_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 模拟5v电压采集 */
+#define DC5V_ADC_CHAN     ADC_CHANNEL_3 //adc012
+#define DC5V_ADC_GROUP 	GPIOA
+#define DC5V_ADC_PIN 	GPIO_PIN_3
+#define DC5V_ADC_RCU 	RCU_GPIOA
+#define DC5V_ADC_MODE 	GPIO_MODE_AIN
+
+/* 0v电压采集,主要是用来给上一次的采集放电 */
+#define ZERO_ADC_CHAN     ADC_CHANNEL_13 //adc012
+#define ZERO_ADC_GROUP 	GPIOC
+#define ZERO_ADC_PIN 	GPIO_PIN_3
+#define ZERO_ADC_RCU 	RCU_GPIOC
+#define ZERO_ADC_MODE 	GPIO_MODE_AIN
+
+/* 刹车手把输入 */
+#define GPIO_BREAK_MODE GPIO_LOW_BRK_MODE
+#define GPIO_BRAKE_IN_GROUP 	GPIOB
+#define GPIO_BRAKE_IN_PIN 	GPIO_PIN_3
+#define GPIO_BRAKE_IN_RCU 	RCU_GPIOB
+#define GPIO_BRAKE_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE_IRQ  EXTI3_IRQn
+#define GPIO_BRAKE_EXTI EXTI_3
+#define GPIO_BRAKE_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define GPIO_BRAKE_EXIT_SRC_PIN GPIO_PIN_SOURCE_3
+#define GPIO_BRAKE_PIN_REMAP GPIO_SWJ_SWDPENABLE_REMAP
+
+/* 锁电机线,  使用查询模式 */
+#define GPIO_MLOCK_IN_GROUP GPIOC
+#define GPIO_MLOCK_IN_PIN GPIO_PIN_13
+#define GPIO_MLOCK_IN_RCU RCU_GPIOC
+#define GPIO_MLOCK_IN_MODE 	GPIO_MODE_IN_FLOATING
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 	GPIOB
+#define GPIO_UDEC_OUT_PIN 	GPIO_PIN_7
+#define GPIO_UDEC_OUT_RCU 	RCU_GPIOB
+#define GPIO_UDEC_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 风扇 PWM */
+#define GPIO_FAN_OUT_GROUP 	GPIOC
+#define GPIO_FAN_OUT_PIN 	GPIO_PIN_8
+#define GPIO_FAN_OUT_RCU 	RCU_GPIOC
+#define GPIO_FAN_OUT_MODE 	GPIO_MODE_AF_PP
+#define FAN_PWM_TIMER TIMER7
+#define FAN_PWM_CHAN  TIMER_CH_2
+#define FAN_TIMER_RCU  RCU_TIMER7
+
+/* 风扇1检测 */
+#define GPIO_FAN1_IN_GROUP 	GPIOC
+#define GPIO_FAN1_IN_PIN 	GPIO_PIN_11
+#define GPIO_FAN1_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN1_IRQ  EXTI10_15_IRQn
+#define GPIO_FAN1_EXTI EXTI_11
+#define GPIO_FAN1_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOC
+#define GPIO_FAN1_EXIT_SRC_PIN GPIO_PIN_SOURCE_11
+
+/* LED 灯控制 */
+#define GPIO_LED_OUT_GROUP 	GPIOC
+#define GPIO_LED_OUT_PIN 	GPIO_PIN_14
+#define GPIO_LED_OUT_RCU 	RCU_GPIOC
+#define GPIO_LED_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 刹车灯控制,能量回收的时候需要电量刹车灯 */
+#define GPIO_BRAKE_LIGHT_OUT_GROUP 	GPIOD
+#define GPIO_BRAKE_LIGHT_OUT_PIN 	GPIO_PIN_2
+#define GPIO_BRAKE_LIGHT_OUT_RCU 	RCU_GPIOD
+#define GPIO_BRAKE_LIGHT_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 一键修复,低电平有效 */
+#define REPEAR_IN_GROUP 	GPIOC
+#define REPEAR_IN_PIN 	GPIO_PIN_10
+#define REPEAR_IN_RCU 	RCU_GPIOC
+#define REPEAR_IN_MODE 	GPIO_MODE_IN_FLOATING
+
+/* CAN 定义 */
+#define CAN_TX_GROUP GPIOB
+#define CAN_TX_PIN   GPIO_PIN_9
+#define CAN_RX_GROUP GPIOB
+#define CAN_RX_PIN   GPIO_PIN_8
+#define CAN_PIN_RCU  RCU_GPIOB
+#ifdef GD32F30X_CL
+#define CAN_REMAP    GPIO_CAN0_PARTIAL_REMAP
+#define CAN_IRQ0     CAN0_RX0_IRQn
+#define CAN_RX0_IRQHandler  CAN0_RX0_IRQHandler
+#else
+#define CAN_REMAP    GPIO_CAN_PARTIAL_REMAP
+#define CAN_IRQ0     USBD_LP_CAN0_RX0_IRQn
+#define CAN_RX0_IRQHandler  USBD_LP_CAN0_RX0_IRQHandler
+#endif
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MT
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOB
+#define ENC_A_PIN GPIO_PIN_4
+#define ENC_A_RCU RCU_GPIOB
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOB
+#define ENC_B_PIN GPIO_PIN_5
+#define ENC_B_RCU RCU_GPIOB
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define TIMER2_PB4_PB5_REMAP GPIO_TIMER2_PARTIAL_REMAP
+
+#define ENC_PWM_GROUP GPIOA
+#define ENC_PWM_PIN GPIO_PIN_15
+#define ENC_PWM_RCU RCU_GPIOA
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+#define TIMER1_PA15_REMAP GPIO_TIMER1_PARTIAL_REMAP0
+
+#define ENC_I_GROUP GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_6
+#define ENC_I_RCU RCU_GPIOB
+#if 0
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI5_9_IRQn
+#define ENC_I_EXTI EXTI_6
+#define ENC_I_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE_6
+#else
+#define ENC_I_MODE GPIO_MODE_IN_FLOATING
+#define ENC_I_TIMER TIMER3    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_I_TIMER_RCU RCU_TIMER3
+#define ENC_I_TIMER_IRQ TIMER3_IRQn
+#define ENC_I_TIMER_CHAN  TIMER_CH_0
+#define ENC_I_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_I_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_I_IRQHandler TIMER3_IRQHandler
+#endif
+#define ENC_TIMER TIMER2  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER2
+#define ENC_TIMER_IRQ TIMER2_IRQn
+#define ENC_TIMER_IRQHandler TIMER2_IRQHandler
+
+#define ENC_PWM_TIMER TIMER1    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER1
+#define ENC_PWM_TIMER_IRQ TIMER1_IRQn
+#define ENC_PWM_TIMER_CHAN  TIMER_CH_0
+#define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_PWM_IRQHandler TIMER1_IRQHandler
+
+/* board id, 0x01=>v3, 0x02=>v4 */
+#define BOOT_PIN_0_GROUP GPIOC 
+#define BOOT_PIN_0_PIN   GPIO_PIN_6
+#define BOOT_PIN_1_GROUP GPIOC 
+#define BOOT_PIN_1_PIN   GPIO_PIN_7
+
+#define BOARD_105_VERSION_3 2
+#define BOARD_105_VERSION_4 1
+
+#define ENC_MAX_interpolation 1.0F
+
+#define CONFIG_ENC_FILTER_NR          12 //1100: fSAMP=fDTS/16, N=8,采样率 120M/16 = 7.5M
+#define CONFIG_PWM_FILTER_NR          12
+
+#ifdef CONFIG_PWM_UV_SWAP
+#define ENCODER_CC_INVERT 1
+#endif
+/* 编码器参数      */
+#define ENC_MAX_RES  4096.0f
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+#define ENC_PWM_Min_P 0.0f//(1.0f/(131.0f + 1.0f))
+#define ENC_PWM_Max_P  1.0f
+
+#if ENCODER_TYPE==ENCODER_MPS
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+#elif ENCODER_TYPE==ENCODER_MT
+/*min. 994 hz*/
+#define ENC_PWM_MAX_RES    4119.0F
+#define ENC_PWM_INIT_WIDTH 16.0F //PWM 起始宽度
+#define ENC_PWM_END_WIDTH   8.0F
+//#define ENC_PWM_Min_P      (ENC_PWM_INIT_WIDTH/(ENC_PWM_MAX_RES + 1.0f))
+//#define ENC_PWM_Max_P      ((ENC_PWM_MAX_RES-ENC_PWM_END_WIDTH)/(ENC_PWM_MAX_RES - 1.0f))
+#define PWM_Duty(d, t) ((d)/(t))
+#define ENC_Duty(d, t) ((PWM_Duty(d, t)*ENC_PWM_MAX_RES - ENC_PWM_INIT_WIDTH)/(ENC_PWM_MAX_RES - ENC_PWM_END_WIDTH - ENC_PWM_INIT_WIDTH))
+#else
+#error "Postion sensor ERROR"
+
+#endif
+#define DEBUG_PORT_UART2
+
+#ifndef CONFIG_MOT_TYPE
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_A1
+#endif
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V3_H__ */
+
+

+ 257 - 0
Applications/bsp/gd32/board_yuanqu.h

@@ -0,0 +1,257 @@
+#ifndef _BOARD_MC_V1_H__
+#define _BOARD_MC_V1_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define CONFIG_MOS_MAX_VOL 145.0F
+#define CONFIG_MAX_DC_VOL 120.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (36.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 200.0f
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   400.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       50.0F
+
+#define CONFIG_CURRENT_BANDWITH  1000.0f /* 电流环带宽 */
+#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+#define CONFIG_MAX_FW_D_CURR     100.0F //d轴最大的退磁电流
+
+#define CONFIG_CURR_LP_CUT_FREQ (2500.0F)
+
+#define CONFIG_CURR_LP_PARAM (CONFIG_CURR_LP_CUT_FREQ*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (55.0F)
+
+#define SCHED_TIMER TIMER5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIMER5_IRQn
+#define SCHED_TIMER_IRQHandler TIMER5_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define HW_DEAD_TIME_NS  200u
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 300u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4096.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER TIMER0
+#define PWM_MODE TIMER_OC_MODE_PWM0
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_BRAKE_GROUP 	GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PIN_12
+#define PWM_BRAKE_RCU 	RCU_GPIOB
+#define PWM_BRAKE_MODE 	GPIO_MODE_IN_FLOATING
+
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  ADC_CHANNEL_5
+#define W_PHASE_I_CHAN  ADC_CHANNEL_6
+
+#define V_PHASE_ADC_GROUP 	GPIOA
+#define V_PHASE_ADC_PIN 	GPIO_PIN_5
+#define V_PHASE_ADC_RCU 	RCU_GPIOA
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOA
+#define W_PHASE_ADC_PIN 	GPIO_PIN_6
+#define W_PHASE_ADC_RCU 	RCU_GPIOA
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define ADC_TO_CURR_ceof1 (0.3362f)
+#define ADC_TO_CURR_ceof2 (0.3404f)
+
+#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL2
+#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_1B
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 		ADC_CHANNEL_4
+#define VBUS_V_ADC_GROUP 	GPIOA
+#define VBUS_V_ADC_PIN 		GPIO_PIN_4
+#define VBUS_V_ADC_RCU 		RCU_GPIOA
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_VOL_CEOF (ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN     ADC_CHANNEL_3
+#define MOS_TEMP_ADC_GROUP 	GPIOA
+#define MOS_TEMP_ADC_PIN 	GPIO_PIN_3
+#define MOS_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOS_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOS_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     ADC_CHANNEL_0
+#define MOTOR_TEMP_ADC_GROUP 	GPIOA
+#define MOTOR_TEMP_ADC_PIN 	GPIO_PIN_0
+#define MOTOR_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOTOR_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOTOR_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把电压采集 */
+#define THROTTLE_CHAN           ADC_CHANNEL_1 //转把信号
+#define THROTTLE_V_ADC_GROUP 	GPIOA
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_1
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+#define THROTTLE_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     ADC_CHANNEL_9
+#define U_VOL_ADC_GROUP 	GPIOB
+#define U_VOL_ADC_PIN 	GPIO_PIN_1
+#define U_VOL_ADC_RCU 	RCU_GPIOB
+#define U_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_VOL_ADC_CHAN     ADC_CHANNEL_8
+#define V_VOL_ADC_GROUP 	GPIOB
+#define V_VOL_ADC_PIN 	GPIO_PIN_0
+#define V_VOL_ADC_RCU 	RCU_GPIOB
+#define V_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_VOL_ADC_CHAN     ADC_CHANNEL_7
+#define W_VOL_ADC_GROUP 	GPIOA
+#define W_VOL_ADC_PIN 	GPIO_PIN_7
+#define W_VOL_ADC_RCU 	RCU_GPIOA
+#define W_VOL_ADC_MODE 	GPIO_MODE_AIN
+#define UVW_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 刹车手把输入 */
+#define GPIO_BRAKE_IN_GROUP 	GPIOB
+#define GPIO_BRAKE_IN_PIN 	GPIO_PIN_3
+#define GPIO_BRAKE_IN_RCU 	RCU_GPIOB
+#define GPIO_BRAKE_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE_IRQ  EXTI3_IRQn
+#define GPIO_BRAKE_EXTI EXTI_3
+#define GPIO_BRAKE_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define GPIO_BRAKE_EXIT_SRC_PIN GPIO_PIN_SOURCE_3
+
+#define GPIO_BREAK_MODE GPIO_LOW_BRK_MODE      
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 	GPIOA
+#define GPIO_UDEC_OUT_PIN 	GPIO_PIN_14
+#define GPIO_UDEC_OUT_RCU 	RCU_GPIOA
+#define GPIO_UDEC_OUT_MODE 	GPIO_MODE_OUT_PP
+#define GPIO_UDEC_OUT_REMAP_DISABLE  GPIO_SWJ_DISABLE_REMAP
+#define GPIO_UDEC_OUT_REMAP_ENABLE  GPIO_SWJ_SWDPENABLE_REMAP
+
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MPS
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOB
+#define ENC_A_PIN GPIO_PIN_4
+#define ENC_A_RCU RCU_GPIOB
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOB
+#define ENC_B_PIN GPIO_PIN_5
+#define ENC_B_RCU RCU_GPIOB
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define TIMER2_PB4_PB5_REMAP GPIO_TIMER2_PARTIAL_REMAP
+
+#define ENC_PWM_GROUP GPIOA
+#define ENC_PWM_PIN GPIO_PIN_15
+#define ENC_PWM_RCU RCU_GPIOA
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+#define TIMER1_PA15_REMAP GPIO_TIMER1_PARTIAL_REMAP0
+
+#define ENC_I_GROUP GPIOB     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_8
+#define ENC_I_RCU RCU_GPIOB
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI5_9_IRQn
+#define ENC_I_EXTI EXTI_8
+#define ENC_I_EXIT_SRC_GROUP GPIO_PORT_SOURCE_GPIOB
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE_8
+
+#define ENC_TIMER TIMER2  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER2
+#define ENC_TIMER_IRQ TIMER2_IRQn
+#define ENC_TIMER_IRQHandler TIMER2_IRQHandler
+
+#define ENC_PWM_TIMER TIMER1    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER1
+#define ENC_PWM_TIMER_IRQ TIMER1_IRQn
+#define ENC_PWM_TIMER_CHAN  TIMER_CH_0
+#define ENC_PWM_TIMER_IRQ_CH TIMER_INT_CH0
+#define ENC_PWM_TIMER_INT_FLG TIMER_INT_FLAG_CH0
+#define ENC_PWM_IRQHandler TIMER1_IRQHandler
+
+#define ENC_MAX_interpolation 4.0F
+
+#define ENC_FILTER_NR          15
+
+/* 编码器参数      */
+#define ENC_MAX_RES  1024
+#define ENC_PWM_Min_P (0.0f)
+#define ENC_PWM_Max_P  1.0f
+
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+
+#define DEBUG_PORT_UART2
+
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_ZD_100
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V1_H__ */
+

+ 33 - 35
Applications/bsp/bsp.c → Applications/bsp/gd32/bsp.c

@@ -1,26 +1,21 @@
 #include "bsp/bsp.h"
-#include "bsp/gd32_bkp.h"
+#include "bsp/bsp_driver.h"
 #include "libs/logger.h"
-#include "os/os_type.h"
-#include "bsp/uart.h"
-#include "bsp/timer_count32.h"
+#include "os/os_types.h"
 #include "version.h"
 
 static void wdog_enable(void);
-static void normal_task_timer_init(void);
 
 void bsp_init(void){
 	wdog_enable();
 	gd32_bkp_init();
 	dbg_periph_enable(DBG_TIMER0_HOLD);
 	dbg_periph_enable(DBG_TIMER1_HOLD);
-	dbg_periph_enable(DBG_TIMER2_HOLD);
-	cpu_counts_enable();
-	timer_count32_init();
-#if LOG_UART==1
+	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
+	systick_open();
+	task_ticks_enable();
+	gpio_pin_init();
 	shark_uart_init(SHARK_UART0);
-#endif
-	normal_task_timer_init();
 }
 
 
@@ -28,6 +23,33 @@ void system_reboot(void){
 	NVIC_SystemReset();
 }
 
+void systick_close(void)
+{
+	SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;
+}
+
+void systick_open(void)
+{
+	SysTick_Config(SystemCoreClock / 1000);
+}
+
+u8 mcu_chip_id(u8 *buff)
+{
+	u32 values[] = { REG32(0x1FFFF7E8), REG32(0x1FFFF7EC), REG32(0x1FFFF7F0), REG32(0x1FFFF7E0) };
+	memcpy(buff, values, sizeof(values));
+	return sizeof(values);
+}
+
+static u32 _mcu_rst_status = 0xFFFFFFFF;
+u32 get_mcu_reset_source(void)
+{
+	if (_mcu_rst_status == 0xFFFFFFFF) {
+		_mcu_rst_status = RCU_RSTSCK;
+		rcu_all_reset_flag_clear();
+	}
+	return _mcu_rst_status;
+}
+
 void wdog_reload(void){
 #if CONFIG_DEBUG == 0
     fwdgt_counter_reload();
@@ -80,28 +102,4 @@ int wdog_set_timeout(int wdog_time)
 	return 0;
 }
 
-//10 ms
-static void normal_task_timer_init(void) {
-    timer_parameter_struct timer_initpara;
-    u32 timer = TIMER5;
-    rcu_periph_clock_enable(RCU_TIMER5);
-
-    timer_deinit(timer);
-	
-	memset(&timer_initpara, 0, sizeof(timer_initpara));
-    timer_initpara.prescaler        = 12000 - 1; //clk 10000
-    timer_initpara.alignedmode      = TIMER_COUNTER_EDGE;
-    timer_initpara.period          = 100;
-    timer_initpara.clockdivision    = TIMER_CKDIV_DIV1;
-    timer_initpara.repetitioncounter = 0;
-    timer_init(timer,&timer_initpara);
-	timer_counter_value_config(timer, 0);
-	timer_autoreload_value_config(timer, 100);
-	timer_counter_up_direction(timer);
-	timer_auto_reload_shadow_enable(timer);
-	timer_interrupt_enable(timer, TIMER_INT_UP);
-	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_UP);
-	nvic_irq_enable(TIMER5_IRQn, 5, 0);
-	timer_enable(timer);
-}
 

+ 41 - 0
Applications/bsp/gd32/bsp.h

@@ -0,0 +1,41 @@
+#ifndef __BSP_GD32_H__
+#define __BSP_GD32_H__
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#include "gd32f30x.h"
+#elif defined GD32E10x
+#include "gd32e10x.h"
+#endif
+
+#define SYSTEM_CLOCK (120000000u) //system clk 120M Hz
+#define TIM_CLOCK (SYSTEM_CLOCK) /*SystemClock_Config��TIM1��clk��sys PLL �������̶�2����PLLƵ��*/
+#define TIM_CLOCK_MHz (120u)
+#define ADC_CLOCK (30000000u)
+#define ADC_CLOCK_MHz (30u)
+#define NS_PER_TCLK (8u) /* (1/120000000 * 1000000000) */
+#define NS_2_TCLK(ns) (((ns)/NS_PER_TCLK) + 1u) //ns תΪpwmʹ�õ��Ǹ�TIM��clk count
+#define FOC_PWM_FS (16000u)
+#define FOC_PWM_period (TIM_CLOCK/FOC_PWM_FS)
+#define FOC_PWM_Half_Period (FOC_PWM_period/2)
+
+#define FOC_CTRL_US (1.0f/(float)FOC_PWM_FS)
+
+#define ADC_REGCHAN_SAMPLE_TIME ADC_SAMPLETIME_71POINT5
+#define ADC_TRIG_CONV_LATENCY_CYCLES 12.5f
+#define ADC_SAMPLING_CYCLES 13.5f
+
+#ifdef GD32_FOC_DEMO
+#include "bsp/board_gd32demo.h"
+#elif defined (YUANQU_HW_V1)
+#include "bsp/board_yuanqu.h"
+#elif defined (MC100_HW_V1)
+#include "bsp/gd32/board_mc100_v1.h"
+#define CONFIG_BOARD_MCXXX
+#define CONFIG_BOARD_NAME "MC100"
+#define CONFIG_HW_VERSION 2
+#elif defined (MC105_HW_V3)
+#include "bsp/gd32/board_mc105_v3.h"
+#define CONFIG_BOARD_MCXXX
+#define CONFIG_BOARD_NAME "MC105"
+#define CONFIG_HW_VERSION 3
+#endif
+#endif /* __BSP_GD32_H__ */

+ 91 - 72
Applications/bsp/can.c → Applications/bsp/gd32/can.c

@@ -1,8 +1,8 @@
 #include <stdio.h>
-#include "bsp.h"
-#include "can.h"
-#include "libs/utils.h"
 #include "os/queue.h"
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "libs/circle_buffer.h"
 
 #define CAN_RX_MESSAGE_RX_ID 1
 #define CAN_SEND_QUEUE_SIZE 32
@@ -12,38 +12,60 @@
 #define CAN_SEND_WAIT_TIMEOUT -2
 
 
-static co_queue_t tx_queue;
-static co_queue_t rx_queue;
-static int shark_send_can0_to_fifo(can_trasnmit_message_struct *P_message);
+#define TX_NUM 64
+#define RX_NUM 64
+static c_buffer_t g_tx_circle;
+static c_buffer_t g_rx_circle;
+static uint8_t _g_tx_buffer[sizeof(can_trasnmit_message_struct) * TX_NUM + 1];
+static uint8_t _g_rx_buffer[sizeof(can_receive_message_struct) * RX_NUM + 1];
+
 static int shark_send_can0_data(can_trasnmit_message_struct *P_message);
-static void _can_tx_task(void *args);
-static void _can_rx_task(void *args);
+static uint8_t can_get_mailbox(uint32_t can_periph);
 /* this function can be overide by app, which need recv the can frame */
 __weak void handle_can_frame(can_id_t id, uint8_t *data, int len){
 
 }
 
-static void _can_rx_task(void *args){
+void can_rx_poll(void){
 	can_receive_message_struct message;
-	while(1) {
-		if (queue_get(rx_queue, &message)) {
-			can_id_t can_id;
-			can_id.id = message.rx_efid;
-			handle_can_frame(can_id, message.rx_data, message.rx_dlen);		
+	if (circle_get_data(&g_rx_circle, (uint8_t *)&message, sizeof(message)) != sizeof(message)) {
+		return;
+	}	
+	can_id_t can_id;
+	can_id.id = message.rx_efid;
+	handle_can_frame(can_id, message.rx_data, message.rx_dlen); 
+	return ;
+}
+
+void can_tx_poll(void){
+	can_trasnmit_message_struct can_tr_m;
+	if (CAN_ERR(CAN0) & CAN_ERR_BOERR){
+		shark_can0_reset();
+	}
+	while (can_get_mailbox(CAN0) != CAN_NOMAILBOX) {
+		if (circle_get_data(&g_tx_circle, (uint8_t * )&can_tr_m, sizeof(can_tr_m)) != sizeof(can_tr_m)) {
+			break;
 		}
-		co_task_yield();
+		can_message_transmit(CAN0,&can_tr_m);
 	}
 }
 
+static u32 _can_poll_task(void *args) {
+	can_rx_poll();
+	can_tx_poll();
+	return 0;
+}
+
 static __inline__ void can_fifo_recv(int fifo){
-	can_receive_message_struct message;
+	can_receive_message_struct Rxmessage;
+
+	can_message_receive(CAN0, fifo, &Rxmessage);
 
-	can_message_receive(CAN0, fifo, &message);  
+	circle_put_data(&g_rx_circle, (uint8_t *)&Rxmessage,  sizeof(Rxmessage));
 
-	queue_put(rx_queue, &message);
 }
 
-void USBD_LP_CAN0_RX0_IRQHandler(void)
+void CAN_RX0_IRQHandler(void)
 {
 	can_fifo_recv(CAN_FIFO0);
 }
@@ -56,14 +78,14 @@ void CAN0_RX1_IRQHandler(void)
 static void shark_can0_txrx_pin_config(void){
     /* enable can clock */
     rcu_periph_clock_enable(RCU_CAN0);
-    rcu_periph_clock_enable(RCU_GPIOA);	
+    rcu_periph_clock_enable(CAN_PIN_RCU);
     rcu_periph_clock_enable(RCU_AF);
 
-	//gpio_pin_remap_config(GPIO_CAN_FULL_REMAP,DISABLE);
-	//gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
-	
-    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
-	gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11); 
+#ifdef CAN_REMAP
+	gpio_pin_remap_config(CAN_REMAP,ENABLE);
+#endif
+    gpio_init(CAN_TX_GROUP, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_TX_PIN);
+	gpio_init(CAN_RX_GROUP, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_RX_PIN);
 }
 
 
@@ -101,62 +123,44 @@ static void shark_can0_config(void)
     
     /* recv my can ID, use fifo0 */
     can_filter_mask_mode_init(CAN_MY_ADDRESS, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO0, 0);
-
-  	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);  
-  	nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn,2,0);	
+ 
+  	nvic_irq_enable(CAN_IRQ0,CAN_IRQ_PRIORITY,0);	
     /* enable can receive FIFO0 not empty interrupt */
     can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
-	/* recv broadcast, fifo1 */
-	can_filter_mask_mode_init(CAN_NODE_ADDR_FF, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 1);
-	/* recv ccu aux fifo2*/
-	can_filter_mask_mode_init(CAN_NODE_ADDR_CCU_AUX, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 2);
-	/* recv ble fifo3*/
-	can_filter_mask_mode_init(CAN_NODE_ADDR_BLE, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 3);
-	
-	can_filter_mask_mode_init(CAN_NODE_ADDR_ACU, CAN_FILTER_DEST_MASK, CAN_EXTENDED_FIFO1, 4);
-	
-	nvic_irq_enable(CAN0_RX1_IRQn,10,0);	
-    /* enable can receive FIFO1 not empty interrupt */
-    can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE1);
 }
 
 
 static int shark_send_can0_data(can_trasnmit_message_struct *P_message){
-	if (queue_put(tx_queue, P_message)){
+	can_tx_poll();
+	if (circle_put_data(&g_tx_circle, (u8 *)P_message, sizeof(can_trasnmit_message_struct))){
 		return CAN_SEND_OK;
 	}
 	return CAN_SEND_ERROR;
 }
 
-static void _can_tx_task(void *args){
-	can_trasnmit_message_struct trasnmit_msg;
-	while(1) {
-		if (queue_get(tx_queue, &trasnmit_msg)) {
-			shark_send_can0_to_fifo(&trasnmit_msg);
-		}
-		co_task_yield();
-	}
-}
 
-/*when system scheduler is not start or stoped, we MUST not use FreeRTOS 
-system api which can cause sleep,context switch */
-static int shark_send_can0_to_fifo(can_trasnmit_message_struct *P_message){
-	uint8_t mailbox_number = CAN_NOMAILBOX;
-	uint32_t retry_count = 2000;
-	if (CAN_ERR(CAN0) & CAN_ERR_BOERR){
-		shark_can0_reset();
-	}
-	do {
-		mailbox_number = can_message_transmit(CAN0, P_message);
-		if (mailbox_number < CAN_NOMAILBOX){
-			return CAN_SEND_OK;
-		}
-	}while(retry_count-- > 0); //wait sender fifo empty
-
-	shark_can0_reset();	
-	return CAN_SEND_ERROR;
+static uint8_t can_get_mailbox(uint32_t can_periph)
+{
+    uint8_t mailbox_number = CAN_MAILBOX0;
+    
+    /* select one empty mailbox */
+    if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
+        mailbox_number = CAN_MAILBOX0;
+    }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
+        mailbox_number = CAN_MAILBOX1;
+    }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
+        mailbox_number = CAN_MAILBOX2;
+    }else{
+        mailbox_number = CAN_NOMAILBOX;
+    }
+    /* return no mailbox empty */
+    if(CAN_NOMAILBOX == mailbox_number){
+        return CAN_NOMAILBOX;
+    }
+	return mailbox_number;
 }
 
+
 int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
 	can_trasnmit_message_struct trasnmit_msg;
 	can_id_t can_frame_id;
@@ -186,6 +190,22 @@ int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
 
 }
 
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len){
+	can_trasnmit_message_struct trasnmit_msg;
+	
+	trasnmit_msg.tx_sfid	= 0;
+	trasnmit_msg.tx_efid	= can_id;				
+	trasnmit_msg.tx_ft	= CAN_FT_DATA;
+	trasnmit_msg.tx_ff	= CAN_FF_EXTENDED;
+	trasnmit_msg.tx_dlen = min(CAN_DLC_LENGTH,len);
+	memcpy((char *)trasnmit_msg.tx_data, (char *)buff, trasnmit_msg.tx_dlen);
+
+	if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
+		return CAN_SEND_ERROR;
+	}
+	return CAN_SEND_OK;
+}
+
 
 void shark_can0_reset(void){
 	shark_can0_txrx_pin_config();
@@ -195,14 +215,13 @@ void shark_can0_reset(void){
 void shark_can0_deinit(void){
 	can_deinit(CAN0);
 	rcu_periph_clock_disable(RCU_CAN0);
-	gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_9);  
 }
 
 void shark_can0_init(void){
-	tx_queue = queue_create(32, sizeof(can_trasnmit_message_struct));
-	rx_queue = queue_create(32, sizeof(can_trasnmit_message_struct));
-	co_task_create(_can_tx_task, NULL, 256);
-	co_task_create(_can_rx_task, NULL, 512);
+	circle_buffer_init(&g_tx_circle, _g_tx_buffer, sizeof(_g_tx_buffer));
+	circle_buffer_init(&g_rx_circle, _g_rx_buffer, sizeof(_g_rx_buffer));
+
+	shark_task_create(_can_poll_task, NULL);
 	shark_can0_txrx_pin_config();
 	shark_can0_config();
 }

+ 76 - 0
Applications/bsp/gd32/can.h

@@ -0,0 +1,76 @@
+#ifndef _Shark_Can0_h__
+#define _Shark_Can0_h__
+#include <stdio.h>
+#include "os/os_types.h"
+#include "config.h"
+//CAN DLC lenght
+#define   CAN_DLC_LENGTH     8
+
+
+#define CAN_EXTENDE_FRAME 1
+#ifdef CAN_EXTENDE_FRAME
+#define CAN_DATA_SIZE CAN_DLC_LENGTH
+#else
+#define CAN_DATA_SIZE 64
+#endif
+
+typedef union {
+	uint32_t id;
+	struct {
+		uint32_t	dest		:7; /*bit 0-6  */
+		uint32_t	src 			:7; /*bit 7-13 */
+		uint32_t	idx 			:5; /*bit 14-18 */
+		uint32_t	total		:5; /*bit 19-23 */
+		uint32_t	type		:2; /*bit 24-25 */ /*1:PT_REQ_NEED_RES ; 2:PT_RES 3:PT_REQ_NO_IND*/
+		uint32_t	retry		:3; /*bit 26-28 */
+		uint32_t	length 		:3; /*bit 29-13 */ //0-7:1-8
+	};
+}can_id_t;
+
+//CAN filter setting
+#ifdef CAN_COMMUNICATION_SPEC_V1P4
+//specification 1.4
+#define CAN_ID_FILTER_START_OFFSET       3
+#define CAN_ID_FILTER_FLAG_OFFSET         7
+#define CAN_ID_FILTER_FLAG                       0x7F
+#else
+//specification 1.3
+#define CAN_ID_FILTER_START_OFFSET       3
+#define CAN_ID_FILTER_FLAG_OFFSET         8
+#define CAN_ID_FILTER_FLAG                       0xFF
+#endif
+
+#define CAN_FILTER_DEST_MASK 0x7F
+
+#define ptype_beat_heart		0 // can heat heart
+#define ptype_request  	1 // can request with need response
+#define ptype_response			2 // can response of the request
+#define ptype_indicater	3 // can request with no need response
+
+
+#define  can_packet_priority_value       0x06
+#define  can_packet_quick_packet_value    0x01  
+
+//used when can recv
+static __inline__ uint16_t decoder_can_key(const void *buf){
+	uint8_t *key_buf = (uint8_t *)buf;
+	return key_buf[1]<<8 | key_buf[0];
+} 
+
+//used when can send
+static __inline__ void encoder_can_key(uint8_t *buff, uint16_t key) {
+	buff[0] = key & 0xFF;
+	buff[1] = (key >> 8) & 0xFF;
+}
+
+
+int shark_can0_send_message(uint32_t can_id, const void*buff, int len);
+void shark_can0_route_message(uint32_t can_id, const void *buff, int len);
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len);
+void shark_can0_init(void);
+void shark_can0_reset(void);
+void shark_can0_deinit(void);
+void can_rx_poll(void);
+
+#endif /* _Shark_Can0_h__ */
+

+ 232 - 0
Applications/bsp/gd32/enc_intf.c

@@ -0,0 +1,232 @@
+#include "bsp/bsp_driver.h"
+#include "libs/logger.h"
+
+static void _io_init(void) {
+	rcu_periph_clock_enable(ENC_A_RCU);
+	rcu_periph_clock_enable(ENC_B_RCU);
+	rcu_periph_clock_enable(ENC_PWM_RCU);
+	rcu_periph_clock_enable(ENC_I_RCU);
+#ifdef TIMER2_PB4_PB5_REMAP
+	gpio_pin_remap_config(TIMER2_PB4_PB5_REMAP, ENABLE);
+#endif
+#ifdef TIMER1_PA15_REMAP
+	gpio_pin_remap_config(TIMER1_PA15_REMAP, ENABLE);
+#endif
+	gpio_init(ENC_A_GROUP, ENC_A_MODE, GPIO_OSPEED_50MHZ, ENC_A_PIN);
+	gpio_init(ENC_B_GROUP, ENC_B_MODE, GPIO_OSPEED_50MHZ, ENC_B_PIN);
+	gpio_init(ENC_PWM_GROUP, ENC_PWM_MODE, GPIO_OSPEED_50MHZ, ENC_PWM_PIN);
+	gpio_init(ENC_I_GROUP, ENC_I_MODE, GPIO_OSPEED_50MHZ, ENC_I_PIN);
+}
+
+static void z_io_init_irq(void) {
+#ifdef ENC_I_IRQ
+	gpio_exti_source_select(ENC_I_EXIT_SRC_GROUP, ENC_I_EXIT_SRC_PIN);
+	exti_init(ENC_I_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	exti_interrupt_flag_clear(ENC_I_EXTI);
+	exti_interrupt_enable(ENC_I_EXTI);
+	nvic_irq_enable(ENC_I_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0U);
+#endif
+}
+
+void enc_intf_init(u32 rate) {
+	_io_init();
+	enc_intf_pwm_counter();
+	enc_intf_quadrature_init(rate);
+	z_io_init_irq();
+	enc_intf_z_counter();
+}
+
+void enc_intf_quadrature_init(u32 rate) {
+	timer_parameter_struct timer_initpara;
+	timer_ic_parameter_struct timer_icinitpara;
+
+	u32 timer = ENC_TIMER;
+
+	rcu_periph_clock_enable(ENC_TIMER_RCU);
+
+	timer_deinit(timer);
+
+	/* TIMER configuration */
+	timer_struct_para_init(&timer_initpara);
+	timer_initpara.prescaler		= 0;//TIM_CLOCK/PWM_TIME_CLK - 1;
+	timer_initpara.alignedmode		= TIMER_COUNTER_EDGE;
+	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+	timer_initpara.period		   = rate-1;
+	timer_initpara.clockdivision	= TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+	timer_init(timer,&timer_initpara);
+
+    /* initialize TIMER channel input parameter struct */
+    timer_channel_input_struct_para_init(&timer_icinitpara);
+    /* TIMER2 CH0 input capture configuration */
+    timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;
+    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
+    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
+    timer_icinitpara.icfilter    = CONFIG_ENC_FILTER_NR;//采样频率120M, 这个必须要加入滤波,否则AB的计数可能不对
+    timer_input_capture_config(timer,TIMER_CH_0,&timer_icinitpara);
+	
+	timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;
+	timer_input_capture_config(timer,TIMER_CH_1,&timer_icinitpara);
+
+	timer_quadrature_decoder_mode_config(timer ,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_FALLING, TIMER_IC_POLARITY_RISING);
+	
+	/* auto-reload preload enable */
+	timer_auto_reload_shadow_enable(timer);	
+
+	
+	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_UP);
+
+	//timer_interrupt_enable(timer, TIMER_INT_UP);
+	//nvic_irq_enable(ENC_TIMER_IRQ, ENC_TIMER_IRQ_PRIORITY, 0);
+
+	/* TIMER2 counter enable */
+	timer_enable(timer);
+}
+
+void enc_intf_pwm_counter(void) {
+	timer_ic_parameter_struct timer_icinitpara;
+	timer_parameter_struct timer_initpara;
+	u32 timer = ENC_PWM_TIMER;
+
+	rcu_periph_clock_enable(ENC_PWM_TIMER_RCU);
+
+	timer_deinit(timer);
+
+	/* TIMER configuration */
+	timer_struct_para_init(&timer_initpara);
+	timer_initpara.prescaler		= TIM_CLOCK/PWM_TIME_CLK - 1;
+	timer_initpara.alignedmode		= TIMER_COUNTER_EDGE;
+	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+	timer_initpara.period		   = 65535;
+	timer_initpara.clockdivision	= TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+	timer_init(timer,&timer_initpara);
+
+	timer_channel_input_struct_para_init(&timer_icinitpara);
+	/* TIMER CH0 PWM input capture configuration */
+	timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;
+	timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
+	timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
+	timer_icinitpara.icfilter	 = CONFIG_PWM_FILTER_NR;
+	timer_input_pwm_capture_config(timer, ENC_PWM_TIMER_CHAN, &timer_icinitpara);
+
+	/* slave mode selection: TIMER */
+	timer_input_trigger_source_select(timer, TIMER_SMCFG_TRGSEL_CI0FE0);
+	timer_slave_mode_select(timer, TIMER_SLAVE_MODE_RESTART);
+
+	/* select the master slave mode */
+	timer_master_slave_mode_config(timer, TIMER_MASTER_SLAVE_MODE_ENABLE);
+
+    /* auto-reload preload enable */
+    timer_auto_reload_shadow_enable(timer);
+    /* clear channel 0 interrupt bit */
+    timer_interrupt_flag_clear(timer, ENC_PWM_TIMER_INT_FLG);
+    /* channel 0 interrupt enable */
+    timer_interrupt_enable(timer, ENC_PWM_TIMER_IRQ_CH);
+	nvic_irq_enable(ENC_PWM_TIMER_IRQ, ENC_PWM_IRQ_PRIORITY, 0);
+    /* TIMER2 counter enable */
+    timer_enable(timer);
+}
+
+
+void enc_intf_z_counter(void) {
+#ifdef ENC_I_TIMER
+	timer_ic_parameter_struct timer_icinitpara;
+	timer_parameter_struct timer_initpara;
+	u32 timer = ENC_I_TIMER;
+
+	rcu_periph_clock_enable(ENC_I_TIMER_RCU);
+
+	timer_deinit(timer);
+
+	/* TIMER configuration */
+	timer_struct_para_init(&timer_initpara);
+	timer_initpara.prescaler		= TIM_CLOCK/PWM_TIME_CLK - 1;
+	timer_initpara.alignedmode		= TIMER_COUNTER_EDGE;
+	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+	timer_initpara.period		   = 65535;
+	timer_initpara.clockdivision	= TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+	timer_init(timer,&timer_initpara);
+
+	timer_channel_input_struct_para_init(&timer_icinitpara);
+	/* TIMER CH0 PWM input capture configuration */
+	timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;
+	timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
+	timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
+	timer_icinitpara.icfilter	 = CONFIG_PWM_FILTER_NR;
+	timer_input_capture_config(timer, ENC_I_TIMER_CHAN, &timer_icinitpara);
+
+	/* slave mode selection: TIMER */
+	timer_input_trigger_source_select(timer, TIMER_SMCFG_TRGSEL_CI0FE0);
+	timer_slave_mode_select(timer, TIMER_SLAVE_MODE_RESTART);
+
+	/* select the master slave mode */
+	timer_master_slave_mode_config(timer, TIMER_MASTER_SLAVE_MODE_ENABLE);
+
+    /* auto-reload preload enable */
+    timer_auto_reload_shadow_enable(timer);
+    /* clear channel 0 interrupt bit */
+    timer_interrupt_flag_clear(timer, ENC_I_TIMER_INT_FLG);
+    /* channel 0 interrupt enable */
+    timer_interrupt_enable(timer, ENC_I_TIMER_IRQ_CH);
+	nvic_irq_enable(ENC_I_TIMER_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0);
+    /* TIMER2 counter enable */
+    timer_enable(timer);
+#endif
+}
+
+__weak void ENC_TIMER_Overflow(void) {
+
+}
+
+void ENC_TIMER_IRQHandler(void) {
+	if (SET == timer_interrupt_flag_get(ENC_TIMER, TIMER_INT_FLAG_UP)) {
+		timer_interrupt_flag_clear(ENC_TIMER, TIMER_INT_FLAG_UP);
+		ENC_TIMER_Overflow();
+	}
+}
+
+
+__weak void ENC_ABI_IRQHandler(void) {
+
+}
+
+void ABI_I_IRQHandler(void) {
+#ifdef ENC_I_IRQ
+	ENC_ABI_IRQHandler();
+#endif
+}
+
+void ENC_I_IRQHandler(void) {
+#ifdef ENC_I_TIMER
+    if(SET == timer_interrupt_flag_get(ENC_I_TIMER, ENC_I_TIMER_INT_FLG)){
+        /* clear channel 0 interrupt bit */
+        timer_interrupt_flag_clear(ENC_I_TIMER, ENC_I_TIMER_INT_FLG);
+		ENC_ABI_IRQHandler();
+    }
+#endif
+}
+
+__weak void ENC_PWM_Duty_Handler(float t, float d) {
+
+}
+
+static float pwm_freq = 0.0f;
+void ENC_PWM_IRQHandler(void) {
+    if(SET == timer_interrupt_flag_get(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG)){
+        /* clear channel 0 interrupt bit */
+        timer_interrupt_flag_clear(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG);
+        /* read channel 0 capture value */
+        u32 ic0value = TIMER_CH0CV(ENC_PWM_TIMER)+1;
+		u32 ic1value = TIMER_CH1CV(ENC_PWM_TIMER)+1;
+		float p_calc = ENC_PWM_Calc_P(ic0value);
+		float d_calc = ENC_PWM_Calc_P(ic1value);
+		ENC_PWM_Duty_Handler(p_calc, d_calc);
+		pwm_freq = (float)PWM_TIME_CLK/((float)ic0value);
+    }
+}
+
+float enc_get_pwm_freq(void) {
+	return pwm_freq;
+}

+ 29 - 0
Applications/bsp/gd32/enc_intf.h

@@ -0,0 +1,29 @@
+#ifndef _ENC_INTF_H__
+#define _ENC_INTF_H__
+#include "os/os_types.h"
+#include "bsp/bsp.h"
+
+#define PWM_TIME_CLK 10000000U
+
+
+#define ENC_DIR_UP 1
+#define ENC_DIR_DOWN 2
+
+#define ENC_PWM_Calc_P(t) ((float)t / (float)PWM_TIME_CLK)
+
+#define ENC_COUNT TIMER_CNT(ENC_TIMER)
+
+#define ENC_Direction() ((TIMER_CTL0(ENC_TIMER) & TIMER_CTL0_DIR)?ENC_DIR_DOWN:ENC_DIR_UP)
+
+#define ENC_OverFlow() ((TIMER_INTF(ENC_TIMER) & TIMER_FLAG_UP)?true:false)
+#define ENC_ClearUpFlags() (TIMER_INTF(ENC_TIMER) = (~(uint32_t)TIMER_FLAG_UP))
+
+void enc_intf_quadrature_init(u32 rate);
+void enc_intf_pwm_counter(void);
+void enc_intf_z_counter(void);
+
+void enc_intf_init(u32 rate);
+float enc_get_pwm_freq(void);
+
+#endif /*_ENC_INTF_H__*/
+

+ 83 - 0
Applications/bsp/gd32/fan_pwm.c

@@ -0,0 +1,83 @@
+#include "fan_pwm.h"
+
+void fan_pwm_init(void){
+	uint16_t chno = FAN_PWM_CHAN;
+    /* -----------------------------------------------------------------------
+    TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
+    TIMER1CLK = SystemCoreClock / 108 = 1MHz
+
+    TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
+    TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
+    TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
+    ----------------------------------------------------------------------- */
+    timer_oc_parameter_struct timer_ocintpara;
+    timer_parameter_struct timer_initpara;
+
+	rcu_periph_clock_enable(GPIO_FAN_OUT_RCU);
+    rcu_periph_clock_enable(RCU_AF);
+
+    /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
+    gpio_init(GPIO_FAN_OUT_GROUP, GPIO_FAN_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN_OUT_PIN);	
+	
+    rcu_periph_clock_enable(FAN_TIMER_RCU);
+
+    timer_deinit(FAN_PWM_TIMER);
+
+    /* TIMER1 configuration 1M*/
+    timer_initpara.prescaler         = 119;
+    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
+    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period            = FAN_MAX_DUTY_COUNT;
+    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
+    timer_initpara.repetitioncounter = 1;
+    timer_init(FAN_PWM_TIMER,&timer_initpara);
+
+    /* CH2 and CH3 configuration in PWM mode1 */
+    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
+    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
+    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_LOW;
+    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
+    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
+
+    timer_channel_output_config(FAN_PWM_TIMER,chno,&timer_ocintpara);
+
+    /* CH2 configuration in PWM mode1,duty cycle 46% */
+    timer_channel_output_pulse_value_config(FAN_PWM_TIMER,chno,FAN_MAX_DUTY_COUNT-1);
+    timer_channel_output_mode_config(FAN_PWM_TIMER,chno,TIMER_OC_MODE_PWM0);
+    timer_channel_output_shadow_config(FAN_PWM_TIMER,chno,TIMER_OC_SHADOW_ENABLE);
+    /* auto-reload preload enable */
+    timer_auto_reload_shadow_enable(FAN_PWM_TIMER);
+
+	timer_enable(FAN_PWM_TIMER);
+}
+
+
+void fan_stop(void) {
+	timer_disable(FAN_PWM_TIMER);
+}
+
+void fan_set_duty(u8 duty) {
+	uint16_t chno = FAN_PWM_CHAN;
+	if (duty > 100) {
+		duty = 100;
+	}else if (duty > 0 && duty < 30) {
+		duty = 30;
+	}
+	u32 count = (float)duty * (float)FAN_MAX_DUTY_COUNT / 100.0f;
+	timer_channel_output_pulse_value_config(FAN_PWM_TIMER,chno, count);
+	if (count == 0) {
+		timer_primary_output_config(FAN_PWM_TIMER,DISABLE);
+	}else {
+		timer_primary_output_config(FAN_PWM_TIMER,ENABLE);
+	}
+}
+
+
+bool fan_pwm_is_running(void) {
+	if (TIMER_CCHP(FAN_PWM_TIMER) & (uint32_t)TIMER_CCHP_POEN) {
+		return true;
+	}
+	return false;
+}
+

+ 23 - 0
Applications/bsp/gd32/fan_pwm.h

@@ -0,0 +1,23 @@
+#ifndef _FAN_PWM_H__
+#define _FAN_PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define PWM_FREQ_HZ    200
+#define FAN_DUTY_COUNT (1000000/200)
+#define FAN_MAX_DUTY_COUNT (FAN_DUTY_COUNT/2)
+
+#ifdef CONFIG_BOARD_MCXXX
+void fan_pwm_init(void);
+void fan_stop(void);
+void fan_set_duty(u8 duty); //duty 0-100
+bool fan_pwm_is_running(void);
+#else
+static void fan_pwm_init(void) {}
+static void fan_stop(void) {}
+static void fan_set_duty(u8 duty) {}
+bool fan_pwm_is_running(void){return false;}
+
+#endif
+#endif /* _FAN_PWM_H__ */
+

+ 223 - 0
Applications/bsp/gd32/fmc_flash.c

@@ -0,0 +1,223 @@
+#include "bsp/bsp_driver.h"
+
+#if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
+#define FMC_FLAG_PGERR  FMC_FLAG_BANK0_PGERR
+#define FMC_FLAG_PGAERR  FMC_FLAG_BANK0_PGERR
+#define FMC_FLAG_WPERR  FMC_FLAG_BANK0_WPERR
+#define FMC_FLAG_END  FMC_FLAG_BANK0_END
+#endif
+
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_addr(uint32_t addr, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len);
+
+static uint32_t _sn_addr(void);
+static uint32_t _data_addr(int index);
+static uint32_t _maigc_addr(void);
+
+static uint32_t _nv_tbl_write_addr = 0;
+
+static u8 _nv_tbl_write_cache[4];
+static u8 _nv_tbl_write_remain;
+
+void fmc_write_sn(uint8_t *sn, int len){
+	_fmc_erase_write_data(_sn_addr(), sn, len);
+}
+
+void fmc_read_sn(uint8_t *sn, int len){
+	_fmc_read_data(_sn_addr(), sn, len);
+}
+
+void fmc_write_data(int index, uint8_t *data, int len){
+	_fmc_erase_write_data(_data_addr(index), data, len);
+}
+
+void fmc_read_data(int index, uint8_t *data, int len){
+	_fmc_read_data(_data_addr(index), data, len);
+}
+
+void fmc_read_data_with_offset(int index, u32 off, uint8_t *data, int len) {
+	uint32_t addr = _data_addr(index) + off;
+	_fmc_read_data(addr, data, len);
+}
+
+static __inline__ void _fmc_flag_clear(void) {
+	fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+}
+
+
+void fmc_write_magic(uint32_t magic){
+	uint32_t address = _maigc_addr();
+	uint32_t length, checksum, value;
+
+	value = REG32(address + 8);
+	if (magic == value) {
+		return;
+	}
+
+	length = REG32(address);
+	checksum = REG32(address + 4);
+
+	fmc_unlock();
+
+	if (value != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		fmc_page_erase(address);
+
+		_fmc_flag_clear();
+		fmc_word_program(address, length);
+
+		_fmc_flag_clear();
+		fmc_word_program(address + 4, checksum);
+	}
+
+	if (magic != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		fmc_word_program(address + 8, magic);
+	}
+
+	fmc_lock();
+}
+
+uint32_t fmc_read_magic(void){
+	uint32_t magic = 0x5555aaaa;
+	_fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
+	return magic;
+}
+
+//if flash is lager than 256k, we just use the 256k
+static uint32_t __inline__ _flash_capatity(void){
+	uint32_t capacity;
+	capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	if (capacity > (256 * 1024)){
+		capacity =  256 * 1024;
+	}
+	return capacity;
+}
+
+static uint32_t _sn_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
+}
+
+static uint32_t _data_addr(int index){
+	return 0x08000000 + (_flash_capatity() - one_page_size * index);
+}
+
+static uint32_t _maigc_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
+}
+
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
+	int i = 0;
+	for (i = 0; i < len; i++){
+		data[i] = REG8(addr + i);
+	}
+}
+
+uint32_t fmc_get_addr(int page) {
+	return 0x08000000 + (_flash_capatity() - one_page_size * page);
+}
+
+void fmc_erase_trq_table(int addr, int len){
+	_fmc_erase_addr(addr, len);
+	_nv_tbl_write_addr = 0;
+}
+void fmc_write_trq_table(int addr, uint8_t *data, int len){
+	_fmc_write_data(addr + _nv_tbl_write_addr, data, len);
+	_nv_tbl_write_addr += len;
+}
+
+void fmc_write_trq_table_begin(int addr)
+{
+	_nv_tbl_write_addr = addr;
+	_nv_tbl_write_remain = 0;
+}
+
+static void fmc_write_trq_table_flush(void)
+{
+	u32 value = *(u32 *) _nv_tbl_write_cache;
+
+	if ((_nv_tbl_write_addr % one_page_size) == 0) {
+		fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+		fmc_page_erase(_nv_tbl_write_addr);
+	}
+
+	fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+	fmc_word_program(_nv_tbl_write_addr, value);
+
+	_nv_tbl_write_addr += _nv_tbl_write_remain;
+	_nv_tbl_write_remain = 0;
+}
+
+void fmc_write_trq_table_continue(const u8 *data, int len)
+{
+	const u8 *data_end;
+
+	fmc_unlock();
+
+	for (data_end = data + len; data < data_end; data++) {
+		if (_nv_tbl_write_remain >= sizeof(_nv_tbl_write_cache)) {
+			fmc_write_trq_table_flush();
+		}
+
+		_nv_tbl_write_cache[_nv_tbl_write_remain] = *data;
+		_nv_tbl_write_remain++;
+	}
+
+	fmc_lock();
+}
+
+void fmc_write_trq_table_end(void)
+{
+	if (_nv_tbl_write_remain > 0) {
+		fmc_unlock();
+		fmc_write_trq_table_flush();
+		fmc_lock();
+	}
+}
+
+extern void wdog_reload(void);
+static void _fmc_erase_addr(uint32_t addr, int len){
+	fmc_unlock();
+	uint32_t pages = len/one_page_size + (((len % one_page_size) > 0)?1:0);
+	for (int i = 0; i < pages; i++){
+		fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+		fmc_page_erase(addr + i * one_page_size);
+		wdog_reload();
+	}
+	fmc_lock();
+}
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
+	fmc_unlock();
+	int total_words = len / 4;
+	uint32_t *p_u32_data = (uint32_t *)data;
+	int i;
+	for (i = 0; i < total_words; i++){
+		fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+		fmc_word_program(addr, p_u32_data[i]);
+		data += 4;
+		addr += 4;
+	}
+
+	int remain_len = len - total_words * 4;
+	if (remain_len > 0){
+		uint32_t words = 0;
+		for (int i = 0; i < remain_len; i++){
+			words |= data[i] << (8*i);
+		}
+		fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
+		fmc_word_program(addr, words);
+	}
+	fmc_lock();
+}
+
+
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len){
+	_fmc_erase_addr(addr, len);
+	_fmc_write_data(addr, data, len);
+}
+

+ 24 - 0
Applications/bsp/gd32/fmc_flash.h

@@ -0,0 +1,24 @@
+#ifndef _FMC_FLASH_H__
+#define _FMC_FLASH_H__
+#include <stdint.h>
+
+#define one_page_size 2048
+
+#define sn_page_index 2
+#define magic_page_index 1 //must is the last page in 256K eara
+
+void fmc_write_sn(uint8_t *sn, int len);
+void fmc_read_sn(uint8_t *sn, int len);
+
+void fmc_write_data(int index, uint8_t *data, int len);
+void fmc_read_data(int index, uint8_t *data, int len);
+void fmc_write_magic(uint32_t magic);
+uint32_t fmc_read_magic(void);
+uint32_t fmc_get_addr(int page);
+void fmc_write_trq_table_begin(int addr);
+void fmc_write_trq_table_continue(const u8 *data, int len);
+void fmc_write_trq_table_end(void);
+void fmc_read_data_with_offset(int index, u32 off, uint8_t *data, int len);
+
+#endif /* _FMC_FLASH_H__ */
+

+ 0 - 8
Applications/bsp/gd32_bkp.c → Applications/bsp/gd32/gd32_bkp.c

@@ -76,12 +76,4 @@ void gd32_bkp_get_backtrace(uint32_t *backtrace, uint32_t *stack_over, uint32_t
 	*line = bkp_read_data(BACK_TRACE_LINE_REG);
 }
 
-uint32_t  gd32_get_reset_source(void)
-{
-	uint32_t reset_source = 0;
-
-	reset_source = RCU_RSTSCK;
-	return reset_source;
-}
-
 

+ 1 - 1
Applications/bsp/gd32_bkp.h → Applications/bsp/gd32/gd32_bkp.h

@@ -12,7 +12,7 @@
 #define bkp_read_data bkp_data_read
 #endif
 #include "config.h"
-#include "os/os_type.h"
+#include "os/os_types.h"
 
 #define POWER_FIRSTFLAG_REG BKP_DATA_0
 #define POWER_FIRSTFLAG_VALUE 0x5AA5

+ 11 - 6
Applications/bsp/gd32_rtc.c → Applications/bsp/gd32/gd32_rtc.c

@@ -1,8 +1,6 @@
 #include <stdio.h>
 #include <string.h>
-#include "bsp/bsp.h"
-#include "bsp/gd32_bkp.h"
-
+#include "bsp/bsp_driver.h"
 
 #define IS_LEAP_YEAR(year)      ((year % 4 == 0) && ( year % 100 != 0) || (year % 400 == 0))
 
@@ -115,7 +113,7 @@ static void gd32_rtc_first_init(void){
 
 static void gd32_rtc_enable_second_irq(int enable){
 	if (enable){
-		nvic_irq_enable(RTC_IRQn, 2U, 0U);
+		nvic_irq_enable(RTC_IRQn, RTC_IRQ_PRIORITY, 0U);
 	}else{
 		nvic_irq_disable(RTC_IRQn);
 	}
@@ -126,8 +124,11 @@ void gd32_rtc_init(void){
 
 	//3?¡§o?¡§o?¨¤1??¨¤?RTC alarm¡§o?3?
 	gd32_rtc_stop_alarm();
-	
+#ifdef GD32F30X_CL
+	nvic_irq_disable(RTC_ALARM_IRQn);
+#else
 	nvic_irq_disable(RTC_Alarm_IRQn);
+#endif
 	exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
 	exti_flag_clear(EXTI_17);
 	exti_interrupt_enable(EXTI_17);
@@ -161,7 +162,11 @@ static int set_rtc_alarm(uint32_t sencod){
 
 
 int gd32_rtc_start_alarm(uint32_t second){
-    nvic_irq_enable(RTC_Alarm_IRQn, 2U, 0U);
+#ifdef GD32F30X_CL
+	nvic_irq_enable(RTC_ALARM_IRQn, RTC_IRQ_PRIORITY, 0U);
+#else
+    nvic_irq_enable(RTC_Alarm_IRQn, RTC_IRQ_PRIORITY, 0U);
+#endif
     exti_flag_clear(EXTI_17);
     exti_interrupt_enable(EXTI_17);
 	rtc_register_sync_wait();

+ 0 - 0
Applications/bsp/gd32_rtc.h → Applications/bsp/gd32/gd32_rtc.h


+ 278 - 0
Applications/bsp/gd32/gpio.c

@@ -0,0 +1,278 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+
+#ifdef GD32_FOC_DEMO
+#define IR2136S_Enable_pin 0
+#define LED1_Enable_pin 1
+#define LED2_Enable_pin 2
+#define LED3_Enable_pin 3
+#define KEY_Start_pin   4
+#define KEY_Stop_pin    5
+#define KEY_Func_pin   6
+#endif
+/*
+* gpio.c
+* all pins used as gpio(in/out/irq) must be init&accessed here
+*/
+const static gpio_pin_config_t _pins[] = {
+#ifdef GD32_FOC_DEMO
+	[IR2136S_Enable_pin] = {GPIOA, GPIO_PIN_12, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, 0},
+	[LED1_Enable_pin] = {GPIOD, GPIO_PIN_2, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, 0},
+	[LED2_Enable_pin] = {0, GPIO_PIN_9, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, 0},
+	[LED3_Enable_pin] = {GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, 0},
+	[KEY_Start_pin] = {GPIOB, GPIO_PIN_5, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, 0},
+	[KEY_Stop_pin] = {GPIOB, GPIO_PIN_11, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, 0},
+#endif	
+};
+void gpio_pin_init(void){
+	rcu_periph_clock_enable(RCU_GPIOA);
+    rcu_periph_clock_enable(RCU_GPIOB);
+	rcu_periph_clock_enable(RCU_GPIOC);
+	rcu_periph_clock_enable(RCU_GPIOD);
+	rcu_periph_clock_enable(RCU_GPIOF);
+	rcu_periph_clock_enable(RCU_AF);
+	
+	for (int i = 0; i < ARRAY_SIZE(_pins); i++){
+		if (_pins[i].init_value != -1){
+			gpio_bit_write(_pins[i].group, _pins[i].pin, (bit_status)_pins[i].init_value);
+		}
+		if (_pins[i].group != 0) {
+			gpio_init(_pins[i].group, _pins[i].mode, _pins[i].speed, _pins[i].pin);
+		}
+	}
+#ifdef CONFIG_BEEP
+	gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
+	gpio_beep(50);
+#endif
+}
+
+
+void gpio_beep(u32 ms) {
+#ifdef CONFIG_BEEP
+	gpio_bit_write(GPIOB, GPIO_PIN_2, SET);
+	delay_ms(ms);
+	gpio_bit_write(GPIOB, GPIO_PIN_2, RESET);
+#endif
+}
+
+void gpio_mc_brk_init(void) {
+#ifdef GPIO_BRAKE_IN_GROUP
+	rcu_periph_clock_enable(GPIO_BRAKE_IN_RCU);
+#ifdef GPIO_BRAKE_PIN_REMAP
+	gpio_pin_remap_config(GPIO_BRAKE_PIN_REMAP, ENABLE);
+#endif
+	gpio_init(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE_IN_PIN);
+	
+	gpio_exti_source_select(GPIO_BRAKE_EXIT_SRC_GROUP, GPIO_BRAKE_EXIT_SRC_PIN);
+	exti_init(GPIO_BRAKE_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(GPIO_BRAKE_IRQ, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_BRAKE_EXTI);
+	exti_interrupt_enable(GPIO_BRAKE_EXTI);	
+#endif
+#ifdef GPIO_BRAKE1_IN_GROUP
+	rcu_periph_clock_enable(GPIO_BRAKE1_IN_RCU);
+	gpio_init(GPIO_BRAKE1_IN_GROUP, GPIO_BRAKE1_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE1_IN_PIN);
+
+	gpio_exti_source_select(GPIO_BRAKE1_EXIT_SRC_GROUP, GPIO_BRAKE1_EXIT_SRC_PIN);
+	exti_init(GPIO_BRAKE1_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(GPIO_BRAKE1_IRQ, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_BRAKE1_EXTI);
+	exti_interrupt_enable(GPIO_BRAKE1_EXTI);
+#endif
+}
+
+void gpio_mlock_init(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	rcu_periph_clock_enable(GPIO_MLOCK_IN_RCU);
+	gpio_init(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_MLOCK_IN_PIN);
+#endif
+}
+
+void gpio_fan_det_init(void) {
+#ifdef GPIO_FAN1_IN_GROUP
+	rcu_periph_clock_enable(GPIO_FAN1_IN_RCU);
+	gpio_init(GPIO_FAN1_IN_GROUP, GPIO_FAN1_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN1_IN_PIN);
+	gpio_exti_source_select(GPIO_FAN1_EXIT_SRC_GROUP, GPIO_FAN1_EXIT_SRC_PIN);
+	exti_init(GPIO_FAN1_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	nvic_irq_enable(GPIO_FAN1_IRQ, ENC_OTHER_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_FAN1_EXTI);
+	exti_interrupt_enable(GPIO_FAN1_EXTI);
+#endif
+#ifdef GPIO_FAN2_IN_GROUP
+	rcu_periph_clock_enable(GPIO_FAN2_IN_RCU);
+	gpio_init(GPIO_FAN2_IN_GROUP, GPIO_FAN2_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN2_IN_PIN);
+	gpio_exti_source_select(GPIO_FAN2_EXIT_SRC_GROUP, GPIO_FAN2_EXIT_SRC_PIN);
+	exti_init(GPIO_FAN2_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	nvic_irq_enable(GPIO_FAN2_IRQ, ENC_OTHER_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_FAN2_EXTI);
+	exti_interrupt_enable(GPIO_FAN2_EXTI);
+#endif
+}
+
+void gpio_phase_u_detect(bool enable) {
+#ifdef GPIO_UDEC_OUT_GROUP
+	if (enable) {
+		gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_DISABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_DISABLE, ENABLE);
+	#endif
+		gpio_bit_write(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_PIN, SET);
+	}else {
+		gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_ENABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_ENABLE, ENABLE);
+	#endif
+	}
+#endif
+}
+
+
+void gpio_led_init(void) {
+#ifdef GPIO_LED_OUT_GROUP
+	rcu_periph_clock_enable(GPIO_LED_OUT_RCU);
+	gpio_init(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_LED_OUT_PIN);
+	gpio_bit_reset(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_PIN);
+#endif
+}
+
+void gpio_brk_light_init(void) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	rcu_periph_clock_enable(GPIO_BRAKE_LIGHT_OUT_RCU);
+	gpio_init(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE_LIGHT_OUT_PIN);
+	gpio_bit_reset(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN);
+#endif
+}
+
+void gpio_board_id_init(void) {
+#ifdef BOOT_PIN_0_GROUP
+	gpio_init(BOOT_PIN_0_GROUP, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, BOOT_PIN_0_PIN);
+	gpio_init(BOOT_PIN_1_GROUP, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, BOOT_PIN_1_PIN);
+#endif
+}
+
+u8  gpio_hw_board_id(void) {
+	u8 id = BOARD_105_VERSION_4;
+#ifdef BOOT_PIN_0_GROUP
+	u8 b0 = gpio_input_bit_get(BOOT_PIN_0_GROUP, BOOT_PIN_0_PIN);
+	u8 b1 = gpio_input_bit_get(BOOT_PIN_1_GROUP, BOOT_PIN_1_PIN);
+	id = ((b1 << 1) | b0);
+#endif
+	return id;
+}
+
+void gpio_repear_key_init(void) {
+#ifdef REPEAR_IN_GROUP
+	gpio_init(REPEAR_IN_GROUP, REPEAR_IN_MODE, GPIO_OSPEED_50MHZ, REPEAR_IN_PIN);
+#endif
+}
+static u8 _board_id = BOARD_105_VERSION_4;
+void mc_gpio_init(void) {
+	gpio_mlock_init();
+	gpio_mc_brk_init();
+	gpio_fan_det_init();
+	gpio_led_init();
+	gpio_brk_light_init();
+	gpio_board_id_init();
+	gpio_repear_key_init();
+	int count = 10;
+	do {
+		delay_ms(5);
+		_board_id = gpio_hw_board_id();
+		if (_board_id == BOARD_105_VERSION_3 || _board_id == BOARD_105_VERSION_4) {
+			break;
+		}
+	}while(count-- > 0);
+}
+
+bool gpio_is_repear_mode(void) {
+#ifndef REPEAR_IN_GROUP
+	return false;
+#else
+	return gpio_input_bit_get(REPEAR_IN_GROUP, REPEAR_IN_PIN) == RESET;
+#endif
+}
+
+void gpio_led_enable(bool enable) {
+#ifdef GPIO_LED_OUT_GROUP
+	gpio_bit_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?SET:RESET);
+#endif
+}
+
+void gpio_brk_light_enable(bool enable) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	gpio_bit_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?SET:RESET);
+#endif
+}
+
+u8  gpio_board_id(void) {
+	return _board_id;
+}
+
+bool mc_get_gpio_brake(void) {
+	return gpio_input_bit_get(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_PIN) == SET;
+}
+
+bool mc_get_gpio_brake1(void) {
+#ifdef GPIO_BRAKE1_IN_GROUP
+	return gpio_input_bit_get(GPIO_BRAKE1_IN_GROUP, GPIO_BRAKE1_IN_PIN) == SET;
+#else
+	return mc_get_gpio_brake();
+#endif
+}
+
+
+bool gpio_motor_locked(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	return gpio_input_bit_get(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_PIN) == RESET;
+#else
+	return false;
+#endif
+}
+
+
+
+void gpio_ir2136_enable(bool enable) {
+#ifdef GD32_FOC_DEMO
+	gpio_bit_write(_pins[IR2136S_Enable_pin].group, _pins[IR2136S_Enable_pin].pin, (enable)?SET:RESET);
+#endif
+}
+
+void gpio_led1_enable(bool enable) {
+#ifdef GD32_FOC_DEMO
+	gpio_bit_write(_pins[LED1_Enable_pin].group, _pins[LED1_Enable_pin].pin, (enable)?SET:RESET);
+#endif
+}
+
+void gpio_led2_enable(bool enable) {
+#ifdef GD32_FOC_DEMO
+	//gpio_bit_write(_pins[LED2_Enable_pin].group, _pins[LED2_Enable_pin].pin, (enable)?SET:RESET);
+#endif
+}
+
+void gpio_led3_enable(bool enable) {
+#ifdef GD32_FOC_DEMO
+	gpio_bit_write(_pins[LED3_Enable_pin].group, _pins[LED3_Enable_pin].pin, (enable)?SET:RESET);
+#endif
+}
+
+int gpio_startkey_value(void) {
+#ifdef GD32_FOC_DEMO
+	return gpio_input_bit_get(_pins[KEY_Start_pin].group, _pins[KEY_Start_pin].pin)==SET?1:0;
+#else
+	return 1;
+#endif
+}
+
+int gpio_stopkey_value(void) {
+#ifdef GD32_FOC_DEMO
+	return gpio_input_bit_get(_pins[KEY_Stop_pin].group, _pins[KEY_Stop_pin].pin)==SET?1:0;
+#else
+	return 1;
+#endif
+}
+
+int gpio_funckey_value(void) {
+	return 0;
+}
+
+

+ 43 - 0
Applications/bsp/gd32/gpio.h

@@ -0,0 +1,43 @@
+
+
+#ifndef _GPIO_PIN_H__
+#define _GPIO_PIN_H__
+
+#include "bsp.h"
+#include "os/os_types.h"
+typedef struct {
+	uint32_t group;
+	uint32_t pin;
+	uint32_t mode;
+	uint32_t speed;
+	int init_value; //-1 input, 0 L, 1 H
+}gpio_pin_config_t;
+
+#define GPIOA_VALUE ((u16)GPIO_ISTAT(GPIOA))
+#define GPIOB_VALUE ((u16)GPIO_ISTAT(GPIOB))
+#define GPIOC_VALUE ((u16)GPIO_ISTAT(GPIOC))
+#define GPIOD_VALUE ((u16)GPIO_ISTAT(GPIOD))
+#define GPIOE_VALUE ((u16)GPIO_ISTAT(GPIOE))
+
+void gpio_pin_init(void);
+bool gpio_get_brake(void) ;
+void gpio_ir2136_enable(bool enable);
+void gpio_led1_enable(bool enable);
+void gpio_led2_enable(bool enable);
+void gpio_led3_enable(bool enable);
+int gpio_startkey_value(void);
+int gpio_stopkey_value(void);
+int gpio_funckey_value(void);
+void gpio_beep(u32 ms);
+void gpio_phase_u_detect(bool enable);
+void mc_brk_gpio_init(void);
+bool mc_get_gpio_brake(void);
+void mc_gpio_init(void);
+bool gpio_motor_locked(void);
+bool mc_get_gpio_brake1(void);
+void gpio_led_enable(bool enable);
+void gpio_brk_light_enable(bool enable);
+u8  gpio_board_id(void);
+bool gpio_is_repear_mode(void);
+
+#endif /* _GPIO_PIN_H__ */

+ 2 - 1
Applications/bsp/i2c.c → Applications/bsp/gd32/i2c.c

@@ -1,6 +1,7 @@
-#include "bsp.h"
+#include "bsp_driver.h"
 #include "i2c.h"
 #include "libs/utils.h"
+
 static int _shark_i2c_rw_bytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *buffer, int length, int write);
 
 #define iic_device(id) ((id == 0)?I2C0:I2C1)

+ 0 - 0
Applications/bsp/i2c.h → Applications/bsp/gd32/i2c.h


+ 65 - 28
Applications/bsp/mc_irqs.c → Applications/bsp/gd32/mc_irqs.c

@@ -73,49 +73,74 @@ void DebugMon_Handler(void)
 {
 }
 
-extern void mc_phase_current_irq(void);
-extern void mc_brake_irq(void);
-extern void hall_sensor_handler(void);
-extern void foc_normal_task(void);
-extern void foc_brake_handler(bool brake);
-extern void foc_pwm_up_handler(void);
 
+__weak void MC_Brake_IRQHandler(void) {
+
+}
+__weak void MC_Protect_IRQHandler(void) {
+
+}
+__weak void TIMER_UP_IRQHandler(void) {
+
+}
+
+__weak void ADC_IRQHandler(void) {
+
+}
+
+__weak void HALL_IRQHandler(void) {
+
+}
+
+__weak void ABI_I_IRQHandler(void) {
+
+}
+
+__weak void Fan_IRQHandler(int idx) {
+
+}
 
 void ADC0_1_IRQHandler(void)
 {
-	if (adc_eoic_interrupt()) {//phase I samples
-		mc_phase_current_irq();
-    	/* clear the ADC flag */
-		adc_clear_eoic_flags();
-	}	
+	ADC_IRQHandler();
+	adc_clear_irq_flags();
 }
 
-void TIMER0_UP_IRQHandler(void) {
+void PWM_UP_IRQHandler(void) {
 	if (timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_UP)) {
 		timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_UP);
-		foc_pwm_up_handler();
+		TIMER_UP_IRQHandler();
 	}
 }
 
-void TIMER0_BRK_IRQHandler(void) {
+void PWM_BRK_IRQHandler(void) {
 	if (timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_BRK)) {
 		timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_BRK);
-		foc_brake_handler(true);
+		MC_Protect_IRQHandler();
 	}
 }
 
-void TIMER5_IRQHandler(void) {
-	if (timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_UP)) {
-		timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_UP);
-		foc_normal_task();
-	}
+void EXTI0_IRQHandler(void)
+{
+	if(RESET != exti_interrupt_flag_get(EXTI_0)){
+		exti_interrupt_flag_clear(EXTI_0);
+#if (ENC_I_EXTI == EXTI_0)
+		ABI_I_IRQHandler();
+#elif defined (USE_ENCODER_HALL)
+		HALL_IRQHandler();
+#else
+	#error "Postion sensor ERROR"
+#endif
+	}	
 }
 
-
 void EXTI2_IRQHandler(void)
 {
 	if(RESET != exti_interrupt_flag_get(EXTI_2)){
 		exti_interrupt_flag_clear(EXTI_2);
+#if (GPIO_BRAKE1_EXTI == EXTI_2)
+		MC_Brake_IRQHandler();
+#endif
 	}	
 }
 
@@ -124,34 +149,38 @@ void EXTI3_IRQHandler(void)
 {
 	if(RESET != exti_interrupt_flag_get(EXTI_3)){
 		exti_interrupt_flag_clear(EXTI_3);
-	}	
+#if (GPIO_BRAKE_EXTI == EXTI_3)
+		MC_Brake_IRQHandler();
+#endif
+	}
 }
 
 void EXTI4_IRQHandler(void)
 {
 	if(RESET != exti_interrupt_flag_get(EXTI_4)){
 		exti_interrupt_flag_clear(EXTI_4);
-		mc_brake_irq();
+		//MC_Brake_IRQHandler();
 	}	
 }
 
-
 void EXTI5_9_IRQHandler(void){
 	if(RESET != exti_interrupt_flag_get(EXTI_5)){
 		exti_interrupt_flag_clear(EXTI_5);
-		mc_brake_irq();
 	}
 	if(RESET != exti_interrupt_flag_get(EXTI_6)){
 		exti_interrupt_flag_clear(EXTI_6);
-		hall_sensor_handler();
+#if (ENC_I_EXTI == EXTI_6)
+		ABI_I_IRQHandler();
+#endif
 	}	
 	if(RESET != exti_interrupt_flag_get(EXTI_7)){
 		exti_interrupt_flag_clear(EXTI_7);
-		hall_sensor_handler();
 	}
 	if(RESET != exti_interrupt_flag_get(EXTI_8)){
 		exti_interrupt_flag_clear(EXTI_8);
-		hall_sensor_handler();
+#if (ENC_I_EXTI == EXTI_8)
+		ABI_I_IRQHandler();
+#endif
 	}
 	if(RESET != exti_interrupt_flag_get(EXTI_9)){
 		exti_interrupt_flag_clear(EXTI_9);
@@ -161,9 +190,17 @@ void EXTI5_9_IRQHandler(void){
 void EXTI10_15_IRQHandler(void){
 	if(RESET != exti_interrupt_flag_get(EXTI_10)){
 		exti_interrupt_flag_clear(EXTI_10);
+#if (GPIO_FAN1_EXTI==EXTI_10)
+		Fan_IRQHandler(0);
+#endif
 	}
 	if(RESET != exti_interrupt_flag_get(EXTI_11)){
 		exti_interrupt_flag_clear(EXTI_11);
+#if (GPIO_FAN1_EXTI==EXTI_11)
+		Fan_IRQHandler(0);
+#elif (GPIO_FAN2_EXTI==EXTI_11)
+		Fan_IRQHandler(1);
+#endif
 	}	
 	if(RESET != exti_interrupt_flag_get(EXTI_12)){
 		exti_interrupt_flag_clear(EXTI_12);

+ 310 - 0
Applications/bsp/gd32/pwm.c

@@ -0,0 +1,310 @@
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+/*
+以下主要是在某一相电路无法采集的时候,需要对这相的pwm挖坑处理
+timer 分配:
+timer0 -> ch0-2 互补pwm
+        ch4 event, update event 触发DMA(ch3,4)实现CCR的自更新
+timer1 -> 触发ADC采样,GD32不支持多channel 或方式触发输出,通过timer1的 ch0 compara 配置 TRGO触发ADC,但是需要在一个PWM周期内触发2次(单电阻)
+timer0 master --> timer1 slave/master 确保timer0,1同步开始,同频同相位
+
+DMA 分配:
+DMA0 ch4 -> timer0 update event
+    ch3 -> timer0 chan3 CC event
+
+    ch1 -> timer1 update event,需要更新CCR
+*/
+
+static void _init_pwm_timer(bool);
+static void _pwm_gpio_config(void);
+#ifndef PWM_BRAKE_GROUP
+static void _gpio_brakein_irq_enable(void);
+#endif
+u16 timer_update_buffer[6] = {0};
+
+static rcu_periph_enum _rcu_clk(u32 timer) {
+    if (timer == TIMER0) {
+        return RCU_TIMER0;
+    }
+    if (timer == TIMER1) {
+        return RCU_TIMER1;
+    }
+    if (timer == TIMER2) {
+        return RCU_TIMER2;
+    }
+    return RCU_TIMER2;      
+}
+
+void pwm_3phase_init(void){
+	_pwm_gpio_config();
+    _init_pwm_timer(true);
+}
+
+void pwm_3phase_sides(bool pwm, u8 mask) {
+	timer_deinit(MOS_PWM_TIMER);
+	if (pwm) {
+		_pwm_gpio_config();
+		_init_pwm_timer(false);
+		return;
+	}
+	rcu_periph_clock_enable(_rcu_clk(MOS_PWM_TIMER));
+    gpio_init(PWM_U_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_U_P_PIN);
+    gpio_init(PWM_V_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_V_P_PIN);
+    gpio_init(PWM_W_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_W_P_PIN);
+
+    gpio_init(PWM_U_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_U_N_PIN);
+    gpio_init(PWM_V_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_V_N_PIN);
+    gpio_init(PWM_W_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_W_N_PIN);
+
+	sys_debug("pwm_3phase_sides\n");
+	gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, RESET);
+	gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, RESET);
+	gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, RESET);
+	gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, RESET);
+	gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, RESET);
+	gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, RESET);
+	delay_us(1);
+	
+	if (mask & 0x01) {
+		gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, SET);
+		gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, RESET);
+	}else {
+		gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, RESET);
+		gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, SET);
+	}
+	if (mask & 0x02) {
+		gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, SET);
+		gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, RESET);
+	}else {
+		gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, RESET);
+		gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, SET);
+	}
+	if (mask & 0x04) {
+		gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, SET);
+		gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, RESET);
+	}else {
+		gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, RESET);
+		gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, SET);
+	}
+}
+
+static void _pwm_gpio_config(void)
+{
+    rcu_periph_clock_enable(PWM_U_P_RCU);
+    rcu_periph_clock_enable(PWM_V_P_RCU);
+	rcu_periph_clock_enable(PWM_W_P_RCU);
+    rcu_periph_clock_enable(PWM_U_N_RCU);
+    rcu_periph_clock_enable(PWM_V_N_RCU);
+	rcu_periph_clock_enable(PWM_W_N_RCU);	
+    rcu_periph_clock_enable(RCU_AF);
+
+    /*configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/
+    gpio_init(PWM_U_P_GROUP,PWM_U_P_MODE,GPIO_OSPEED_50MHZ,PWM_U_P_PIN);
+    gpio_init(PWM_V_P_GROUP,PWM_V_P_MODE,GPIO_OSPEED_50MHZ,PWM_V_P_PIN);
+    gpio_init(PWM_W_P_GROUP,PWM_W_P_MODE,GPIO_OSPEED_50MHZ,PWM_W_P_PIN);
+
+    /*configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/
+    gpio_init(PWM_U_N_GROUP,PWM_U_N_MODE,GPIO_OSPEED_50MHZ,PWM_U_N_PIN);
+    gpio_init(PWM_V_N_GROUP,PWM_V_N_MODE,GPIO_OSPEED_50MHZ,PWM_V_N_PIN);
+    gpio_init(PWM_W_N_GROUP,PWM_W_N_MODE,GPIO_OSPEED_50MHZ,PWM_W_N_PIN);
+
+	/*configure BRAKE IN*/
+#ifdef PWM_BRAKE_GROUP
+    /* TIMER0 BKIN */
+	rcu_periph_clock_enable(PWM_BRAKE_RCU);
+    gpio_init(PWM_BRAKE_GROUP, PWM_BRAKE_MODE, GPIO_OSPEED_50MHZ, PWM_BRAKE_PIN);
+#endif
+}
+
+static u8 _dead_time(u16 t) {
+	if (t < 128) {
+		return (u8 )t;
+	}else if (t <= (64 + 63) * 2) { //11 1111
+		return ((((u8)2<<6) + (t-64)/2));
+	}else if (t <= (32 + 31) * 8) {
+		return (((u8)3 << 6) + (t - 32)/8);
+	}else {
+		if ((t-32)/16 > 63) {
+			return 0xFF;
+		}
+		return (((u8)7<<3) + (t - 32)/16);
+	}
+}
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+#define PWM_CNT_REPEAT 0
+#else
+#define PWM_CNT_REPEAT 1
+#endif
+static void _init_pwm_timer(bool enable_brk) {
+	timer_oc_parameter_struct timer_ocintpara;
+	timer_parameter_struct timer_initpara;
+	
+	u32 timer = MOS_PWM_TIMER;
+	u32 half_period = FOC_PWM_Half_Period;
+	rcu_periph_clock_enable(_rcu_clk(timer));
+
+	timer_deinit(timer);
+
+    /* TIMER0 configuration */
+	memset(&timer_initpara, 0, sizeof(timer_initpara));
+	memset(&timer_ocintpara, 0, sizeof(timer_ocintpara));
+    timer_initpara.prescaler        = 0;
+    timer_initpara.alignedmode      = TIMER_COUNTER_CENTER_UP;
+	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period          = half_period;
+    timer_initpara.clockdivision    = TIMER_CKDIV_DIV1;
+    timer_initpara.repetitioncounter = PWM_CNT_REPEAT;
+    timer_init(timer,&timer_initpara);
+    /* auto-reload preload enable */
+    timer_auto_reload_shadow_enable(timer);
+
+    /* CH1,CH2 and CH3 configuration in PWM mode */
+    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
+    timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
+    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
+    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
+    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+
+    timer_channel_output_config(timer,TIMER_CH_0,&timer_ocintpara);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_0,half_period/2);
+    timer_channel_output_mode_config(timer,TIMER_CH_0,PWM_MODE);
+    timer_channel_output_shadow_config(timer,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
+
+    timer_channel_output_config(timer,TIMER_CH_1,&timer_ocintpara);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_1,half_period/2);
+    timer_channel_output_mode_config(timer,TIMER_CH_1,PWM_MODE);
+    timer_channel_output_shadow_config(timer,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);
+
+    timer_channel_output_config(timer,TIMER_CH_2,&timer_ocintpara);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_2,half_period/2);
+    timer_channel_output_mode_config(timer,TIMER_CH_2,PWM_MODE);
+    timer_channel_output_shadow_config(timer,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
+    
+    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
+    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
+    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
+	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
+    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+
+    /* chan3 trigger adc O3CPRE is alwary active high, adc trigger is rising */
+    timer_channel_output_config(timer,TIMER_CH_3,&timer_ocintpara);
+    timer_channel_output_pulse_value_config(timer,TIMER_CH_3,half_period-5);
+    timer_channel_output_mode_config(timer,TIMER_CH_3,TIMER_OC_MODE_PWM1);
+    timer_channel_output_shadow_config(timer,TIMER_CH_3,TIMER_OC_SHADOW_ENABLE);
+
+#ifdef PWM_BRAKE_GROUP
+	timer_break_parameter_struct timer_breakpara;
+    timer_breakpara.runoffstate        = TIMER_ROS_STATE_DISABLE;
+    timer_breakpara.ideloffstate       = TIMER_ROS_STATE_DISABLE;
+    timer_breakpara.protectmode        = TIMER_CCHP_PROT_OFF; 
+    timer_breakpara.deadtime           = _dead_time(NS_2_TCLK(PWM_DEAD_TIME_NS));
+    timer_breakpara.breakstate         = enable_brk?TIMER_BREAK_ENABLE:TIMER_BREAK_DISABLE;
+    timer_breakpara.breakpolarity      = TIMER_BREAK_POLARITY_LOW;
+    timer_breakpara.outputautostate    = TIMER_OUTAUTO_DISABLE;
+    timer_break_config(timer,&timer_breakpara);
+	timer_interrupt_enable(timer, TIMER_INT_BRK);
+	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_BRK);
+	nvic_irq_enable(PWM_BRK_IRQ, EBREAK_IRQ_PRIORITY, 0);		
+#else
+	_gpio_brakein_irq_enable();
+#endif
+
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_ENABLE);
+	timer_master_output_trigger_source_select(timer,TIMER_TRI_OUT_SRC_UPDATE);
+#else
+	timer_master_slave_mode_config(timer,TIMER_MASTER_SLAVE_MODE_DISABLE);
+#endif
+	pwm_enable_channel();
+
+	timer_interrupt_disable(timer, TIMER_INT_UP);
+	timer_interrupt_flag_clear(timer, TIMER_INT_FLAG_UP);
+	nvic_irq_enable(PWM_UP_IRQ, TIMER_UP_IRQ_PRIORITY, 0);
+    timer_enable(timer);
+
+#ifdef GD32_FOC_DEMO
+	/* IR2136S enable */
+    gpio_ir2136_enable(true);
+#endif
+
+}
+
+
+
+#ifndef PWM_BRAKE_GROUP
+static void _gpio_brakein_irq_enable(void){
+#ifndef GD32_FOC_DEMO
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_4);
+	exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(EXTI4_IRQn, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(EXTI_4);
+	exti_interrupt_enable(EXTI_4);
+
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_5);
+	exti_init(EXTI_5, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(EXTI5_9_IRQn, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(EXTI_5);
+	exti_interrupt_enable(EXTI_5);
+#endif	
+}
+#endif
+
+void pwm_start(void){
+	pwm_update_duty(FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	/* wait for a new PWM period to flush last HF task */
+	timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP);
+
+	timer_event_software_generate(MOS_PWM_TIMER, TIMER_EVENT_SRC_UPG);
+	while ( timer_flag_get(MOS_PWM_TIMER, TIMER_FLAG_UP) == RESET ){}
+	/* Clear Update Flag */
+	timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP);
+
+	timer_primary_output_config(MOS_PWM_TIMER,ENABLE);
+}
+
+void pwm_stop(void){
+	timer_primary_output_config(MOS_PWM_TIMER,DISABLE);
+
+	timer_interrupt_disable(MOS_PWM_TIMER, TIMER_INT_UP);
+	/* wait for a new PWM period to flush last HF task */
+	timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP);
+	while ( timer_flag_get(MOS_PWM_TIMER, TIMER_FLAG_UP) == RESET ){}
+	/* Clear Update Flag */
+	timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP);
+}
+
+void pwm_enable_output(bool enable) {
+	if (enable) {
+		timer_primary_output_config(MOS_PWM_TIMER,ENABLE);
+	}else {
+		timer_primary_output_config(MOS_PWM_TIMER,DISABLE);
+	}
+}
+
+/*open low side of the mosfet*/
+void pwm_turn_on_low_side(void)
+{
+	pwm_update_duty(0, 0, 0);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	timer_flag_clear(MOS_PWM_TIMER,TIMER_FLAG_UP);
+	timer_event_software_generate(MOS_PWM_TIMER, TIMER_EVENT_SRC_UPG);
+  	while (timer_flag_get(MOS_PWM_TIMER,TIMER_FLAG_UP) == RESET );
+  	/* Main PWM Output Enable */
+  	timer_primary_output_config(MOS_PWM_TIMER, ENABLE);
+}
+
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector) {
+	if (samp1 < FOC_PWM_Half_Period) {
+		TIMER_CH3CV(MOS_PWM_TIMER) = samp1;
+		pwm_change_t3_mode(TIMER_OC_MODE_PWM1);
+	}else {
+		TIMER_CH3CV(MOS_PWM_TIMER) = samp2;
+		pwm_change_t3_mode(TIMER_OC_MODE_PWM0);
+	}
+	adc_current_sample_config(sector);
+}

+ 101 - 0
Applications/bsp/gd32/pwm.h

@@ -0,0 +1,101 @@
+#ifndef _PWM_H__
+#define _PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define TIMxCCER_MASK_CH012        ((uint16_t)  (TIMER_CHCTL2_CH0EN|TIMER_CHCTL2_CH0NEN|\
+                                                 TIMER_CHCTL2_CH1EN|TIMER_CHCTL2_CH1NEN|\
+                                                 TIMER_CHCTL2_CH2EN|TIMER_CHCTL2_CH2NEN))
+
+#define pwm_enable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) |= TIMxCCER_MASK_CH012;}
+#define pwm_disable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) &= ~TIMxCCER_MASK_CH012;}
+
+
+#define ch0_update_duty(duty) 	TIMER_CH0CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define ch1_update_duty(duty) 	TIMER_CH1CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define ch2_update_duty(duty) 	TIMER_CH2CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define update_adc_trigger(time) TIMER_CH3CV(MOS_PWM_TIMER) = (uint32_t)time
+
+#ifdef CONFIG_PWM_UV_SWAP
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyC);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyA);\
+	}while(0)
+
+#else
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyA);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyC);\
+	}while(0)
+
+#endif
+
+#define pwm_update_2smaples(samp1, sampl2) \
+	do { \
+		TIMER_CH3CV(MOS_PWM_TIMER) = (uint32_t)samp1; \
+	}while(0)
+
+
+
+#define enable_pwm_timer_dma() TIMER_DMAINTEN(MOS_PWM_TIMER) |= (uint32_t) TIMER_DMA_CH3D
+#define disable_pwm_timer_dma() TIMER_DMAINTEN(MOS_PWM_TIMER) &= ~((uint32_t) TIMER_DMA_CH3D)
+
+
+#define pwm_clear_updata() \
+	timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP);
+
+#define pwm_wait_and_clear_updata() \
+	do { \
+		while ( timer_flag_get(MOS_PWM_TIMER, TIMER_FLAG_UP) == RESET ); \
+		timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP); \
+	}while(0)
+
+#define pwm_change_t3_mode(m) \
+	do { \
+		if (((TIMER_CHCTL1(MOS_PWM_TIMER) >> 12) & 0x7) != m) { \
+			TIMER_CHCTL1(MOS_PWM_TIMER) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); \
+        	TIMER_CHCTL1(MOS_PWM_TIMER) |= (uint32_t)((uint32_t)(m) << 8U); \
+		} \
+	}while(0)
+
+#define pwm_brake_enable(n) \
+	do { \
+		if (n) { \
+			nvic_irq_enable(PWM_BRK_IRQ, EBREAK_IRQ_PRIORITY, 0); \
+		}else { \
+			nvic_irq_disable(PWM_BRK_IRQ); \
+		} \
+	}while(0)
+
+#define pwm_up_enable(n) \
+	do { \
+		if (n) { \
+			timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP); \
+			timer_interrupt_enable(MOS_PWM_TIMER, TIMER_INT_UP); \
+		}else { \
+			timer_flag_clear(MOS_PWM_TIMER, TIMER_FLAG_UP); \
+			timer_interrupt_disable(MOS_PWM_TIMER, TIMER_INT_UP); \
+		} \
+	}while(0)
+
+#define get_deadtime() (TIMER_CCHP(MOS_PWM_TIMER) & 0xFF)
+
+#ifdef CONFIG_SENSORLESS_TOW_SAMPLES
+#define PWM_Direction_Down() ((TIMER_CTL0(MOS_PWM_TIMER) & TIMER_CTL0_DIR) == 0)
+#else
+#define PWM_Direction_Down() true
+#endif
+void pwm_3phase_init(void);
+void pwm_3phase_sides(bool pwm, u8 mask);
+void pwm_start(void);
+void pwm_stop(void);
+void pwm_turn_on_low_side(void);
+void pwm_enable_output(bool enable);
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector);
+
+#endif  /*_PWM_H__*/
+

+ 35 - 0
Applications/bsp/gd32/sched_timer.c

@@ -0,0 +1,35 @@
+#include "bsp/bsp_driver.h"
+
+void sched_timer_enable(u32 us) {
+    timer_parameter_struct timer_initpara;
+
+    rcu_periph_clock_enable(SCHED_TIMER_RCU);
+
+    timer_deinit(SCHED_TIMER);
+    /* initialize TIMER init parameter struct */
+    timer_struct_para_init(&timer_initpara);
+
+    timer_initpara.prescaler         = TIM_CLOCK_MHz-1;
+    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
+    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period            = us-1;//400;
+    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+    timer_init(SCHED_TIMER, &timer_initpara);
+	timer_counter_value_config(SCHED_TIMER,0);
+
+	timer_interrupt_flag_clear(SCHED_TIMER, TIMER_INT_UP);
+	
+    timer_interrupt_enable(SCHED_TIMER, TIMER_INT_UP);
+
+	nvic_irq_enable(SCHED_TIMER_IRQ, SCHED_TIMER_IRQ_PRIORITY, 0);
+
+	timer_enable(SCHED_TIMER);
+}
+__weak void Sched_MC_mTask(void) {}
+void SCHED_TIMER_IRQHandler(void) {
+	if(SET == timer_interrupt_flag_get(SCHED_TIMER, TIMER_INT_UP)) {
+		timer_interrupt_flag_clear(SCHED_TIMER, TIMER_INT_UP);
+		Sched_MC_mTask();
+	}
+}

+ 8 - 0
Applications/bsp/gd32/sched_timer.h

@@ -0,0 +1,8 @@
+#ifndef _Sched_Timer_H__
+#define _Sched_Timer_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+void sched_timer_enable(u32 us);
+
+#endif /* _Sched_Timer_H__ */

+ 74 - 85
Applications/bsp/uart.c → Applications/bsp/gd32/uart.c

@@ -1,40 +1,53 @@
 #include "uart.h"
-#include "os/co_task.h"
+#include "os/os_task.h"
 #include "libs/crc16.h"
 #include "libs/logger.h"
 #include "libs/utils.h"
 
-#define SHARK_UART_BAUDRATE				38400
-
-#define SHARK_UART0_com					UART3
+#define SHARK_UART_BAUDRATE				230400
+
+#ifdef DEBUG_PORT_UART1
+#define SHARK_UART0_com					USART1
+#define SHARK_UART0_tx_port				GPIOA
+#define SHARK_UART0_tx_pin				GPIO_PIN_2
+#define SHARK_UART0_rx_port				GPIOA
+#define SHARK_UART0_rx_pin				GPIO_PIN_3
+#define SHARK_UART0_irq					USART1_IRQn
+#define SHARK_UART0_clk					RCU_USART1
+#define SHARK_UART0_tx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_rx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_tx_dma				DMA0
+#define SHARK_UART0_tx_dma_ch			DMA_CH6
+#define SHARK_UART0_tx_dma_clk			RCU_DMA0
+#define SHARK_UART0_rx_dma				DMA0
+#define SHARK_UART0_rx_dma_ch			DMA_CH5
+#define SHARK_UART0_rx_dma_clk			RCU_DMA0
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel6_IRQn
+#define UART_DMA_IRQHandler             DMA0_Channel6_IRQHandler
+#else
+#define SHARK_UART0_com					USART2
 #define SHARK_UART0_tx_port				GPIOB
 #define SHARK_UART0_tx_pin				GPIO_PIN_10
 #define SHARK_UART0_rx_port				GPIOB
 #define SHARK_UART0_rx_pin				GPIO_PIN_11
-#define SHARK_UART0_irq					UART3_IRQn
-#define SHARK_UART0_clk					RCU_UART3
+#define SHARK_UART0_irq					USART2_IRQn
+#define SHARK_UART0_clk					RCU_USART2
 #define SHARK_UART0_tx_gpio_clk			RCU_GPIOB
 #define SHARK_UART0_rx_gpio_clk			RCU_GPIOB
-#define SHARK_UART0_tx_dma				DMA1
-#define SHARK_UART0_tx_dma_ch			DMA_CH4
-#define SHARK_UART0_tx_dma_clk			RCU_DMA1
-#define SHARK_UART0_rx_dma				DMA1
+#define SHARK_UART0_tx_dma				DMA0
+#define SHARK_UART0_tx_dma_ch			DMA_CH1
+#define SHARK_UART0_tx_dma_clk			RCU_DMA0
+#define SHARK_UART0_rx_dma				DMA0
 #define SHARK_UART0_rx_dma_ch			DMA_CH2
-#define SHARK_UART0_rx_dma_clk			RCU_DMA1
-
+#define SHARK_UART0_rx_dma_clk			RCU_DMA0
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel1_IRQn
+#define UART_DMA_IRQHandler             DMA0_Channel1_IRQHandler
+#endif
 
 // ================================================================================
 #define ENABLE_RX_DMA 1
-#define UART_NUM 1
 static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
-#if UART_NUM==2
-static u8 shark_uart1_tx_cache[SHARK_UART_TX_MEM_SIZE];
-#endif
-
 static u8 shark_uart0_rx_cache[SHARK_UART_RX_MEM_SIZE];
-#if UART_NUM==2
-static u8 shark_uart1_rx_cache[SHARK_UART_RX_MEM_SIZE];
-#endif
 
 static shark_uart_t _shark_uart[1];
 ///static bool uart_no_data = false;
@@ -46,7 +59,7 @@ static shark_uart_t _shark_uart[1];
 
 // ================================================================================
 static uart_enum_t _uart_index(uint32_t com){
-	return com == SHARK_UART0_com?SHARK_UART0:SHARK_UART1;
+	return SHARK_UART0;
 }
 static bool shark_uart_on_rx_frame(shark_uart_t *uart)
 {
@@ -62,10 +75,10 @@ static bool shark_uart_on_rx_frame(shark_uart_t *uart)
 
 static void shark_uart_rx(shark_uart_t *uart){
 	while(1) {
-		u8 data;
+		u8 data = 0;
 		update_dma_w_pos(uart);
 		if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
-			break;
+			return;
 		}
 		switch(data){
 			case CH_START:
@@ -124,7 +137,7 @@ static void shark_uart_dma_tx(shark_uart_t *uart)
 		if (SET != dma_flag_get(SHARK_UART0_tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF)) {
 			return;
 		}
-
+		dma_flag_clear(SHARK_UART0_tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF);
 		byte_queue_skip(&uart->tx_queue, uart->tx_length);
 		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value & (~DMA_CHXCTL_CHEN);
 	}
@@ -133,8 +146,6 @@ static void shark_uart_dma_tx(shark_uart_t *uart)
 	if (uart->tx_length > 0) {
 		DMA_CHCNT(SHARK_UART0_tx_dma, uart->tx_dma_ch) = uart->tx_length;
 		DMA_CHMADDR(SHARK_UART0_tx_dma, uart->tx_dma_ch) = (u32) byte_queue_head(&uart->tx_queue);
-
-		dma_flag_clear(SHARK_UART0_tx_dma, uart->tx_dma_ch, DMA_FLAG_FTF);
 		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value | DMA_CHXCTL_CHEN;
 	}
 }
@@ -159,13 +170,23 @@ static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
 
 static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
 {
-	shark_uart_write(uart, &value, 1);
+	byte_queue_write(&uart->tx_queue, &value, 1);
 }
 
 
+void shark_uart_write_log(char *buffer){
+	int len = strlen(buffer);
+	shark_uart_t *uart = (_shark_uart+SHARK_UART0);
+	if (len > byte_queue_get_free(&uart->tx_queue)){
+		return;
+	}
+	byte_queue_write(&uart->tx_queue, (const u8 *)buffer, len);
+	shark_uart_dma_tx(uart);
+}
+
 static void shark_uart_tx_dma_init(shark_uart_t *uart){
 	dma_parameter_struct dma_init_struct;
-	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART0_tx_dma_clk);
+	rcu_periph_clock_enable(SHARK_UART0_tx_dma_clk);
 	dma_deinit(SHARK_UART0_tx_dma, uart->tx_dma_ch);
 	dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
 	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
@@ -178,20 +199,12 @@ static void shark_uart_tx_dma_init(shark_uart_t *uart){
 	dma_circulation_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
 	dma_memory_to_memory_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
 	usart_dma_transmit_config(uart->uart_com, USART_DENT_ENABLE);
-#if 0
-	if (uart->tx_dma_ch == DMA_CH1) {
-		nvic_irq_enable(DMA_Channel1_2_IRQn ,4, 0);
-	}else {
-		nvic_irq_enable(DMA_Channel3_4_IRQn ,4, 0);
-	}
-	dma_interrupt_enable(uart->tx_dma_ch, DMA_INT_FTF);
-#endif
 }
 
 #if ENABLE_RX_DMA==1
 static void shark_uart_rx_dma_init(shark_uart_t *uart){
 	dma_parameter_struct dma_init_struct;
-	rcu_periph_clock_enable(_uart_index(uart->uart_com)== SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART0_rx_dma_clk);
+	rcu_periph_clock_enable(SHARK_UART0_rx_dma_clk);
 	dma_deinit(SHARK_UART0_rx_dma, uart->rx_dma_ch);
 	dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
 	dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
@@ -213,7 +226,8 @@ static void shark_uart_pin_init(shark_uart_t *uart){
 	rcu_periph_clock_enable(SHARK_UART0_clk);
 	rcu_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
 	rcu_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
-	gpio_init(SHARK_UART0_tx_port, GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
+	rcu_periph_clock_enable(RCU_AF);
+	gpio_init(SHARK_UART0_tx_port, GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
 	gpio_init(SHARK_UART0_rx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
 }
 
@@ -244,16 +258,14 @@ static void shark_uart_device_init(shark_uart_t *uart){
 #endif
 }
 
-static void shark_uart_task(void *args)
+static u32 shark_uart_task(void *args)
 {
 	shark_uart_t *uart = (shark_uart_t *)args;
-	while(1) {
-		if(uart->uart_com != 0) {
-			shark_uart_rx(uart);
-			shark_uart_dma_tx(uart);
-		}
-		co_task_yield();
+	if(uart->uart_com != 0) {
+		shark_uart_rx(uart);
+		shark_uart_dma_tx(uart);
 	}
+	return 0;
 }
 
 
@@ -263,15 +275,7 @@ void shark_uart_flush(void){
 		while(!byte_queue_empty(&uart->tx_queue)) {
 			shark_uart_dma_tx(uart);
 		}
-	}
-#if UART_NUM==2	
-	uart = _shark_uart + SHARK_UART1;
-	if (uart->uart_com != 0) {
-		while(!byte_queue_empty(&uart->tx_queue)) {
-			shark_uart_dma_tx(uart);
-		}
-	}
-#endif	
+	}	
 }
 
 
@@ -294,19 +298,11 @@ void DMA_Channel3_4_IRQHandler(void){
 #endif
 
 static u8 *tx_cache_addr(uart_enum_t uart_no){
-#if UART_NUM==2
-	return (uart_no == SHARK_UART0)?shark_uart0_tx_cache:shark_uart1_tx_cache;
-#else
 	return shark_uart0_tx_cache;
-#endif
 }
 
 static u8 *rx_cache_addr(uart_enum_t uart_no){
-#if UART_NUM==2
-	return (uart_no == SHARK_UART0)?shark_uart0_rx_cache:shark_uart1_rx_cache;
-#else
 	return shark_uart0_rx_cache;
-#endif
 }
 
 
@@ -315,22 +311,16 @@ void shark_uart_deinit(uart_enum_t uart_no){
 	if (uart->uart_com != 0) {
 		usart_disable(uart->uart_com);
 		usart_deinit(uart->uart_com);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_clk:SHARK_UART0_clk);
+		rcu_periph_clock_disable(SHARK_UART0_clk);
 		dma_channel_disable(SHARK_UART0_rx_dma, uart->rx_dma_ch);
 		dma_channel_disable(SHARK_UART0_tx_dma, uart->tx_dma_ch);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_tx_dma_clk:SHARK_UART0_tx_dma_clk);
-		rcu_periph_clock_disable(uart_no == SHARK_UART0?SHARK_UART0_rx_dma_clk:SHARK_UART0_rx_dma_clk);
+		rcu_periph_clock_disable(SHARK_UART0_tx_dma_clk);
+		rcu_periph_clock_disable(SHARK_UART0_rx_dma_clk);
 		shark_uart_pin_deinit(uart);
 	}
-	if (uart_no == SHARK_UART0) {
 #if ENABLE_RX_DMA==0
-		nvic_irq_disable(USART0_IRQn);
+	nvic_irq_disable(SHARK_UART0_irq);	
 #endif
-	}else {
-#if ENABLE_RX_DMA==0
-		nvic_irq_disable(USART1_IRQn);
-#endif
-	}
 }
 
 
@@ -347,13 +337,13 @@ void shark_uart_init(uart_enum_t uart_no)
 	uart->escape = false;
 	uart->rx_length = 0;
 	uart->tx_length = 0;
-	uart->uart_com = (uart_no == SHARK_UART0)?SHARK_UART0_com:SHARK_UART0_com;
+	uart->uart_com = SHARK_UART0_com;
 
 	circle_buffer_init(&uart->rx_queue, rx_cache_addr(uart_no), SHARK_UART_RX_MEM_SIZE);
 	byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
 
-	uart->rx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_rx_dma_ch:SHARK_UART0_rx_dma_ch;
-	uart->tx_dma_ch = (uart_no == SHARK_UART0)?SHARK_UART0_tx_dma_ch:SHARK_UART0_tx_dma_ch;
+	uart->rx_dma_ch = SHARK_UART0_rx_dma_ch;
+	uart->tx_dma_ch = SHARK_UART0_tx_dma_ch;
 
 	shark_uart_pin_init(uart);
 	shark_uart_device_init(uart);
@@ -363,16 +353,10 @@ void shark_uart_init(uart_enum_t uart_no)
 	shark_uart_tx_dma_init(uart);
 	usart_enable(uart->uart_com);
 
-	co_task_create(shark_uart_task, uart, 256);
-	if (uart_no == SHARK_UART0) {
+	shark_task_create(shark_uart_task, uart);
 #if ENABLE_RX_DMA==0
-		nvic_irq_enable(UART3_IRQn, 3, 0);
+	nvic_irq_enable(SHARK_UART0_irq, UART_IRQ_PRIORITY, 0);
 #endif
-	}else {
-#if ENABLE_RX_DMA==0
-		nvic_irq_enable(USART1_IRQn, 3, 0);
-#endif
-	}
 	uart->uart_no_data = false;
 }
 
@@ -386,6 +370,11 @@ void USART3_IRQHandler(void){
 }
 #endif
 
+
+void UART_DMA_IRQHandler(void) {
+	
+}
+
 static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
 {
 	switch (value) {
@@ -440,6 +429,7 @@ void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
 	shark_uart_tx_start(uart);
 	shark_uart_tx_continue(uart, bytes, len);
 	shark_uart_tx_end(uart);
+	shark_uart_dma_tx(uart);
 }
 
 void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
@@ -461,9 +451,8 @@ void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
 	shark_uart_write(_shark_uart + uart_no, buff, size);
 }
 
-#if LOG_UART==1
 int fputc(int c, FILE *fp){
 	shark_uart_write_byte(_shark_uart+SHARK_UART0, (u8)c);
 	return 1;
 }
-#endif
+

+ 2 - 2
Applications/bsp/uart.h → Applications/bsp/gd32/uart.h

@@ -1,6 +1,6 @@
 #pragma once
 #include "bsp/bsp.h"
-#include "os/co_task.h"
+#include "os/os_task.h"
 #include "libs/byte_queue.h"
 #include "libs/circle_buffer.h"
 
@@ -11,7 +11,7 @@
 #define CH_ESC_END						0x06
 #define CH_ESC_ESC						0x07
 
-#define SHARK_UART_TX_MEM_SIZE			512
+#define SHARK_UART_TX_MEM_SIZE			(5 * 1024)
 #define SHARK_UART_RX_MEM_SIZE			512
 #define RX_FRAME_MAX_LEN 260
 #define RX_OLD_FRAME_MAX_LEN 256

+ 0 - 13
Applications/bsp/gpio.c

@@ -1,13 +0,0 @@
-
-#include "bsp/gpio.h"
-
-/*
-* gpio.c
-* all pins used as gpio(in/out/irq) must be init&accessed here
-*/
-
-void gpio_pin_init(void){
-
-}
-
-

+ 0 - 64
Applications/bsp/gpio.h

@@ -1,64 +0,0 @@
-
-
-#ifndef _GPIO_PIN_H__
-#define _GPIO_PIN_H__
-
-#include "bsp.h"
-
-typedef struct {
-	uint32_t group;
-	uint32_t pin;
-	uint32_t mode;
-	uint32_t speed;
-	int init_value; //-1 input, 0 L, 1 H
-}gpio_pin_config_t;
-
-void gpio_pin_init(void);
-void gpio_pin_set_low(int pin);
-void gpio_pin_set_high(int pin);
-void gpio_pin_set_active_high(int pin, int active);
-void gpio_pin_set_active_low(int pin, int active);
-void can_enable_transmit(int enable);
-int can_power_is_enabled(void);
-void can_backup_power_enable(int enable);
-void spi_flash_cs(int cs);
-void power_4v_output_enable(int enable);
-void sync_line_irq_enable(int enable);
-void left_light_enable(int enable);
-void right_light_enable(int enable);
-void day_light_enable(int enable);
-void near_light_enable(int enable);
-void far_light_enable(int enable);
-void far_led_enable(int enable);
-int sys_12v_is_enabled(void);
-int acc_12v_is_enabled(void);
-int charger_working(void);
-void charger_enable(int enable);
-void audio_classK_enable(int enable);
-int phase_detect(void);
-void ble_power_enable(int enable);
-void aux_mcu_power_enable(int enable);
-int slock_is_locked(void);//×øÍ°Ëø×´Ì¬¼ì²â
-void wireless_433_power_enable(int enable);
-int charger_is_enabled(void);
-void sync_allow_vehicle_sleep(int enable);
-void  wheel_detect_irq_enable(int enable);
-void  battery_plug_irq_enable(int enable);
-void ready_key_irq_enable(int enable);
-void ble_wakeup_irq_enable(int enable);
-void gsensor_irq_enable(int enable);
-void wireless_433_irq_enable(int enable);
-int is_ready_key_detect(void);
-void ready_led_enable(int enable);
-int hlock_is_locked(void);
-void slock_out(int enable);
-void slock_in(int enable);
-void sync_allow_vehicle_sleep(int enable);
-void sync_line_pulse_enable(int enable);
-void sync_line_pulse(void);
-void hlock_out(int enable);
-void hlock_in(int enable);
-void mcu_indicat_sleep(int sleep);
-int ble_is_busy(void);
-
-#endif /* _GPIO_PIN_H__ */

+ 0 - 58
Applications/bsp/mc_hall_gpio.c

@@ -1,58 +0,0 @@
-#include "bsp/mc_hall_gpio.h"
-static void _gpio_irq_enable(void);
-
-void mc_hall_init(void){
-	rcu_periph_clock_enable(HALL_GPOI_CLK);
-	gpio_init(HALL_1_GROUP,  GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, HALL_1_PIN);
-	gpio_init(HALL_2_GROUP,  GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, HALL_2_PIN);
-	gpio_init(HALL_3_GROUP,  GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, HALL_3_PIN);
-
-	_gpio_irq_enable();
-}
-
-#if 0
-int get_hall_stat(int samples) {
-	int h1 = 0, h2 = 0, h3 = 0;
-	int tres = (samples + 1) / 2;
-
-	while (samples--) {
-		h1 += READ_HALL1();
-		h2 += READ_HALL2();
-		h3 += READ_HALL3();
-	}
-#if HALL_PLACE==DEGREES_60	
-	return (((h2>tres)^1) << 2) | ((h3 > tres) << 1) | (h2 > tres);
-#else
-	return (h1 > tres) | ((h2 > tres) << 1) | ((h3 > tres) << 2);
-#endif
-}
-#else
-int get_hall_stat(int samples) {
-#if HALL_PLACE==DEGREES_60	
-	return (((READ_HALL2())^1) << 2) | ((READ_HALL3()) << 1) | (READ_HALL1());
-#else
-	return (READ_HALL1()) | ((READ_HALL2()) << 1) | ((READ_HALL3()) << 2);
-#endif
-}
-
-#endif
-static void _gpio_irq_enable(void){
-	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_6);
-	exti_init(EXTI_6, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
-	exti_interrupt_flag_clear(EXTI_6);
-	exti_interrupt_enable(EXTI_6);
-
-	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_7);
-	exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
-	exti_interrupt_flag_clear(EXTI_7);
-	exti_interrupt_enable(EXTI_7);
-
-	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_8);
-	exti_init(EXTI_8, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
-	exti_interrupt_flag_clear(EXTI_8);
-	exti_interrupt_enable(EXTI_8);
-
-	nvic_irq_enable(EXTI5_9_IRQn, HALL_IRQ_PRIORITY, 0U);
-}
-
-

+ 0 - 36
Applications/bsp/mc_hall_gpio.h

@@ -1,36 +0,0 @@
-#ifndef _MC_HALL_H__
-#define _MC_HALL_H__
-#include "bsp/bsp.h"
-
-#define HALL_GPOI_CLK RCU_GPIOB
-#define HALL_1_PIN GPIO_PIN_6
-#define HALL_1_GROUP GPIOB
-#define HALL_2_PIN GPIO_PIN_7
-#define HALL_2_GROUP GPIOB
-#define HALL_3_PIN GPIO_PIN_8
-#define HALL_3_GROUP GPIOB
-
-#define DEGREES_120 0u
-#define DEGREES_60 1u
-
-#define HALL_PLACE DEGREES_120
-
-static int __inline__ hall_bit_get(uint32_t gpio_periph,uint32_t pin)
-{
-    if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
-        return 1; 
-    }else{
-        return 0;
-    }
-}
-
-
-#define READ_HALL1() (hall_bit_get(HALL_1_GROUP, HALL_1_PIN))
-#define READ_HALL2() (hall_bit_get(HALL_2_GROUP, HALL_2_PIN))
-#define READ_HALL3() (hall_bit_get(HALL_3_GROUP, HALL_3_PIN))
-
-void mc_hall_init(void);
-int get_hall_stat(int samples);
-
-#endif /*_MC_HALL_H__ */
-

+ 399 - 0
Applications/bsp/n32/adc.c

@@ -0,0 +1,399 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+#include "math/fast_math.h"
+
+#if (CONFIG_HW_VERSION==3)
+#define ADC01_NUM (8)
+
+#define VBUS_V_BUFF_IDX 0
+#define ACC_V_BUFF_IDX 2
+#define VBUS_I_BUFF_IDX 4
+#define V_VOL_BUFF_IDX 6
+#define THROTTLE_5V_BUFF_IDX 8
+//zero chan             10
+#define VREF_BUFF_IDX   12
+#define VREF5v_BUFF_IDX 14
+
+
+#define MOS_TEMP_BUFF_IDX 1
+#define MOTOR_TEMP_BUFF_IDX 3
+//zero                      5
+#define THROTTLE_BUFF_IDX 7
+#define THROTTLE2_BUFF_IDX 9
+#define U_VOL_BUFF_IDX 11
+#define W_VOL_BUFF_IDX 13
+//zero                 15
+
+#define REG_CHAN_NUM (ADC01_NUM + ADC01_NUM)
+#define ADC_DUAL_MODE ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL
+
+#endif
+
+u16 adc_buffer[REG_CHAN_NUM];
+float vref_adc = 1408.0f;
+float vref_5v_adc = 2047.0f;
+
+#define VREF_ADC_DATA 1509.0F //1498, 1.21/3.3*4095
+
+static void adc01_dma_init(void)
+{
+	DMA_InitType DMA_InitStructure;
+    rcu_ahb_periph_clock_enable(RCU_DMA1);
+
+    DMA_DeInit(DMA1_CH1);
+    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC1->DAT;
+    DMA_InitStructure.MemAddr        = (uint32_t)adc_buffer;
+    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
+    DMA_InitStructure.BufSize        = REG_CHAN_NUM/2;
+    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
+    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
+    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_WORD;
+    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Word;
+    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
+    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
+    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
+    DMA_Init(DMA1_CH1, &DMA_InitStructure);
+    /* Enable DMA1 Channel1 */
+    DMA_EnableChannel(DMA1_CH1, ENABLE);
+}
+
+static void adc01_init(void) {
+	ADC_InitType ADC_InitStructure;
+    /* config ADC clock */
+    RCC_ConfigAdcHclk(RCC_ADCHCLK_DIV4);
+
+	rcu_ahb_periph_clock_enable(RCU_ADC1);
+	rcu_ahb_periph_clock_enable(RCU_ADC2);
+
+	ADC_DeInit(ADC1);
+	ADC_DeInit(ADC2);
+
+	//ADC1 and ADC2 configuration
+	ADC_InitStruct(&ADC_InitStructure);
+	ADC_InitStructure.WorkMode = ADC_WORKMODE_REG_INJECT_SIMULT;
+	ADC_InitStructure.MultiChEn = ENABLE;
+	ADC_InitStructure.ContinueConvEn = ENABLE;
+	ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIG_INJ_CONV_T1_CC4 | ADC_EXT_TRIGCONV_NONE; //inject trigger T1CC4, regular trigger software
+	ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
+	ADC_InitStructure.ChsNumber = ADC01_NUM;
+	ADC_Init(ADC1, &ADC_InitStructure);
+	ADC_Init(ADC2, &ADC_InitStructure);
+
+	//Config Sampling Time
+	ADC_ConfigInjectedSequencerLength(ADC1,INJ_CHAN_NUM);
+	ADC_ConfigInjectedChannel(ADC1, V_PHASE_I_CHAN, 1, ADC_INJ_SAMPLE_TIME);
+#if (INJ_CHAN_NUM == 4)
+	ADC_ConfigInjectedChannel(ADC1, V_PHASE_I_CHAN, 2, ADC_INJ_SAMPLE_TIME);
+	ADC_ConfigInjectedChannel(ADC1, V_PHASE_I_CHAN, 3, ADC_INJ_SAMPLE_TIME);
+	ADC_ConfigInjectedChannel(ADC1, V_PHASE_I_CHAN, 4, ADC_INJ_SAMPLE_TIME);
+#endif
+	ADC_ConfigInjectedSequencerLength(ADC2,INJ_CHAN_NUM);
+	ADC_ConfigInjectedChannel(ADC2, W_PHASE_I_CHAN, 1, ADC_INJ_SAMPLE_TIME);
+#if (INJ_CHAN_NUM == 4)
+	ADC_ConfigInjectedChannel(ADC2, W_PHASE_I_CHAN, 2, ADC_INJ_SAMPLE_TIME);
+	ADC_ConfigInjectedChannel(ADC2, W_PHASE_I_CHAN, 3, ADC_INJ_SAMPLE_TIME);
+	ADC_ConfigInjectedChannel(ADC2, W_PHASE_I_CHAN, 4, ADC_INJ_SAMPLE_TIME);
+#endif
+	//ADC1 and ADC2 TrigInJectConv Enable
+	ADC_EnableExternalTrigInjectedConv(ADC1,ENABLE);
+	ADC_EnableExternalTrigInjectedConv(ADC2,ENABLE);
+
+	ADC_ConfigRegularChannel(ADC1, VBUS_V_CHAN, 1, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, ACC_V_CHAN, 2, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, VBUS_I_CHAN, 3, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, V_VOL_ADC_CHAN, 4, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, THROTTLE_5V_CHAN, 5, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, ZERO_ADC_CHAN, 6, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, ADC_CH_INT_VREF, 7, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC1, DC5V_ADC_CHAN, 8, ADC_REGCHAN_SAMPLE_TIME); 
+	ADC_EnableExternalTrigConv(ADC1, ENABLE);
+	
+    ADC_ConfigRegularChannel(ADC2, MOS_TEMP_ADC_CHAN, 1, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, MOTOR_TEMP_ADC_CHAN, 2, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, ZERO_ADC_CHAN, 3, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, THROTTLE_CHAN, 4, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, THROTTLE2_CHAN, 5, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, U_VOL_ADC_CHAN, 6, ADC_REGCHAN_SAMPLE_TIME);
+	ADC_ConfigRegularChannel(ADC2, W_VOL_ADC_CHAN, 7, ADC_REGCHAN_SAMPLE_TIME); //adc12
+	ADC_ConfigRegularChannel(ADC2, ZERO_ADC_CHAN, 8, ADC_REGCHAN_SAMPLE_TIME);	
+
+	ADC_EnableExternalTrigConv(ADC2, ENABLE);
+
+	/* Enable Vrefint channel17 */
+	ADC_EnableTempSensorVrefint(ENABLE);
+
+	ADC_EnableDMA(ADC1, ENABLE);
+
+	/* Enable ADC1 */
+	ADC_Enable(ADC1, ENABLE);
+	/*Check ADC Ready*/
+	while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET)
+		 ;
+	/* Start ADC1 calibration */
+	ADC_StartCalibration(ADC1);
+	/* Check the end of ADC1 calibration */
+	while (ADC_GetCalibrationStatus(ADC1))
+		 ;
+	
+	/* Enable ADC2 */
+	ADC_Enable(ADC2, ENABLE);
+	/*Check ADC Ready*/
+	while(ADC_GetFlagStatusNew(ADC2,ADC_FLAG_RDY) == RESET)
+		 ;
+	/* Start ADC2 calibration */
+	ADC_StartCalibration(ADC2);
+	/* Check the end of ADC2 calibration */
+	while (ADC_GetCalibrationStatus(ADC2))
+		 ;
+	
+	adc_disable_ext_trigger();
+
+	nvic_irq_enable(ADC1_2_IRQn, ADC_IRQ_PRIORITY, 0);
+
+	/* Start ADC1 Software Conversion */
+	ADC_EnableSoftwareStartConv(ADC1, ENABLE);
+}
+
+
+static void adc_gpio_init(void) {
+
+	rcu_apb2_periph_clock_enable(RCU_AF);
+		/* configure ADC pin, current sampling -- ADC_IN1(PA1) ADC_IN12(PC2) ADC_IN13(PC3) */
+#ifdef U_PHASE_ADC_GROUP
+		rcu_apb2_periph_clock_enable(U_PHASE_ADC_RCU);
+		gpio_init(U_PHASE_ADC_GROUP, U_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, U_PHASE_ADC_PIN);
+#endif
+#ifdef V_PHASE_ADC_GROUP
+		rcu_apb2_periph_clock_enable(V_PHASE_ADC_RCU);
+		gpio_init(V_PHASE_ADC_GROUP, V_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, V_PHASE_ADC_PIN);
+#endif
+#ifdef W_PHASE_ADC_GROUP
+		rcu_apb2_periph_clock_enable(W_PHASE_ADC_RCU);
+		gpio_init(W_PHASE_ADC_GROUP, W_PHASE_ADC_MODE, GPIO_OSPEED_50MHZ, W_PHASE_ADC_PIN);
+#endif
+
+#ifdef VBUS_V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(VBUS_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(VBUS_V_ADC_GROUP, VBUS_V_ADC_MODE, GPIO_OSPEED_50MHZ, VBUS_V_ADC_PIN);
+#endif
+
+#ifdef VBUS_I_ADC_GROUP
+	rcu_apb2_periph_clock_enable(VBUS_I_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(VBUS_I_ADC_GROUP, VBUS_I_ADC_MODE, GPIO_OSPEED_50MHZ, VBUS_I_ADC_PIN);
+#endif
+
+
+#ifdef ACC_V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(ACC_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(ACC_V_ADC_GROUP, ACC_V_ADC_MODE, GPIO_OSPEED_50MHZ, ACC_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(THROTTLE_V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE_V_ADC_GROUP, THROTTLE_V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE_V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(THROTTLE2_V_ADC_RCU);
+	gpio_init(THROTTLE2_V_ADC_GROUP, THROTTLE2_V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE2_V_ADC_PIN);
+#endif
+
+#ifdef THROTTLE_5V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(THROTTLE_5V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE_5V_ADC_GROUP, THROTTLE_5V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE_5V_ADC_PIN);
+#endif
+#ifdef THROTTLE2_5V_ADC_GROUP
+	rcu_apb2_periph_clock_enable(THROTTLE2_5V_ADC_RCU);
+	/* configure ADC pin, bus voltage sampling -- ADC_IN0(PA0) */
+	gpio_init(THROTTLE2_5V_ADC_GROUP, THROTTLE2_5V_ADC_MODE, GPIO_OSPEED_50MHZ, THROTTLE2_5V_ADC_PIN);
+#endif
+
+#ifdef U_VOL_ADC_GROUP
+	rcu_apb2_periph_clock_enable(U_VOL_ADC_RCU);
+	gpio_init(U_VOL_ADC_GROUP, U_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, U_VOL_ADC_PIN);
+#endif
+#ifdef V_VOL_ADC_GROUP
+	rcu_apb2_periph_clock_enable(V_VOL_ADC_RCU);
+	gpio_init(V_VOL_ADC_GROUP, V_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, V_VOL_ADC_PIN);
+#endif
+#ifdef W_VOL_ADC_GROUP
+	rcu_apb2_periph_clock_enable(W_VOL_ADC_RCU);
+	gpio_init(W_VOL_ADC_GROUP, W_VOL_ADC_MODE, GPIO_OSPEED_50MHZ, W_VOL_ADC_PIN);
+#endif
+#ifdef MOS_TEMP_ADC_GROUP
+	rcu_apb2_periph_clock_enable(MOS_TEMP_ADC_RCU);
+	gpio_init(MOS_TEMP_ADC_GROUP, MOS_TEMP_ADC_MODE, GPIO_OSPEED_50MHZ, MOS_TEMP_ADC_PIN);
+#endif
+#ifdef MOS_TEMP1_ADC_GROUP
+	rcu_apb2_periph_clock_enable(MOS_TEMP1_ADC_RCU);
+	gpio_init(MOS_TEMP1_ADC_GROUP, MOS_TEMP1_ADC_MODE, GPIO_OSPEED_50MHZ, MOS_TEMP1_ADC_PIN);
+#endif
+
+#ifdef MOTOR_TEMP_ADC_GROUP
+	rcu_apb2_periph_clock_enable(MOTOR_TEMP_ADC_RCU);
+	gpio_init(MOTOR_TEMP_ADC_GROUP, MOTOR_TEMP_ADC_MODE, GPIO_OSPEED_50MHZ, MOTOR_TEMP_ADC_PIN);
+#endif
+
+#ifdef ZERO_ADC_GROUP
+	rcu_apb2_periph_clock_enable(ZERO_ADC_RCU);
+	gpio_init(ZERO_ADC_GROUP, ZERO_ADC_MODE, GPIO_OSPEED_50MHZ, ZERO_ADC_PIN);
+#endif
+
+}
+
+void adc_init(void) {
+	adc_gpio_init();
+	adc01_dma_init();
+	adc01_init();
+	adc_current_sample_config(0);
+}
+
+void adc_set_vref_calc(float v) {
+	vref_adc = v;
+}
+
+void adc_set_5vref_calc(float v) {
+	vref_5v_adc = v;
+}
+
+#define VREF_COMP_LFP_CEOF (0.0001F)
+static float vref_compestion_filter = 1.0f;
+#define VREF_3V3_COMPESTION() (vref_adc/(float)adc_buffer[VREF_BUFF_IDX])
+void adc_3v3ref_filter(void) {
+	float value = VREF_3V3_COMPESTION();
+	LowPass_Filter(vref_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_vref_compesion(void) {
+	return vref_compestion_filter;
+}
+
+static float vref_5v_compestion_filter = 1.0f;
+#define VREF_5V_COMPESTION() (vref_5v_adc/(float)adc_buffer[VREF5v_BUFF_IDX])
+void adc_5vref_filter(void) {
+	float value = VREF_5V_COMPESTION();
+	LowPass_Filter(vref_5v_compestion_filter, value, VREF_COMP_LFP_CEOF);
+}
+
+float adc_5vref_compesion(void) {
+	return vref_5v_compestion_filter;
+}
+
+void adc_vref_filter(void) {
+	adc_3v3ref_filter();
+	adc_5vref_filter();
+}
+
+u16 adc_get_vbus(void) {
+	return (float)adc_buffer[VBUS_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+}
+
+u16 adc_get_acc(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[ACC_V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_vbus();
+#endif
+}
+
+u16 adc_get_ibus(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return (float)adc_buffer[VBUS_I_BUFF_IDX] * VREF_5V_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_throttle(void) {
+	return adc_buffer[THROTTLE_BUFF_IDX] * VREF_3V3_COMPESTION();
+}
+
+u16 adc_get_throttle2(void) {
+#ifdef THROTTLE2_BUFF_IDX
+	return adc_buffer[THROTTLE2_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return adc_get_throttle();
+#endif
+}
+
+u16 adc_get_thro_5v(void) {
+#ifdef THROTTLE_5V_BUFF_IDX
+	return adc_buffer[THROTTLE_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_thro2_5v(void) {
+#ifdef THROTTLE2_5V_BUFF_IDX
+	return adc_buffer[THROTTLE2_5V_BUFF_IDX] * VREF_3V3_COMPESTION();
+#else
+	return 0;
+#endif
+}
+
+void adc_get_uvw_phaseV(u16 *uvw) {
+	uvw[0] = adc_buffer[U_VOL_BUFF_IDX];
+	uvw[1] = adc_buffer[V_VOL_BUFF_IDX];
+	uvw[2] = adc_buffer[W_VOL_BUFF_IDX];
+}
+
+u16 adc_get_mos_temp(void) {
+	return adc_buffer[MOS_TEMP_BUFF_IDX];
+}
+
+u16 adc_get_motor_temp(void) {
+	return adc_buffer[MOTOR_TEMP_BUFF_IDX];
+}
+
+u16 adc_get_vref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+u16 adc_get_5v_ref(void) {
+#ifdef CONFIG_BOARD_MCXXX
+	return adc_buffer[VREF5v_BUFF_IDX];
+#else
+	return 0;
+#endif
+}
+
+void adc_start_convert(void) {
+	int drop = 16;
+    /* clear the ADC flag */
+    ADC_ClearFlag(ADC1, ADC_FLAG_JENDC);
+	ADC_ClearFlag(ADC2, ADC_FLAG_JENDC);
+
+	adc_enable_ext_trigger();
+	while(drop-- > 0) {
+		while (ADC_GetFlagStatus(ADC1, ADC_FLAG_JENDC) == RESET);
+		ADC_ClearFlag(ADC1, ADC_FLAG_JENDC);
+	}
+    /* enable ADC interrupt */
+
+	ADC_ConfigInt(ADC1, ADC_INT_JENDC, ENABLE);
+	
+	adc_update_ext_trigger(ADC_TRIGGER_PHASE);
+}
+
+void adc_stop_convert(void) {
+	adc_disable_ext_trigger();
+    /* disable ADC interrupt */
+
+	ADC_ConfigInt(ADC1, ADC_INT_JENDC, DISABLE);
+
+    /* clear the ADC flag */
+    ADC_ClearFlag(ADC1, ADC_FLAG_JENDC);
+	ADC_ClearFlag(ADC2, ADC_FLAG_JENDC);
+}
+

+ 131 - 0
Applications/bsp/n32/adc.h

@@ -0,0 +1,131 @@
+#ifndef _ADC_H__
+#define _ADC_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+float adc_vref_compesion(void);
+float adc_5vref_compesion(void);
+
+/*
+inserted ADC 由timer0 ch3触发,
+注意:adc所有外部触发都是下降沿触发 
+*/
+#define ISQ0_OFFSET 0
+#define ISQ1_OFFSET 5
+#define ISQ2_OFFSET 10
+#define ISQ3_OFFSET 15
+#define IL_OFFSET   20
+
+#define ADC_INJ_SAMPLE_TIME ADC_SAMP_TIME_7CYCLES5
+#define ADC_REGCHAN_SAMPLE_TIME ADC_SAMP_TIME_239CYCLES5
+
+
+#define ADC_TRIGGER_PHASE ADC_EXT_TRIG_INJ_CONV_T1_CC4
+
+#define PHASE_AB 0
+#define PHASE_AC 1
+#define PHASE_BC 2
+
+#define JDAT_OFFSET ((uint8_t)0x28)
+#define CTRL2_INJ_EXT_TRIG_SET   ((uint32_t)0x00008000)
+#define CTRL2_INJ_EXT_TRIG_RESET ((uint32_t)0xFFFF7FFF)
+#define INJ_CHAN_NUM 4
+static u16 __inline ADC_GetInjectedDat(ADC_Module* ADCx, uint8_t ADC_InjectedChannel)
+{
+    __IO uint32_t tmp = 0;
+
+    tmp = (uint32_t)ADCx;
+    tmp += ADC_InjectedChannel + JDAT_OFFSET;
+
+    /* Returns the selected injected channel conversion data value */
+    return (uint16_t)(*(__IO uint32_t*)tmp);
+}
+
+#define v_calc(sum, v, min, max) \
+	do { \
+		if (v > max) { \
+			max = v; \
+		} \
+		if (v < min) { \
+			min = v; \
+		}\
+		sum += v; \
+	}while(0);
+
+static void __inline adc_phase_current_read(u8 phases, s32 *pv1, s32 *pv2) {
+#if (INJ_CHAN_NUM == 4)
+	u16 min, max;
+	u16 sum = 0;
+	u16 v1 = ADC_GetInjectedDat(ADC1, ADC_INJ_CH_1);
+	u16 v2 = ADC_GetInjectedDat(ADC1, ADC_INJ_CH_2);
+	u16 v3 = ADC_GetInjectedDat(ADC1, ADC_INJ_CH_3);
+	u16 v4 = ADC_GetInjectedDat(ADC1, ADC_INJ_CH_4);
+	min = max = v1;
+	sum += v1;
+	v_calc(sum, v2, min, max);
+	v_calc(sum, v3, min, max);
+	v_calc(sum, v4, min, max);
+	*pv1 = (s32) ((sum-min-max)/2.0f * adc_5vref_compesion());
+
+	sum = 0;
+	v1 = ADC_GetInjectedDat(ADC2, ADC_INJ_CH_1);
+	v2 = ADC_GetInjectedDat(ADC2, ADC_INJ_CH_2);
+	v3 = ADC_GetInjectedDat(ADC2, ADC_INJ_CH_3);
+	v4 = ADC_GetInjectedDat(ADC2, ADC_INJ_CH_4);
+	min = max = v1;
+	sum += v1;
+	v_calc(sum, v2, min, max);
+	v_calc(sum, v3, min, max);
+	v_calc(sum, v4, min, max);
+	*pv2 = (s32) ((sum-min-max)/2.0f * adc_5vref_compesion());
+#else
+	*pv1 = (s32)((float)ADC_GetInjectedDat(ADC1, ADC_INJ_CH_1) * adc_5vref_compesion());
+	*pv2 = (s32)((float)ADC_GetInjectedDat(ADC2, ADC_INJ_CH_1) * adc_5vref_compesion());
+#endif
+}
+
+
+static void __inline adc_current_sample_config(u8 phases) {
+
+}
+
+static void __inline adc_disable_ext_trigger(void) {   
+	//ADC1->CTRL2 &= CTRL2_INJ_EXT_TRIG_RESET;
+}
+
+static void __inline adc_enable_ext_trigger(void) {	
+	//ADC1->CTRL2 |= CTRL2_INJ_EXT_TRIG_SET;
+}
+
+
+static __inline__ void adc_clear_irq_flags(void) {
+	ADC1->STS = (~(uint32_t)ADC_FLAG_JENDC);
+	ADC2->STS = (~(uint32_t)ADC_FLAG_JENDC);
+}
+
+
+static __inline void adc_update_ext_trigger(u32 trigger) {
+	//ADC1->CTRL2 |= trigger;
+}
+
+void adc_init(void);
+s32 adc_sample_regular_channel(int chan, int times);
+void adc_start_convert(void);
+void adc_stop_convert(void);
+u16 adc_get_vbus(void);
+u16 adc_get_acc(void);
+u16 adc_get_throttle(void);
+void adc_get_uvw_phaseV(u16 *uvw);
+u16 adc_get_mos_temp(void);
+u16 adc_get_motor_temp(void);
+u16 adc_get_ibus(void);
+u16 adc_get_vref(void);
+void adc_set_vref_calc(float v);
+void adc_vref_filter(void);
+u16 adc_get_5v_ref(void);
+void adc_set_5vref_calc(float v);
+u16 adc_get_throttle2(void);
+u16 adc_get_thro_5v(void);
+u16 adc_get_thro2_5v(void);
+
+#endif /* _ADC_H__ */

+ 380 - 0
Applications/bsp/n32/board_n32_mc105_v3.h

@@ -0,0 +1,380 @@
+#ifndef _BOARD_MC_V3_H__
+#define _BOARD_MC_V3_H__
+
+#define CONFIG_MOS_MAX_VOL 145.0F
+#define CONFIG_MAX_DC_VOL 110.0F
+#define CONFIG_RATED_DC_VOL (96.0f)   /* 母线最大电压 V*/
+#define CONFIG_MIN_DC_VOL   (36.0f)
+
+#define CONFIG_MAX_VBUS_CURRENT 120.0f
+#define CONFIG_MAX_MOT_RPM      9000.0f
+#define CONFIG_MAX_PHASE_CURR   500.0F
+#define CONFIG_MAX_PHASE_VOL    (CONFIG_MOS_MAX_VOL - 20.0F)
+#define CONFIG_MAX_TORQUE       CONFIG_MAX_PHASE_CURR
+#define CONFIG_MAX_LOCK_TORQUE  20
+
+//#define CONFIG_BEEP 
+#define CONFIG_STALL_MAX_CURRENT 100.0f //最大堵转相电流电流
+#define CONFIG_STALL_MAX_TIME    3000   //ms, 超过最大堵转电流持续时间,判断堵转
+#define CONFIG_UNDER_VOL_RPM     1000
+#define CONFIG_UNDER_VOL_PHASE_CURR 100.0F
+#define CONFIG_UNDER_VOL_DC_CURR 15.0F
+
+#define CONFIG_CURR_LP_WC (600.0F)
+
+#define CONFIG_CURR_LP_CEOF (CONFIG_CURR_LP_WC*2*3.14F/(float)FOC_PWM_FS)
+
+#define CONFIG_96V_MODE_VOL (60.0F)
+
+#define CONFIG_SMO_OBSERVER 1
+#define CONFIG_SPEED_LADRC  1
+//#define CONFIG_FORCE_96V_MODE 1
+
+#define SCHED_TIMER TIM5
+#define SCHED_TIMER_RCU RCU_TIMER5
+#define SCHED_TIMER_IRQ TIM5_IRQn
+#define SCHED_TIMER_IRQHandler TIM5_IRQHandler
+
+#define PWM_DEAD_TIME_NS 400u
+#define HW_DEAD_TIME_NS  200u
+#define HW_RISE_TIME_NS  500u
+#define HW_NOISE_TIME_NS 300u
+
+#define TDead NS_2_TCLK(HW_DEAD_TIME_NS + PWM_DEAD_TIME_NS)/* ����ʱ�� */ 
+#define TRise NS_2_TCLK(HW_RISE_TIME_NS)/* MOS ����ʱ��*/
+#define TNoise NS_2_TCLK(HW_NOISE_TIME_NS)/* MOS��������Ŀ�������ʱ�� */
+#define TADC  ((uint16_t)((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) *2 * TIM_CLOCK_MHz) / ADC_CLOCK_MHz + 1u)/* ADC ����ʱ�� */
+#define TSampleMIN (TDead + TRise + TADC) //采样需要的总时间
+#define TSampleBefore (TDead + TRise) //采样开始前需要等待的时间
+
+#define ADC_REFERENCE_VOLTAGE  (3.3F)
+#define ADC_FULL_MAX          (4095.0F)
+
+/* MOS驱动 */
+#define MOS_PWM_TIMER 		TIM1
+#define PWM_TIM_CLK     RCU_TIMER1
+#define PWM_MODE 		TIM_OCMODE_PWM1
+#define PWM_U_P_GROUP 	GPIOA
+#define PWM_U_P_PIN 	GPIO_PIN_8
+#define PWM_U_P_RCU 	RCU_GPIOA
+#define PWM_U_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_U_N_GROUP 	GPIOB
+#define PWM_U_N_PIN 	GPIO_PIN_13
+#define PWM_U_N_RCU 	RCU_GPIOB
+#define PWM_U_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_P_GROUP 	GPIOA
+#define PWM_V_P_PIN 	GPIO_PIN_9
+#define PWM_V_P_RCU 	RCU_GPIOA
+#define PWM_V_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_V_N_GROUP 	GPIOB
+#define PWM_V_N_PIN 	GPIO_PIN_14
+#define PWM_V_N_RCU 	RCU_GPIOB
+#define PWM_V_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_P_GROUP 	GPIOA
+#define PWM_W_P_PIN 	GPIO_PIN_10
+#define PWM_W_P_RCU 	RCU_GPIOA
+#define PWM_W_P_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_W_N_GROUP 	GPIOB
+#define PWM_W_N_PIN 	GPIO_PIN_15
+#define PWM_W_N_RCU 	RCU_GPIOB
+#define PWM_W_N_MODE 	GPIO_MODE_AF_PP
+
+#define PWM_BRAKE_GROUP 	GPIOB
+#define PWM_BRAKE_PIN 	GPIO_PIN_12
+#define PWM_BRAKE_RCU 	RCU_GPIOB
+#define PWM_BRAKE_MODE 	GPIO_MODE_IN_FLOATING
+
+
+#define PWM_BRK_IRQ TIM1_BRK_IRQn
+#define PWM_UP_IRQ  TIM1_UP_IRQn
+#define PWM_UP_IRQHandler   TIM1_UP_IRQHandler
+#define PWM_BRK_IRQHandler  TIM1_BRK_IRQHandler
+
+
+
+#define HALL_SENSOR_CEOF 0.32F
+
+/* 高边电流传感器采样 */
+#define HIGH_SIDE_CURRENT_SENSOR
+
+#define V_PHASE_I_CHAN  ADC_CH_6   //adc12
+#define W_PHASE_I_CHAN  ADC_CH_5   //adc2
+
+#define V_PHASE_ADC_GROUP 	GPIOC
+#define V_PHASE_ADC_PIN 	GPIO_PIN_4
+#define V_PHASE_ADC_RCU 	RCU_GPIOC
+#define V_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_PHASE_ADC_GROUP 	GPIOC
+#define W_PHASE_ADC_PIN 	GPIO_PIN_0
+#define W_PHASE_ADC_RCU 	RCU_GPIOC
+#define W_PHASE_ADC_MODE 	GPIO_MODE_AIN
+
+#define ADC_TO_CURR_ceof1  (HALL_SENSOR_CEOF)
+#define ADC_TO_CURR_ceof2  (HALL_SENSOR_CEOF)
+
+#define CONFIG_PWM_UV_SWAP 1
+
+//#define CONFIG_HW_MUTISAMPLE ADC_OVERSAMPLING_RATIO_MUL8
+//#define CONFIG_HW_MUTISAMPLE_SHIFT ADC_OVERSAMPLING_SHIFT_3B
+//#define CONFIG_SW_MUTISAMPLE 1
+
+/* 母线电压采集 */
+#define VBUS_V_CHAN 		ADC_CH_8  //adc12
+#define VBUS_V_ADC_GROUP 	GPIOC
+#define VBUS_V_ADC_PIN 		GPIO_PIN_2
+#define VBUS_V_ADC_RCU 		RCU_GPIOC
+#define VBUS_V_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define ACC_V_CHAN 			ADC_CH_7    //adc12
+#define ACC_V_ADC_GROUP 	GPIOC
+#define ACC_V_ADC_PIN 		GPIO_PIN_1
+#define ACC_V_ADC_RCU 		RCU_GPIOC
+#define ACC_V_ADC_MODE 		GPIO_MODE_AIN
+#define ACC_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*41/ADC_FULL_MAX)
+
+#define VBUS_I_CHAN 		ADC_CH_1 //adc1
+#define VBUS_I_ADC_GROUP 	GPIOA
+#define VBUS_I_ADC_PIN 		GPIO_PIN_0
+#define VBUS_I_ADC_RCU 		RCU_GPIOA
+#define VBUS_I_ADC_MODE 	GPIO_MODE_AIN
+#define VBUS_I_CEOF         (HALL_SENSOR_CEOF)
+#define VBUS_I_POSITIVE     1
+
+/* MOS 温度采集 */
+#define MOS_TEMP_ADC_CHAN    ADC_CH_3  //adc2
+#define MOS_TEMP_ADC_GROUP 	 GPIOB
+#define MOS_TEMP_ADC_PIN 	 GPIO_PIN_1
+#define MOS_TEMP_ADC_RCU 	 RCU_GPIOB
+#define MOS_TEMP_ADC_MODE 	 GPIO_MODE_AIN
+#define MOS_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/(10.0f*1000.0f)))
+
+/* 电机温度采集 */
+#define MOTOR_TEMP_ADC_CHAN     ADC_CH_2 //adc2
+#define MOTOR_TEMP_ADC_GROUP 	GPIOA
+#define MOTOR_TEMP_ADC_PIN 	GPIO_PIN_5
+#define MOTOR_TEMP_ADC_RCU 	RCU_GPIOA
+#define MOTOR_TEMP_ADC_MODE 	GPIO_MODE_AIN
+#define MOTOR_TEMP_R(adc) ((adc)/ADC_FULL_MAX / ((1.0f - (adc)/ADC_FULL_MAX)/2000.0f))
+
+/* 是否有母线电流采集 */
+//#define NO_SAMPLE_IDC //如果硬件没有采集母线电流,定义一下
+
+/* 转把信号电压采集 */
+#define THROTTLE_CHAN           ADC_CH_1 //adc2
+#define THROTTLE_V_ADC_GROUP 	GPIOA
+#define THROTTLE_V_ADC_PIN 		GPIO_PIN_4
+#define THROTTLE_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_V_ADC_MODE 	GPIO_MODE_AIN
+#define THROTTLE_VOL_CEOF 		(ADC_REFERENCE_VOLTAGE*(15.1f/10.0f)/ADC_FULL_MAX)
+
+/* 第二路转把信号电压采集 */
+#define THROTTLE2_CHAN           	ADC_CH_4 //adc2
+#define THROTTLE2_V_ADC_GROUP 		GPIOA
+#define THROTTLE2_V_ADC_PIN 		GPIO_PIN_7
+#define THROTTLE2_V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE2_V_ADC_MODE 		GPIO_MODE_AIN
+
+/* 转把供电5V电压采集 */
+#define THROTTLE_5V_CHAN           ADC_CH_3 //adc1
+#define THROTTLE_5V_ADC_GROUP 	GPIOA
+#define THROTTLE_5V_ADC_PIN 		GPIO_PIN_6
+#define THROTTLE_5V_ADC_RCU 		RCU_GPIOA
+#define THROTTLE_5V_ADC_MODE 	GPIO_MODE_AIN
+
+#if 0
+/* 第二路供电5V电压采集 */
+#define THROTTLE2_5V_CHAN           	ADC_CH_9
+#define THROTTLE2_5V_ADC_GROUP 		GPIOB
+#define THROTTLE2_5V_ADC_PIN 		GPIO_PIN_1
+#define THROTTLE2_5V_ADC_RCU 		RCU_GPIOB
+#define THROTTLE2_5V_ADC_MODE 		GPIO_MODE_AIN
+#endif
+
+/* UVW三相对地电压采集 */
+#define U_VOL_ADC_CHAN     ADC_CH_12 //adc2
+#define U_VOL_ADC_GROUP 	GPIOC
+#define U_VOL_ADC_PIN 	GPIO_PIN_5
+#define U_VOL_ADC_RCU 	RCU_GPIOC
+#define U_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define V_VOL_ADC_CHAN     ADC_CH_2 //adc1
+#define V_VOL_ADC_GROUP 	GPIOA
+#define V_VOL_ADC_PIN 	GPIO_PIN_1
+#define V_VOL_ADC_RCU 	RCU_GPIOA
+#define V_VOL_ADC_MODE 	GPIO_MODE_AIN
+
+#define W_VOL_ADC_CHAN     ADC_CH_11 //adc12
+#define W_VOL_ADC_GROUP 	GPIOA
+#define W_VOL_ADC_PIN 	GPIO_PIN_2
+#define W_VOL_ADC_RCU 	RCU_GPIOA
+#define W_VOL_ADC_MODE 	GPIO_MODE_AIN
+#define UVW_VOL_CEOF (ADC_REFERENCE_VOLTAGE*(41.0f)/ADC_FULL_MAX)
+
+/* 模拟5v电压采集 */
+#define DC5V_ADC_CHAN     ADC_CH_4 //adc1
+#define DC5V_ADC_GROUP 	GPIOA
+#define DC5V_ADC_PIN 	GPIO_PIN_3
+#define DC5V_ADC_RCU 	RCU_GPIOA
+#define DC5V_ADC_MODE 	GPIO_MODE_AIN
+
+/* 0v电压采集,主要是用来给上一次的采集放电 */
+#define ZERO_ADC_CHAN     ADC_CH_9 //adc12
+#define ZERO_ADC_GROUP 	GPIOC
+#define ZERO_ADC_PIN 	GPIO_PIN_3
+#define ZERO_ADC_RCU 	RCU_GPIOC
+#define ZERO_ADC_MODE 	GPIO_MODE_AIN
+
+/* 刹车手把输入 */
+#define GPIO_BREAK_MODE GPIO_LOW_BRK_MODE
+#define GPIO_BRAKE_IN_GROUP 	GPIOB
+#define GPIO_BRAKE_IN_PIN 	GPIO_PIN_3
+#define GPIO_BRAKE_IN_RCU 	RCU_GPIOB
+#define GPIO_BRAKE_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_BRAKE_IRQ  EXTI3_IRQn
+#define GPIO_BRAKE_EXTI EXTI_LINE3
+#define GPIO_BRAKE_EXIT_SRC_GROUP GPIOB_PORT_SOURCE
+#define GPIO_BRAKE_EXIT_SRC_PIN GPIO_PIN_SOURCE3
+#define GPIO_BRAKE_PIN_REMAP GPIO_RMP_SW_JTAG_SW_ENABLE
+
+/* 锁电机线,  使用查询模式 */
+#define GPIO_MLOCK_IN_GROUP GPIOC
+#define GPIO_MLOCK_IN_PIN GPIO_PIN_13
+#define GPIO_MLOCK_IN_RCU RCU_GPIOC
+#define GPIO_MLOCK_IN_MODE 	GPIO_MODE_IN_FLOATING
+
+/* 触发U相检测 */
+#define GPIO_UDEC_OUT_GROUP 	GPIOB
+#define GPIO_UDEC_OUT_PIN 	GPIO_PIN_7
+#define GPIO_UDEC_OUT_RCU 	RCU_GPIOB
+#define GPIO_UDEC_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 风扇 PWM */
+#define GPIO_FAN_OUT_GROUP 	GPIOC
+#define GPIO_FAN_OUT_PIN 	GPIO_PIN_8
+#define GPIO_FAN_OUT_RCU 	RCU_GPIOC
+#define GPIO_FAN_OUT_MODE 	GPIO_MODE_AF_PP
+#define FAN_PWM_TIMER TIM8
+#define FAN_PWM_CHAN  TIM_CH_3
+#define FAN_TIMER_RCU  RCU_TIMER8
+
+/* 风扇1检测 */
+#define GPIO_FAN1_IN_GROUP 	GPIOC
+#define GPIO_FAN1_IN_PIN 	GPIO_PIN_11
+#define GPIO_FAN1_IN_RCU 	RCU_GPIOC
+#define GPIO_FAN1_IN_MODE 	GPIO_MODE_IN_FLOATING
+#define GPIO_FAN1_IRQ  EXTI15_10_IRQn
+#define GPIO_FAN1_EXTI EXTI_LINE11
+#define GPIO_FAN1_EXIT_SRC_GROUP GPIOC_PORT_SOURCE
+#define GPIO_FAN1_EXIT_SRC_PIN GPIO_PIN_SOURCE11
+
+/* LED 灯控制 */
+#define GPIO_LED_OUT_GROUP 	GPIOC
+#define GPIO_LED_OUT_PIN 	GPIO_PIN_14
+#define GPIO_LED_OUT_RCU 	RCU_GPIOC
+#define GPIO_LED_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* 刹车灯控制,能量回收的时候需要电量刹车灯 */
+#define GPIO_BRAKE_LIGHT_OUT_GROUP 	GPIOD
+#define GPIO_BRAKE_LIGHT_OUT_PIN 	GPIO_PIN_2
+#define GPIO_BRAKE_LIGHT_OUT_RCU 	RCU_GPIOD
+#define GPIO_BRAKE_LIGHT_OUT_MODE 	GPIO_MODE_OUT_PP
+
+/* CAN 定义 */
+#define CAN_TX_GROUP GPIOB
+#define CAN_TX_PIN   GPIO_PIN_9
+#define CAN_RX_GROUP GPIOB
+#define CAN_RX_PIN   GPIO_PIN_8
+#define CAN_PIN_RCU  RCU_GPIOB
+#define CAN_REMAP    GPIO_RMP2_CAN1
+#define CAN_IRQ0     USB_LP_CAN1_RX0_IRQn
+#define CAN_RX0_IRQHandler  USB_LP_CAN1_RX0_IRQHandler
+#define CAN_RX1_IRQHandler  CAN1_RX1_IRQHandler
+
+/* 是否用编码器 */
+#define USE_ENCODER_ABI
+#define ENCODER_TYPE ENCODER_MT
+
+/* 编码器 */
+#define ENC_A_GROUP GPIOB
+#define ENC_A_PIN GPIO_PIN_4
+#define ENC_A_RCU RCU_GPIOB
+#define ENC_A_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_B_GROUP GPIOB
+#define ENC_B_PIN GPIO_PIN_5
+#define ENC_B_RCU RCU_GPIOB
+#define ENC_B_MODE GPIO_MODE_IN_FLOATING
+
+#define TIMER2_PB4_PB5_REMAP GPIO_PART1_RMP_TIM3
+
+#define ENC_PWM_GROUP GPIOB
+#define ENC_PWM_PIN GPIO_PIN_6
+#define ENC_PWM_RCU RCU_GPIOB
+#define ENC_PWM_MODE GPIO_MODE_IN_FLOATING
+
+#define ENC_I_GROUP GPIOA     /*测量编码器的ABI的I信号,360度同步一次*/
+#define ENC_I_PIN GPIO_PIN_15
+#define ENC_I_RCU RCU_GPIOA
+#define ENC_I_MODE GPIO_MODE_IPU
+#define ENC_I_IRQ  EXTI15_10_IRQn
+#define ENC_I_EXTI EXTI_LINE15
+#define ENC_I_EXIT_SRC_GROUP GPIOB_PORT_SOURCE
+#define ENC_I_EXIT_SRC_PIN GPIO_PIN_SOURCE15
+
+#define ENC_TIMER TIM3  /* 测量编码器的ABI信号的AB信号 */
+#define ENC_TIMER_RCU RCU_TIMER3
+#define ENC_TIMER_IRQ TIM3_IRQn
+#define ENC_TIMER_IRQHandler TIM3_IRQHandler
+
+#define ENC_PWM_TIMER TIM4    /* 测量绝对编码器PWM输出的占空比,获取转子angle*/
+#define ENC_PWM_TIMER_RCU RCU_TIMER4
+#define ENC_PWM_TIMER_IRQ TIM4_IRQn
+#define ENC_PWM_TIMER_CHAN  TIM_CH_1
+#define ENC_PWM_TIMER_IRQ_CH TIM_INT_CC1
+#define ENC_PWM_TIMER_INT_FLG TIM_INT_CC1
+#define ENC_PWM_IRQHandler TIM4_IRQHandler
+
+#define ENC_MAX_interpolation 1.0F
+
+#define ENC_FILTER_NR          15
+#ifdef CONFIG_PWM_UV_SWAP
+#define ENCODER_CC_INVERT 1
+#endif
+/* 编码器参数      */
+#define ENC_MAX_RES  4096.0f
+#define ENC_Duty_2_Pluse_Nr(duty) (duty * ENC_MAX_RES) //通过占空比计算有几个脉冲
+#define ENC_Pluse_Nr_2_angle(Nr) (360.0f/(float)ENC_MAX_RES * (Nr))
+#define ENC_PWM_Min_P 0.0f//(1.0f/(131.0f + 1.0f))
+#define ENC_PWM_Max_P  1.0f
+
+#if ENCODER_TYPE==ENCODER_MPS
+#define ENC_Duty(d, t) ((1.0f/128.0f) * (130.0f * (d)/(t) - 1.0f))
+#elif ENCODER_TYPE==ENCODER_MT
+/*min. 994 hz*/
+#define ENC_PWM_MAX_RES    4119.0F
+#define ENC_PWM_INIT_WIDTH 16.0F //PWM 起始宽度
+#define ENC_PWM_END_WIDTH   8.0F
+//#define ENC_PWM_Min_P      (ENC_PWM_INIT_WIDTH/(ENC_PWM_MAX_RES + 1.0f))
+//#define ENC_PWM_Max_P      ((ENC_PWM_MAX_RES-ENC_PWM_END_WIDTH)/(ENC_PWM_MAX_RES - 1.0f))
+#define PWM_Duty(d, t) ((d)/(t))
+#define ENC_Duty(d, t) ((PWM_Duty(d, t)*ENC_PWM_MAX_RES - ENC_PWM_INIT_WIDTH)/(ENC_PWM_MAX_RES - ENC_PWM_END_WIDTH - ENC_PWM_INIT_WIDTH))
+#else
+#error "Postion sensor ERROR"
+
+#endif
+#define DEBUG_PORT_UART2
+
+#define CONFIG_MOT_TYPE MOTOR_BLUESHARK_A1
+
+//#define CONFIG_DQ_STEP_RESPONSE
+
+#endif /*_BOARD_MC_V3_H__ */
+
+

+ 93 - 0
Applications/bsp/n32/bsp.c

@@ -0,0 +1,93 @@
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+#include "libs/logger.h"
+#include "os/os_types.h"
+#include "version.h"
+
+static void wdog_enable(void);
+#define DGB_TIM1_STOP (1<<10)
+#define DGB_TIM8_STOP (1<<17)
+
+static void dbg_stop_tim1_8(void) {
+    __IO uint32_t *p = (uint32_t*)0xE0042004;
+    *p |= DGB_TIM1_STOP;
+    *p |= DGB_TIM8_STOP;
+}
+void bsp_init(void){
+	wdog_enable();
+	SystemCoreClockUpdate();
+	dbg_stop_tim1_8();
+	systick_open();
+	task_ticks_enable();
+	gpio_pin_init();
+	shark_uart_init(SHARK_UART0);
+}
+
+
+void system_reboot(void){
+	NVIC_SystemReset();
+}
+
+void systick_close(void)
+{
+	SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;
+}
+
+void systick_open(void)
+{
+	SysTick_Config(SystemCoreClock / 1000);
+}
+
+u8 mcu_chip_id(u8 *buff)
+{
+	u32 values[] = { REG32(0x1FFFF7E8), REG32(0x1FFFF7EC), REG32(0x1FFFF7F0), REG32(0x1FFFF7E0) };
+	memcpy(buff, values, sizeof(values));
+	return sizeof(values);
+}
+
+static u32 _mcu_rst_status = 0xFFFFFFFF;
+u32 get_mcu_reset_source(void)
+{
+	if (_mcu_rst_status == 0xFFFFFFFF) {
+		_mcu_rst_status = RCC->CTRLSTS;
+		RCC_ClrFlag();
+	}
+	return _mcu_rst_status;
+}
+
+void wdog_reload(void){
+#if CONFIG_DEBUG == 0
+    IWDG_ReloadKey();
+#endif    
+}
+
+static void wdog_enable(void)
+{
+#if CONFIG_DEBUG == 0  
+    /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
+       dispersion) */
+    /* Enable write access to IWDG_PR and IWDG_RLR registers */
+    IWDG_WriteConfig(IWDG_WRITE_ENABLE);
+    /* IWDG counter clock: LSI/32 */
+    IWDG_SetPrescalerDiv(IWDG_PRESCALER_DIV128);
+    /* Set counter reload value to obtain 250ms IWDG TimeOut.
+       Counter Reload Value = 250ms/IWDG counter clock period
+                            = 250ms / (LSI/32)
+                            = 0.25s / (LsiFreq/32)
+                            = LsiFreq/(32 * 4)
+                            = LsiFreq/128
+     */
+    IWDG_CntReload(1600);
+    /* Reload IWDG counter */
+    IWDG_ReloadKey();
+    /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
+    IWDG_Enable();
+#endif    
+}
+
+int wdog_set_timeout(int wdog_time)
+{  
+	return 0;
+}
+
+

+ 41 - 0
Applications/bsp/n32/bsp.h

@@ -0,0 +1,41 @@
+#ifndef __BSP_N32_H__
+#define __BSP_N32_H__
+#if defined N32G45X
+#include "n32g45x.h"
+#endif
+
+#define SYSTEM_CLOCK (144000000u) //system clk 120M Hz
+#define TIM_CLOCK (SYSTEM_CLOCK) /*SystemClock_Config��TIM1��clk��sys PLL �������̶�2����PLLƵ��*/
+#define TIM_CLOCK_MHz (144u)
+#define TIM_SCHED_CLK (SYSTEM_CLOCK/2)
+#define TIM_SCHED_CLK_MHz (TIM_CLOCK_MHz/2)
+
+#define TIM_PWM_CLK (SYSTEM_CLOCK/2)
+#define TIM_PWM_CLK_MHz (TIM_CLOCK_MHz/2)
+
+
+#define ADC_CLOCK (30000000u)
+#define ADC_CLOCK_MHz (30u)
+#define NS_PER_TCLK (7u) /* (1/120000000 * 1000000000) */
+#define NS_2_TCLK(ns) (((ns)/NS_PER_TCLK) + 1u) //ns תΪpwmʹ�õ��Ǹ�TIM��clk count
+#define FOC_PWM_FS (16000u)
+#define FOC_PWM_period (TIM_CLOCK/FOC_PWM_FS)
+#define FOC_PWM_Half_Period (FOC_PWM_period/2)
+
+#define FOC_CTRL_US (1.0f/(float)FOC_PWM_FS)
+
+#define ADC_TRIG_CONV_LATENCY_CYCLES 12.5f
+#define ADC_SAMPLING_CYCLES 13.5f
+
+#include "bsp/n32/bsp_wrapper.h"
+
+#if defined (MC105_HW_V3)
+#include "bsp/n32/board_n32_mc105_v3.h"
+#define CONFIG_BOARD_MCXXX
+#define CONFIG_BOARD_NAME "MC105"
+#define CONFIG_HW_VERSION 3
+#endif
+
+
+#endif /* __BSP_N32_H__ 
+*/

+ 129 - 0
Applications/bsp/n32/bsp_wrapper.h

@@ -0,0 +1,129 @@
+#ifndef __BSP_WRAPPER_H__
+#define __BSP_WRAPPER_H__
+
+#define BIT(x)        ((uint32_t)((uint32_t)0x01U<<(x)))
+#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))
+
+#define GPIO_MODE_AF_PP         GPIO_Mode_AF_PP
+#define GPIO_MODE_AIN           GPIO_Mode_AIN
+#define GPIO_MODE_IN_FLOATING   GPIO_Mode_IN_FLOATING
+#define GPIO_MODE_OUT_PP        GPIO_Mode_Out_PP
+#define GPIO_OSPEED_50MHZ       GPIO_Speed_50MHz
+#define GPIO_MODE_IPU           GPIO_Mode_IPU
+
+#define RCU_GPIOA               RCC_APB2_PERIPH_GPIOA
+#define RCU_GPIOB               RCC_APB2_PERIPH_GPIOB
+#define RCU_GPIOC               RCC_APB2_PERIPH_GPIOC
+#define RCU_GPIOD               RCC_APB2_PERIPH_GPIOD
+#define RCU_AF                  RCC_APB2_PERIPH_AFIO
+#define RCU_TIMER5              RCC_APB1_PERIPH_TIM5
+#define RCU_TIMER1              RCC_APB2_PERIPH_TIM1
+#define RCU_TIMER7				RCC_APB1_PERIPH_TIM7
+#define RCU_TIMER3				RCC_APB1_PERIPH_TIM3
+#define RCU_TIMER4				RCC_APB1_PERIPH_TIM4
+#define RCU_TIMER8              RCC_APB2_PERIPH_TIM8
+#define RCU_DMA1				RCC_AHB_PERIPH_DMA1
+#define RCU_ADC1				RCC_AHB_PERIPH_ADC1
+#define RCU_ADC2				RCC_AHB_PERIPH_ADC2
+#define RCU_CAN0                RCC_APB1_PERIPH_CAN1
+
+#define SET Bit_SET
+#define RESET Bit_RESET
+
+#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
+#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
+#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))
+
+
+#define TIMER_CNT(TIMx) (TIMx->CNT)
+#define TIMER_CTL0(TIMx) (TIMx->CTRL1)
+#define TIMER_INTF(TIMx) (TIMx->STS)
+#define TIMER_CTL0_DIR   BIT(4)              /*!< timer counter direction */
+#define TIMER_CH0CV(TIMx) (TIMx->CCDAT1)
+#define TIMER_CH1CV(TIMx) (TIMx->CCDAT2)
+#define TIMER_CH2CV(TIMx) (TIMx->CCDAT3)
+#define TIMER_CH3CV(TIMx) (TIMx->CCDAT4)
+#define TIMER_CCHP(TIMx)  (TIMx->BKDT)
+#define TIMER_CHCTL1(TIMx) (TIMx->CCMOD2)
+#define TIMER_CHCTL2(TIMx) (TIMx->CCEN)
+
+
+#define gpio_init(gpio_periph, mode, speed, pin) \
+    do {\
+        GPIO_InitType GPIO_InitStructure; \
+        GPIO_InitStructure.Pin = pin; \
+	    GPIO_InitStructure.GPIO_Speed = speed; \
+	    GPIO_InitStructure.GPIO_Mode = mode; \
+	    GPIO_InitPeripheral(gpio_periph, &GPIO_InitStructure); \
+    }while(0);
+
+#define gpio_input_bit_get(gpio_periph, pin)    GPIO_ReadInputDataBit(gpio_periph, pin)
+#define gpio_bit_write(gpio_periph, pin, value) GPIO_WriteBit(gpio_periph, pin, value)
+#define gpio_bit_reset(gpio_periph, pin)        GPIO_ResetBits(gpio_periph, pin) 
+#define gpio_pin_remap_config(pin, mode)        GPIO_ConfigPinRemap(pin, mode)
+
+#define rcu_ahb_periph_clock_enable(clk)            RCC_EnableAHBPeriphClk(clk, ENABLE)
+#define rcu_ahb_periph_clock_disable(clk)           RCC_EnableAHBPeriphClk(clk, DISABLE)
+
+#define rcu_apb1_periph_clock_enable(clk)            RCC_EnableAPB1PeriphClk(clk, ENABLE)
+#define rcu_apb1_periph_clock_disable(clk)           RCC_EnableAPB1PeriphClk(clk, DISABLE)
+
+#define rcu_apb2_periph_clock_enable(clk)            RCC_EnableAPB2PeriphClk(clk, ENABLE)
+#define rcu_apb2_periph_clock_disable(clk)           RCC_EnableAPB2PeriphClk(clk, DISABLE)
+
+#define EXTI_INTERRUPT  EXTI_Mode_Interrupt
+#define EXTI_TRIG_RISING  EXTI_Trigger_Rising
+#define EXTI_TRIG_BOTH  EXTI_Trigger_Rising_Falling
+
+#define nvic_irq_enable(irq, pri, subpri) \
+    do { \
+        NVIC_InitType NVIC_InitStructure; \
+        NVIC_InitStructure.NVIC_IRQChannel = irq; \
+	    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = pri; \
+	    NVIC_InitStructure.NVIC_IRQChannelSubPriority = subpri; \
+	    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; \
+	    NVIC_Init(&NVIC_InitStructure); \
+    }while(0);
+
+#define nvic_irq_disable(irq) \
+		do { \
+			NVIC_InitType NVIC_InitStructure; \
+			NVIC_InitStructure.NVIC_IRQChannel = irq; \
+			NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; \
+			NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; \
+			NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; \
+			NVIC_Init(&NVIC_InitStructure); \
+		}while(0);
+
+#define gpio_exti_source_select(group, pin)   GPIO_ConfigEXTILine(group, pin)
+
+#define exti_init(line, mode, edge)  \
+    do { \
+        EXTI_InitType EXTI_InitStructure; \
+        EXTI_InitStructure.EXTI_Line    = line; \
+        EXTI_InitStructure.EXTI_Mode    = mode; \
+        EXTI_InitStructure.EXTI_Trigger = edge; \
+        EXTI_InitStructure.EXTI_LineCmd = ENABLE; \
+        EXTI_InitPeripheral(&EXTI_InitStructure); \
+    }while(0);
+
+#define exti_interrupt_flag_clear(flg) EXTI_ClrITPendBit(flg)
+#define exti_interrupt_flag_get(flg)   EXTI_GetITStatus(flg)
+
+#define exti_interrupt_enable(line)  \
+    do { \
+        EXTI_InitType EXTI_InitStructure; \
+        EXTI_InitStructure.EXTI_Line    = line; \
+        EXTI_InitStructure.EXTI_LineCmd = ENABLE; \
+        EXTI_InitPeripheral(&EXTI_InitStructure); \
+    }while(0);
+
+#define exti_interrupt_disable(line)  \
+    do { \
+        EXTI_InitType EXTI_InitStructure; \
+        EXTI_InitStructure.EXTI_Line    = line; \
+        EXTI_InitStructure.EXTI_LineCmd = DISABLE; \
+        EXTI_InitPeripheral(&EXTI_InitStructure); \
+    }while(0);
+#endif /* __BSP_WRAPPER_H__ 
+*/

+ 240 - 0
Applications/bsp/n32/can.c

@@ -0,0 +1,240 @@
+#include <stdio.h>
+#include "os/queue.h"
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+#include "libs/circle_buffer.h"
+
+#define CAN_RX_MESSAGE_RX_ID 1
+#define CAN_SEND_QUEUE_SIZE 32
+#define RX_ID_OFFSET 16
+#define CAN_SEND_OK 0
+#define CAN_SEND_ERROR -1
+#define CAN_SEND_WAIT_TIMEOUT -2
+
+#define CAN_DEV CAN1
+
+#define TX_NUM 64
+#define RX_NUM 64
+static c_buffer_t g_tx_circle;
+static c_buffer_t g_rx_circle;
+static uint8_t _g_tx_buffer[sizeof(CanTxMessage) * TX_NUM + 1];
+static uint8_t _g_rx_buffer[sizeof(CanRxMessage) * RX_NUM + 1];
+
+static int shark_send_can0_data(CanTxMessage *P_message);
+static uint8_t can_get_mailbox(CAN_Module *an_periph);
+/* this function can be overide by app, which need recv the can frame */
+__weak void handle_can_frame(can_id_t id, uint8_t *data, int len){
+
+}
+
+void can_rx_poll(void){
+	CanRxMessage message;
+	if (circle_get_data(&g_rx_circle, (uint8_t *)&message, sizeof(message)) != sizeof(message)) {
+		return;
+	}	
+	can_id_t can_id;
+	can_id.id = message.ExtId;
+	handle_can_frame(can_id, message.Data , message.DLC); 
+	return ;
+}
+
+void can_tx_poll(void){
+	CanTxMessage can_tr_m;
+	if (CAN_GetFlagSTS(CAN_DEV, CAN_FLAG_BOFFL)){
+		shark_can0_reset();
+	}
+	while (can_get_mailbox(CAN_DEV) != CAN_TxSTS_NoMailBox) {
+		if (circle_get_data(&g_tx_circle, (uint8_t * )&can_tr_m, sizeof(can_tr_m)) != sizeof(can_tr_m)) {
+			break;
+		}
+		CAN_TransmitMessage(CAN_DEV,&can_tr_m);
+	}
+}
+
+static u32 _can_poll_task(void *args) {
+	can_rx_poll();
+	can_tx_poll();
+	return 0;
+}
+
+static __inline__ void can_fifo_recv(int fifo){
+	CanRxMessage Rxmessage;
+
+	CAN_ReceiveMessage(CAN_DEV, fifo, &Rxmessage);
+
+	circle_put_data(&g_rx_circle, (uint8_t *)&Rxmessage,  sizeof(Rxmessage));
+
+}
+
+void CAN_RX0_IRQHandler(void)
+{
+	can_fifo_recv(CAN_FIFO0);
+}
+
+void CAN_RX1_IRQHandler(void)
+{
+	can_fifo_recv(CAN_FIFO1);
+}
+
+static void shark_can0_txrx_pin_config(void){
+    /* enable can clock */
+    rcu_apb1_periph_clock_enable(RCU_CAN0);
+    rcu_apb2_periph_clock_enable(CAN_PIN_RCU);
+    rcu_apb2_periph_clock_enable(RCU_AF);
+
+#ifdef CAN_REMAP
+	gpio_pin_remap_config(CAN_REMAP,ENABLE);
+#endif
+    gpio_init(CAN_TX_GROUP, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_TX_PIN);
+	gpio_init(CAN_RX_GROUP, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_RX_PIN);
+}
+
+static void can_filter_init(u32 id, u32 mask, u8 fifo, u8 filter)
+{
+    CAN_FilterInitType CAN_FilterInitStructure;
+    /* CAN filter init */
+    CAN_FilterInitStructure.Filter_Num            = filter;
+    CAN_FilterInitStructure.Filter_Mode           = CAN_Filter_IdMaskMode;
+    CAN_FilterInitStructure.Filter_Scale          = CAN_Filter_32bitScale;
+    CAN_FilterInitStructure.Filter_HighId         = (uint16_t)id >> 13;
+    CAN_FilterInitStructure.Filter_LowId          = (0x003F8U & (uint16_t)(id << 3)) | (1U << 2);  
+    CAN_FilterInitStructure.FilterMask_HighId     = (uint16_t)mask >> 13;
+    CAN_FilterInitStructure.FilterMask_LowId      = (0x003F8U & (uint16_t)(mask << 3)) | (1U << 2);  
+    CAN_FilterInitStructure.Filter_FIFOAssignment = fifo;
+    CAN_FilterInitStructure.Filter_Act            = ENABLE;
+    CAN1_InitFilter(&CAN_FilterInitStructure);
+    CAN_INTConfig(CAN_DEV, CAN_INT_FMP0, ENABLE);
+}
+
+static void shark_can0_config(void)
+{
+
+    CAN_InitType CAN_InitStructure;
+    /* CAN register init */
+    CAN_DeInit(CAN_DEV);
+    /* Struct init*/
+    CAN_InitStruct(&CAN_InitStructure);
+    /* CAN cell init */
+    CAN_InitStructure.TTCM              = DISABLE;
+    CAN_InitStructure.ABOM              = DISABLE;
+    CAN_InitStructure.AWKUM             = DISABLE;
+    CAN_InitStructure.NART              = ENABLE;
+    CAN_InitStructure.RFLM              = DISABLE;
+    CAN_InitStructure.TXFP              = ENABLE;
+    CAN_InitStructure.OperatingMode     = CAN_Normal_Mode;
+    CAN_InitStructure.RSJW              = CAN_RSJW_1tq;
+    CAN_InitStructure.TBS1              = CAN_TBS1_4tq;
+    CAN_InitStructure.TBS2              = CAN_TBS2_3tq;
+    CAN_InitStructure.BaudRatePrescaler = 18;
+    /*Initializes the CAN */
+    CAN_Init(CAN_DEV, &CAN_InitStructure);
+
+    /* recv my can ID, use fifo0 */
+    can_filter_init(CAN_MY_ADDRESS, CAN_FILTER_DEST_MASK, CAN_FIFO0, 0);
+
+  	//nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);  
+
+  	nvic_irq_enable(CAN_IRQ0,CAN_IRQ_PRIORITY,0);	
+}
+
+
+static int shark_send_can0_data(CanTxMessage *P_message){
+	can_tx_poll();
+	if (circle_put_data(&g_tx_circle, (u8 *)P_message, sizeof(CanTxMessage))){
+		return CAN_SEND_OK;
+	}
+	return CAN_SEND_ERROR;
+}
+
+
+static uint8_t can_get_mailbox(CAN_Module *can_periph)
+{
+    uint8_t transmit_mailbox = 0;
+    /* Check the parameters */
+
+    /* Select one empty transmit mailbox */
+    if ((CAN_DEV->TSTS & CAN_TSTS_TMEM0) == CAN_TSTS_TMEM0)
+    {
+        transmit_mailbox = 0;
+    }
+    else if ((CAN_DEV->TSTS & CAN_TSTS_TMEM1) == CAN_TSTS_TMEM1)
+    {
+        transmit_mailbox = 1;
+    }
+    else if ((CAN_DEV->TSTS & CAN_TSTS_TMEM2) == CAN_TSTS_TMEM2)
+    {
+        transmit_mailbox = 2;
+    }
+    else
+    {
+        transmit_mailbox = CAN_TxSTS_NoMailBox;
+    }
+	return transmit_mailbox;
+}
+
+
+int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
+	CanTxMessage trasnmit_msg;
+	can_id_t can_frame_id;
+	u32 total_frames = ((len + 7) >> 3);
+	int send_len = len;
+	u32 frame_id = 1;
+	can_frame_id.id = can_id;
+	can_frame_id.total = total_frames;
+
+	while(send_len > 0){
+		can_frame_id.idx = frame_id;
+
+		trasnmit_msg.StdId	= 0;
+		trasnmit_msg.ExtId	= can_frame_id.id;				
+		trasnmit_msg.RTR	= CAN_RTRQ_DATA;
+		trasnmit_msg.IDE    = CAN_ID_EXT;
+		trasnmit_msg.DLC = min(CAN_DATA_SIZE,send_len);
+		memcpy((char *)trasnmit_msg.Data, (char *)buff + (len - send_len), trasnmit_msg.DLC);
+		send_len -= trasnmit_msg.DLC;
+		frame_id ++;
+		if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
+			return CAN_SEND_ERROR;
+		}
+	}
+
+	return CAN_SEND_OK;
+
+}
+
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len){
+	CanTxMessage trasnmit_msg;
+	
+	trasnmit_msg.StdId	= 0;
+	trasnmit_msg.ExtId	= can_id;				
+	trasnmit_msg.RTR	= CAN_RTRQ_DATA;
+	trasnmit_msg.IDE	= CAN_ID_EXT;
+	trasnmit_msg.DLC = min(CAN_DLC_LENGTH,len);
+	memcpy((char *)trasnmit_msg.Data, (char *)buff, trasnmit_msg.DLC);
+
+	if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
+		return CAN_SEND_ERROR;
+	}
+	return CAN_SEND_OK;
+}
+
+
+void shark_can0_reset(void){
+	shark_can0_txrx_pin_config();
+	shark_can0_config();
+}
+
+void shark_can0_deinit(void){
+	CAN_DeInit(CAN_DEV);
+	rcu_apb1_periph_clock_disable(RCU_CAN0);
+}
+
+void shark_can0_init(void){
+	circle_buffer_init(&g_tx_circle, _g_tx_buffer, sizeof(_g_tx_buffer));
+	circle_buffer_init(&g_rx_circle, _g_rx_buffer, sizeof(_g_rx_buffer));
+
+	shark_task_create(_can_poll_task, NULL);
+	shark_can0_txrx_pin_config();
+	shark_can0_config();
+}
+

+ 76 - 0
Applications/bsp/n32/can.h

@@ -0,0 +1,76 @@
+#ifndef _Shark_Can0_h__
+#define _Shark_Can0_h__
+#include <stdio.h>
+#include "os/os_types.h"
+#include "config.h"
+//CAN DLC lenght
+#define   CAN_DLC_LENGTH     8
+
+
+#define CAN_EXTENDE_FRAME 1
+#ifdef CAN_EXTENDE_FRAME
+#define CAN_DATA_SIZE CAN_DLC_LENGTH
+#else
+#define CAN_DATA_SIZE 64
+#endif
+
+typedef union {
+	uint32_t id;
+	struct {
+		uint32_t	dest		:7; /*bit 0-6  */
+		uint32_t	src 			:7; /*bit 7-13 */
+		uint32_t	idx 			:5; /*bit 14-18 */
+		uint32_t	total		:5; /*bit 19-23 */
+		uint32_t	type		:2; /*bit 24-25 */ /*1:PT_REQ_NEED_RES ; 2:PT_RES 3:PT_REQ_NO_IND*/
+		uint32_t	retry		:3; /*bit 26-28 */
+		uint32_t	length 		:3; /*bit 29-13 */ //0-7:1-8
+	};
+}can_id_t;
+
+//CAN filter setting
+#ifdef CAN_COMMUNICATION_SPEC_V1P4
+//specification 1.4
+#define CAN_ID_FILTER_START_OFFSET       3
+#define CAN_ID_FILTER_FLAG_OFFSET         7
+#define CAN_ID_FILTER_FLAG                       0x7F
+#else
+//specification 1.3
+#define CAN_ID_FILTER_START_OFFSET       3
+#define CAN_ID_FILTER_FLAG_OFFSET         8
+#define CAN_ID_FILTER_FLAG                       0xFF
+#endif
+
+#define CAN_FILTER_DEST_MASK 0x7F
+
+#define ptype_beat_heart		0 // can heat heart
+#define ptype_request  	1 // can request with need response
+#define ptype_response			2 // can response of the request
+#define ptype_indicater	3 // can request with no need response
+
+
+#define  can_packet_priority_value       0x06
+#define  can_packet_quick_packet_value    0x01  
+
+//used when can recv
+static __inline__ uint16_t decoder_can_key(const void *buf){
+	uint8_t *key_buf = (uint8_t *)buf;
+	return key_buf[1]<<8 | key_buf[0];
+} 
+
+//used when can send
+static __inline__ void encoder_can_key(uint8_t *buff, uint16_t key) {
+	buff[0] = key & 0xFF;
+	buff[1] = (key >> 8) & 0xFF;
+}
+
+
+int shark_can0_send_message(uint32_t can_id, const void*buff, int len);
+void shark_can0_route_message(uint32_t can_id, const void *buff, int len);
+int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len);
+void shark_can0_init(void);
+void shark_can0_reset(void);
+void shark_can0_deinit(void);
+void can_rx_poll(void);
+
+#endif /* _Shark_Can0_h__ */
+

+ 158 - 0
Applications/bsp/n32/enc_intf.c

@@ -0,0 +1,158 @@
+#include "bsp/bsp_driver.h"
+#include "libs/logger.h"
+
+static void _io_init(void) {
+	rcu_apb2_periph_clock_enable(ENC_A_RCU);
+	rcu_apb2_periph_clock_enable(ENC_B_RCU);
+	rcu_apb2_periph_clock_enable(ENC_PWM_RCU);
+	rcu_apb2_periph_clock_enable(ENC_I_RCU);
+#ifdef TIMER2_PB4_PB5_REMAP
+	gpio_pin_remap_config(TIMER2_PB4_PB5_REMAP, ENABLE);
+#endif
+#ifdef TIMER1_PA15_REMAP
+	gpio_pin_remap_config(TIMER1_PA15_REMAP, ENABLE);
+#endif
+	gpio_init(ENC_A_GROUP, ENC_A_MODE, GPIO_OSPEED_50MHZ, ENC_A_PIN);
+	gpio_init(ENC_B_GROUP, ENC_B_MODE, GPIO_OSPEED_50MHZ, ENC_B_PIN);
+	gpio_init(ENC_PWM_GROUP, ENC_PWM_MODE, GPIO_OSPEED_50MHZ, ENC_PWM_PIN);
+	gpio_init(ENC_I_GROUP, ENC_I_MODE, GPIO_OSPEED_50MHZ, ENC_I_PIN);
+}
+
+static void _io_init_irq(void) {
+	gpio_exti_source_select(ENC_I_EXIT_SRC_GROUP, ENC_I_EXIT_SRC_PIN);
+	exti_init(ENC_I_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	exti_interrupt_flag_clear(ENC_I_EXTI);
+	exti_interrupt_enable(ENC_I_EXTI);
+
+	nvic_irq_enable(ENC_I_IRQ, ENC_I_EXIT_IRQ_PRIORITY, 0U);
+}
+
+void enc_intf_init(u32 rate) {
+	_io_init();
+	enc_intf_pwm_counter();
+	enc_intf_quadrature_init(rate);
+	_io_init_irq();
+}
+
+void enc_intf_quadrature_init(u32 rate) {
+	TIM_TimeBaseInitType TIM_TimeBaseStructure;
+	TIM_ICInitType TIM_ICInitStructure;
+
+	rcu_apb1_periph_clock_enable(ENC_TIMER_RCU);
+	
+	TIM_Module* TIMx = ENC_TIMER;
+	
+	//initial tim for encode
+	TIM_DeInit(TIMx);
+	TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
+	TIM_TimeBaseStructure.Period = rate - 1;
+	TIM_TimeBaseStructure.Prescaler = 0;
+	TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
+	TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;
+	TIM_InitTimeBase(TIMx,&TIM_TimeBaseStructure);
+
+	TIM_InitIcStruct(&TIM_ICInitStructure);
+	TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_RISING;
+	TIM_ICInitStructure.IcFilter = ENC_FILTER_NR;
+	TIM_ICInitStructure.Channel = TIM_CH_1;
+	TIM_ICInit(TIMx,&TIM_ICInitStructure);
+	TIM_ICInitStructure.Channel = TIM_CH_2;
+	TIM_ICInit(TIMx,&TIM_ICInitStructure);
+
+	//qr encode set
+	TIM_ConfigEncoderInterface(TIMx,TIM_ENCODE_MODE_TI12,TIM_IC_POLARITY_FALLING,TIM_IC_POLARITY_RISING);
+		
+	TIM_ConfigArPreload(TIMx,ENABLE);
+	TIM_SetCnt(TIMx,0);
+	TIM_Enable(TIMx,ENABLE);
+	
+	TIM_ClearFlag(TIMx,TIM_FLAG_UPDATE);
+	TIM_ConfigInt(TIMx,TIM_INT_UPDATE,ENABLE);
+}
+
+void enc_intf_pwm_counter(void) {
+	TIM_TimeBaseInitType TIM_TimeBaseStructure;
+	TIM_ICInitType TIM_ICInitStructure;
+
+	rcu_apb1_periph_clock_enable(ENC_PWM_TIMER_RCU);
+
+	TIM_Module* TIMx = ENC_PWM_TIMER;
+
+	TIM_DeInit(TIMx);
+	TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
+	TIM_TimeBaseStructure.Period = 65535;
+	TIM_TimeBaseStructure.Prescaler = TIM_PWM_CLK/PWM_TIME_CLK - 1;
+	TIM_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
+	TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;
+	TIM_InitTimeBase(TIMx,&TIM_TimeBaseStructure);
+
+    TIM_ICInitStructure.Channel     = ENC_PWM_TIMER_CHAN;
+    TIM_ICInitStructure.IcPolarity  = TIM_IC_POLARITY_RISING;
+    TIM_ICInitStructure.IcSelection = TIM_IC_SELECTION_DIRECTTI;
+    TIM_ICInitStructure.IcPrescaler = TIM_IC_PSC_DIV1;
+    TIM_ICInitStructure.IcFilter    = ENC_FILTER_NR;
+
+    TIM_ConfigPwmIc(TIMx, &TIM_ICInitStructure);
+
+    /* Select the TIM3 Input Trigger: TI2FP2 */
+    TIM_SelectInputTrig(TIMx, TIM_TRIG_SEL_TI1FP1);
+
+    /* Select the slave Mode: Reset Mode */
+    TIM_SelectSlaveMode(TIMx, TIM_SLAVE_MODE_RESET);
+
+    /* Enable the Master/Slave Mode */
+    TIM_SelectMasterSlaveMode(TIMx, TIM_MASTER_SLAVE_MODE_ENABLE);
+
+    /* TIM enable counter */
+    TIM_Enable(TIMx, ENABLE);
+
+	TIM_ClearFlag(TIMx,ENC_PWM_TIMER_INT_FLG);
+    /* Enable the CC2 Interrupt Request */
+    TIM_ConfigInt(TIMx, ENC_PWM_TIMER_IRQ_CH, ENABLE);
+
+	nvic_irq_enable(ENC_PWM_TIMER_IRQ, ENC_PWM_IRQ_PRIORITY, 0);
+
+}
+
+__weak void ENC_TIMER_Overflow(void) {
+
+}
+
+void ENC_TIMER_IRQHandler(void) {
+	if (SET == TIM_GetIntStatus(ENC_TIMER, TIM_INT_UPDATE)) {
+		TIM_ClrIntPendingBit(ENC_TIMER, TIM_INT_UPDATE);
+		ENC_TIMER_Overflow();
+	}
+}
+
+
+__weak void ENC_ABI_IRQHandler(void) {
+
+}
+
+void ABI_I_IRQHandler(void) {
+	ENC_ABI_IRQHandler();
+}
+
+__weak void ENC_PWM_Duty_Handler(float t, float d) {
+
+}
+
+static float pwm_freq = 0.0f;
+void ENC_PWM_IRQHandler(void) {
+    if(SET == TIM_GetIntStatus(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG)){
+        /* clear channel 0 interrupt bit */
+        TIM_ClrIntPendingBit(ENC_PWM_TIMER, ENC_PWM_TIMER_INT_FLG);
+        /* read channel 0 capture value */
+        u32 ic0value = TIMER_CH0CV(ENC_PWM_TIMER)+1;
+		u32 ic1value = TIMER_CH1CV(ENC_PWM_TIMER)+1;
+		float p_calc = ENC_PWM_Calc_P(ic0value);
+		float d_calc = ENC_PWM_Calc_P(ic1value);
+		ENC_PWM_Duty_Handler(p_calc, d_calc);
+		pwm_freq = (float)PWM_TIME_CLK/((float)ic0value);
+    }
+}
+
+float enc_get_pwm_freq(void) {
+	return pwm_freq;
+}

+ 27 - 0
Applications/bsp/n32/enc_intf.h

@@ -0,0 +1,27 @@
+#ifndef _ENC_INTF_H__
+#define _ENC_INTF_H__
+#include "os/os_types.h"
+#include "bsp/bsp.h"
+
+#define PWM_TIME_CLK 9000000U
+
+
+#define ENC_DIR_UP 1
+#define ENC_DIR_DOWN 2
+
+#define ENC_PWM_Calc_P(t) ((float)t / (float)PWM_TIME_CLK)
+
+#define ENC_COUNT TIMER_CNT(ENC_TIMER)
+
+#define ENC_Direction() ((TIMER_CTL0(ENC_TIMER) & TIMER_CTL0_DIR)?ENC_DIR_DOWN:ENC_DIR_UP)
+
+#define ENC_OverFlow() ((TIMER_INTF(ENC_TIMER) & TIM_FLAG_UPDATE)?true:false)
+#define ENC_ClearUpFlags() (TIMER_INTF(ENC_TIMER) = (~(uint32_t)TIM_FLAG_UPDATE))
+
+void enc_intf_quadrature_init(u32 rate);
+void enc_intf_pwm_counter(void);
+void enc_intf_init(u32 rate);
+float enc_get_pwm_freq(void);
+
+#endif /*_ENC_INTF_H__*/
+

+ 87 - 0
Applications/bsp/n32/fan_pwm.c

@@ -0,0 +1,87 @@
+#include "fan_pwm.h"
+
+void fan_pwm_init(void){
+	uint16_t chno = FAN_PWM_CHAN;
+	TIM_TimeBaseInitType TIM_TimeBaseStructure;
+	OCInitType TIM_OCInitStructure;
+
+	TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
+    /* Time base configuration */
+    TIM_TimeBaseStructure.Period    = FAN_MAX_DUTY_COUNT;
+    TIM_TimeBaseStructure.Prescaler = TIM_CLOCK_MHz - 1;
+    TIM_TimeBaseStructure.ClkDiv    = 0;
+    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
+
+    TIM_InitTimeBase(FAN_PWM_TIMER, &TIM_TimeBaseStructure);
+
+    /* PWM1 Mode configuration: Channel1 */
+    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
+    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
+    TIM_OCInitStructure.Pulse       = FAN_MAX_DUTY_COUNT-1;
+    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;
+	if (chno == TIM_CH_1) {
+		TIM_InitOc1(FAN_PWM_TIMER, &TIM_OCInitStructure);
+	}else if (chno == TIM_CH_2) {
+		TIM_InitOc2(FAN_PWM_TIMER, &TIM_OCInitStructure);
+	}else if (chno == TIM_CH_3) {
+		TIM_InitOc3(FAN_PWM_TIMER, &TIM_OCInitStructure);
+	}else if (chno == TIM_CH_4) {
+		TIM_InitOc4(FAN_PWM_TIMER, &TIM_OCInitStructure);
+	}
+
+    TIM_ConfigOc1Preload(FAN_PWM_TIMER, TIM_OC_PRE_LOAD_ENABLE);
+
+    TIM_ConfigArPreload(FAN_PWM_TIMER, ENABLE);
+
+    /* TIM3 enable counter */
+    TIM_Enable(FAN_PWM_TIMER, ENABLE);
+
+}
+
+
+void fan_stop(void) {
+	TIM_Enable(FAN_PWM_TIMER, DISABLE);
+}
+
+void fan_set_duty(u8 duty) {
+	uint16_t chno = FAN_PWM_CHAN;
+	if (duty > 100) {
+		duty = 100;
+	}else if (duty > 0 && duty < 30) {
+		duty = 30;
+	}
+	u32 count = (float)duty * (float)FAN_MAX_DUTY_COUNT / 100.0f;
+	if (chno == TIM_CH_1) {
+		TIM_SetCmp1(FAN_PWM_TIMER, count);
+	}else if (chno == TIM_CH_2) {
+		TIM_SetCmp2(FAN_PWM_TIMER, count);
+	}else if (chno == TIM_CH_3) {
+		TIM_SetCmp3(FAN_PWM_TIMER, count);
+	}else if (chno == TIM_CH_4) {
+		TIM_SetCmp4(FAN_PWM_TIMER, count);
+	}
+	if (FAN_PWM_TIMER == TIM8) {
+		if (count == 0) {
+			TIM_EnableCtrlPwmOutputs(FAN_PWM_TIMER, DISABLE);
+		}else {
+			TIM_EnableCtrlPwmOutputs(FAN_PWM_TIMER, ENABLE);
+		}
+	}
+}
+
+
+bool fan_pwm_is_running(void) {
+	uint16_t chno = FAN_PWM_CHAN;
+	u32 count = 0;
+	if (chno == TIM_CH_1) {
+		count = TIM_GetCap1(FAN_PWM_TIMER);
+	}else if (chno == TIM_CH_2) {
+		count = TIM_GetCap2(FAN_PWM_TIMER);
+	}else if (chno == TIM_CH_3) {
+		count = TIM_GetCap3(FAN_PWM_TIMER);
+	}else if (chno == TIM_CH_4) {
+		count = TIM_GetCap4(FAN_PWM_TIMER);
+	}
+	return (count != 0);
+}
+

+ 23 - 0
Applications/bsp/n32/fan_pwm.h

@@ -0,0 +1,23 @@
+#ifndef _FAN_PWM_H__
+#define _FAN_PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define PWM_FREQ_HZ    200
+#define FAN_DUTY_COUNT (1000000/200)
+#define FAN_MAX_DUTY_COUNT (FAN_DUTY_COUNT/2)
+
+#ifdef CONFIG_BOARD_MCXXX
+void fan_pwm_init(void);
+void fan_stop(void);
+void fan_set_duty(u8 duty); //duty 0-100
+bool fan_pwm_is_running(void);
+#else
+static void fan_pwm_init(void) {}
+static void fan_stop(void) {}
+static void fan_set_duty(u8 duty) {}
+bool fan_pwm_is_running(void){return false;}
+
+#endif
+#endif /* _FAN_PWM_H__ */
+

+ 210 - 0
Applications/bsp/n32/fmc_flash.c

@@ -0,0 +1,210 @@
+#include "bsp/bsp_driver.h"
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_addr(uint32_t addr, int len);
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len);
+
+static uint32_t _sn_addr(void);
+static uint32_t _data_addr(int index);
+static uint32_t _maigc_addr(void);
+
+static uint32_t _nv_tbl_write_addr = 0;
+
+static u8 _nv_tbl_write_cache[4];
+static u8 _nv_tbl_write_remain;
+
+void fmc_write_sn(uint8_t *sn, int len){
+	_fmc_erase_write_data(_sn_addr(), sn, len);
+}
+
+void fmc_read_sn(uint8_t *sn, int len){
+	_fmc_read_data(_sn_addr(), sn, len);
+}
+
+void fmc_write_data(int index, uint8_t *data, int len){
+	_fmc_erase_write_data(_data_addr(index), data, len);
+}
+
+void fmc_read_data(int index, uint8_t *data, int len){
+	_fmc_read_data(_data_addr(index), data, len);
+}
+
+static __inline__ void _fmc_flag_clear(void) {
+	FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_PVERR | FLASH_FLAG_EVERR | FLASH_FLAG_EOP);
+}
+
+
+void fmc_write_magic(uint32_t magic){
+	uint32_t address = _maigc_addr();
+	uint32_t length, checksum, value;
+
+	value = REG32(address + 8);
+	if (magic == value) {
+		return;
+	}
+
+	length = REG32(address);
+	checksum = REG32(address + 4);
+
+	FLASH_Unlock();
+
+	if (value != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		FLASH_EraseOnePage(address);
+
+		_fmc_flag_clear();
+		FLASH_ProgramWord(address, length);
+
+		_fmc_flag_clear();
+		FLASH_ProgramWord(address + 4, checksum);
+	}
+
+	if (magic != 0xFFFFFFFF) {
+		_fmc_flag_clear();
+		FLASH_ProgramWord(address + 8, magic);
+	}
+
+	FLASH_Lock();
+}
+
+uint32_t fmc_read_magic(void){
+	uint32_t magic = 0x5555aaaa;
+	_fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
+	return magic;
+}
+
+//if flash is lager than 256k, we just use the 256k
+static uint32_t __inline__ _flash_capatity(void){
+	uint32_t capacity;
+	capacity = /*(REG32(0x1FFFF7E0) & 0xFFFF)*/256 << 10;
+	if (capacity > (256 * 1024)){
+		capacity =  256 * 1024;
+	}
+	return capacity;
+}
+
+static uint32_t _sn_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
+}
+
+static uint32_t _data_addr(int index){
+	return 0x08000000 + (_flash_capatity() - one_page_size * index);
+}
+
+static uint32_t _maigc_addr(void){
+	return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
+}
+
+static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
+	int i = 0;
+	for (i = 0; i < len; i++){
+		data[i] = REG8(addr + i);
+	}
+}
+
+uint32_t fmc_get_addr(int page) {
+	return 0x08000000 + (_flash_capatity() - one_page_size * page);
+}
+
+void fmc_erase_trq_table(int addr, int len){
+	_fmc_erase_addr(addr, len);
+	_nv_tbl_write_addr = 0;
+}
+void fmc_write_trq_table(int addr, uint8_t *data, int len){
+	_fmc_write_data(addr + _nv_tbl_write_addr, data, len);
+	_nv_tbl_write_addr += len;
+}
+
+void fmc_write_trq_table_begin(int addr)
+{
+	_nv_tbl_write_addr = addr;
+	_nv_tbl_write_remain = 0;
+}
+
+static void fmc_write_trq_table_flush(void)
+{
+	u32 value = *(u32 *) _nv_tbl_write_cache;
+
+	if ((_nv_tbl_write_addr % one_page_size) == 0) {
+		_fmc_flag_clear();
+		FLASH_EraseOnePage(_nv_tbl_write_addr);
+	}
+
+	_fmc_flag_clear();
+	FLASH_ProgramWord(_nv_tbl_write_addr, value);
+
+	_nv_tbl_write_addr += _nv_tbl_write_remain;
+	_nv_tbl_write_remain = 0;
+}
+
+void fmc_write_trq_table_continue(const u8 *data, int len)
+{
+	const u8 *data_end;
+
+	FLASH_Unlock();
+
+	for (data_end = data + len; data < data_end; data++) {
+		if (_nv_tbl_write_remain >= sizeof(_nv_tbl_write_cache)) {
+			fmc_write_trq_table_flush();
+		}
+
+		_nv_tbl_write_cache[_nv_tbl_write_remain] = *data;
+		_nv_tbl_write_remain++;
+	}
+
+	FLASH_Lock();
+}
+
+void fmc_write_trq_table_end(void)
+{
+	if (_nv_tbl_write_remain > 0) {
+		FLASH_Unlock();
+		fmc_write_trq_table_flush();
+		FLASH_Lock();
+	}
+}
+
+extern void wdog_reload(void);
+static void _fmc_erase_addr(uint32_t addr, int len){
+	FLASH_Unlock();
+	uint32_t pages = len/one_page_size + (((len % one_page_size) > 0)?1:0);
+	for (int i = 0; i < pages; i++){
+		_fmc_flag_clear();
+		FLASH_EraseOnePage(addr + i * one_page_size);
+		wdog_reload();
+	}
+	FLASH_Lock();
+}
+
+static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
+	FLASH_Unlock();
+	int total_words = len / 4;
+	uint32_t *p_u32_data = (uint32_t *)data;
+	int i;
+	for (i = 0; i < total_words; i++){
+		_fmc_flag_clear();
+		FLASH_ProgramWord(addr, p_u32_data[i]);
+		data += 4;
+		addr += 4;
+	}
+
+	int remain_len = len - total_words * 4;
+	if (remain_len > 0){
+		uint32_t words = 0;
+		for (int i = 0; i < remain_len; i++){
+			words |= data[i] << (8*i);
+		}
+		_fmc_flag_clear();
+		FLASH_ProgramWord(addr, words);
+	}
+	FLASH_Lock();
+}
+
+
+static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len){
+	_fmc_erase_addr(addr, len);
+	_fmc_write_data(addr, data, len);
+}
+

+ 25 - 0
Applications/bsp/n32/fmc_flash.h

@@ -0,0 +1,25 @@
+#ifndef _FMC_FLASH_H__
+#define _FMC_FLASH_H__
+#include <stdint.h>
+
+#define one_page_size 2048
+
+#define data_bk_page_index 4
+#define data_page_index 3
+#define sn_page_index 2
+#define magic_page_index 1 //must is the last page in 256K eara
+
+void fmc_write_sn(uint8_t *sn, int len);
+void fmc_read_sn(uint8_t *sn, int len);
+
+void fmc_write_data(int index, uint8_t *data, int len);
+void fmc_read_data(int index, uint8_t *data, int len);
+void fmc_write_magic(uint32_t magic);
+uint32_t fmc_read_magic(void);
+uint32_t fmc_get_addr(int page);
+void fmc_write_trq_table_begin(int addr);
+void fmc_write_trq_table_continue(const u8 *data, int len);
+void fmc_write_trq_table_end(void);
+
+#endif /* _FMC_FLASH_H__ */
+

+ 162 - 0
Applications/bsp/n32/gpio.c

@@ -0,0 +1,162 @@
+#include "bsp/bsp_driver.h"
+#include "libs/utils.h"
+
+/*
+* gpio.c
+* all pins used as gpio(in/out/irq) must be init&accessed here
+*/
+
+void gpio_pin_init(void){
+	rcu_apb2_periph_clock_enable(RCU_GPIOA);
+    rcu_apb2_periph_clock_enable(RCU_GPIOB);
+	rcu_apb2_periph_clock_enable(RCU_GPIOC);
+	rcu_apb2_periph_clock_enable(RCU_GPIOD);
+	rcu_apb2_periph_clock_enable(RCU_AF);
+
+#ifdef CONFIG_BEEP
+	gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
+	gpio_beep(50);
+#endif
+}
+
+
+void gpio_beep(u32 ms) {
+#ifdef CONFIG_BEEP
+	gpio_bit_write(GPIOB, GPIO_PIN_2, SET);
+	delay_ms(ms);
+	gpio_bit_write(GPIOB, GPIO_PIN_2, RESET);
+#endif
+}
+
+void gpio_mc_brk_init(void) {
+#ifdef GPIO_BRAKE_IN_GROUP
+	rcu_apb2_periph_clock_enable(GPIO_BRAKE_IN_RCU);
+#ifdef GPIO_BRAKE_PIN_REMAP
+	gpio_pin_remap_config(GPIO_BRAKE_PIN_REMAP, ENABLE);
+#endif
+	gpio_init(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE_IN_PIN);
+	
+	gpio_exti_source_select(GPIO_BRAKE_EXIT_SRC_GROUP, GPIO_BRAKE_EXIT_SRC_PIN);
+	exti_init(GPIO_BRAKE_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(GPIO_BRAKE_IRQ, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_BRAKE_EXTI);
+	exti_interrupt_enable(GPIO_BRAKE_EXTI);	
+#endif
+#ifdef GPIO_BRAKE1_IN_GROUP
+	rcu_periph_clock_enable(GPIO_BRAKE1_IN_RCU);
+	gpio_init(GPIO_BRAKE1_IN_GROUP, GPIO_BRAKE1_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE1_IN_PIN);
+
+	gpio_exti_source_select(GPIO_BRAKE1_EXIT_SRC_GROUP, GPIO_BRAKE1_EXIT_SRC_PIN);
+	exti_init(GPIO_BRAKE1_EXTI, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+	nvic_irq_enable(GPIO_BRAKE1_IRQ, EBREAK_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_BRAKE1_EXTI);
+	exti_interrupt_enable(GPIO_BRAKE1_EXTI);
+#endif
+}
+
+void gpio_mlock_init(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	rcu_apb2_periph_clock_enable(GPIO_MLOCK_IN_RCU);
+	gpio_init(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_MLOCK_IN_PIN);
+#endif
+}
+
+void gpio_fan_det_init(void) {
+#ifdef GPIO_FAN1_IN_GROUP
+	rcu_apb2_periph_clock_enable(GPIO_FAN1_IN_RCU);
+	gpio_init(GPIO_FAN1_IN_GROUP, GPIO_FAN1_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN1_IN_PIN);
+	gpio_exti_source_select(GPIO_FAN1_EXIT_SRC_GROUP, GPIO_FAN1_EXIT_SRC_PIN);
+	exti_init(GPIO_FAN1_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	nvic_irq_enable(GPIO_FAN1_IRQ, ENC_OTHER_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_FAN1_EXTI);
+	exti_interrupt_enable(GPIO_FAN1_EXTI);
+#endif
+#ifdef GPIO_FAN2_IN_GROUP
+	rcu_periph_clock_enable(GPIO_FAN2_IN_RCU);
+	gpio_init(GPIO_FAN2_IN_GROUP, GPIO_FAN2_IN_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN2_IN_PIN);
+	gpio_exti_source_select(GPIO_FAN2_EXIT_SRC_GROUP, GPIO_FAN2_EXIT_SRC_PIN);
+	exti_init(GPIO_FAN2_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+	nvic_irq_enable(GPIO_FAN2_IRQ, ENC_OTHER_IRQ_PRIORITY, 0U);
+	exti_interrupt_flag_clear(GPIO_FAN2_EXTI);
+	exti_interrupt_enable(GPIO_FAN2_EXTI);
+#endif
+}
+
+void gpio_phase_u_detect(bool enable) {
+#ifdef GPIO_UDEC_OUT_GROUP
+	if (enable) {
+		gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_DISABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_DISABLE, ENABLE);
+	#endif
+		gpio_bit_write(GPIO_UDEC_OUT_GROUP, GPIO_UDEC_OUT_PIN, SET);
+	}else {
+		gpio_init(GPIO_UDEC_OUT_GROUP, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_UDEC_OUT_PIN);
+	#ifdef GPIO_UDEC_OUT_REMAP_ENABLE
+		gpio_pin_remap_config(GPIO_UDEC_OUT_REMAP_ENABLE, ENABLE);
+	#endif
+	}
+#endif
+}
+
+
+void gpio_led_init(void) {
+#ifdef GPIO_LED_OUT_GROUP
+	rcu_apb2_periph_clock_enable(GPIO_LED_OUT_RCU);
+	gpio_init(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_LED_OUT_PIN);
+	gpio_bit_reset(GPIO_LED_OUT_GROUP, GPIO_LED_OUT_PIN);
+#endif
+}
+
+void gpio_brk_light_init(void) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	rcu_apb2_periph_clock_enable(GPIO_BRAKE_LIGHT_OUT_RCU);
+	gpio_init(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_BRAKE_LIGHT_OUT_PIN);
+	gpio_bit_reset(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN);
+#endif
+}
+
+void mc_gpio_init(void) {
+	gpio_mlock_init();
+	gpio_mc_brk_init();
+	gpio_fan_det_init();
+	gpio_led_init();
+	gpio_brk_light_init();
+}
+
+
+void gpio_led_enable(bool enable) {
+#ifdef GPIO_LED_OUT_GROUP
+	gpio_bit_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?SET:RESET);
+#endif
+}
+
+void gpio_brk_light_enable(bool enable) {
+#ifdef GPIO_BRAKE_LIGHT_OUT_GROUP
+	gpio_bit_write(GPIO_BRAKE_LIGHT_OUT_GROUP, GPIO_BRAKE_LIGHT_OUT_PIN, enable?SET:RESET);
+#endif
+}
+
+
+bool mc_get_gpio_brake(void) {
+	return gpio_input_bit_get(GPIO_BRAKE_IN_GROUP, GPIO_BRAKE_IN_PIN) == SET;
+}
+
+bool mc_get_gpio_brake1(void) {
+#ifdef GPIO_BRAKE1_IN_GROUP
+	return gpio_input_bit_get(GPIO_BRAKE1_IN_GROUP, GPIO_BRAKE1_IN_PIN) == SET;
+#else
+	return mc_get_gpio_brake();
+#endif
+}
+
+
+bool gpio_motor_locked(void) {
+#ifdef GPIO_MLOCK_IN_GROUP
+	return gpio_input_bit_get(GPIO_MLOCK_IN_GROUP, GPIO_MLOCK_IN_PIN) == RESET;
+#else
+	return false;
+#endif
+}
+
+

+ 28 - 0
Applications/bsp/n32/gpio.h

@@ -0,0 +1,28 @@
+
+
+#ifndef _GPIO_PIN_H__
+#define _GPIO_PIN_H__
+
+#include "bsp.h"
+#include "os/os_types.h"
+typedef struct {
+	uint32_t group;
+	uint32_t pin;
+	uint32_t mode;
+	uint32_t speed;
+	int init_value; //-1 input, 0 L, 1 H
+}gpio_pin_config_t;
+
+void gpio_pin_init(void);
+bool gpio_get_brake(void) ;
+void gpio_beep(u32 ms);
+void gpio_phase_u_detect(bool enable);
+void mc_brk_gpio_init(void);
+bool mc_get_gpio_brake(void);
+void mc_gpio_init(void);
+bool gpio_motor_locked(void);
+bool mc_get_gpio_brake1(void);
+void gpio_led_enable(bool enable);
+void gpio_brk_light_enable(bool enable);
+
+#endif /* _GPIO_PIN_H__ */

+ 199 - 0
Applications/bsp/n32/mc_irqs.c

@@ -0,0 +1,199 @@
+#include <stdbool.h>
+#include "bsp.h"
+#include "adc.h"
+/*!
+    \brief      this function handles NMI exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void NMI_Handler(void)
+{
+	while(1);
+}
+
+/*!
+    \brief      this function handles HardFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void HardFault_Handler(void){
+	while(1) {
+	}
+}
+
+/*!
+    \brief      this function handles MemManage exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void MemManage_Handler(void)
+{
+    /* if Memory Manage exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles BusFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void BusFault_Handler(void)
+{
+    /* if Bus Fault exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles UsageFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void UsageFault_Handler(void)
+{
+    /* if Usage Fault exception occurs, go to infinite loop */
+    while (1){
+    }
+}
+
+/*!
+    \brief      this function handles DebugMon exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void DebugMon_Handler(void)
+{
+	while(1);
+}
+
+void SVC_Handler(void) {
+	while(1);
+}
+
+void PendSV_Handler(void) {
+	while(1);
+}
+__weak void MC_Brake_IRQHandler(void) {
+
+}
+__weak void MC_Protect_IRQHandler(void) {
+
+}
+__weak void TIMER_UP_IRQHandler(void) {
+
+}
+
+__weak void ADC_IRQHandler(void) {
+
+}
+
+__weak void HALL_IRQHandler(void) {
+
+}
+
+__weak void ABI_I_IRQHandler(void) {
+
+}
+
+__weak void Fan_IRQHandler(int idx) {
+
+}
+
+void ADC1_2_IRQHandler(void)
+{
+	ADC_IRQHandler();
+	adc_clear_irq_flags();
+}
+
+void PWM_UP_IRQHandler(void) {
+	if (TIM_GetIntStatus(MOS_PWM_TIMER, TIM_INT_UPDATE)) {
+		TIM_ClrIntPendingBit(MOS_PWM_TIMER, TIM_INT_UPDATE);
+		TIMER_UP_IRQHandler();
+	}
+}
+
+void PWM_BRK_IRQHandler(void) {
+	if (TIM_GetIntStatus(MOS_PWM_TIMER, TIM_INT_BREAK)) {
+		TIM_ClrIntPendingBit(MOS_PWM_TIMER, TIM_INT_BREAK);
+		MC_Protect_IRQHandler();
+	}
+}
+
+void EXTI0_IRQHandler(void)
+{
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE0)){
+		exti_interrupt_flag_clear(EXTI_LINE0);
+
+	}	
+}
+
+void EXTI2_IRQHandler(void)
+{
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE2)){
+		exti_interrupt_flag_clear(EXTI_LINE2);
+	}	
+}
+
+
+void EXTI3_IRQHandler(void)
+{
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE3)){
+		exti_interrupt_flag_clear(EXTI_LINE3);
+		MC_Brake_IRQHandler();
+	}
+}
+
+void EXTI4_IRQHandler(void)
+{
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE4)){
+		exti_interrupt_flag_clear(EXTI_LINE4);
+	}	
+}
+
+void EXTI9_5_IRQHandler(void){
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE5)){
+		exti_interrupt_flag_clear(EXTI_LINE5);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE6)){
+		exti_interrupt_flag_clear(EXTI_LINE6);
+	}	
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE7)){
+		exti_interrupt_flag_clear(EXTI_LINE7);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE8)){
+		exti_interrupt_flag_clear(EXTI_LINE8);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE9)){
+		exti_interrupt_flag_clear(EXTI_LINE9);
+	}	
+}
+
+void EXTI15_10_IRQHandler(void){
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE10)){
+		exti_interrupt_flag_clear(EXTI_LINE10);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE11)){
+		exti_interrupt_flag_clear(EXTI_LINE11);
+		Fan_IRQHandler(0);
+	}	
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE12)){
+		exti_interrupt_flag_clear(EXTI_LINE12);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE13)){
+		exti_interrupt_flag_clear(EXTI_LINE13);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE14)){
+		exti_interrupt_flag_clear(EXTI_LINE14);
+	}
+	if(RESET != exti_interrupt_flag_get(EXTI_LINE15)){
+		exti_interrupt_flag_clear(EXTI_LINE15);
+		ABI_I_IRQHandler();
+	}	
+}

+ 242 - 0
Applications/bsp/n32/pwm.c

@@ -0,0 +1,242 @@
+#include "bsp/bsp.h"
+#include "bsp/bsp_driver.h"
+#include "os/os_task.h"
+#include "libs/logger.h"
+/*
+以下主要是在某一相电路无法采集的时候,需要对这相的pwm挖坑处理
+timer 分配:
+timer0 -> ch0-2 互补pwm
+        ch4 event, update event 触发DMA(ch3,4)实现CCR的自更新
+timer1 -> 触发ADC采样,GD32不支持多channel 或方式触发输出,通过timer1的 ch0 compara 配置 TRGO触发ADC,但是需要在一个PWM周期内触发2次(单电阻)
+timer0 master --> timer1 slave/master 确保timer0,1同步开始,同频同相位
+
+DMA 分配:
+DMA0 ch4 -> timer0 update event
+    ch3 -> timer0 chan3 CC event
+
+    ch1 -> timer1 update event,需要更新CCR
+*/
+
+static void _init_pwm_timer(bool);
+static void _pwm_gpio_config(void);
+#ifndef PWM_BRAKE_GROUP
+static void _gpio_brakein_irq_enable(void);
+#endif
+u16 timer_update_buffer[6] = {0};
+
+
+void pwm_3phase_init(void){
+	_pwm_gpio_config();
+    _init_pwm_timer(true);
+}
+
+void pwm_3phase_sides(bool hon, bool lon) {
+	if (hon && lon) {
+		return;
+	}
+	TIM_DeInit(MOS_PWM_TIMER);
+	rcu_apb2_periph_clock_enable(PWM_TIM_CLK);
+    gpio_init(PWM_U_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_U_P_PIN);
+    gpio_init(PWM_V_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_V_P_PIN);
+    gpio_init(PWM_W_P_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_W_P_PIN);
+
+    gpio_init(PWM_U_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_U_N_PIN);
+    gpio_init(PWM_V_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_V_N_PIN);
+    gpio_init(PWM_W_N_GROUP,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,PWM_W_N_PIN);
+
+	sys_debug("pwm_3phase_sides\n");
+	/* 开上桥或者下桥之前先关闭下桥或者上桥 */
+	if (hon) {
+		_pwm_gpio_config();
+		_init_pwm_timer(false);
+		delay_us(10);
+		pwm_start();
+		pwm_update_duty(FOC_PWM_Half_Period-200, FOC_PWM_Half_Period-200, FOC_PWM_Half_Period-200);
+	}else if (lon) {
+		gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, RESET);
+		gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, RESET);
+		gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, RESET);
+
+		delay_us(10);
+		gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, SET);
+		gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, SET);
+		gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, SET);
+	}else {
+#if 0		
+		gpio_bit_write(PWM_U_P_GROUP, PWM_U_P_PIN, RESET);
+		gpio_bit_write(PWM_V_P_GROUP, PWM_V_P_PIN, RESET);
+		gpio_bit_write(PWM_W_P_GROUP, PWM_W_P_PIN, RESET);
+
+		gpio_bit_write(PWM_U_N_GROUP, PWM_U_N_PIN, RESET);
+		gpio_bit_write(PWM_V_N_GROUP, PWM_V_N_PIN, RESET);
+		gpio_bit_write(PWM_W_N_GROUP, PWM_W_N_PIN, RESET);
+#else
+		pwm_3phase_init();
+#endif
+	}
+}
+
+static void _pwm_gpio_config(void)
+{
+    rcu_apb2_periph_clock_enable(PWM_U_P_RCU);
+    rcu_apb2_periph_clock_enable(PWM_V_P_RCU);
+	rcu_apb2_periph_clock_enable(PWM_W_P_RCU);
+    rcu_apb2_periph_clock_enable(PWM_U_N_RCU);
+    rcu_apb2_periph_clock_enable(PWM_V_N_RCU);
+	rcu_apb2_periph_clock_enable(PWM_W_N_RCU);	
+    rcu_apb2_periph_clock_enable(RCU_AF);
+
+    /*configure PA8 PA9 PA10(TIMER0 CH0 CH1 CH2) as alternate function*/
+    gpio_init(PWM_U_P_GROUP,PWM_U_P_MODE,GPIO_OSPEED_50MHZ,PWM_U_P_PIN);
+    gpio_init(PWM_V_P_GROUP,PWM_V_P_MODE,GPIO_OSPEED_50MHZ,PWM_V_P_PIN);
+    gpio_init(PWM_W_P_GROUP,PWM_W_P_MODE,GPIO_OSPEED_50MHZ,PWM_W_P_PIN);
+
+    /*configure PB13 PB14 PB15(TIMER0 CH0N CH1N CH2N) as alternate function*/
+    gpio_init(PWM_U_N_GROUP,PWM_U_N_MODE,GPIO_OSPEED_50MHZ,PWM_U_N_PIN);
+    gpio_init(PWM_V_N_GROUP,PWM_V_N_MODE,GPIO_OSPEED_50MHZ,PWM_V_N_PIN);
+    gpio_init(PWM_W_N_GROUP,PWM_W_N_MODE,GPIO_OSPEED_50MHZ,PWM_W_N_PIN);
+
+	/*configure BRAKE IN*/
+#ifdef PWM_BRAKE_GROUP
+    /* TIMER0 BKIN */
+	rcu_apb2_periph_clock_enable(PWM_BRAKE_RCU);
+    gpio_init(PWM_BRAKE_GROUP, PWM_BRAKE_MODE, GPIO_OSPEED_50MHZ, PWM_BRAKE_PIN);
+#endif
+}
+
+static u8 _dead_time(u16 t) {
+	if (t < 128) {
+		return (u8 )t;
+	}else if (t <= (64 + 63) * 2) { //11 1111
+		return ((((u8)2<<6) + (t-64)/2));
+	}else if (t <= (32 + 31) * 8) {
+		return (((u8)3 << 6) + (t - 32)/8);
+	}else {
+		if ((t-32)/16 > 63) {
+			return 0xFF;
+		}
+		return (((u8)7<<3) + (t - 32)/16);
+	}
+}
+
+static void _init_pwm_timer(bool enable_brk) {
+	TIM_TimeBaseInitType TIM1_TimeBaseStructure;
+	OCInitType TIM1_OCInitStructure;
+	TIM_BDTRInitType TIM1_BDTRInitStructure;
+	TIM_Module *TIMx = MOS_PWM_TIMER;
+	u32 half_period = FOC_PWM_Half_Period;
+
+	rcu_apb2_periph_clock_enable(PWM_TIM_CLK);
+
+	TIM_DeInit(TIMx);
+
+	TIM_InitTimBaseStruct(&TIM1_TimeBaseStructure);
+	TIM1_TimeBaseStructure.Prescaler = 0;
+	TIM1_TimeBaseStructure.CntMode = TIM_CNT_MODE_CENTER_ALIGN1;// 01: \,irq flag only counter down
+	TIM1_TimeBaseStructure.Period = half_period;
+	TIM1_TimeBaseStructure.ClkDiv = TIM_CLK_DIV1;
+	TIM1_TimeBaseStructure.RepetCnt = 1;
+	TIM_InitTimeBase(TIMx, &TIM1_TimeBaseStructure);
+	//Channel 1, 2,3 in PWM mode
+	TIM_InitOcStruct(&TIM1_OCInitStructure);
+	TIM1_OCInitStructure.OcMode = TIM_OCMODE_PWM1;//Pos logic(when '<' is active,when '>' is inactive)
+	TIM1_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE; 
+	TIM1_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_ENABLE;                  
+	TIM1_OCInitStructure.Pulse = (half_period>>1);
+	TIM1_OCInitStructure.OcPolarity = TIM_OC_POLARITY_HIGH;
+	TIM1_OCInitStructure.OcNPolarity = TIM_OCN_POLARITY_HIGH; 
+	TIM1_OCInitStructure.OcIdleState = TIM_OC_IDLE_STATE_RESET;
+	TIM1_OCInitStructure.OcNIdleState = TIM_OC_IDLE_STATE_RESET;          
+	TIM_InitOc1(TIMx, &TIM1_OCInitStructure); 
+	TIM_InitOc2(TIMx, &TIM1_OCInitStructure);
+	TIM_InitOc3(TIMx, &TIM1_OCInitStructure);
+	//Channel 4 Configuration in OC 
+	TIM1_OCInitStructure.OcMode = TIM_OCMODE_PWM2;
+	TIM1_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
+	TIM1_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_DISABLE;
+	TIM1_OCInitStructure.Pulse = half_period - 1;//3400;
+	TIM_InitOc4(TIMx, &TIM1_OCInitStructure);
+	
+	//Enables the TIM1 Preload on CC1,CC2,CC3,CC4 Register
+	TIM_ConfigOc1Preload(TIMx, TIM_OC_PRE_LOAD_ENABLE);
+	TIM_ConfigOc2Preload(TIMx, TIM_OC_PRE_LOAD_ENABLE);
+	TIM_ConfigOc3Preload(TIMx, TIM_OC_PRE_LOAD_ENABLE);
+
+	//Automatic Output enable, Break, dead time and lock configuration
+	TIM1_BDTRInitStructure.OssrState = TIM_OSSR_STATE_DISABLE;
+	TIM1_BDTRInitStructure.OssiState = TIM_OSSI_STATE_DISABLE;
+	TIM1_BDTRInitStructure.LockLevel = TIM_LOCK_LEVEL_OFF; 
+	TIM1_BDTRInitStructure.DeadTime = _dead_time(NS_2_TCLK(PWM_DEAD_TIME_NS));
+	TIM1_BDTRInitStructure.Break = enable_brk?TIM_BREAK_IN_ENABLE:TIM_BREAK_IN_DISABLE;
+	TIM1_BDTRInitStructure.BreakPolarity = TIM_BREAK_POLARITY_LOW;
+	TIM1_BDTRInitStructure.AutomaticOutput = TIM_AUTO_OUTPUT_DISABLE;
+    TIM1_BDTRInitStructure.IomBreakEn = true;
+	TIM_ConfigBkdt(TIMx, &TIM1_BDTRInitStructure);
+	
+	pwm_enable_channel();
+
+	TIM_ClearFlag(TIMx,TIM_FLAG_UPDATE);
+	TIM_ConfigInt(TIMx, TIM_INT_UPDATE, DISABLE);
+	nvic_irq_enable(PWM_UP_IRQ, TIMER_UP_IRQ_PRIORITY, 0);
+	TIM_ClearFlag(TIMx,TIM_FLAG_BREAK);
+	TIM_ConfigInt(TIMx, TIM_INT_BREAK, ENABLE);
+	nvic_irq_enable(PWM_BRK_IRQ, EBREAK_IRQ_PRIORITY, 0);
+	//TIM1 counter enable
+	TIM_Enable(TIMx, ENABLE);
+}
+
+void pwm_start(void){
+	pwm_update_duty(FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2, FOC_PWM_Half_Period/2);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	/* wait for a new PWM period to flush last HF task */
+	TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE);
+
+	TIM_GenerateEvent(MOS_PWM_TIMER, TIM_EVT_SRC_UPDATE);
+	while ( TIM_GetFlagStatus(MOS_PWM_TIMER, TIM_FLAG_UPDATE) == RESET ){}
+	/* Clear Update Flag */
+	TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE);
+
+	TIM_EnableCtrlPwmOutputs(MOS_PWM_TIMER,ENABLE);
+}
+
+void pwm_stop(void){
+	TIM_EnableCtrlPwmOutputs(MOS_PWM_TIMER,DISABLE);
+
+	TIM_ConfigInt(MOS_PWM_TIMER, TIM_INT_UPDATE, DISABLE);
+	/* wait for a new PWM period to flush last HF task */
+	TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE);
+	while ( TIM_GetFlagStatus(MOS_PWM_TIMER, TIM_FLAG_UPDATE) == RESET ){}
+	/* Clear Update Flag */
+	TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE);
+}
+
+void pwm_enable_output(bool enable) {
+	if (enable) {
+		TIM_EnableCtrlPwmOutputs(MOS_PWM_TIMER,ENABLE);
+	}else {
+		TIM_EnableCtrlPwmOutputs(MOS_PWM_TIMER,DISABLE);
+	}
+}
+
+/*open low side of the mosfet*/
+void pwm_turn_on_low_side(void)
+{
+	pwm_update_duty(0, 0, 0);
+	pwm_update_2smaples(FOC_PWM_Half_Period-1, FOC_PWM_Half_Period + 1);
+	TIM_ClearFlag(MOS_PWM_TIMER,TIM_FLAG_UPDATE);
+	TIM_GenerateEvent(MOS_PWM_TIMER, TIM_EVT_SRC_UPDATE);
+  	while (TIM_GetFlagStatus(MOS_PWM_TIMER, TIM_FLAG_UPDATE) == RESET );
+  	/* Main PWM Output Enable */
+  	TIM_EnableCtrlPwmOutputs(MOS_PWM_TIMER, ENABLE);
+}
+
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector) {
+	if (samp1 < FOC_PWM_Half_Period) {
+		TIMER_CH3CV(MOS_PWM_TIMER) = samp1;
+		pwm_change_t3_mode(TIM_OCMODE_PWM2);
+	}else {
+		TIMER_CH3CV(MOS_PWM_TIMER) = samp2;
+		pwm_change_t3_mode(TIM_OCMODE_PWM1);
+	}
+	adc_current_sample_config(sector);
+}

+ 101 - 0
Applications/bsp/n32/pwm.h

@@ -0,0 +1,101 @@
+#ifndef _PWM_H__
+#define _PWM_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+#define TIMER_CHCTL2_CH0EN               BIT(0)              /*!< channel 0 capture/compare function enable */
+#define TIMER_CHCTL2_CH0P                BIT(1)              /*!< channel 0 capture/compare function polarity */
+#define TIMER_CHCTL2_CH0NEN              BIT(2)              /*!< channel 0 complementary output enable */
+#define TIMER_CHCTL2_CH0NP               BIT(3)              /*!< channel 0 complementary output polarity */
+#define TIMER_CHCTL2_CH1EN               BIT(4)              /*!< channel 1 capture/compare function enable  */
+#define TIMER_CHCTL2_CH1P                BIT(5)              /*!< channel 1 capture/compare function polarity */
+#define TIMER_CHCTL2_CH1NEN              BIT(6)              /*!< channel 1 complementary output enable */
+#define TIMER_CHCTL2_CH1NP               BIT(7)              /*!< channel 1 complementary output polarity */
+#define TIMER_CHCTL2_CH2EN               BIT(8)              /*!< channel 2 capture/compare function enable  */
+#define TIMER_CHCTL2_CH2P                BIT(9)              /*!< channel 2 capture/compare function polarity */
+#define TIMER_CHCTL2_CH2NEN              BIT(10)             /*!< channel 2 complementary output enable */
+#define TIMER_CHCTL2_CH2NP               BIT(11)             /*!< channel 2 complementary output polarity */
+
+#define TIMxCCER_MASK_CH012        ((uint16_t)  (TIMER_CHCTL2_CH0EN|TIMER_CHCTL2_CH0NEN|\
+                                                 TIMER_CHCTL2_CH1EN|TIMER_CHCTL2_CH1NEN|\
+                                                 TIMER_CHCTL2_CH2EN|TIMER_CHCTL2_CH2NEN))
+
+#define pwm_enable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) |= TIMxCCER_MASK_CH012;}
+#define pwm_disable_channel() {TIMER_CHCTL2(MOS_PWM_TIMER) &= ~TIMxCCER_MASK_CH012;}
+
+
+#define ch0_update_duty(duty) 	TIMER_CH0CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define ch1_update_duty(duty) 	TIMER_CH1CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define ch2_update_duty(duty) 	TIMER_CH2CV(MOS_PWM_TIMER) = (uint32_t)duty
+#define update_adc_trigger(time) TIMER_CH3CV(MOS_PWM_TIMER) = (uint32_t)time
+
+#ifdef CONFIG_PWM_UV_SWAP
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyC);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyA);\
+	}while(0)
+
+#else
+#define pwm_update_duty(dutyA, dutyB, dutyC) \
+	do {\
+		ch0_update_duty(dutyA);\
+		ch1_update_duty(dutyB);\
+		ch2_update_duty(dutyC);\
+	}while(0)
+
+#endif
+
+#define pwm_update_2smaples(samp1, sampl2) \
+	do { \
+		TIMER_CH3CV(MOS_PWM_TIMER) = (uint32_t)samp1; \
+	}while(0)
+
+
+#define pwm_wait_and_clear_updata() \
+	do { \
+		while ( TIM_GetFlagStatus(MOS_PWM_TIMER, TIM_FLAG_UPDATE) == RESET ); \
+		TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE); \
+	}while(0)
+
+#define pwm_change_t3_mode(m) \
+	do { \
+		if (((TIMER_CHCTL1(MOS_PWM_TIMER) >> 8)) != m) { \
+			TIMER_CHCTL1(MOS_PWM_TIMER) &= (~(uint32_t)TIM_CCMOD2_OC4MD); \
+        	TIMER_CHCTL1(MOS_PWM_TIMER) |= (m << 8); \
+		} \
+	}while(0)
+
+#define pwm_brake_enable(n) \
+	do { \
+		if (n) { \
+			nvic_irq_enable(PWM_BRK_IRQ, EBREAK_IRQ_PRIORITY, 0); \
+		}else { \
+			nvic_irq_disable(PWM_BRK_IRQ); \
+		} \
+	}while(0)
+
+#define pwm_up_enable(n) \
+	do { \
+		if (n) { \
+			TIM_ClearFlag(MOS_PWM_TIMER, TIM_FLAG_UPDATE); \
+			TIM_ConfigInt(MOS_PWM_TIMER, TIM_INT_UPDATE, ENABLE); \
+		}else { \
+			TIM_ConfigInt(MOS_PWM_TIMER, TIM_INT_UPDATE, DISABLE); \
+			TIM_ClrIntPendingBit(MOS_PWM_TIMER, TIM_INT_UPDATE); \
+		} \
+	}while(0)
+
+#define get_deadtime() (TIMER_CCHP(MOS_PWM_TIMER) & 0xFF)
+
+void pwm_3phase_init(void);
+void pwm_3phase_sides(bool hon, bool lon);
+void pwm_start(void);
+void pwm_stop(void);
+void pwm_turn_on_low_side(void);
+void pwm_enable_output(bool enable);
+void pwm_update_sample(u32 samp1, u32 samp2, u8 sector);
+
+#endif  /*_PWM_H__*/
+

+ 34 - 0
Applications/bsp/n32/sched_timer.c

@@ -0,0 +1,34 @@
+#include "bsp/bsp_driver.h"
+
+void sched_timer_enable(u32 us) {
+    TIM_TimeBaseInitType TIM_TimeBaseStructure;
+
+    rcu_apb1_periph_clock_enable(SCHED_TIMER_RCU);
+
+    TIM_DeInit(SCHED_TIMER);
+
+	TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
+    TIM_TimeBaseStructure.Period    = us-1;
+    TIM_TimeBaseStructure.Prescaler = TIM_SCHED_CLK_MHz-1;
+    TIM_TimeBaseStructure.ClkDiv    = 0;
+    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
+
+    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
+
+	TIM_SetCnt(SCHED_TIMER,0);
+
+	TIM_ClearFlag(SCHED_TIMER, TIM_FLAG_UPDATE);
+
+	TIM_ConfigInt(SCHED_TIMER, TIM_INT_UPDATE, ENABLE);
+
+	nvic_irq_enable(SCHED_TIMER_IRQ, SCHED_TIMER_IRQ_PRIORITY, 0);
+
+	TIM_Enable(SCHED_TIMER, ENABLE);
+}
+__weak void Sched_MC_mTask(void) {}
+void SCHED_TIMER_IRQHandler(void) {
+	if(SET == TIM_GetIntStatus(SCHED_TIMER, TIM_INT_UPDATE)) {
+		TIM_ClrIntPendingBit(SCHED_TIMER, TIM_INT_UPDATE);
+		Sched_MC_mTask();
+	}
+}

+ 8 - 0
Applications/bsp/n32/sched_timer.h

@@ -0,0 +1,8 @@
+#ifndef _Sched_Timer_H__
+#define _Sched_Timer_H__
+#include "bsp/bsp.h"
+#include "os/os_types.h"
+
+void sched_timer_enable(u32 us);
+
+#endif /* _Sched_Timer_H__ */

+ 413 - 0
Applications/bsp/n32/uart.c

@@ -0,0 +1,413 @@
+#include "uart.h"
+#include "os/os_task.h"
+#include "libs/crc16.h"
+#include "libs/logger.h"
+#include "libs/utils.h"
+
+#define SHARK_UART_BAUDRATE				230400
+
+#ifdef DEBUG_PORT_UART1
+#define SHARK_UART0_com					USART1
+#define SHARK_UART0_tx_port				GPIOA
+#define SHARK_UART0_tx_pin				GPIO_PIN_2
+#define SHARK_UART0_rx_port				GPIOA
+#define SHARK_UART0_rx_pin				GPIO_PIN_3
+#define SHARK_UART0_irq					USART1_IRQn
+#define SHARK_UART0_clk					RCU_USART1
+#define SHARK_UART0_tx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_rx_gpio_clk			RCU_GPIOA
+#define SHARK_UART0_tx_dma				DMA0
+#define SHARK_UART0_tx_dma_ch			DMA_CH6
+#define SHARK_UART0_tx_dma_clk			RCU_DMA0
+#define SHARK_UART0_rx_dma				DMA0
+#define SHARK_UART0_rx_dma_ch			DMA_CH5
+#define SHARK_UART0_rx_dma_clk			RCU_DMA0
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel6_IRQn
+#define UART_DMA_IRQHandler             DMA0_Channel6_IRQHandler
+#else
+#define SHARK_UART0_com					USART3
+#define SHARK_UART0_tx_port				GPIOB
+#define SHARK_UART0_tx_pin				GPIO_PIN_10
+#define SHARK_UART0_rx_port				GPIOB
+#define SHARK_UART0_rx_pin				GPIO_PIN_11
+#define SHARK_UART0_irq					USART3_IRQn
+#define SHARK_UART0_clk					RCC_APB1_PERIPH_USART3
+#define SHARK_UART0_tx_gpio_clk			RCC_APB2_PERIPH_GPIOB
+#define SHARK_UART0_rx_gpio_clk			RCC_APB2_PERIPH_GPIOB
+#define SHARK_UART0_tx_dma				DMA1
+#define SHARK_UART0_tx_dma_ch			DMA1_CH2
+#define SHARK_UART0_tx_dma_clk			RCC_AHB_PERIPH_DMA1
+#define SHARK_UART0_rx_dma				DMA0
+#define SHARK_UART0_rx_dma_ch			DMA1_CH3
+#define SHARK_UART0_rx_dma_clk			RCC_AHB_PERIPH_DMA1
+#define SHARK_UART0_DMA_TX_IRQ          DMA0_Channel1_IRQn
+
+#define USARTy_Tx_DMA_FLAG    DMA1_FLAG_TC2
+#define USARTy_Rx_DMA_FLAG    DMA1_FLAG_TC3
+
+#define UART_DMA_IRQHandler             DMA0_Channel1_IRQHandler
+#endif
+
+// ================================================================================
+#define ENABLE_RX_DMA 1
+static u8 shark_uart0_tx_cache[SHARK_UART_TX_MEM_SIZE];
+static u8 shark_uart0_rx_cache[SHARK_UART_RX_MEM_SIZE];
+
+static shark_uart_t _shark_uart[1];
+///static bool uart_no_data = false;
+#if ENABLE_RX_DMA==1
+#define update_dma_w_pos(uart) circle_update_write_position(&uart->rx_queue, SHARK_UART_RX_MEM_SIZE - DMA_GetCurrDataCounter(SHARK_UART0_rx_dma_ch))
+#else
+#define update_dma_w_pos(uart){}
+#endif
+
+// ================================================================================
+
+static bool shark_uart_on_rx_frame(shark_uart_t *uart)
+{
+	u16 crc0 = decode_u16(uart->rx_frame + uart->rx_length);
+	u16 crc1 = crc16_get(uart->rx_frame, uart->rx_length);
+
+	if (crc0 != crc1) {
+		return false;
+	}
+	//protocol_recv_frame(_uart_index(uart->uart_com), (char *)uart->rx_frame, uart->rx_length);
+	return true;
+}
+
+static void shark_uart_rx(shark_uart_t *uart){
+	while(1) {
+		u8 data = 0;
+		update_dma_w_pos(uart);
+		if (circle_get_one_data(&uart->rx_queue, &data) != 1) {
+			return;
+		}
+		switch(data){
+			case CH_START:
+				uart->rx_length = 0;
+				uart->escape = false;
+				uart->start = true;
+				break;
+			case CH_END:
+				if (uart->rx_length > 2 && uart->rx_length != 0xFFFF){
+					uart->rx_length -= 2; //skip crc
+					shark_uart_on_rx_frame(uart);
+				}
+				uart->rx_length = 0xFFFF;
+				uart->start = false;
+				break;
+			case CH_ESC:
+				uart->escape = true;
+				break;
+			default:
+				if (uart->escape) {
+					uart->escape = false;
+					switch (data) {
+						case CH_ESC_START:
+							data = CH_START;
+							break;
+
+						case CH_ESC_END:
+							data = CH_END;
+							break;
+
+						case CH_ESC_ESC:
+							data = CH_ESC;
+							break;
+
+						default:
+							data = 0xFF;
+					}
+				}
+
+				if (uart->rx_length < sizeof(uart->rx_frame)) {
+					uart->rx_frame[uart->rx_length] = data;
+					uart->rx_length++;
+				} else {
+					uart->rx_length = 0xFFFF;
+				}			
+		}
+	}
+}
+
+#define DMA_CHCTL(SHARK_UART0_tx_dma, tx_dma_ch)   (tx_dma_ch->CHCFG)
+static void shark_uart_dma_tx(shark_uart_t *uart)
+{
+	u32 value = DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch);
+
+	if (value & DMA_CHCFG1_CHEN) {
+		if (SET != DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG, SHARK_UART0_tx_dma)) {
+			return;
+		}
+		DMA_ClearFlag(USARTy_Tx_DMA_FLAG, SHARK_UART0_tx_dma);
+		byte_queue_skip(&uart->tx_queue, uart->tx_length);
+		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value & (~DMA_CHCFG1_CHEN);
+	}
+
+	uart->tx_length = byte_queue_peek(&uart->tx_queue);
+	if (uart->tx_length > 0) {
+		DMA_SetCurrDataCounter(uart->tx_dma_ch, uart->tx_length);
+		uart->tx_dma_ch->MADDR = (u32) byte_queue_head(&uart->tx_queue);
+		DMA_CHCTL(SHARK_UART0_tx_dma, uart->tx_dma_ch) = value | DMA_CHCFG1_CHEN;
+	}
+}
+
+
+
+static void shark_uart_write(shark_uart_t *uart, const u8 *buff, u16 size)
+{
+	while (size > 0) {
+		u16 length = byte_queue_write(&uart->tx_queue, buff, size);
+
+		if (length == size) {
+			shark_uart_dma_tx(uart);
+			break;
+		}
+
+		shark_uart_dma_tx(uart);
+		buff += length;
+		size -= length;
+	}
+}
+
+static void shark_uart_write_byte(shark_uart_t *uart, u8 value)
+{
+	byte_queue_write(&uart->tx_queue, &value, 1);
+}
+
+
+void shark_uart_write_log(char *buffer){
+	int len = strlen(buffer);
+	shark_uart_t *uart = (_shark_uart+SHARK_UART0);
+	if (len > byte_queue_get_free(&uart->tx_queue)){
+		return;
+	}
+	byte_queue_write(&uart->tx_queue, (const u8 *)buffer, len);
+	shark_uart_dma_tx(uart);
+}
+
+static void shark_uart_tx_dma_init(shark_uart_t *uart){
+
+	rcu_ahb_periph_clock_enable(SHARK_UART0_tx_dma_clk);
+
+    DMA_InitType DMA_InitStructure;
+
+    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
+    DMA_DeInit(SHARK_UART0_tx_dma_ch);
+    DMA_InitStructure.PeriphAddr     = (u32)uart->uart_com + 0x04;
+    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
+    DMA_InitStructure.BufSize        = 0;
+    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
+    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
+    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
+    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Byte;
+    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
+    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
+    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
+    DMA_Init(SHARK_UART0_tx_dma_ch, &DMA_InitStructure);
+
+	USART_EnableDMA(uart->uart_com, USART_DMAREQ_TX, ENABLE);
+}
+
+#if ENABLE_RX_DMA==1
+static void shark_uart_rx_dma_init(shark_uart_t *uart){
+
+	rcu_ahb_periph_clock_enable(SHARK_UART0_rx_dma_clk);
+
+    DMA_InitType DMA_InitStructure;
+
+    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
+    DMA_DeInit(SHARK_UART0_rx_dma_ch);
+    DMA_InitStructure.PeriphAddr     = (u32)uart->uart_com + 0x04;
+    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
+    DMA_InitStructure.BufSize        = uart->rx_queue.buffer_len;
+	DMA_InitStructure.MemAddr        = (u32)uart->rx_queue.buffer;
+    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
+    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
+    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
+    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Byte;
+    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
+    DMA_InitStructure.Priority       = DMA_PRIORITY_VERY_HIGH;
+    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
+    DMA_Init(SHARK_UART0_rx_dma_ch, &DMA_InitStructure);
+
+	USART_EnableDMA(uart->uart_com, USART_DMAREQ_RX, ENABLE);
+
+}
+#endif
+static void shark_uart_pin_init(shark_uart_t *uart){
+	rcu_apb1_periph_clock_enable(SHARK_UART0_clk);
+	rcu_apb2_periph_clock_enable(SHARK_UART0_rx_gpio_clk);
+	rcu_apb2_periph_clock_enable(SHARK_UART0_tx_gpio_clk);
+	rcu_apb2_periph_clock_enable(RCU_AF);
+	gpio_init(SHARK_UART0_tx_port, GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,SHARK_UART0_tx_pin);
+	gpio_init(SHARK_UART0_rx_port, GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,SHARK_UART0_rx_pin);
+}
+
+
+static void shark_uart_device_init(shark_uart_t *uart){
+	USART_InitType USART_InitStructure;
+
+	USART_StructInit(&USART_InitStructure);
+    USART_InitStructure.BaudRate            = SHARK_UART_BAUDRATE;
+    USART_InitStructure.WordLength          = USART_WL_8B;
+    USART_InitStructure.StopBits            = USART_STPB_1;
+    USART_InitStructure.Parity              = USART_PE_NO;
+    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
+    USART_InitStructure.Mode                = USART_MODE_RX | USART_MODE_TX;
+	/* Configure USARTy and USARTz */
+	USART_Init(uart->uart_com, &USART_InitStructure);
+
+	USART_Enable(uart->uart_com, ENABLE);
+}
+
+static u32 shark_uart_task(void *args)
+{
+	shark_uart_t *uart = (shark_uart_t *)args;
+	if(uart->uart_com != 0) {
+		shark_uart_rx(uart);
+		shark_uart_dma_tx(uart);
+	}
+	return 0;
+}
+
+
+void shark_uart_flush(void){
+	shark_uart_t *uart = _shark_uart + SHARK_UART0;
+	if (uart->uart_com != 0) {
+		while(!byte_queue_empty(&uart->tx_queue)) {
+			shark_uart_dma_tx(uart);
+		}
+	}	
+}
+
+static u8 *tx_cache_addr(uart_enum_t uart_no){
+	return shark_uart0_tx_cache;
+}
+
+static u8 *rx_cache_addr(uart_enum_t uart_no){
+	return shark_uart0_rx_cache;
+}
+
+
+void shark_uart_deinit(uart_enum_t uart_no){
+
+}
+
+
+bool shark_uart_timeout(void){
+#if UART_NUM==2	
+	return (_shark_uart[0].uart_no_data && _shark_uart[1].uart_no_data)?TRUE:FALSE;
+#else
+	return (_shark_uart[0].uart_no_data)?TRUE:FALSE;
+#endif
+}
+void shark_uart_init(uart_enum_t uart_no)
+{
+	shark_uart_t *uart = _shark_uart + uart_no;
+	uart->escape = false;
+	uart->rx_length = 0;
+	uart->tx_length = 0;
+	uart->uart_com = SHARK_UART0_com;
+
+	circle_buffer_init(&uart->rx_queue, rx_cache_addr(uart_no), SHARK_UART_RX_MEM_SIZE);
+	byte_queue_init(&uart->tx_queue,tx_cache_addr(uart_no), SHARK_UART_TX_MEM_SIZE);
+
+	uart->rx_dma_ch = SHARK_UART0_rx_dma_ch;
+	uart->tx_dma_ch = SHARK_UART0_tx_dma_ch;
+
+	shark_uart_pin_init(uart);
+	shark_uart_device_init(uart);
+	shark_uart_rx_dma_init(uart);
+	shark_uart_tx_dma_init(uart);
+
+	shark_task_create(shark_uart_task, uart);
+
+	uart->uart_no_data = false;
+}
+
+void UART_DMA_IRQHandler(void) {
+	
+}
+
+static void shark_uart_write_byte_esc(shark_uart_t *uart, u8 value)
+{
+	switch (value) {
+	case CH_START:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_START;
+		break;
+
+	case CH_END:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_END;
+		break;
+
+	case CH_ESC:
+		shark_uart_write_byte(uart, CH_ESC);
+		value = CH_ESC_ESC;
+		break;
+	}
+
+	shark_uart_write_byte(uart, value);
+}
+
+static void shark_uart_write_esc(shark_uart_t *uart, const u8 *buff, u16 length)
+{
+	const u8 *buff_end;
+
+	for (buff_end = buff + length; buff < buff_end; buff++) {
+		shark_uart_write_byte_esc(uart, *buff);
+	}
+}
+
+static void shark_uart_tx_start(shark_uart_t *uart)
+{
+	shark_uart_write_byte(uart, CH_START);
+	uart->tx_crc16 = 0;
+}
+
+static void shark_uart_tx_continue(shark_uart_t *uart, const void *buff, u16 length)
+{
+	shark_uart_write_esc(uart, (const u8 *) buff, length);
+	uart->tx_crc16 = crc16_update(uart->tx_crc16, (const u8 *) buff, length);
+}
+
+static void shark_uart_tx_end(shark_uart_t *uart)
+{
+	shark_uart_write_esc(uart, (u8 *)&uart->tx_crc16, sizeof(uart->tx_crc16));
+	shark_uart_write_byte(uart, CH_END);
+}
+
+void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+	shark_uart_tx_end(uart);
+	shark_uart_dma_tx(uart);
+}
+
+void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_start(uart);
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len){
+	shark_uart_t *uart = _shark_uart + uart_no;
+	shark_uart_tx_continue(uart, bytes, len);
+}
+
+void shark_uart_frame_end(uart_enum_t uart_no){
+	shark_uart_tx_end(_shark_uart + uart_no);
+}
+
+void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size){
+	shark_uart_write(_shark_uart + uart_no, buff, size);
+}
+
+int fputc(int c, FILE *fp){
+	shark_uart_write_byte(_shark_uart+SHARK_UART0, (u8)c);
+	return 1;
+}
+

+ 53 - 0
Applications/bsp/n32/uart.h

@@ -0,0 +1,53 @@
+#pragma once
+#include "bsp/bsp.h"
+#include "os/os_task.h"
+#include "libs/byte_queue.h"
+#include "libs/circle_buffer.h"
+
+#define CH_START						0xF5
+#define CH_END							0xF6
+#define CH_ESC							0xF7
+#define CH_ESC_START					0x05
+#define CH_ESC_END						0x06
+#define CH_ESC_ESC						0x07
+
+#define SHARK_UART_TX_MEM_SIZE			(10 * 1024)
+#define SHARK_UART_RX_MEM_SIZE			512
+#define RX_FRAME_MAX_LEN 260
+#define RX_OLD_FRAME_MAX_LEN 256
+
+typedef enum {
+	SHARK_UART0 = 0,
+	SHARK_UART1,
+	SHARK_UART2,
+	SHARK_UART3,
+	SHARK_UART4,
+	SHARK_UART_COUNT
+} uart_enum_t;
+
+typedef struct {
+	byte_queue_t tx_queue;
+	c_buffer_t rx_queue;
+	DMA_ChannelType *rx_dma_ch;
+	DMA_ChannelType *tx_dma_ch;
+	uint16_t tx_length;
+	uint16_t tx_crc16;
+	USART_Module *uart_com;//uart device
+	uint8_t rx_frame[RX_FRAME_MAX_LEN];
+	uint16_t rx_length;
+	bool escape;
+	bool start;
+	bool uart_no_data;
+}shark_uart_t;
+
+void shark_uart_init(uart_enum_t uart_no);
+void shark_uart_deinit(uart_enum_t uart_no);
+void shark_uart_write_frame(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_start(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_continue(uart_enum_t uart_no, uint8_t *bytes, int len);
+void shark_uart_frame_end(uart_enum_t uart_no);
+void shark_uart_write_bytes(uart_enum_t uart_no, u8 *buff, u16 size);
+void shark_uart_flush(void);
+bool shark_uart_timeout(void);
+void shark_uart_log(void);
+

Some files were not shown because too many files changed in this diff