From 1d75c96f74653d02d8a51642d8eed6e040a119e0 Mon Sep 17 00:00:00 2001 From: 4x-tech Date: Tue, 18 Nov 2025 14:37:42 +0800 Subject: [PATCH] test soft i2c write and read passed --- 3rd/delay.c | 16 ++-- 3rd/delay.h | 1 + 3rd/mt6701.c | 239 +++++++++++++++++++++++++------------------------ 3rd/soft_i2c.c | 39 +++++++- empty.c | 89 +++++++++++------- empty.syscfg | 33 ++----- 6 files changed, 233 insertions(+), 184 deletions(-) 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 62f3a9d..ae9076d 100644 --- a/3rd/mt6701.c +++ b/3rd/mt6701.c @@ -28,129 +28,134 @@ volatile uint32_t gClockSelFreq; volatile uint32_t gDelayCycles; /* I2C Target address */ -#define I2C_TARGET_ADDRESS (0x06) - -// void MT6701_iic_read_angel(void) { - -// 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_RecviveAck(); - -// I2C_Start(); -// I2C_SendByte(I2C_TARGET_ADDRESS | 0x01); -// I2C_RecviveAck(); -// gRxPacket[1] = I2C_RecviveData(); -// I2C_SendAck(1); -// I2C_Stop(); -// } +#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"); - } - /* - * 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); + I2C_Start(); + I2C_SendByte(I2C_TARGET_ADDRESS); + I2C_RecviveAck(); + I2C_SendByte(0X03); + I2C_RecviveAck(); - /* Wait for I2C to be Idle */ - while ( - !(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) - ; + I2C_Start(); + I2C_SendByte(I2C_TARGET_ADDRESS | 0x01); + I2C_RecviveAck(); + gRxPacket[0] = I2C_RecviveData(); + I2C_SendAck(1); - /* 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 | 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; diff --git a/3rd/soft_i2c.c b/3rd/soft_i2c.c index ff6ec9c..da900d1 100644 --- a/3rd/soft_i2c.c +++ b/3rd/soft_i2c.c @@ -1,20 +1,46 @@ +#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) { - DL_GPIO_writePinsVal(SOFT_I2C_PORT, SOFT_I2C_CLK_PIN, 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) { - DL_GPIO_writePinsVal(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN, 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) { - uint8_t BitValue; + uint32_t BitValue; BitValue = DL_GPIO_readPins(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN); - return BitValue; + return (uint8_t)(BitValue >> 9); } void I2C_Start(void) { @@ -44,11 +70,13 @@ 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; } @@ -64,9 +92,12 @@ 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/empty.c b/empty.c index d149968..8bc5ec9 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; @@ -96,43 +96,70 @@ int main(void) { SYSCFG_DL_init(); - int count = 10; - while (count--) { - DL_GPIO_writePinsVal(LED_PORT, LED_PA0_PIN, 1); - delay_ms(100); - DL_GPIO_writePinsVal(LED_PORT, LED_PA0_PIN, 0); - delay_ms(100); - } - /* Configure DMA source, destination and size */ - DL_DMA_setSrcAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t)(&UART_0_INST->RXDATA)); - DL_DMA_setDestAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t)&gUartRxPacket[0]); - DL_DMA_setTransferSize(DMA, DMA_CH1_CHAN_ID, UART_PACKET_SIZE); - DL_DMA_enableChannel(DMA, DMA_CH1_CHAN_ID); + // DL_DMA_setSrcAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t)(&UART_0_INST->RXDATA)); + // DL_DMA_setDestAddr(DMA, DMA_CH1_CHAN_ID, (uint32_t)&gUartRxPacket[0]); + // DL_DMA_setTransferSize(DMA, DMA_CH1_CHAN_ID, UART_PACKET_SIZE); + // DL_DMA_enableChannel(DMA, DMA_CH1_CHAN_ID); NVIC_EnableIRQ(UART_0_INST_INT_IRQN); - DL_TimerA_startCounter(PWM_0_INST); + // DL_TimerA_startCounter(PWM_0_INST); - NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); - DL_TimerG_startCounter(TIMER_0_INST); - - FOC_Init(12); - DL_SYSTICK_resetValue(); + // NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); + // DL_TimerG_startCounter(TIMER_0_INST); + // FOC_Init(12); + // DL_SYSTICK_resetValue(); + uint32_t readback = 0xffff; while (1) { - // DL_GPIO_togglePins(LED_PORT, LED_PA0_PIN); - // delay_ms(10); - // 开环 - // velocityopenloop(Target); - // 闭环 - Set_Angle(Target); - if (gCheckUART) { - gCheckUART = false; - parse_uart_cmd(); - // Set_Angle(Target); - } - // delay_ms(10); + I2C_Start(); + I2C_SendByte(0x06 << 1); + I2C_RecviveAck(); + I2C_SendByte(0x03); + I2C_RecviveAck(); + I2C_Stop(); + + // DL_GPIO_writePinsVal(LED_PORT, LED_PA0_PIN, 1); + // readback = DL_GPIO_readPins(LED_PORT, LED_PA0_PIN); + // printf("pa 0readback is %d \n", readback); + // delay_ms(100); + + // DL_GPIO_writePinsVal(LED_PORT, LED_PA0_PIN, 0); + // readback = DL_GPIO_readPins(LED_PORT, LED_PA0_PIN); + // printf("pa0 readback is %d \n", readback); + // delay_ms(100); + + // DL_GPIO_disableOutput(SOFT_I2C_PORT, SOFT_I2C_CLK_PIN); + // DL_GPIO_initDigitalInputFeatures( + // SOFT_I2C_CLK_IOMUX, DL_GPIO_INVERSION_DISABLE, + // DL_GPIO_RESISTOR_PULL_UP, DL_GPIO_HYSTERESIS_DISABLE, + // DL_GPIO_WAKEUP_DISABLE); + // 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); + + // readback = + // DL_GPIO_readPins(SOFT_I2C_PORT, SOFT_I2C_CLK_PIN | SOFT_I2C_SDA_PIN); + // printf("soft_i2c_clk readback is %x \n", readback); + // delay_ms(100); + + // // DL_GPIO_togglePins(LED_PORT, LED_PA0_PIN); + // // delay_ms(10); + + // // 开环 + // // velocityopenloop(Target); + // // 闭环 + // Set_Angle(Target); + // if (gCheckUART) { + // gCheckUART = false; + // parse_uart_cmd(); + // // Set_Angle(Target); + // } + // // delay_ms(10); } } diff --git a/empty.syscfg b/empty.syscfg index 63d743e..8e9db4a 100644 --- a/empty.syscfg +++ b/empty.syscfg @@ -29,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; @@ -41,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"; @@ -60,18 +50,12 @@ Board.peripheral.$assign = "DEBUGSS"; Board.peripheral.swclkPin.$assign = "PA20"; Board.peripheral.swdioPin.$assign = "PA19"; -GPIO2.$name = "SOFT_I2C"; -GPIO2.port = "PORTA"; -GPIO2.portSegment = "Lower"; +GPIO2.$name = "SOFT_I2C"; GPIO2.associatedPins.create(2); -GPIO2.associatedPins[0].initialValue = "SET"; -GPIO2.associatedPins[0].$name = "CLK"; -GPIO2.associatedPins[0].ioStructure = "HS"; -GPIO2.associatedPins[0].pin.$assign = "PA13"; -GPIO2.associatedPins[1].initialValue = "SET"; -GPIO2.associatedPins[1].ioStructure = "HS"; -GPIO2.associatedPins[1].$name = "SDA"; -GPIO2.associatedPins[1].pin.$assign = "PA14"; +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"; @@ -153,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";