diff --git a/F3:F303/I2C_scan/i2c.c b/F3:F303/I2C_scan/i2c.c index 27d8404..416e6e9 100644 --- a/F3:F303/I2C_scan/i2c.c +++ b/F3:F303/I2C_scan/i2c.c @@ -64,15 +64,21 @@ void i2c_setup(I2C_SPEED speed){ GPIOB->PUPDR = (GPIOB->PUPDR & !(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7)) | GPIO_PUPDR6_PU | GPIO_PUPDR7_PU; // pullup (what if there's no external pullup?) GPIOB->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7; // both open-drain outputs - // I2C (default timing from PCLK - 64MHz) + // I2C (default timing from sys clock - 72MHz) RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // clocking - if(speed == LOW_SPEED){ // 10kHz - // PRESC=F, SCLDEL=4, SDADEL=2, SCLH=0xC3, SCLL=0xC7 - I2C1->TIMINGR = (0xF<<28) | (4<<20) | (2<<16) | (0xC3<<8) | (0xC7); - }else if(speed == HIGH_SPEED){ // 100kHz - I2C1->TIMINGR = (0xF<<28) | (4<<20) | (2<<16) | (0xF<<8) | (0x13); - }else{ // VERYLOW_SPEED - the lowest speed by STM register: ~7.7kHz - I2C1->TIMINGR = (0xF<<28) | (4<<20) | (2<<16) | (0xff<<8) | (0xff); + if(speed == HIGH_SPEED){ + // activate "fast mode plus" + SYSCFG->CFGR1 |= SYSCFG_CFGR1_I2C1_FMP | SYSCFG_CFGR1_I2C_PB6_FMP | SYSCFG_CFGR1_I2C_PB7_FMP; + }else{ + SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_I2C1_FMP | SYSCFG_CFGR1_I2C_PB6_FMP | SYSCFG_CFGR1_I2C_PB7_FMP); + } + if(speed == LOW_SPEED){ // 100kHz + I2C1->TIMINGR = (0xf<<28) | (0x04<<20) | (0x03<<16) | (0x12<<8) | (0x15); + // PRESC SCLDEL SDADEL SCLH SCLL + }else if(speed == HIGH_SPEED){ // 400kHz + I2C1->TIMINGR = (0x06<<28) | (0x04<<20) | (0x03<<16) | (0x06<<8) | (0x08); + }else{ // VERYLOW_SPEED - 10kHz + I2C1->TIMINGR = (0xf<<28) | (0x04<<20) | (0x03<<16) | (0xc3<<8) | (0xc7); } I2C1->CR1 = I2CCR1; RCC->AHBENR |= RCC_AHBENR_DMA1EN; @@ -97,31 +103,37 @@ static void i2cDMAsetup(int tx, uint8_t len){ } } -static uint8_t i2c_start(uint8_t busychk){ +static uint8_t i2c_chk(uint8_t busychk){ + I2C1->CR2 = 0; if(busychk){ cntr = Tms; while(I2C1->ISR & I2C_ISR_BUSY){ IWDG->KR = IWDG_REFRESH; if(Tms - cntr > I2C_TIMEOUT){ - USND("Line busy\n"); + USND("i2c_chk: Line busy\n"); return 0; // check busy }} - } + }/* cntr = Tms; while(I2C1->CR2 & I2C_CR2_START){ IWDG->KR = IWDG_REFRESH; if(Tms - cntr > I2C_TIMEOUT){ - USND("No start\n"); + USND("i2c_chk: No start\n"); return 0; // check start - }} + }}*/ return 1; } // start writing static uint8_t i2c_startw(uint8_t addr, uint8_t nbytes, uint8_t stop){ - if(!i2c_start(1)) return 0; + if(!i2c_chk(1)) return 0; I2C1->CR2 = nbytes << 16 | addr; - if(stop) I2C1->CR2 |= I2C_CR2_AUTOEND; // autoend + if(stop){ + I2C1->CR2 |= I2C_CR2_AUTOEND; // autoend + }else{ + //I2C1->CR2 &= ~I2C_CR2_AUTOEND; + //I2C1->CR2 |= I2C_CR2_RELOAD; + } // now start transfer I2C1->CR2 |= I2C_CR2_START; return 1; @@ -143,21 +155,31 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t s IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ I2C1->ICR |= I2C_ICR_NACKCF; - //USND("NAK\n"); + USND("write_i2cs: NAK\n"); return 0; } if(Tms - cntr > I2C_TIMEOUT){ - //USND("Timeout\n"); + USND("write_i2cs: Timeout\n"); return 0; } } I2C1->TXDR = data[i]; // send data + USND("write_i2cs: "); USND(uhex2str(data[i])); newline(); } cntr = Tms; - // wait for data gone - while(I2C1->ISR & I2C_ISR_BUSY){ - IWDG->KR = IWDG_REFRESH; - if(Tms - cntr > I2C_TIMEOUT){break;} + if(stop){ + while(I2C1->ISR & I2C_ISR_BUSY){ + IWDG->KR = IWDG_REFRESH; + if(Tms - cntr > I2C_TIMEOUT){USND("write_i2cs: Busy timeout\n"); break;} + } + }else{ // repeated start + while(!(I2C1->ISR & I2C_ISR_TC)){ + IWDG->KR = IWDG_REFRESH; + if(Tms - cntr > I2C_TIMEOUT){ + USND("write_i2cs: TC timeout\n"); + return 0; + } + } } return 1; } @@ -181,10 +203,11 @@ uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint8_t nbytes){ // start reading static uint8_t i2c_startr(uint8_t addr, uint8_t nbytes, uint8_t busychk){ - if(!i2c_start(busychk)) return 0; + if(!i2c_chk(busychk)) return 0; // read N bytes - I2C1->CR2 = (nbytes<<16) | addr | 1 | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN; + I2C1->CR2 = (nbytes<<16) | addr /*| I2C_CR2_AUTOEND*/ | I2C_CR2_RD_WRN; I2C1->CR2 |= I2C_CR2_START; + I2C1->CR2 |= I2C_CR2_AUTOEND; return 1; } @@ -203,18 +226,27 @@ static uint8_t read_i2cb(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t bu IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ I2C1->ICR |= I2C_ICR_NACKCF; - //USND("NAK\n"); + USND("read_i2_nostart: NAK\n"); return 0; } if(Tms - cntr > I2C_TIMEOUT){ - //USND("Timeout\n"); + USND("read_i2_nostart: Timeout\n"); return 0; } } *data++ = I2C1->RXDR; + }/* + cntr = Tms; + while(!(I2C1->ISR & I2C_ISR_TC)){ + IWDG->KR = IWDG_REFRESH; + if(Tms - cntr > I2C_TIMEOUT){ + USND("read_i2cs: TC timeout\n"); + return 0; + } } + I2C1->CR2 = I2C_CR2_STOP;*/ return 1; - } +} uint8_t read_i2c(uint8_t addr, uint8_t *data, uint8_t nbytes){ if(isI2Cbusy()) return 0; @@ -243,6 +275,7 @@ uint8_t read_i2c_reg(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t nbytes){ // read 16bit register reg uint8_t read_i2c_reg16(uint8_t addr, uint16_t reg16, uint8_t *data, uint8_t nbytes){ if(isI2Cbusy()) return 0; + reg16 = __REV16(reg16); if(!write_i2cs(addr, (uint8_t*)®16, 2, 0)) return 0; return read_i2cb(addr, data, nbytes, 0); } diff --git a/F3:F303/I2C_scan/i2cscan.bin b/F3:F303/I2C_scan/i2cscan.bin index 886c411..e043dbc 100755 Binary files a/F3:F303/I2C_scan/i2cscan.bin and b/F3:F303/I2C_scan/i2cscan.bin differ diff --git a/F3:F303/I2C_scan/i2cscan.creator.user b/F3:F303/I2C_scan/i2cscan.creator.user index 19feb85..69da5ac 100644 --- a/F3:F303/I2C_scan/i2cscan.creator.user +++ b/F3:F303/I2C_scan/i2cscan.creator.user @@ -1,20 +1,20 @@ - + EnvironmentId - {cf63021e-ef53-49b0-b03b-2f2570cdf3b6} + {7bd84e39-ca37-46d3-be9d-99ebea85bc0d} ProjectExplorer.Project.ActiveTarget - 0 + 0 ProjectExplorer.Project.EditorSettings + true true - false true Cpp @@ -28,32 +28,35 @@ QmlJSGlobal - 2 + 2 KOI8-R false 4 false + 0 80 true true 1 + 0 false true false - 1 + 0 true true 0 8 true false - 2 + 1 true false true *.md, *.MD, Makefile false true + true @@ -67,17 +70,17 @@ true true + false + 0 true - - true - Builtin.BuildSystem true true Builtin.DefaultTidyAndClazy - 1 + 2 + false @@ -89,14 +92,15 @@ ProjectExplorer.Project.Target.0 Desktop + true Desktop Desktop - {91347f2c-5221-46a7-80b1-0a054ca02f79} - 0 - 0 - 0 + {65a14f9e-e008-4c1b-89df-4eaa4774b6e3} + 0 + 0 + 0 - /home/eddy/C-files/stm32samples/F3:F303/I2C_scan + /Big/Data/00__Electronics/STM32/F303-nolib/blink @@ -105,9 +109,9 @@ true GenericProjectManager.GenericMakeStep - 1 - Сборка - Сборка + 1 + Build + Build ProjectExplorer.BuildSteps.Build @@ -118,9 +122,9 @@ true GenericProjectManager.GenericMakeStep - 1 - Очистка - Очистка + 1 + Clean + Clean ProjectExplorer.BuildSteps.Clean 2 @@ -128,15 +132,47 @@ false - По умолчанию + Default GenericProjectManager.GenericBuildConfiguration + 0 + 0 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + true + + 1 - 1 + 1 - 0 - Развёртывание - Развёртывание + 0 + Deploy + Deploy ProjectExplorer.BuildSteps.Deploy 1 @@ -144,24 +180,29 @@ false ProjectExplorer.DefaultDeployConfiguration - 1 + 1 + true + true + true 2 + false + -e cpu-cycles --call-graph dwarf,4096 -F 250 + ProjectExplorer.CustomExecutableRunConfiguration - false + false true - false true - 1 + 1 ProjectExplorer.Project.TargetCount - 1 + 1 ProjectExplorer.Project.Updater.FileVersion diff --git a/F3:F303/I2C_scan/i2cscan.creator.user.cf63021 b/F3:F303/I2C_scan/i2cscan.creator.user.cf63021 new file mode 100644 index 0000000..19feb85 --- /dev/null +++ b/F3:F303/I2C_scan/i2cscan.creator.user.cf63021 @@ -0,0 +1,174 @@ + + + + + + EnvironmentId + {cf63021e-ef53-49b0-b03b-2f2570cdf3b6} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + KOI8-R + false + 4 + false + 80 + true + true + 1 + false + true + false + 1 + true + true + 0 + 8 + true + false + 2 + true + false + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + Builtin.BuildSystem + + true + true + Builtin.DefaultTidyAndClazy + 1 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {91347f2c-5221-46a7-80b1-0a054ca02f79} + 0 + 0 + 0 + + /home/eddy/C-files/stm32samples/F3:F303/I2C_scan + + + + all + + true + GenericProjectManager.GenericMakeStep + + 1 + Сборка + Сборка + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + GenericProjectManager.GenericMakeStep + + 1 + Очистка + Очистка + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + По умолчанию + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Развёртывание + Развёртывание + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + 2 + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/F3:F303/I2C_scan/proto.c b/F3:F303/I2C_scan/proto.c index c2e4452..7003a7d 100644 --- a/F3:F303/I2C_scan/proto.c +++ b/F3:F303/I2C_scan/proto.c @@ -46,19 +46,19 @@ const char *helpstring = static uint8_t i2cinited = 0; TRUE_INLINE const char *setupI2C(const char *buf){ buf = omit_spaces(buf); - if(*buf < '0' || *buf > '2') return "Wrong speed"; + if(*buf < '0' || *buf > '2') return "Wrong speed\n"; i2c_setup(*buf - '0'); i2cinited = 1; - return "OK"; + return "OK\n"; } static uint8_t I2Caddress = 0; TRUE_INLINE const char *saI2C(const char *buf){ uint32_t addr; - if(!getnum(buf, &addr) || addr > 0x7f) return "Wrong address"; + if(!getnum(buf, &addr) || addr > 0x7f) return "Wrong address\n"; I2Caddress = (uint8_t) addr << 1; USND("I2Caddr="); USND(uhex2str(addr)); newline(); - return "OK"; + return "OK\n"; } static void rdI2C(const char *buf, int is16){ uint32_t N = 0; @@ -111,7 +111,7 @@ static void rdI2C(const char *buf, int is16){ } } } - if(N == 0){ USND("OK"); return; } + if(N == 0){ USND("OK\n"); return; } if(!noreg){USND("Register "); USND(uhex2str(reg)); USND(":\n");} hexdump(USB_sendstr, locBuffer, N); } @@ -132,8 +132,8 @@ static const char *wrI2C(const char *buf, int isdma){ uint16_t N = readNnumbers(buf); int result = isdma ? write_i2c_dma(I2Caddress, locBuffer, N) : write_i2c(I2Caddress, locBuffer, N); - if(!result) return "Error writing I2C"; - return "OK"; + if(!result) return "Error writing I2C\n"; + return "OK\n"; } const char *parse_cmd(const char *buf){ diff --git a/F3:F303/I2C_scan/version.inc b/F3:F303/I2C_scan/version.inc index cde0d53..18928cb 100644 --- a/F3:F303/I2C_scan/version.inc +++ b/F3:F303/I2C_scan/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "17" -#define BUILD_DATE "2023-01-22" +#define BUILD_NUMBER "64" +#define BUILD_DATE "2025-09-13" diff --git a/F3:F303/inc/Fx/stm32f3.h b/F3:F303/inc/Fx/stm32f3.h index c50b043..79b3c61 100644 --- a/F3:F303/inc/Fx/stm32f3.h +++ b/F3:F303/inc/Fx/stm32f3.h @@ -123,6 +123,8 @@ TRUE_INLINE int StartHSE(){ // system bus 72MHz from PLL WAITWHILE(!(RCC->CR & RCC_CR_PLLRDY)); // Select PLL as system clock source RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; + // select system clock as I2C source + RCC->CFGR3 |= RCC_CFGR3_I2C1SW_SYSCLK | RCC_CFGR3_I2C1SW_SYSCLK; // Wait till PLL is used as system clock source WAITWHILE((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); SysFreq = 72000000;