diff --git a/F3:F303/I2C_scan/i2c.c b/F3:F303/I2C_scan/i2c.c index cbe1ded..433208b 100644 --- a/F3:F303/I2C_scan/i2c.c +++ b/F3:F303/I2C_scan/i2c.c @@ -136,40 +136,35 @@ static void i2cDMAsetup(int tx, uint16_t len){ // wait until bit set or clear; return 1 if OK, 0 in case of timeout static uint8_t waitISRbit(uint32_t bit, uint8_t isset){ uint32_t waitwhile = (isset) ? 0 : bit; // wait until != - const char *errmsg = NULL; + //const char *errmsg = NULL; cntr = Tms; - if(bit != I2C_ISR_RXNE){ U("ISR wait "); U(uhex2str(bit)); USND(isset ? "set" : "reset"); } + //if(bit != I2C_ISR_RXNE){ U("ISR wait "); U(uhex2str(bit)); USND(isset ? "set" : "reset"); } while((I2C1->ISR & bit) == waitwhile){ IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ - errmsg = "NAK"; + //errmsg = "NAK"; goto goterr; } if(Tms - cntr > I2C_TIMEOUT){ - errmsg = "timeout"; + //errmsg = "timeout"; goto goterr; } } return 1; goterr: - U("wait ISR bit: "); USND(errmsg); - U("I2c->ISR = "); USND(uhex2str(I2C1->ISR)); + /*U("wait ISR bit: "); USND(errmsg); + U("I2c->ISR = "); USND(uhex2str(I2C1->ISR));*/ I2C1->ICR = 0xff; return 0; } // start writing -static uint8_t i2c_startw(uint8_t addr, uint16_t nbytes, uint8_t stop){ +static uint8_t i2c_startw(uint8_t addr, uint8_t nbytes, uint8_t stop){ if(!waitISRbit(I2C_ISR_BUSY, 0)) return 0; - I2C1->CR2 = nbytes << 16 | addr; - if(stop){ - I2C1->CR2 |= I2C_CR2_AUTOEND; // autoend - }else{ - //I2C1->CR2 &= ~I2C_CR2_AUTOEND; - //I2C1->CR2 |= I2C_CR2_RELOAD; - } + uint32_t cr2 = nbytes << 16 | addr | I2C_CR2_START; + if(stop) cr2 |= I2C_CR2_AUTOEND; // now start transfer - I2C1->CR2 |= I2C_CR2_START; + I2C1->CR2 = cr2; return 1; } @@ -181,7 +176,7 @@ static uint8_t i2c_startw(uint8_t addr, uint16_t nbytes, uint8_t stop){ * @param stop - to set STOP * @return 0 if error */ -static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint16_t nbytes, uint8_t stop){ +static uint8_t i2c_writes(uint8_t addr, uint8_t *data, uint8_t nbytes, uint8_t stop){ if(!i2c_startw(addr, nbytes, stop)) return 0; for(int i = 0; i < nbytes; ++i){ cntr = Tms; @@ -189,16 +184,16 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint16_t nbytes, uint8_t IWDG->KR = IWDG_REFRESH; if(I2C1->ISR & I2C_ISR_NACKF){ I2C1->ICR |= I2C_ICR_NACKCF; - USND("write_i2cs: NAK"); + //USND("i2c_writes: NAK"); return 0; } if(Tms - cntr > I2C_TIMEOUT){ - USND("write_i2cs: Timeout"); + //USND("i2c_writes: Timeout"); return 0; } } I2C1->TXDR = data[i]; // send data - U("write_i2cs: "); USND(uhex2str(data[i])); + //U("i2c_writes: "); USND(uhex2str(data[i])); } cntr = Tms; if(stop){ @@ -209,19 +204,13 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint16_t nbytes, uint8_t return 1; } -uint8_t write_i2c(uint8_t addr, uint8_t *data, uint16_t nbytes){ +uint8_t i2c_write(uint8_t addr, uint8_t *data, uint8_t nbytes){ if(isI2Cbusy()) return 0; - return write_i2cs(addr, data, nbytes, 1); + return i2c_writes(addr, data, nbytes, 1); } -/* -uint8_t write_i2c16(uint8_t addr, uint8_t *data, uint8_t nbytes){ - if(isI2Cbusy()) return 0; - return write_i2cs(addr, data, nbytes, 1); -}*/ - -uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint16_t nbytes){ - if(!data || nbytes < 1 || nbytes > I2C_BUFSIZE) return 0; +uint8_t i2c_write_dma(uint8_t addr, uint8_t *data, uint8_t nbytes){ + if(!data || nbytes < 1) return 0; if(isI2Cbusy()) return 0; memcpy(I2Cbuf, data, nbytes); i2cDMAsetup(1, nbytes); @@ -232,8 +221,8 @@ uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint16_t nbytes){ return 1; } -uint8_t write_i2c_dma16(uint8_t addr, uint16_t *data, uint16_t nwords){ - if(!data || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0; +uint8_t i2c_write_dma16(uint8_t addr, uint16_t *data, uint8_t nwords){ + if(!data || nwords < 1 || nwords > 127) return 0; if(isI2Cbusy()) return 0; uint16_t nbytes = nwords << 1; if(bigendian){ @@ -251,10 +240,8 @@ uint8_t write_i2c_dma16(uint8_t addr, uint16_t *data, uint16_t nwords){ // start reading of `nbytes` from `addr`; if `start`==`, set START static uint8_t i2c_startr(uint8_t addr, uint16_t nbytes, uint8_t start){ uint32_t cr2 = addr | I2C_CR2_RD_WRN; - if(nbytes > 255){ - nbytes = 255; cr2 |= I2C_CR2_RELOAD; - }else cr2 |= I2C_CR2_AUTOEND; - cr2 |= (nbytes << 16); + if(nbytes > 255) cr2 |= I2C_CR2_RELOAD | (0xff0000); + else cr2 |= I2C_CR2_AUTOEND | (nbytes << 16); I2C1->CR2 = (start) ? cr2 | I2C_CR2_START : cr2; return 1; } @@ -265,64 +252,64 @@ static uint8_t i2c_startr(uint8_t addr, uint16_t nbytes, uint8_t start){ * `data` should be an array with at least `nbytes` length * @return 1 if all OK, 0 if NACK or no device found */ -static uint8_t *read_i2cb(uint8_t addr, uint16_t nbytes, uint8_t busychk){ - if(busychk && !waitISRbit(I2C_ISR_BUSY, 0)) return NULL; +static uint8_t *i2c_readb(uint8_t addr, uint16_t nbytes){ uint8_t start = 1; uint8_t *bptr = I2Cbuf; while(nbytes){ - U("Read "); U(u2str(nbytes)); USND(" bytes"); + //U("Read "); U(u2str(nbytes)); USND(" bytes"); if(!i2c_startr(addr, nbytes, start)) return NULL; if(nbytes < 256){ for(int i = 0; i < nbytes; ++i){ if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout; *bptr++ = I2C1->RXDR; } - while(waitISRbit(I2C_ISR_RXNE, 1)){ + /*while(waitISRbit(I2C_ISR_RXNE, 1)){ U("OOOps! We have another byte: "); USND(uhex2str(I2C1->RXDR)); - } + }*/ break; }else while(!(I2C1->ISR & I2C_ISR_TCR)){ // until first part read if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout; *bptr++ = I2C1->RXDR; } - USND("next"); + //USND("next"); nbytes -= 255; start = 0; } return I2Cbuf; tmout: - USND("read I2C: Timeout"); + //USND("read I2C: Timeout"); return NULL; } -uint8_t *read_i2c(uint8_t addr, uint16_t nbytes){ - if(isI2Cbusy()) return 0; - return read_i2cb(addr, nbytes, 1); +uint8_t *i2c_read(uint8_t addr, uint16_t nbytes){ + if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return 0; + return i2c_readb(addr, nbytes); } -static uint8_t dmard(uint8_t addr, uint16_t nbytes, uint8_t stop){ +static uint8_t dmard(uint8_t addr, uint16_t nbytes){ if(nbytes < 1 || nbytes > I2C_BUFSIZE) return 0; - if(isI2Cbusy()) return 0; i2cDMAsetup(0, nbytes); goterr = 0; i2c_got_DMA = 0; - if(!i2c_startr(addr, nbytes, stop)) return 0; - dma_remain = nbytes > 255 ? nbytes - 255 : 0; // remainder after first read finish (void) I2C1->RXDR; // avoid wrong first byte DMA1_Channel7->CCR = DMARXCCR | DMA_CCR_EN; // init DMA before START sequence + if(!i2c_startr(addr, nbytes, 1)) return 0; + dma_remain = nbytes > 255 ? nbytes - 255 : 0; // remainder after first read finish I2Cbusy = 1; return 1; } -uint8_t read_i2c_dma(uint8_t addr, uint16_t nbytes){ - uint8_t got = dmard(addr, nbytes, 1); +uint8_t i2c_read_dma(uint8_t addr, uint16_t nbytes){ + if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return 0; + uint8_t got = dmard(addr, nbytes); if(got) dma16bit = 0; return got; } -uint8_t read_i2c_dma16(uint8_t addr, uint16_t nwords){ +uint8_t i2c_read_dma16(uint8_t addr, uint16_t nwords){ if(nwords > I2C_BUFSIZE/2) return 0; // what if `nwords` is very large? we should check it - uint8_t got = dmard(addr, nwords<<1, 1); + if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return 0; + uint8_t got = dmard(addr, nwords<<1); if(got) dma16bit = 1; return got; } @@ -334,30 +321,29 @@ static void swapbytes(uint16_t *data, uint16_t datalen){ } // read register reg -uint8_t *read_i2c_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma){ - if(isI2Cbusy()) return NULL; - if(!write_i2cs(addr, ®, 1, 0)) return NULL; +uint8_t *i2c_read_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma){ + if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return NULL; + if(!i2c_writes(addr, ®, 1, 0)) return NULL; if(isdma){ - if(dmard(addr, nbytes, 0)){ dma16bit = 0; return I2Cbuf;} // for DMA we just return something non-null to check OK + if(dmard(addr, nbytes)){ dma16bit = 0; return I2Cbuf;} // for DMA we just return something non-null to check OK return NULL; } - return read_i2cb(addr, nbytes, 0); + return i2c_readb(addr, nbytes); } // read 16bit register reg -uint16_t *read_i2c_reg16(uint8_t addr, uint16_t reg16, uint16_t nwords, uint8_t isdma){ - if(isI2Cbusy() || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0; +uint16_t *i2c_read_reg16(uint8_t addr, uint16_t reg16, uint16_t nwords, uint8_t isdma){ + if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0) || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0; if(bigendian) reg16 = __REV16(reg16); - if(!write_i2cs(addr, (uint8_t*)®16, 2, 0)) return NULL; + if(!i2c_writes(addr, (uint8_t*)®16, 2, 0)) return NULL; if(isdma){ - if(dmard(addr, nwords<<1, 0)){ dma16bit = 1; return (uint16_t*)I2Cbuf; } + if(dmard(addr, nwords<<1)){ dma16bit = 1; return (uint16_t*)I2Cbuf; } return NULL; } - if(!read_i2cb(addr, nwords*2, 0)) return NULL; - uint16_t *buf = (uint16_t*)I2Cbuf; - if(bigendian) swapbytes(buf, nwords); - return buf; + if(!i2c_readb(addr, nwords<<1)) return NULL; + if(bigendian) swapbytes((uint16_t*)I2Cbuf, nwords); + return (uint16_t*)I2Cbuf; } void i2c_init_scan_mode(){ @@ -376,7 +362,7 @@ int i2c_scan_next_addr(uint8_t *addr){ i2c_scanmode = 0; return 0; } - if(!read_i2c((i2caddr++)<<1, 1)) return 0; + if(!i2c_read((i2caddr++)<<1, 1)) return 0; return 1; } @@ -389,31 +375,30 @@ void i2c_bufdudump(){ if(i2cbuflen < 1) return; USND("I2C buffer:"); if(dma16bit) hexdump16(USB_sendstr, (uint16_t*)I2Cbuf, i2cbuflen); - hexdump(USB_sendstr, I2Cbuf, i2cbuflen); + else hexdump(USB_sendstr, I2Cbuf, i2cbuflen); } // get DMA buffer with conversion to little-endian (if transfer was for 16-bit) -uint8_t *i2cdma_getbuf(uint16_t *len){ +uint8_t *i2c_dma_getbuf(uint16_t *len){ if(!i2c_got_DMA || i2cbuflen < 1) return NULL; i2c_got_DMA = 0; if(dma16bit){ i2cbuflen >>= 1; // for hexdump16 - now buffer have uint16_t! - uint16_t *b = (uint16_t*)I2Cbuf; - if(bigendian){ - for(int i = 0; i < i2cbuflen; ++i) b[i] = __REV(b[i]); - } + if(bigendian) swapbytes((uint16_t*)I2Cbuf, i2cbuflen); } if(len) *len = i2cbuflen; return I2Cbuf; } -int i2cdma_haderr(){ +int i2c_dma_haderr(){ int r = goterr; goterr = 0; return r; } -void endianness(uint8_t isbig){ +int i2c_busy(){ return I2Cbusy;} + +void i2c_endianness(uint8_t isbig){ bigendian = isbig; } diff --git a/F3:F303/I2C_scan/i2c.h b/F3:F303/I2C_scan/i2c.h index ff7c6a9..3869051 100644 --- a/F3:F303/I2C_scan/i2c.h +++ b/F3:F303/I2C_scan/i2c.h @@ -35,23 +35,25 @@ extern i2c_speed_t i2c_curspeed; extern volatile uint8_t i2c_scanmode; // timeout of I2C bus in ms -#define I2C_TIMEOUT (5) +#define I2C_TIMEOUT (5) void i2c_setup(i2c_speed_t speed); -uint8_t *read_i2c(uint8_t addr, uint16_t nbytes); -uint8_t *read_i2c_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma); -uint16_t *read_i2c_reg16(uint8_t addr, uint16_t reg16, uint16_t nbytes, uint8_t isdma); -uint8_t write_i2c(uint8_t addr, uint8_t *data, uint16_t nbytes); +int i2c_busy(); -uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint16_t nbytes); -uint8_t write_i2c_dma16(uint8_t addr, uint16_t *data, uint16_t nwords); -uint8_t read_i2c_dma(uint8_t addr, uint16_t nbytes); +uint8_t *i2c_read(uint8_t addr, uint16_t nbytes); +uint8_t i2c_read_dma(uint8_t addr, uint16_t nbytes); +uint8_t i2c_read_dma16(uint8_t addr, uint16_t nwords); +uint8_t *i2c_read_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma); +uint16_t *i2c_read_reg16(uint8_t addr, uint16_t reg16, uint16_t nbytes, uint8_t isdma); + +uint8_t i2c_write(uint8_t addr, uint8_t *data, uint8_t nbytes); +uint8_t i2c_write_dma(uint8_t addr, uint8_t *data, uint8_t nbytes); +uint8_t i2c_write_dma16(uint8_t addr, uint16_t *data, uint8_t nwords); void i2c_bufdudump(); -int i2cdma_haderr(); -uint8_t *i2cdma_getbuf(uint16_t *len); -uint8_t read_i2c_dma16(uint8_t addr, uint16_t nwords); -void endianness(uint8_t isbig); +int i2c_dma_haderr(); +uint8_t *i2c_dma_getbuf(uint16_t *len); +void i2c_endianness(uint8_t isbig); int i2c_getwords(uint16_t *buf, int bufsz); void i2c_init_scan_mode(); diff --git a/F3:F303/I2C_scan/i2cscan.bin b/F3:F303/I2C_scan/i2cscan.bin index 19d1344..ca529c2 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 138fc14..63477ae 100644 --- a/F3:F303/I2C_scan/i2cscan.creator.user +++ b/F3:F303/I2C_scan/i2cscan.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/F3:F303/I2C_scan/main.c b/F3:F303/I2C_scan/main.c index c646cd0..becd916 100644 --- a/F3:F303/I2C_scan/main.c +++ b/F3:F303/I2C_scan/main.c @@ -53,7 +53,7 @@ int main(void){ if(l < 0) USND("ERROR: USB buffer overflow or string was too long"); else if(l){ const char *ans = parse_cmd(inbuff); - if(ans) USND(ans); + if(ans) U(ans); } if(i2c_scanmode){ uint8_t addr; @@ -65,7 +65,7 @@ int main(void){ U(") - found device\n"); } } - if(i2cdma_haderr()) USND("Error reading I2C using DMA"); - if(i2cdma_getbuf(NULL)) i2c_bufdudump(); + if(i2c_dma_haderr()) USND("Error reading I2C using DMA"); + if(i2c_dma_getbuf(NULL)) i2c_bufdudump(); } } diff --git a/F3:F303/I2C_scan/proto.c b/F3:F303/I2C_scan/proto.c index e3dc07c..1746609 100644 --- a/F3:F303/I2C_scan/proto.c +++ b/F3:F303/I2C_scan/proto.c @@ -26,6 +26,7 @@ #define LOCBUFFSZ (32) // local buffer for I2C data to send static uint8_t locBuffer[LOCBUFFSZ]; +static uint8_t I2Caddress = 0x33 << 1; extern volatile uint32_t Tms; static const char *OK = "OK\n"; @@ -33,6 +34,7 @@ static const char *helpstring = "https://github.com/eddyem/stm32samples/tree/master/F3:F303/I2C_scan build#" BUILD_NUMBER " @ " BUILD_DATE "\n" "i0..3 - setup I2C with speed 10k, 100k, 400k, 1M or 2M (experimental!)\n" "B - switch to big-endian format for 16-bit registers\n" + "G - get busy state\n" "Ia addr - set I2C address\n" "Ig - dump content of I2Cbuf\n" "Iw bytes - send bytes (hex/dec/oct/bin) to I2C\n" @@ -59,7 +61,6 @@ TRUE_INLINE const char *setupI2C(char *buf){ return OK; } -static uint8_t I2Caddress = 0; TRUE_INLINE const char *saI2C(const char *buf){ uint32_t addr; U("saI2C: '"); U(buf); U("'\n"); @@ -98,24 +99,24 @@ static void rdI2C(const char *buf, int is16, int dmaflag){ if(noreg){ // don't write register if(dmaflag){ U("Try to read using DMA .. "); - if(!read_i2c_dma(I2Caddress, N)) U(erd); + if(!i2c_read_dma(I2Caddress, N)) U(erd); else U(OK); return; }else{ USND("Simple read:"); - if(!(b8 = read_i2c(I2Caddress, N))){ + if(!(b8 = i2c_read(I2Caddress, N))){ U(erd); return; } } }else{ if(is16){ - if(!(b16 = read_i2c_reg16(I2Caddress, reg, N, dmaflag))){ + if(!(b16 = i2c_read_reg16(I2Caddress, reg, N, dmaflag))){ U(erd); return; } }else{ - if(!(b8 = read_i2c_reg(I2Caddress, reg, N, dmaflag))){ + if(!(b8 = i2c_read_reg(I2Caddress, reg, N, dmaflag))){ U(erd); return; } @@ -142,8 +143,8 @@ TRUE_INLINE uint16_t readNnumbers(const char *buf){ static const char *wrI2C(const char *buf, int isdma){ uint16_t N = readNnumbers(buf); if(N == 0) return "Enter at least one number\n"; - int result = isdma ? write_i2c_dma(I2Caddress, locBuffer, N) : - write_i2c(I2Caddress, locBuffer, N); + int result = isdma ? i2c_write_dma(I2Caddress, locBuffer, N) : + i2c_write(I2Caddress, locBuffer, N); if(!result) return "Error writing I2C\n"; return OK; } @@ -185,12 +186,15 @@ const char *parse_cmd(char *buf){ switch(*buf){ case 'i': return setupI2C(NULL); // current settings case 'B': - endianness(1); - return OK; + i2c_endianness(1); + return OK; + break; + case 'G': + U("I2Cbusy="); USB_putbyte('0' + i2c_busy()); newline(); break; case 'L': - endianness(0); - return OK; + i2c_endianness(0); + return OK; break; case 'T': U("T="); diff --git a/F3:F303/I2C_scan/ringbuffer.c b/F3:F303/I2C_scan/ringbuffer.c index b0ffe8e..0f4ffc2 100644 --- a/F3:F303/I2C_scan/ringbuffer.c +++ b/F3:F303/I2C_scan/ringbuffer.c @@ -15,6 +15,8 @@ * along with this program. If not, see . */ +#include + #include "ringbuffer.h" static int datalen(ringbuffer *b){ @@ -58,10 +60,11 @@ int RB_hasbyte(ringbuffer *b, uint8_t byte){ return ret; } +/* // poor memcpy static void mcpy(uint8_t *targ, const uint8_t *src, int l){ while(l--) *targ++ = *src++; -} +}*/ // increment head or tail TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){ @@ -76,9 +79,9 @@ static int read(ringbuffer *b, uint8_t *s, int len){ int _1st = b->length - b->head; if(_1st > l) _1st = l; if(_1st > len) _1st = len; - mcpy(s, b->data + b->head, _1st); + memcpy(s, b->data + b->head, _1st); if(_1st < len && l > _1st){ - mcpy(s+_1st, b->data, l - _1st); + memcpy(s+_1st, b->data, l - _1st); incr(b, &b->head, l); return l; } @@ -132,9 +135,9 @@ static int write(ringbuffer *b, const uint8_t *str, int l){ if(l > r || !l) return 0; int _1st = b->length - b->tail; if(_1st > l) _1st = l; - mcpy(b->data + b->tail, str, _1st); + memcpy(b->data + b->tail, str, _1st); if(_1st < l){ // add another piece from start - mcpy(b->data, str+_1st, l-_1st); + memcpy(b->data, str+_1st, l-_1st); } incr(b, &b->tail, l); return l; diff --git a/F3:F303/I2C_scan/version.inc b/F3:F303/I2C_scan/version.inc index f4704de..390f7b2 100644 --- a/F3:F303/I2C_scan/version.inc +++ b/F3:F303/I2C_scan/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "136" -#define BUILD_DATE "2025-09-18" +#define BUILD_NUMBER "152" +#define BUILD_DATE "2025-09-19"