Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Troppo corto.STM 32 DMA e I2C Slave.

11 views
Skip to first unread message

blisca

unread,
Dec 10, 2021, 8:03:42 AM12/10/21
to

Sottotitolo...non so usare le funzioni giuste già a disposizione

Riassumendo il problema e' il seguente:Il mio uC è I2CSlave
Tutto OK se il master dà lo STOP dopo aver mandato il numero esatto dei dati previsti dal DMA
Invece ,se il master manda meno dati e dà lo STOP succede qualcosa di non gestito.
Quest'ultimo caso lo intercetto in I2C1_EV_IRQHandler testando il flag di STOP:
se è attivo guardo il numero di bytes ancora da trasferire e se li trovo >0 ,perchè appunto il pacchetto era troppo corto faccio qualche azione specifica.
Altrimenti a quel punto,la solita funzione HAL_I2C_EV_IRQHandler(&hi2c1); che dovrebbe occuparsi di ripulire flags ecc mi manda in

Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler,

Riesco a uscirne in questo modo poco ortodosso,ma sicuramente ce ne sarà uno già contemplato,che non so sove andare a prendere.Addirittura mi tocca usare indirizzi assoluti,cosa non molto portabile..

void I2C1_EV_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_EV_IRQn 0 */
volatile uint16_t dummy_buf;
volatile uint32_t* dmastream_NDTR_pt=0x4002608C;//abs. address..non trovo defines x DMA1->S5NDTRcr
volatile uint32_t* dmastream_CR_pt =0x40026088;//abs. address..non trovo defines x DMA1->S5NDTR
global_rx_buf[0]= I2C1->DR;//copio in buffer che mi serve solo x debug

if(I2C1->SR1 & I2C_SR1_STOPF_Msk)//se il pacchetto è finito
{
if(*dmastream_NDTR_pt)//se è arrivato lo stop mentre ho ancora bit da trasferire in DMA
{
*dmastream_CR_pt &=~0x1;//
I2C1->CR2 &=~I2C_CR2_DMAEN_Msk;//disabilito il DMA per l'I2C

dummy_buf=*dmastream_NDTR_pt;//leggo x mia info quanti dati mancano xcompletare DMA

//*dmastream_CR_pt &=~0x1;//l'ho già fatto,solo x ricordare che va azzerato EN
*dmastream_NDTR_pt=MY_PACKET_FIXED_LEN;
*dmastream_CR_pt |= 0x1;

global_mark_too_short_stream=1;//indico che allo STOP il pacchetto era troppo corto
}
}
/* USER CODE END I2C1_EV_IRQn 0 */
HAL_I2C_EV_IRQHandler(&hi2c1);

I2C1->CR1 &=~I2C_CR1_STOP_Msk;//Mi aspettavo fosse pulito dala riga precedente,
//lo pulisco io nei casi in cui è già =0 poco male

}


Funziona,e sembra che non ci siano problemi,
come pure una bici col manubrio attaccato con lo scotch finchè tiene
Quale sarebbe quindi un modo più corretto(usando librerie HAL o LL) per fare convivere:
trasferimento di dati ricevuti da I2CSlave a buffer in DMA quando sono in giusta quantità,
marcare che non sono arrivati abbastanza dati e preparare per il prossimo pacchetto,
Quelli trasferiti nel buffer verranno ignorati
?
Grazie
0 new messages