diff --git a/3rd/config.h b/3rd/config.h index a609801..65dc185 100644 --- a/3rd/config.h +++ b/3rd/config.h @@ -2,6 +2,6 @@ #define CONFIG_H #define DEBUG_ENABLED true -#define DEBUG_MT_ENABLED false +#define DEBUG_MT_ENABLED true #define DEBUG_DFOC_ENABLED false #endif \ No newline at end of file diff --git a/3rd/delay.c b/3rd/delay.c index 1b5a17f..5a7793c 100644 --- a/3rd/delay.c +++ b/3rd/delay.c @@ -1,9 +1,13 @@ #include "delay.h" #include "ti_msp_dl_config.h" -void delay_ms(uint16_t ms) -{ - while(ms--) - { - delay_cycles(CPUCLK_FREQ / 1000); - } +void delay_ms(uint16_t ms) { + while (ms--) { + delay_cycles(CPUCLK_FREQ / 1000); + } +} + +void delay_us(uint16_t us) { + while (us--) { + delay_cycles(CPUCLK_FREQ / 1000000); + } } diff --git a/3rd/delay.h b/3rd/delay.h index 1cd521f..0a7d1d4 100644 --- a/3rd/delay.h +++ b/3rd/delay.h @@ -3,5 +3,6 @@ #include void delay_ms(uint16_t ms); +void delay_us(uint16_t us); #endif /* ti_msp_dl_config_h */ \ No newline at end of file diff --git a/3rd/mt6701.c b/3rd/mt6701.c index 2224332..ae9076d 100644 --- a/3rd/mt6701.c +++ b/3rd/mt6701.c @@ -1,8 +1,9 @@ #include "mt6701.h" +#include "config.h" +#include "soft_i2c.h" +#include "stdio.h" #include "ti_msp_dl_config.h" #include "uart_redircet.h" -#include "stdio.h" -#include "config.h" volatile int16_t angle; volatile float angle_f; @@ -10,13 +11,10 @@ volatile float angle_f_rad; volatile bool gIsI2cError = false; -#define DEBUG_I2C false +#define DEBUG_I2C false /* Data sent to the Target */ -uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = -{ - 0x03 -}; +uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = {0x03}; /* Data received from Target */ volatile uint8_t gRxPacket[I2C_RX_PACKET_SIZE] = {0}; @@ -30,186 +28,193 @@ volatile uint32_t gClockSelFreq; volatile uint32_t gDelayCycles; /* I2C Target address */ -#define I2C_TARGET_ADDRESS (0x06) +#define I2C_TARGET_ADDRESS (0x06 << 1) -void MT6701_iic_read_angel(void) -{ - /* Get I2C clock source and clock divider to use for delay cycle calculation */ - DL_I2C_getClockConfig(I2C_1_INST, &gI2CclockConfig); - switch(gI2CclockConfig.clockSel) - { - case DL_I2C_CLOCK_BUSCLK: - gClockSelFreq = 32000000; - break; - case DL_I2C_CLOCK_MFCLK: - gClockSelFreq = 4000000; - break; - default: - break; - } - /* - * Calculate number of clock cycles to delay after controller transfer initiated - * gDelayCycles = 3 I2C functional clock cycles - * gDelayCycles = 3 * I2C clock divider * (CPU clock freq / I2C clock freq) - */ - gDelayCycles = (5 * (gI2CclockConfig.divideRatio + 1)) * - (CPUCLK_FREQ / gClockSelFreq); - if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) - { - printf("i2c before writing -------\n"); +void MT6701_iic_read_angel(void) { - } - - /* - * Fill FIFO with data. This example will send a MAX of 8 bytes since it - * doesn't handle the case where FIFO is full - */ - DL_I2C_fillControllerTXFIFO(I2C_1_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE); - - /* Wait for I2C to be Idle */ - while(!( - DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) - ; - - /* Send the packet to the controller. - * This function will send Start + Stop automatically. - */ - DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, - DL_I2C_CONTROLLER_DIRECTION_TX, I2C_TX_PACKET_SIZE); - - if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) - { - printf("i2c writing done -------\n"); - } - - /* Workaround for errata I2C_ERR_13 */ - delay_cycles(gDelayCycles); - - /* Poll until the Controller writes all bytes */ - while( - DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY) - ; - - /* Trap if there was an error */ - if(DL_I2C_getControllerStatus(I2C_1_INST) & - DL_I2C_CONTROLLER_STATUS_ERROR) - { - gIsI2cError = true; - - if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) - { - printf("i2c error ------------------------------------------\n"); - } - /* LED will remain high if there is an error */ - __BKPT(0); - return; - } - - /* Wait for I2C to be Idle */ - while(!( - DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) - ; - - /* Add delay between transfers */ - delay_cycles(1000); - - if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) - { - printf("i2c before reading -------\n"); - } - - /* Send a read request to Target */ - DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, - DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE); - - /* - * Receive all bytes from target. LED will remain high if not all bytes - * are received - */ - for(uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) - { - while(DL_I2C_isControllerRXFIFOEmpty(I2C_1_INST)) - ; - gRxPacket[i] = DL_I2C_receiveControllerData(I2C_1_INST); - } - - if(DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) - { - printf("i2c reading done -------\n"); - } + I2C_Start(); + I2C_SendByte(I2C_TARGET_ADDRESS); + I2C_RecviveAck(); + I2C_SendByte(0X03); + I2C_RecviveAck(); + I2C_Start(); + I2C_SendByte(I2C_TARGET_ADDRESS | 0x01); + I2C_RecviveAck(); + gRxPacket[0] = I2C_RecviveData(); + I2C_SendAck(1); + I2C_Start(); + I2C_SendByte(I2C_TARGET_ADDRESS | 0x01); + I2C_RecviveAck(); + gRxPacket[1] = I2C_RecviveData(); + I2C_SendAck(1); + I2C_Stop(); } + +// void MT6701_iic_read_angel(void) { +// /* Get I2C clock source and clock divider to use for delay cycle +// calculation */ +// DL_I2C_getClockConfig(I2C_1_INST, &gI2CclockConfig); +// switch (gI2CclockConfig.clockSel) { +// case DL_I2C_CLOCK_BUSCLK: +// gClockSelFreq = 32000000; +// break; +// case DL_I2C_CLOCK_MFCLK: +// gClockSelFreq = 4000000; +// break; +// default: +// break; +// } +// /* +// * Calculate number of clock cycles to delay after controller transfer +// initiated +// * gDelayCycles = 3 I2C functional clock cycles +// * gDelayCycles = 3 * I2C clock divider * (CPU clock freq / I2C clock +// freq) +// */ +// gDelayCycles = +// (5 * (gI2CclockConfig.divideRatio + 1)) * (CPUCLK_FREQ / +// gClockSelFreq); +// if (DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) { +// printf("i2c before writing -------\n"); +// } + +// /* +// * Fill FIFO with data. This example will send a MAX of 8 bytes since it +// * doesn't handle the case where FIFO is full +// */ +// DL_I2C_fillControllerTXFIFO(I2C_1_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE); + +// /* Wait for I2C to be Idle */ +// while ( +// !(DL_I2C_getControllerStatus(I2C_1_INST) & +// DL_I2C_CONTROLLER_STATUS_IDLE)) +// ; + +// /* Send the packet to the controller. +// * This function will send Start + Stop automatically. +// */ +// DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, +// DL_I2C_CONTROLLER_DIRECTION_TX, +// I2C_TX_PACKET_SIZE); + +// if (DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) { +// printf("i2c writing done -------\n"); +// } + +// /* Workaround for errata I2C_ERR_13 */ +// delay_cycles(gDelayCycles); + +// /* Poll until the Controller writes all bytes */ +// while (DL_I2C_getControllerStatus(I2C_1_INST) & +// DL_I2C_CONTROLLER_STATUS_BUSY) +// ; + +// /* Trap if there was an error */ +// if (DL_I2C_getControllerStatus(I2C_1_INST) & +// DL_I2C_CONTROLLER_STATUS_ERROR) { +// gIsI2cError = true; + +// if (DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) { +// printf("i2c error ------------------------------------------\n"); +// } +// /* LED will remain high if there is an error */ +// __BKPT(0); +// return; +// } + +// /* Wait for I2C to be Idle */ +// while ( +// !(DL_I2C_getControllerStatus(I2C_1_INST) & +// DL_I2C_CONTROLLER_STATUS_IDLE)) +// ; + +// /* Add delay between transfers */ +// delay_cycles(1000); + +// if (DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) { +// printf("i2c before reading -------\n"); +// } + +// /* Send a read request to Target */ +// DL_I2C_startControllerTransfer(I2C_1_INST, I2C_TARGET_ADDRESS, +// DL_I2C_CONTROLLER_DIRECTION_RX, +// I2C_RX_PACKET_SIZE); + +// /* +// * Receive all bytes from target. LED will remain high if not all bytes +// * are received +// */ +// for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) { +// while (DL_I2C_isControllerRXFIFOEmpty(I2C_1_INST)) +// ; +// gRxPacket[i] = DL_I2C_receiveControllerData(I2C_1_INST); +// } + +// if (DEBUG_ENABLED & DEBUG_MT_ENABLED & DEBUG_I2C) { +// printf("i2c reading done -------\n"); +// } +// } volatile float Last_ts = 0.0; volatile float last_angle = 0.0; // 单圈值 -float GetAngle_NoTrack(void) -{ - MT6701_iic_read_angel(); - angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); - angle_f_rad = (float)angle * _2PI / 16384; - if(DEBUG_ENABLED & DEBUG_MT_ENABLED) - { - printf("angle_rad read back is %f \n", angle_f_rad); - } - return angle_f_rad; +float GetAngle_NoTrack(void) { + MT6701_iic_read_angel(); + angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); + angle_f_rad = (float)angle * _2PI / 16384; + if (DEBUG_ENABLED & DEBUG_MT_ENABLED) { + printf("angle_rad read back is %f \n", angle_f_rad); + } + return angle_f_rad; } volatile float full_rotations = 0.0; volatile float Last_Angle_rad = 0.0; -//多圈值 -float GetAngle(void) -{ - volatile float D_Angle_rad = 0.0; - volatile float Angle_rad = GetAngle_NoTrack(); - D_Angle_rad = Angle_rad - Last_Angle_rad; +// 多圈值 +float GetAngle(void) { + volatile float D_Angle_rad = 0.0; + volatile float Angle_rad = GetAngle_NoTrack(); + D_Angle_rad = Angle_rad - Last_Angle_rad; - if(fabs(D_Angle_rad) > (0.8f * 2 * PI)) - { - full_rotations = full_rotations + ((D_Angle_rad > 0) ? -1 : 1); - } + if (fabs(D_Angle_rad) > (0.8f * 2 * PI)) { + full_rotations = full_rotations + ((D_Angle_rad > 0) ? -1 : 1); + } - Last_Angle_rad = Angle_rad; + Last_Angle_rad = Angle_rad; - return (full_rotations * 2 * PI + Last_Angle_rad); + return (full_rotations * 2 * PI + Last_Angle_rad); } volatile float Last_Vel_ts = 0.0; volatile float Vel_Last_Angle = 0.0; -float GetVelocity(void) -{ - volatile float dt = 0.0; - volatile float Vel_ts = SysTick -> VAL; - if(Vel_ts < Last_Vel_ts) - { - dt = (Last_Vel_ts - Vel_ts) / 80 * 1e-6f; - } - else - { - dt = (0xFFFFFF - Vel_ts + Last_Vel_ts) / 80 * 1e-6f; - } +float GetVelocity(void) { + volatile float dt = 0.0; + volatile float Vel_ts = SysTick->VAL; + if (Vel_ts < Last_Vel_ts) { + dt = (Last_Vel_ts - Vel_ts) / 80 * 1e-6f; + } else { + dt = (0xFFFFFF - Vel_ts + Last_Vel_ts) / 80 * 1e-6f; + } - if(dt < 0.0001) - { - dt = 10000; - } + if (dt < 0.0001) { + dt = 10000; + } - float Vel_Angle = GetAngle(); + float Vel_Angle = GetAngle(); - float dv = Vel_Angle - Vel_Last_Angle; + float dv = Vel_Angle - Vel_Last_Angle; - float velocity = (Vel_Angle - Vel_Last_Angle) / dt; + float velocity = (Vel_Angle - Vel_Last_Angle) / dt; - Last_Vel_ts = Vel_ts; - Vel_Last_Angle = Vel_Angle; + Last_Vel_ts = Vel_ts; + Vel_Last_Angle = Vel_Angle; - - return velocity; + return velocity; } -void MT6701_get_angle_degree(void) -{ - MT6701_iic_read_angel(); - angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); - angle_f = (float)angle * 360 / 16384; +void MT6701_get_angle_degree(void) { + MT6701_iic_read_angel(); + angle = ((int16_t)gRxPacket[0] << 6) | (gRxPacket[1] >> 2); + angle_f = (float)angle * 360 / 16384; } diff --git a/3rd/soft_i2c.c b/3rd/soft_i2c.c new file mode 100644 index 0000000..da900d1 --- /dev/null +++ b/3rd/soft_i2c.c @@ -0,0 +1,103 @@ +#include "soft_i2c.h" +#include "delay.h" +#include "ti_msp_dl_config.h" + +#define DELAY 1 +#define SDA_PIN_SHIFT 9 // if pa.8 shift8 , if pa.9 shift 9 +void I2C_ENABLE_OUTPUT_SDA(void) { + DL_GPIO_initDigitalOutput(SOFT_I2C_SDA_IOMUX); + DL_GPIO_enableOutput(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); +} +void I2C_ENABLE_INPUT_SDA(void) { + DL_GPIO_disableOutput(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); + DL_GPIO_initDigitalInputFeatures( + SOFT_I2C_SDA_IOMUX, DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP, + DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_DISABLE); +} + +void I2C_W_SCL(uint8_t BitValue) { + if (BitValue) { + DL_GPIO_setPins(SOFT_I2C_PORT, SOFT_I2C_CLK_PIN); + + } else { + DL_GPIO_clearPins(SOFT_I2C_PORT, SOFT_I2C_CLK_PIN); + } + delay_us(DELAY); +} + +void I2C_W_SDA(uint8_t BitValue) { + if (BitValue) { + DL_GPIO_setPins(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); + + } else { + DL_GPIO_clearPins(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); + } + delay_us(DELAY); +} + +// 读取时钟线数据 +uint8_t I2C_R_SDA(void) { + uint32_t BitValue; + BitValue = DL_GPIO_readPins(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); + + return (uint8_t)(BitValue >> 9); +} + +void I2C_Start(void) { + I2C_W_SCL(1); + I2C_W_SDA(1); + I2C_W_SDA(0); + I2C_W_SCL(0); +} + +void I2C_Stop(void) { + I2C_W_SDA(0); + I2C_W_SCL(1); + I2C_W_SDA(1); +} + +void I2C_SendByte(uint8_t Byte) { + uint8_t i; + + for (i = 0; i < 8; i++) { + I2C_W_SDA(Byte & (0x80 >> i)); + I2C_W_SCL(1); + I2C_W_SCL(0); + } +} + +uint8_t I2C_RecviveData(void) { + uint8_t i, Byte = 0x00; + I2C_W_SDA(1); + for (i = 0; i < 8; i++) { + I2C_ENABLE_INPUT_SDA(); + I2C_W_SCL(1); + if (I2C_R_SDA() == 1) { + Byte |= (0x80 >> i); + } + I2C_W_SCL(0); + I2C_ENABLE_OUTPUT_SDA(); + } + return Byte; +} + +void I2C_SendAck(uint8_t AckBit) { + + I2C_W_SDA(AckBit); + I2C_W_SCL(1); + I2C_W_SCL(0); +} + +uint8_t I2C_RecviveAck(void) { + uint8_t AckBit; + + I2C_W_SDA(1); + I2C_ENABLE_INPUT_SDA(); + I2C_W_SCL(1); + + AckBit = I2C_R_SDA(); + I2C_W_SCL(0); + I2C_ENABLE_OUTPUT_SDA(); + + return AckBit; +} diff --git a/3rd/soft_i2c.h b/3rd/soft_i2c.h new file mode 100644 index 0000000..ca310a2 --- /dev/null +++ b/3rd/soft_i2c.h @@ -0,0 +1,15 @@ +#ifndef __SOFT_I2C_H +#define __SOFT_I2C_H +#include + +void I2C_W_SCL(uint8_t BitValue); +void I2C_W_SDA(uint8_t BitValue); +uint8_t I2C_R_SDA(void); +void I2C_Start(void); +void I2C_Stop(void); +void I2C_SendByte(uint8_t Byte); +uint8_t I2C_RecviveData(void); +void I2C_SendAck(uint8_t AckBit); +uint8_t I2C_RecviveAck(void); + +#endif /* ti_msp_dl_config_h */ \ No newline at end of file diff --git a/empty.c b/empty.c index cdcde4e..8105e35 100644 --- a/empty.c +++ b/empty.c @@ -34,13 +34,13 @@ #include "delay.h" #include "dfoc.h" #include "mt6701.h" +#include "soft_i2c.h" #include "ti_msp_dl_config.h" #include #include #include #include #include - extern float angle_f; extern bool gIsI2cError; @@ -50,8 +50,8 @@ const float num_f = 0.123456f; volatile uint16_t count = 0; volatile float Target = 0; // 串口目标值 -const int pp = 7; // 电机极对数 -const int Dir = 1; // 电机编码器方向 +const int pp = 7; // 电机极对数 +const int Dir = -1; // 电机编码器方向 #define UART_PACKET_SIZE (6) @@ -134,9 +134,8 @@ void TIMER_0_INST_IRQHandler(void) { printf("Target is %f \n", Target); // printf("%s",gUartRxPacket); - printf("angle is %f \n", angle_f); DL_GPIO_togglePins(LED_PORT, LED_PA0_PIN); - Target = Target + 1; + break; default: break; diff --git a/empty.syscfg b/empty.syscfg index fa56caf..8e9db4a 100644 --- a/empty.syscfg +++ b/empty.syscfg @@ -11,6 +11,7 @@ */ const GPIO = scripting.addModule("/ti/driverlib/GPIO", {}, false); const GPIO1 = GPIO.addInstance(); +const GPIO2 = GPIO.addInstance(); const I2C = scripting.addModule("/ti/driverlib/I2C", {}, false); const I2C1 = I2C.addInstance(); const PWM = scripting.addModule("/ti/driverlib/PWM", {}, false); @@ -28,9 +29,6 @@ const UART1 = UART.addInstance(); const divider7 = system.clockTree["PLL_PDIV"]; divider7.divideValue = 2; -const divider9 = system.clockTree["UDIV"]; -divider9.divideValue = 2; - const gate7 = system.clockTree["MFCLKGATE"]; gate7.enable = true; @@ -40,14 +38,7 @@ multiplier2.multiplyValue = 4; const mux4 = system.clockTree["EXHFMUX"]; mux4.inputSelect = "EXHFMUX_XTAL"; -const mux8 = system.clockTree["HSCLKMUX"]; -mux8.inputSelect = "HSCLKMUX_SYSPLL2X"; - -const mux12 = system.clockTree["SYSPLLMUX"]; -mux12.inputSelect = "zSYSPLLMUX_HFCLK"; - const pinFunction4 = system.clockTree["HFXT"]; -pinFunction4.enable = true; pinFunction4.inputFreq = 40; GPIO1.$name = "LED"; @@ -59,6 +50,13 @@ Board.peripheral.$assign = "DEBUGSS"; Board.peripheral.swclkPin.$assign = "PA20"; Board.peripheral.swdioPin.$assign = "PA19"; +GPIO2.$name = "SOFT_I2C"; +GPIO2.associatedPins.create(2); +GPIO2.associatedPins[0].$name = "CLK"; +GPIO2.associatedPins[0].pin.$assign = "PA8"; +GPIO2.associatedPins[1].$name = "SDA"; +GPIO2.associatedPins[1].pin.$assign = "PA9"; + I2C1.$name = "I2C_1"; I2C1.advAnalogGlitchFilter = "DISABLED"; I2C1.basicEnableController = true; @@ -100,9 +98,9 @@ TIMER1.$name = "TIMER_0"; TIMER1.timerClkDiv = 8; TIMER1.timerMode = "PERIODIC"; TIMER1.timerClkPrescale = 8; -TIMER1.interrupts = ["ZERO"]; TIMER1.timerClkSrc = "LFCLK"; -TIMER1.timerPeriod = "1"; +TIMER1.interrupts = ["ZERO"]; +TIMER1.timerPeriod = "2"; TIMER1.peripheral.$assign = "TIMG0"; UART1.$name = "UART_0"; @@ -114,6 +112,7 @@ UART1.txFifoThreshold = "DL_UART_TX_FIFO_LEVEL_ONE_ENTRY"; UART1.enabledDMATXTriggers = "DL_UART_DMA_INTERRUPT_TX"; UART1.enabledInterrupts = ["DMA_DONE_RX"]; UART1.enabledDMARXTriggers = "DL_UART_DMA_INTERRUPT_RX"; +UART1.interruptPriority = "1"; UART1.peripheral.$assign = "UART0"; UART1.peripheral.rxPin.$assign = "PA11"; UART1.peripheral.txPin.$assign = "PA10"; @@ -138,8 +137,5 @@ ProjectConfig.migrationCondition = true; * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to * re-solve from scratch. */ -pinFunction4.peripheral.$suggestSolution = "SYSCTL"; -pinFunction4.peripheral.hfxInPin.$suggestSolution = "PA5"; -pinFunction4.peripheral.hfxOutPin.$suggestSolution = "PA6"; -I2C1.peripheral.$suggestSolution = "I2C1"; -UART1.DMA_CHANNEL_RX.peripheral.$suggestSolution = "DMA_CH1"; +I2C1.peripheral.$suggestSolution = "I2C1"; +UART1.DMA_CHANNEL_RX.peripheral.$suggestSolution = "DMA_CH1";