blisca
unread,Dec 10, 2021, 8:03:42 AM12/10/21You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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