I am using a fast sampling ADC toghether with I2S. The goal is sampling the CAN bus (CAN_L) once a new data frame is incoming in the queue.
To get kind of syncronization I just do the i2s_adc_enable if there is a message in CAN message incoming, like reported below:
Code: Select all
if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE){
i2s_adc_enable(I2S_NUM_0);
i2s_read(I2S_NUM_0, &buffer1, sizeof(buffer1), &bytes_read, 10);
i2s_adc_disable(I2S_NUM_0);
The question is: Is there a way to trigger the ADC with the SOF (start of frame bit) of the CAN frame on the CAN bus?
I set the ADC to obtain a sample per bit (500kpbs since the CAN network is configured with a data rate of 500kbps).
Code: Select all
// i2s init function
void i2sInit(){
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
.sample_rate = 500000, // The format of the signal using ADC_BUILT_IN
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // is fixed at 12bit, stereo, MSB
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, //ESP_INTR_FLAG_LEVEL1
.dma_buf_count = 2,
.dma_buf_len = 100,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_adc_mode(ADC_UNIT_1, ADC_INPUT);
//i2s_adc_enable(I2S_NUM_0);
i2s_adc_disable(I2S_NUM_0);
}
Code: Select all
// CAN init funcion
void canInit(){
CAN_cfg.speed=CAN_SPEED_500KBPS; //can set speed
CAN_cfg.tx_pin_id = GPIO_NUM_5; // can set TX to pin 5
CAN_cfg.rx_pin_id = GPIO_NUM_4; // can set RX to pin 4
CAN_cfg.rx_queue = xQueueCreate(1,sizeof(CAN_frame_t)); // mod queue size 1
//start CAN Module
ESP32Can.CANInit();
}