/***************************************************************************//** * @brief adc_capture *******************************************************************************/ int32_t adc_capture(uint32_t size, uint32_t start_address) { uint32_t reg_val; uint32_t transfer_id; uint32_t length; length = (size * 4); adc_dmac_write(ADC_DMAC_REG_CTRL, 0x0); adc_dmac_write(ADC_DMAC_REG_CTRL, ADC_DMAC_CTRL_ENABLE); adc_dmac_write(ADC_DMAC_REG_IRQ_MASK, 0x0); adc_dmac_read(ADC_DMAC_REG_TRANSFER_ID, &transfer_id); adc_dmac_read(ADC_DMAC_REG_IRQ_PENDING, ®_val); adc_dmac_write(ADC_DMAC_REG_IRQ_PENDING, reg_val); adc_dmac_write(ADC_DMAC_REG_DEST_ADDRESS, start_address); adc_dmac_write(ADC_DMAC_REG_DEST_STRIDE, 0x0); adc_dmac_write(ADC_DMAC_REG_X_LENGTH, length - 1); adc_dmac_write(ADC_DMAC_REG_Y_LENGTH, 0x0); adc_dmac_write(ADC_DMAC_REG_START_TRANSFER, 0x1); /* Wait until the new transfer is queued. */ do { adc_dmac_read(ADC_DMAC_REG_START_TRANSFER, ®_val); } while(reg_val == 1); /* Wait until the current transfer is completed. */ do { adc_dmac_read(ADC_DMAC_REG_IRQ_PENDING, ®_val); } while(reg_val != (ADC_DMAC_IRQ_SOT | ADC_DMAC_IRQ_EOT)); adc_dmac_write(ADC_DMAC_REG_IRQ_PENDING, reg_val); /* Wait until the transfer with the ID transfer_id is completed. */ do { adc_dmac_read(ADC_DMAC_REG_TRANSFER_DONE, ®_val); } while((reg_val & (1 << transfer_id)) != (1 << transfer_id)); return 0; }
/***************************************************************************//** * @brief adc_dmac_isr *******************************************************************************/ void adc_dmac_isr(void *instance) { uint32_t reg_val; adc_dmac_read(core, ADC_DMAC_REG_IRQ_PENDING, ®_val); adc_dmac_write(core, ADC_DMAC_REG_IRQ_PENDING, reg_val); if(reg_val & ADC_DMAC_IRQ_SOT) { adc_sot_flag = 1; adc_dmac_start_address += ADC_DMAC_TRANSFER_SIZE; adc_dmac_write(core, ADC_DMAC_REG_DEST_ADDRESS, adc_dmac_start_address); /* The current transfer was started and a new one is queued. */ adc_dmac_write(core, ADC_DMAC_REG_START_TRANSFER, 0x1); } if(reg_val & ADC_DMAC_IRQ_EOT) { adc_eot_flag = 1; } }
/***************************************************************************//** * @brief adc_capture *******************************************************************************/ int32_t adc_capture(adc_core core, uint32_t no_of_samples, uint32_t start_address) { uint32_t reg_val; uint32_t transfer_id; uint32_t length; length = (no_of_samples * core.no_of_channels * ((core.resolution + 7) / 8)); adc_dmac_write(core, ADC_DMAC_REG_CTRL, 0x0); adc_dmac_write(core, ADC_DMAC_REG_CTRL, ADC_DMAC_CTRL_ENABLE); adc_dmac_write(core, ADC_DMAC_REG_IRQ_MASK, 0x0); adc_dmac_read(core, ADC_DMAC_REG_TRANSFER_ID, &transfer_id); adc_dmac_read(core, ADC_DMAC_REG_IRQ_PENDING, ®_val); adc_dmac_write(core, ADC_DMAC_REG_IRQ_PENDING, reg_val); #ifndef ADC_DMAC_INTERRUPTS adc_dmac_write(core, ADC_DMAC_REG_DEST_ADDRESS, start_address); adc_dmac_write(core, ADC_DMAC_REG_DEST_STRIDE, 0x0); adc_dmac_write(core, ADC_DMAC_REG_X_LENGTH, length - 1); adc_dmac_write(core, ADC_DMAC_REG_Y_LENGTH, 0x0); adc_dmac_write(core, ADC_DMAC_REG_START_TRANSFER, 0x1); /* Wait until the new transfer is queued. */ do { adc_dmac_read(core, ADC_DMAC_REG_START_TRANSFER, ®_val); } while(reg_val == 1); /* Wait until the current transfer is completed. */ do { adc_dmac_read(core, ADC_DMAC_REG_IRQ_PENDING, ®_val); } while(reg_val != (ADC_DMAC_IRQ_SOT | ADC_DMAC_IRQ_EOT)); adc_dmac_write(core, ADC_DMAC_REG_IRQ_PENDING, reg_val); /* Wait until the transfer with the ID transfer_id is completed. */ do { adc_dmac_read(core, ADC_DMAC_REG_TRANSFER_DONE, ®_val); } while((reg_val & (1 << transfer_id)) != (1 << transfer_id)); #else XScuGic_Config *gic_config; XScuGic gic; int32_t status; gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID); if(gic_config == NULL) xil_printf("Error\n"); status = XScuGic_CfgInitialize(&gic, gic_config, gic_config->CpuBaseAddress); if(status) xil_printf("Error\n"); XScuGic_SetPriorityTriggerType(&gic, ADC_DMAC_INT_ID, 0x0, 0x3); status = XScuGic_Connect(&gic, ADC_DMAC_INT_ID, (Xil_ExceptionHandler)adc_dmac_isr, NULL); if(status) xil_printf("Error\n"); XScuGic_Enable(&gic, ADC_DMAC_INT_ID); Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, (void *)&gic); Xil_ExceptionEnable(); adc_dmac_start_address = start_address; adc_dmac_write(core, ADC_DMAC_REG_DEST_ADDRESS, adc_dmac_start_address); adc_dmac_write(core, ADC_DMAC_REG_DEST_STRIDE, 0x0); adc_dmac_write(core, ADC_DMAC_REG_X_LENGTH, ADC_DMAC_TRANSFER_SIZE - 1); adc_dmac_write(core, ADC_DMAC_REG_Y_LENGTH, 0x0); adc_dmac_write(core, ADC_DMAC_REG_START_TRANSFER, 0x1); while(adc_dmac_start_address < (start_address + length + ADC_DMAC_TRANSFER_SIZE)); adc_dmac_write(core, ADC_DMAC_REG_CTRL, 0x0); #endif return 0; }