mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
OK, I2C read by DMA works
This commit is contained in:
parent
934f4fbddd
commit
080be6a1ec
@ -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
|
// 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){
|
static uint8_t waitISRbit(uint32_t bit, uint8_t isset){
|
||||||
uint32_t waitwhile = (isset) ? 0 : bit; // wait until !=
|
uint32_t waitwhile = (isset) ? 0 : bit; // wait until !=
|
||||||
const char *errmsg = NULL;
|
//const char *errmsg = NULL;
|
||||||
cntr = Tms;
|
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){
|
while((I2C1->ISR & bit) == waitwhile){
|
||||||
IWDG->KR = IWDG_REFRESH;
|
IWDG->KR = IWDG_REFRESH;
|
||||||
if(I2C1->ISR & I2C_ISR_NACKF){
|
if(I2C1->ISR & I2C_ISR_NACKF){
|
||||||
errmsg = "NAK";
|
//errmsg = "NAK";
|
||||||
goto goterr;
|
goto goterr;
|
||||||
}
|
}
|
||||||
if(Tms - cntr > I2C_TIMEOUT){
|
if(Tms - cntr > I2C_TIMEOUT){
|
||||||
errmsg = "timeout";
|
//errmsg = "timeout";
|
||||||
goto goterr;
|
goto goterr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
goterr:
|
goterr:
|
||||||
U("wait ISR bit: "); USND(errmsg);
|
/*U("wait ISR bit: "); USND(errmsg);
|
||||||
U("I2c->ISR = "); USND(uhex2str(I2C1->ISR));
|
U("I2c->ISR = "); USND(uhex2str(I2C1->ISR));*/
|
||||||
I2C1->ICR = 0xff;
|
I2C1->ICR = 0xff;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start writing
|
// 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;
|
if(!waitISRbit(I2C_ISR_BUSY, 0)) return 0;
|
||||||
I2C1->CR2 = nbytes << 16 | addr;
|
uint32_t cr2 = nbytes << 16 | addr | I2C_CR2_START;
|
||||||
if(stop){
|
if(stop) cr2 |= I2C_CR2_AUTOEND;
|
||||||
I2C1->CR2 |= I2C_CR2_AUTOEND; // autoend
|
|
||||||
}else{
|
|
||||||
//I2C1->CR2 &= ~I2C_CR2_AUTOEND;
|
|
||||||
//I2C1->CR2 |= I2C_CR2_RELOAD;
|
|
||||||
}
|
|
||||||
// now start transfer
|
// now start transfer
|
||||||
I2C1->CR2 |= I2C_CR2_START;
|
I2C1->CR2 = cr2;
|
||||||
return 1;
|
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
|
* @param stop - to set STOP
|
||||||
* @return 0 if error
|
* @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;
|
if(!i2c_startw(addr, nbytes, stop)) return 0;
|
||||||
for(int i = 0; i < nbytes; ++i){
|
for(int i = 0; i < nbytes; ++i){
|
||||||
cntr = Tms;
|
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;
|
IWDG->KR = IWDG_REFRESH;
|
||||||
if(I2C1->ISR & I2C_ISR_NACKF){
|
if(I2C1->ISR & I2C_ISR_NACKF){
|
||||||
I2C1->ICR |= I2C_ICR_NACKCF;
|
I2C1->ICR |= I2C_ICR_NACKCF;
|
||||||
USND("write_i2cs: NAK");
|
//USND("i2c_writes: NAK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(Tms - cntr > I2C_TIMEOUT){
|
if(Tms - cntr > I2C_TIMEOUT){
|
||||||
USND("write_i2cs: Timeout");
|
//USND("i2c_writes: Timeout");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
I2C1->TXDR = data[i]; // send data
|
I2C1->TXDR = data[i]; // send data
|
||||||
U("write_i2cs: "); USND(uhex2str(data[i]));
|
//U("i2c_writes: "); USND(uhex2str(data[i]));
|
||||||
}
|
}
|
||||||
cntr = Tms;
|
cntr = Tms;
|
||||||
if(stop){
|
if(stop){
|
||||||
@ -209,19 +204,13 @@ static uint8_t write_i2cs(uint8_t addr, uint8_t *data, uint16_t nbytes, uint8_t
|
|||||||
return 1;
|
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;
|
if(isI2Cbusy()) return 0;
|
||||||
return write_i2cs(addr, data, nbytes, 1);
|
return i2c_writes(addr, data, nbytes, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
uint8_t i2c_write_dma(uint8_t addr, uint8_t *data, uint8_t nbytes){
|
||||||
uint8_t write_i2c16(uint8_t addr, uint8_t *data, uint8_t nbytes){
|
if(!data || nbytes < 1) return 0;
|
||||||
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;
|
|
||||||
if(isI2Cbusy()) return 0;
|
if(isI2Cbusy()) return 0;
|
||||||
memcpy(I2Cbuf, data, nbytes);
|
memcpy(I2Cbuf, data, nbytes);
|
||||||
i2cDMAsetup(1, nbytes);
|
i2cDMAsetup(1, nbytes);
|
||||||
@ -232,8 +221,8 @@ uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint16_t nbytes){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t write_i2c_dma16(uint8_t addr, uint16_t *data, uint16_t nwords){
|
uint8_t i2c_write_dma16(uint8_t addr, uint16_t *data, uint8_t nwords){
|
||||||
if(!data || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0;
|
if(!data || nwords < 1 || nwords > 127) return 0;
|
||||||
if(isI2Cbusy()) return 0;
|
if(isI2Cbusy()) return 0;
|
||||||
uint16_t nbytes = nwords << 1;
|
uint16_t nbytes = nwords << 1;
|
||||||
if(bigendian){
|
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
|
// start reading of `nbytes` from `addr`; if `start`==`, set START
|
||||||
static uint8_t i2c_startr(uint8_t addr, uint16_t nbytes, uint8_t start){
|
static uint8_t i2c_startr(uint8_t addr, uint16_t nbytes, uint8_t start){
|
||||||
uint32_t cr2 = addr | I2C_CR2_RD_WRN;
|
uint32_t cr2 = addr | I2C_CR2_RD_WRN;
|
||||||
if(nbytes > 255){
|
if(nbytes > 255) cr2 |= I2C_CR2_RELOAD | (0xff0000);
|
||||||
nbytes = 255; cr2 |= I2C_CR2_RELOAD;
|
else cr2 |= I2C_CR2_AUTOEND | (nbytes << 16);
|
||||||
}else cr2 |= I2C_CR2_AUTOEND;
|
|
||||||
cr2 |= (nbytes << 16);
|
|
||||||
I2C1->CR2 = (start) ? cr2 | I2C_CR2_START : cr2;
|
I2C1->CR2 = (start) ? cr2 | I2C_CR2_START : cr2;
|
||||||
return 1;
|
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
|
* `data` should be an array with at least `nbytes` length
|
||||||
* @return 1 if all OK, 0 if NACK or no device found
|
* @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){
|
static uint8_t *i2c_readb(uint8_t addr, uint16_t nbytes){
|
||||||
if(busychk && !waitISRbit(I2C_ISR_BUSY, 0)) return NULL;
|
|
||||||
uint8_t start = 1;
|
uint8_t start = 1;
|
||||||
uint8_t *bptr = I2Cbuf;
|
uint8_t *bptr = I2Cbuf;
|
||||||
while(nbytes){
|
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(!i2c_startr(addr, nbytes, start)) return NULL;
|
||||||
if(nbytes < 256){
|
if(nbytes < 256){
|
||||||
for(int i = 0; i < nbytes; ++i){
|
for(int i = 0; i < nbytes; ++i){
|
||||||
if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout;
|
if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout;
|
||||||
*bptr++ = I2C1->RXDR;
|
*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));
|
U("OOOps! We have another byte: "); USND(uhex2str(I2C1->RXDR));
|
||||||
}
|
}*/
|
||||||
break;
|
break;
|
||||||
}else while(!(I2C1->ISR & I2C_ISR_TCR)){ // until first part read
|
}else while(!(I2C1->ISR & I2C_ISR_TCR)){ // until first part read
|
||||||
if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout;
|
if(!waitISRbit(I2C_ISR_RXNE, 1)) goto tmout;
|
||||||
*bptr++ = I2C1->RXDR;
|
*bptr++ = I2C1->RXDR;
|
||||||
}
|
}
|
||||||
USND("next");
|
//USND("next");
|
||||||
nbytes -= 255;
|
nbytes -= 255;
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
return I2Cbuf;
|
return I2Cbuf;
|
||||||
tmout:
|
tmout:
|
||||||
USND("read I2C: Timeout");
|
//USND("read I2C: Timeout");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *read_i2c(uint8_t addr, uint16_t nbytes){
|
uint8_t *i2c_read(uint8_t addr, uint16_t nbytes){
|
||||||
if(isI2Cbusy()) return 0;
|
if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return 0;
|
||||||
return read_i2cb(addr, nbytes, 1);
|
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(nbytes < 1 || nbytes > I2C_BUFSIZE) return 0;
|
||||||
if(isI2Cbusy()) return 0;
|
|
||||||
i2cDMAsetup(0, nbytes);
|
i2cDMAsetup(0, nbytes);
|
||||||
goterr = 0;
|
goterr = 0;
|
||||||
i2c_got_DMA = 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
|
(void) I2C1->RXDR; // avoid wrong first byte
|
||||||
DMA1_Channel7->CCR = DMARXCCR | DMA_CCR_EN; // init DMA before START sequence
|
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;
|
I2Cbusy = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t read_i2c_dma(uint8_t addr, uint16_t nbytes){
|
uint8_t i2c_read_dma(uint8_t addr, uint16_t nbytes){
|
||||||
uint8_t got = dmard(addr, nbytes, 1);
|
if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return 0;
|
||||||
|
uint8_t got = dmard(addr, nbytes);
|
||||||
if(got) dma16bit = 0;
|
if(got) dma16bit = 0;
|
||||||
return got;
|
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
|
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;
|
if(got) dma16bit = 1;
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
@ -334,30 +321,29 @@ static void swapbytes(uint16_t *data, uint16_t datalen){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read register reg
|
// read register reg
|
||||||
uint8_t *read_i2c_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma){
|
uint8_t *i2c_read_reg(uint8_t addr, uint8_t reg, uint16_t nbytes, uint8_t isdma){
|
||||||
if(isI2Cbusy()) return NULL;
|
if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0)) return NULL;
|
||||||
if(!write_i2cs(addr, ®, 1, 0)) return NULL;
|
if(!i2c_writes(addr, ®, 1, 0)) return NULL;
|
||||||
if(isdma){
|
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 NULL;
|
||||||
}
|
}
|
||||||
return read_i2cb(addr, nbytes, 0);
|
return i2c_readb(addr, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// read 16bit register reg
|
// read 16bit register reg
|
||||||
uint16_t *read_i2c_reg16(uint8_t addr, uint16_t reg16, uint16_t nwords, uint8_t isdma){
|
uint16_t *i2c_read_reg16(uint8_t addr, uint16_t reg16, uint16_t nwords, uint8_t isdma){
|
||||||
if(isI2Cbusy() || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0;
|
if(isI2Cbusy() || !waitISRbit(I2C_ISR_BUSY, 0) || nwords < 1 || nwords > I2C_BUFSIZE/2) return 0;
|
||||||
if(bigendian) reg16 = __REV16(reg16);
|
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(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;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(!read_i2cb(addr, nwords*2, 0)) return NULL;
|
if(!i2c_readb(addr, nwords<<1)) return NULL;
|
||||||
uint16_t *buf = (uint16_t*)I2Cbuf;
|
if(bigendian) swapbytes((uint16_t*)I2Cbuf, nwords);
|
||||||
if(bigendian) swapbytes(buf, nwords);
|
return (uint16_t*)I2Cbuf;
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2c_init_scan_mode(){
|
void i2c_init_scan_mode(){
|
||||||
@ -376,7 +362,7 @@ int i2c_scan_next_addr(uint8_t *addr){
|
|||||||
i2c_scanmode = 0;
|
i2c_scanmode = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!read_i2c((i2caddr++)<<1, 1)) return 0;
|
if(!i2c_read((i2caddr++)<<1, 1)) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,31 +375,30 @@ void i2c_bufdudump(){
|
|||||||
if(i2cbuflen < 1) return;
|
if(i2cbuflen < 1) return;
|
||||||
USND("I2C buffer:");
|
USND("I2C buffer:");
|
||||||
if(dma16bit) hexdump16(USB_sendstr, (uint16_t*)I2Cbuf, i2cbuflen);
|
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)
|
// 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;
|
if(!i2c_got_DMA || i2cbuflen < 1) return NULL;
|
||||||
i2c_got_DMA = 0;
|
i2c_got_DMA = 0;
|
||||||
if(dma16bit){
|
if(dma16bit){
|
||||||
i2cbuflen >>= 1; // for hexdump16 - now buffer have uint16_t!
|
i2cbuflen >>= 1; // for hexdump16 - now buffer have uint16_t!
|
||||||
uint16_t *b = (uint16_t*)I2Cbuf;
|
if(bigendian) swapbytes((uint16_t*)I2Cbuf, i2cbuflen);
|
||||||
if(bigendian){
|
|
||||||
for(int i = 0; i < i2cbuflen; ++i) b[i] = __REV(b[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(len) *len = i2cbuflen;
|
if(len) *len = i2cbuflen;
|
||||||
return I2Cbuf;
|
return I2Cbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i2cdma_haderr(){
|
int i2c_dma_haderr(){
|
||||||
int r = goterr;
|
int r = goterr;
|
||||||
goterr = 0;
|
goterr = 0;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void endianness(uint8_t isbig){
|
int i2c_busy(){ return I2Cbusy;}
|
||||||
|
|
||||||
|
void i2c_endianness(uint8_t isbig){
|
||||||
bigendian = isbig;
|
bigendian = isbig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,20 +38,22 @@ extern volatile uint8_t i2c_scanmode;
|
|||||||
#define I2C_TIMEOUT (5)
|
#define I2C_TIMEOUT (5)
|
||||||
|
|
||||||
void i2c_setup(i2c_speed_t speed);
|
void i2c_setup(i2c_speed_t speed);
|
||||||
uint8_t *read_i2c(uint8_t addr, uint16_t nbytes);
|
int i2c_busy();
|
||||||
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);
|
|
||||||
|
|
||||||
uint8_t write_i2c_dma(uint8_t addr, uint8_t *data, uint16_t nbytes);
|
uint8_t *i2c_read(uint8_t addr, uint16_t nbytes);
|
||||||
uint8_t write_i2c_dma16(uint8_t addr, uint16_t *data, uint16_t nwords);
|
uint8_t i2c_read_dma(uint8_t addr, uint16_t nbytes);
|
||||||
uint8_t read_i2c_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();
|
void i2c_bufdudump();
|
||||||
int i2cdma_haderr();
|
int i2c_dma_haderr();
|
||||||
uint8_t *i2cdma_getbuf(uint16_t *len);
|
uint8_t *i2c_dma_getbuf(uint16_t *len);
|
||||||
uint8_t read_i2c_dma16(uint8_t addr, uint16_t nwords);
|
void i2c_endianness(uint8_t isbig);
|
||||||
void endianness(uint8_t isbig);
|
|
||||||
int i2c_getwords(uint16_t *buf, int bufsz);
|
int i2c_getwords(uint16_t *buf, int bufsz);
|
||||||
|
|
||||||
void i2c_init_scan_mode();
|
void i2c_init_scan_mode();
|
||||||
|
|||||||
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 17.0.1, 2025-09-18T23:52:40. -->
|
<!-- Written by QtCreator 17.0.1, 2025-09-19T20:47:53. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@ -53,7 +53,7 @@ int main(void){
|
|||||||
if(l < 0) USND("ERROR: USB buffer overflow or string was too long");
|
if(l < 0) USND("ERROR: USB buffer overflow or string was too long");
|
||||||
else if(l){
|
else if(l){
|
||||||
const char *ans = parse_cmd(inbuff);
|
const char *ans = parse_cmd(inbuff);
|
||||||
if(ans) USND(ans);
|
if(ans) U(ans);
|
||||||
}
|
}
|
||||||
if(i2c_scanmode){
|
if(i2c_scanmode){
|
||||||
uint8_t addr;
|
uint8_t addr;
|
||||||
@ -65,7 +65,7 @@ int main(void){
|
|||||||
U(") - found device\n");
|
U(") - found device\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i2cdma_haderr()) USND("Error reading I2C using DMA");
|
if(i2c_dma_haderr()) USND("Error reading I2C using DMA");
|
||||||
if(i2cdma_getbuf(NULL)) i2c_bufdudump();
|
if(i2c_dma_getbuf(NULL)) i2c_bufdudump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#define LOCBUFFSZ (32)
|
#define LOCBUFFSZ (32)
|
||||||
// local buffer for I2C data to send
|
// local buffer for I2C data to send
|
||||||
static uint8_t locBuffer[LOCBUFFSZ];
|
static uint8_t locBuffer[LOCBUFFSZ];
|
||||||
|
static uint8_t I2Caddress = 0x33 << 1;
|
||||||
extern volatile uint32_t Tms;
|
extern volatile uint32_t Tms;
|
||||||
|
|
||||||
static const char *OK = "OK\n";
|
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"
|
"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"
|
"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"
|
"B - switch to big-endian format for 16-bit registers\n"
|
||||||
|
"G - get busy state\n"
|
||||||
"Ia addr - set I2C address\n"
|
"Ia addr - set I2C address\n"
|
||||||
"Ig - dump content of I2Cbuf\n"
|
"Ig - dump content of I2Cbuf\n"
|
||||||
"Iw bytes - send bytes (hex/dec/oct/bin) to I2C\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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t I2Caddress = 0;
|
|
||||||
TRUE_INLINE const char *saI2C(const char *buf){
|
TRUE_INLINE const char *saI2C(const char *buf){
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
U("saI2C: '"); U(buf); U("'\n");
|
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(noreg){ // don't write register
|
||||||
if(dmaflag){
|
if(dmaflag){
|
||||||
U("Try to read using DMA .. ");
|
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);
|
else U(OK);
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
USND("Simple read:");
|
USND("Simple read:");
|
||||||
if(!(b8 = read_i2c(I2Caddress, N))){
|
if(!(b8 = i2c_read(I2Caddress, N))){
|
||||||
U(erd);
|
U(erd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(is16){
|
if(is16){
|
||||||
if(!(b16 = read_i2c_reg16(I2Caddress, reg, N, dmaflag))){
|
if(!(b16 = i2c_read_reg16(I2Caddress, reg, N, dmaflag))){
|
||||||
U(erd);
|
U(erd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(!(b8 = read_i2c_reg(I2Caddress, reg, N, dmaflag))){
|
if(!(b8 = i2c_read_reg(I2Caddress, reg, N, dmaflag))){
|
||||||
U(erd);
|
U(erd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -142,8 +143,8 @@ TRUE_INLINE uint16_t readNnumbers(const char *buf){
|
|||||||
static const char *wrI2C(const char *buf, int isdma){
|
static const char *wrI2C(const char *buf, int isdma){
|
||||||
uint16_t N = readNnumbers(buf);
|
uint16_t N = readNnumbers(buf);
|
||||||
if(N == 0) return "Enter at least one number\n";
|
if(N == 0) return "Enter at least one number\n";
|
||||||
int result = isdma ? write_i2c_dma(I2Caddress, locBuffer, N) :
|
int result = isdma ? i2c_write_dma(I2Caddress, locBuffer, N) :
|
||||||
write_i2c(I2Caddress, locBuffer, N);
|
i2c_write(I2Caddress, locBuffer, N);
|
||||||
if(!result) return "Error writing I2C\n";
|
if(!result) return "Error writing I2C\n";
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -185,11 +186,14 @@ const char *parse_cmd(char *buf){
|
|||||||
switch(*buf){
|
switch(*buf){
|
||||||
case 'i': return setupI2C(NULL); // current settings
|
case 'i': return setupI2C(NULL); // current settings
|
||||||
case 'B':
|
case 'B':
|
||||||
endianness(1);
|
i2c_endianness(1);
|
||||||
return OK;
|
return OK;
|
||||||
break;
|
break;
|
||||||
|
case 'G':
|
||||||
|
U("I2Cbusy="); USB_putbyte('0' + i2c_busy()); newline();
|
||||||
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
endianness(0);
|
i2c_endianness(0);
|
||||||
return OK;
|
return OK;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
static int datalen(ringbuffer *b){
|
static int datalen(ringbuffer *b){
|
||||||
@ -58,10 +60,11 @@ int RB_hasbyte(ringbuffer *b, uint8_t byte){
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// poor memcpy
|
// poor memcpy
|
||||||
static void mcpy(uint8_t *targ, const uint8_t *src, int l){
|
static void mcpy(uint8_t *targ, const uint8_t *src, int l){
|
||||||
while(l--) *targ++ = *src++;
|
while(l--) *targ++ = *src++;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// increment head or tail
|
// increment head or tail
|
||||||
TRUE_INLINE void incr(ringbuffer *b, volatile int *what, int n){
|
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;
|
int _1st = b->length - b->head;
|
||||||
if(_1st > l) _1st = l;
|
if(_1st > l) _1st = l;
|
||||||
if(_1st > len) _1st = len;
|
if(_1st > len) _1st = len;
|
||||||
mcpy(s, b->data + b->head, _1st);
|
memcpy(s, b->data + b->head, _1st);
|
||||||
if(_1st < len && l > _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);
|
incr(b, &b->head, l);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@ -132,9 +135,9 @@ static int write(ringbuffer *b, const uint8_t *str, int l){
|
|||||||
if(l > r || !l) return 0;
|
if(l > r || !l) return 0;
|
||||||
int _1st = b->length - b->tail;
|
int _1st = b->length - b->tail;
|
||||||
if(_1st > l) _1st = l;
|
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
|
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);
|
incr(b, &b->tail, l);
|
||||||
return l;
|
return l;
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#define BUILD_NUMBER "136"
|
#define BUILD_NUMBER "152"
|
||||||
#define BUILD_DATE "2025-09-18"
|
#define BUILD_DATE "2025-09-19"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user