#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"


//ALIENTEK 探索者STM32F407开发板 实验4
//串口通信实验 -库函数版本
//技术支持：www.openedv.com
//淘宝店铺：http://eboard.taobao.com
//广州市星翼电子科技有限公司  
//作者：正点原子 @ALIENTEK

void MX_TIM2_Init(void);
//void PWM_SetPulseWidth(uint16_t pulseWidth);
//void PWM_SetSpeed(int16_t speed);
void Error_Handler(void);

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;
// 定义TMC2240寄存器地址
#define REG_MICROSTEPS 0x03
#define REG_CURRENT       0x05
#define EG_STATUS           0x0F


extern  volatile u16 rx_len;        // 接收计数
extern volatile u8 rx_flag;        // 接收完成标志
#define GCONF          0x00
#define IHOLD_IRUN     0x10
#define TPOWERDOWN     0x11
#define TPWMTHRS       0x13
#define TCOOLTHRS      0x14
#define CHOPCONF       0x6C
#define COOLCONF       0x6D
#define DRV_CONF       0x0A
#define DRV_STATUS     0x6F
#define PWMCONF 			 0x70

#define SOFT_SPI_DR_PORT     GPIOD
#define SOFT_SPI_DR_PIN      GPIO_Pin_3
//forward and reverse
#define D3_DR_forward()     GPIO_SetBits(SOFT_SPI_DR_PORT, SOFT_SPI_DR_PIN)
#define D3_DR_reverse()     GPIO_ResetBits(SOFT_SPI_DR_PORT, SOFT_SPI_DR_PIN)

void TMC2240_Init_rotating() {
    // 启用电压补偿和PWM模式
    TMC2240_WriteReg(GCONF, 0x000000C4);

    // 电流设置：IHOLD=0.5A, IRUN=1.2A
    TMC2240_WriteReg(IHOLD_IRUN, 0x00180C10);

    // 16微步（MRES=4），TOFF=3
    TMC2240_WriteReg(CHOPCONF, 0x030000C3);
		// 设置速度阈值500Hz（低于此值切StealthChop2）
    TMC2240_WriteReg(TPWMTHRS, 200);
    // 驱动配置（根据需求调整）
    TMC2240_WriteReg(DRV_CONF, 0x00000001);

    // 停机电流延时
    TMC2240_WriteReg(TPOWERDOWN, 10);
}

void TMC2240_Init() {
    // 启用StealthChop2自动调谐 + SpreadCycle动态切换
    TMC2240_WriteReg(GCONF, 0x000000C4 | (1 << 7)); // bit7=1
    
    // 电流设置：IRUN=1.2A, IHOLD=0.8A（公式计算值）
    //TMC2240_WriteReg(IHOLD_IRUN, 0x00190C10);
	   TMC2240_WriteReg(IHOLD_IRUN, 0x04090101); //可能运行电流太大，发热，这里调小试试
   // 降低微步分辨率（例如从256微步改为16微步）
		TMC2240_WriteReg(CHOPCONF, 0x070080C3 ); // MRES=4（16微步）
    
    // 设置速度阈值500Hz（低于此值切StealthChop2）
    TMC2240_WriteReg(TPWMTHRS, 50);
    
    // 其他配置保持不变
    TMC2240_WriteReg(DRV_CONF, 0x00000001);
		
    TMC2240_WriteReg(TPOWERDOWN, 10);
}
// 检查驱动器状态
void CheckDriverStatus() {
    uint32_t status = TMC2240_ReadReg(DRV_STATUS);//
    if (status & (1 << 26)) { // 检查短路到地
        printf("Short to ground detected\n");
    }
    if (status & (1 << 25)) { // 检查过温
        printf("Overtemperature detected\n");
    }
    if (status & (1 << 24)) { // 检查失速
        printf("Motor stall detected\n");
    }
}

void motor_steps(uint8_t num, uint8_t dir, uint16_t steps)
{
           GPIO_SetBits(GPIOD, GPIO_Pin_4);    //TMS2240 - 2使能信号
           delay_us(steps);		
           GPIO_ResetBits(GPIOD, GPIO_Pin_4);     //TMS2240 - 1使能信号      
}

void motor_stop(uint8_t num)
{
}


uint8_t crc8_calculate(const uint8_t *data, uint32_t length, uint8_t poly, uint8_t init_val, uint8_t ref_out)
{
    // 1. 初始化 CRC 寄存器
    uint8_t crc = init_val;
    
    // 2. 遍历每个字节
    for (uint32_t i = 0; i < length; i++)
    {
        // 3. 将当前字节与 CRC 寄存器异或（核心步骤）
        crc ^= data[i];
        
        // 4. 遍历当前字节的每一位（8 位）
        for (uint8_t j = 0; j < 8; j++)
        {
            // 5. 判断最高位是否为 1，决定是否异或多项式
            if (crc & 0x80)
            {
                // 左移 1 位，再异或多项式（等价于多项式除法）
                crc = (crc << 1) ^ poly;
            }
            else
            {
                // 最高位为 0，仅左移 1 位
                crc <<= 1;
            }
        }
    }
    
    // 6. 输出反转（若需要）
    if (ref_out)
    {
        // 按位反转 CRC 结果（如 0x12 → 0x48）
        uint8_t reversed = 0;
        for (uint8_t i = 0; i < 8; i++)
        {
            reversed |= ((crc >> i) & 0x01) << (7 - i);
        }
        crc = reversed;
    }
    
    return crc;
}

uint8_t crc8_standard(const uint8_t *data, uint32_t length)
{
    // 适配 CRC-8/MAXIM/ITU 标准：poly=0x07, init=0x00, ref_out=0
    return crc8_calculate(data, length, 0x07, 0x00, 0);
}

uint32_t status ;
u8 flg=0;

extern int flag_microswitch_left;   // 光电开关left 限位
extern int flag_microswitch_right;  // 光电开关right 限位


extern  uint8_t g_usart1_rx_buf[USART_REC_LEN];
extern  uint16_t g_usart1_rx_sta;
extern uint16_t g_usart1_rx_state;

extern uint8_t g_rx1_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */
/* 接收缓冲, 最大USART_REC_LEN个字节. */
extern uint8_t g_usart2_rx_buf[USART_REC_LEN];
extern uint16_t g_usart2_rx_sta;
extern uint8_t g_rx2_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */
/* 接收缓冲, 最大USART_REC_LEN个字节. */
extern uint8_t g_usart3_rx_buf[USART_REC_LEN];
extern uint16_t g_usart3_rx_sta;
extern uint8_t g_rx3_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */
/* 接收缓冲, 最大USART_REC_LEN个字节. */
extern uint8_t g_usart4_rx_buf[USART_REC_LEN];
extern uint16_t g_usart4_rx_sta;
extern uint8_t g_rx4_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */
/* 接收缓冲, 最大USART_REC_LEN个字节. */
extern uint8_t g_usart5_rx_buf[USART_REC_LEN];
extern uint16_t g_usart5_rx_sta;
extern uint8_t g_rx5_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */
/* 接收缓冲, 最大USART_REC_LEN个字节. */
extern uint8_t g_usart6_rx_buf[USART_REC_LEN];
extern uint16_t g_usart6_rx_sta;
extern uint8_t g_rx6_buffer[RXBUFFERSIZE];                  /* HAL库使用的串口接收缓冲 */


int main(void)
{ 
 
	u8 t;
	u8 len;	
	u16 times=0;
  uint8_t frame_updata[6] = {0x30,0x30,0x30,0x30,0x30,0x30};   
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);		//延时初始化 
	uart1_init(115200);	//串口1初始化波特率为115200 手指左
	uart2_init(115200);	//串口1初始化波特率为115200 手指中
	uart3_init(115200);	//串口1初始化波特率为115200 手指右
	uart4_init(115200);	//串口1初始化波特率为115200 用于信息打印
	uart6_init(115200);	//串口6初始化波特率为115200 上传到slide
	gpio_Init();		  		//初始化gpio  
  motor_spi1_init();
	motor_spi2_init();
	TIM1_PWM_Init(16, 32);
	TIM2_PWM_Init(16, 32);
  TIM4_PWM_Init(16, 32);
  TIM_Cmd(TIM1, DISABLE);
	TIM_Cmd(TIM2, DISABLE);
	TIM_Cmd(TIM4, DISABLE);
	while(1)
	{
              printf("I love you lao zhang\n");

	       delay_ms(300);

		 printf("I love you zhengshuo\n");

               delay_ms(300);   

		 Uart4_Send_data(frame_updata,6);			   
		//-------------------------------------------------
		 if(g_usart1_rx_state == 1)
        {
                        //  g_usart1_rx_buf[1] = 0x01;
                        //  g_usart1_rx_buf[3] = 0x34;
                        //  g_usart1_rx_buf[4] = crc8_standard(g_usart1_rx_buf,4);
     
          g_usart1_rx_state = 0;
          memcpy(frame_updata,g_usart1_rx_buf,6 );                
			    memset(g_usart1_rx_buf, 0x0, 6);	
			    g_rx1_buffer[0] = 0x0;	 
          Uart6_Send_data(frame_updata,6);		
        }
		//-------------------------------------------------
		
//		if(USART_RX_STA&0x8000)
//		{					   
//			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
//			printf("\r\n您发送的消息为:\r\n");
//			for(t=0;t<len;t++)
//			{
//				USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
//				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
//			}
//			printf("\r\n\r\n");//插入换行
//			USART_RX_STA=0;
//		}else
//		{
//			times++;
//			if(times%5000==0)
//			{
//				printf("\r\nALIENTEK 探索者STM32F407开发板 串口实验\r\n");
//				printf("正点原子@ALIENTEK\r\n\r\n\r\n");
//			}
//			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
//			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
//			delay_ms(10);   
//		}
	}
}

