#define main drill_entry
#include "firmware/固件/drill_target/src/main.c"
#undef main
#include "firmware/固件/drill_target/src/drill_clock.c"
#include "firmware/固件/drill_target/src/drill_timing.c"
#include "firmware/固件/drill_target/src/drill_pwm_stage.c"
#include "firmware/固件/drill_target/src/drill_spi_transport.c"
#include "firmware/固件/drill_target/src/drill_timebase.c"
#include "firmware/固件/drill_target/src/drill_safe_gpio.c"
#include "firmware/固件/drill_target/src/drill_config_binding.c"
#include "firmware/固件/drill_target/src/drill_config_async.c"
#include "firmware/固件/drill_target/src/drill_current.c"
#include "firmware/固件/drill_driver/drv8316.c"
#include "firmware/固件/drill_target/src/drill_adc_capture.c"
#include "firmware/固件/drill_target/src/drill_dual_adc.c"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "host_clock_fixture.h"
host_dwt_type dwt;host_debug_type coredebug;
#include <setjmp.h>
DMA_TypeDef dma;DMA_Channel_TypeDef dma_channel;DMAMUX_Channel_TypeDef mux;DMAMUX_ChannelStatus_TypeDef mux_status;ADC_TypeDef adc1,adc2;ADC_Common_TypeDef adc_common;RCC_TypeDef rcc;GPIO_TypeDef ga,gb,gf;TIM_TypeDef timer,timer2;SPI_TypeDef spi;host_systick_type systick;unsigned host_systick_config_calls;
static jmp_buf returned;
static unsigned resets,wfi_calls;
void host_wait(void){if(++wfi_calls==1){timer2.CNT+=1000;SysTick_Handler();return;}longjmp(returned,1);}
static void pins(GPIO_TypeDef *p){p->ODR=(p->ODR|(p->BSRR&65535u))&~(p->BSRR>>16);p->IDR=p->ODR;p->BSRR=0;}
void host_dsb(void){if(adc1.ISR==ADC_ISR_ADRDY || adc1.ISR==(ADC_ISR_EOC|ADC_ISR_EOS|ADC_ISR_EOSMP))adc1.ISR=0;if(rcc.AHB2RSTR&RCC_AHB2RSTR_ADC12RST){memset(&adc1,0,sizeof adc1);memset(&adc2,0,sizeof adc2);memset(&adc_common,0,sizeof adc_common);adc1.CR=adc2.CR=ADC_CR_DEEPPWD;}if(rcc.APB1RSTR1&RCC_APB1RSTR1_TIM2RST)memset(&timer2,0,sizeof timer2);if(rcc.APB1RSTR1&RCC_APB1RSTR1_SPI2RST)memset(&spi,0,sizeof spi);pins(&ga);pins(&gb);pins(&gf);if(rcc.APB2RSTR&RCC_APB2RSTR_TIM1RST){memset(&timer,0,sizeof timer);++resets;}}
static void fixture(void){
 drill_debug_current=(cq_record){0};
 memset(&rcc,0,sizeof rcc);memset(&ga,0,sizeof ga);memset(&gb,0,sizeof gb);memset(&gf,0,sizeof gf);memset(&timer,0,sizeof timer);memset(&timer2,0,sizeof timer2);memset(&spi,0,sizeof spi);memset(&systick,0,sizeof systick);memset(&adc1,0,sizeof adc1);memset(&adc2,0,sizeof adc2);memset(&adc_common,0,sizeof adc_common);
 owned=timebase_owned=false;state=UNINITIALIZED;drill_config=(dc_runtime){0};drill_adc_state=DA_IDLE;drill_adc_error=DA_NONE;host_clock_profile();
 drill_safe_boot();assert(drill_pwm_stage_init());assert(drill_timebase_init());assert(drill_spi_init(0));ga.MODER&=~(3u<<12);ga.ODR|=1u<<6;ga.IDR|=1u<<6;gf.BSRR=2u;host_dsb();drill_config=(dc_runtime){.state=DC_READY,.step=22,.npor_required=true,.control2_readback=0x40,.gain_readback=1};spi.SR=SPI_SR_TXE;
}
static void enable(uint32_t n){
 assert(drill_adc_bench_begin(n,true));assert(drill_adc_state==DA_REGULATOR&&adc1.CR==ADC_CR_ADVREGEN&&adc2.CR==ADC_CR_DEEPPWD);
 drill_adc_poll(n+39);assert(drill_adc_state==DA_REGULATOR);drill_adc_poll(n+40);assert(drill_adc_state==DA_CALIBRATION&&(adc1.CR&ADC_CR_ADCAL));
 adc1.CR&=~ADC_CR_ADCAL;drill_adc_poll(n+50);assert(drill_adc_state==DA_CAL_GAP);drill_adc_poll(n+51);assert(!(adc1.CR&ADC_CR_ADEN));drill_adc_poll(n+52);assert(drill_adc_state==DA_ENABLE&&(adc1.CR&ADC_CR_ADEN)&&adc1.ISR==0);
 adc1.ISR=ADC_ISR_ADRDY;drill_adc_poll(n+55);assert(drill_adc_state==DA_READY);
}
static void completed(uint16_t raw,uint32_t n){adc1.DR=raw;adc1.CR&=~ADC_CR_ADSTART;adc1.ISR=ADC_ISR_ADRDY|ADC_ISR_EOC|ADC_ISR_EOS;drill_adc_poll(n);}
static void hard_off(void){assert(drill_adc_state==DA_FAILED&&drill_config.state==DC_FAILED);assert(!(rcc.AHB2ENR&RCC_AHB2ENR_ADC12EN));assert(!(gf.ODR&2u));assert(!(ga.ODR&((1u<<5)|(1u<<7)|(7u<<8)))&&!(gb.ODR&3u)&&(ga.ODR&(1u<<12)));assert(timer.CCER==0&&!(timer.CR1&TIM_CR1_CEN)&&!(timer.BDTR&TIM_BDTR_MOE));assert(!drill_adc_bench_begin(10000,true));}
int main(void){unsigned cases=0;static const uint16_t raw[6]={0,1,2047,2048,4094,4095};
 for(unsigned wrap=0;wrap<2;++wrap)for(unsigned value=0;value<6;++value){fixture();uint32_t n=wrap?UINT32_MAX-100:0;enable(n);
  for(unsigned capture=0;capture<2;++capture){uint32_t start=n+60+capture*1000;assert(drill_adc_capture_start(start));assert(drill_adc_busy());assert(!drill_adc_capture_start(start));
   da_sample out;memset(&out,0xa5,sizeof out);da_sample before=out;assert(!drill_adc_take(&out,start)&&!memcmp(&out,&before,sizeof out));
   for(unsigned ch=0;ch<4;++ch){assert(adc1.SQR1==((ch+1)<<6));completed(raw[(value+ch)%6],start+200*(ch+1));if(ch<3)assert(drill_adc_state==DA_CONVERT);}
   assert(drill_adc_state==DA_DONE&&!drill_adc_busy());assert(!drill_adc_take(NULL,start+800));assert(drill_adc_take(&out,start+800)&&out.sequence==capture+1&&!out.physical_calibration_verified);
   for(unsigned ch=0;ch<4;++ch)assert(out.raw[ch]==raw[(value+ch)%6]&&out.observed_us[ch]==start+200*(ch+1));
   before=out;assert(!drill_adc_take(&out,start+801)&&!memcmp(&out,&before,sizeof out));assert(drill_adc_state==DA_READY);
  }++cases;
 }
 /* Each bit of configuration-bearing registers, including shared ADC2 ownership. */
 for(unsigned reg=0;reg<19;++reg)for(unsigned bit=0;bit<32;++bit){fixture();enable(0);volatile uint32_t *regs[]={&adc_common.CCR,&adc2.CR,&adc1.CFGR,&adc1.CFGR2,&adc1.IER,&adc1.DIFSEL,&adc1.JSQR,&adc1.SMPR1,&adc1.SMPR2,&adc1.SQR1,&adc1.SQR2,&adc1.SQR3,&adc1.SQR4,&adc1.OFR1,&adc1.OFR2,&adc1.OFR3,&adc1.OFR4,&adc1.GCOMP,&adc1.CR};*regs[reg]^=1u<<bit;drill_adc_poll(60);hard_off();assert(drill_adc_error==DA_CONFIG);++cases;}
 for(unsigned flag=0;flag<7;++flag){fixture();enable(0);static const uint32_t badflags[]={ADC_ISR_OVR,ADC_ISR_JQOVF,ADC_ISR_AWD1,ADC_ISR_AWD2,ADC_ISR_AWD3,ADC_ISR_JEOC,ADC_ISR_JEOS};adc1.ISR|=badflags[flag];drill_adc_poll(60);hard_off();assert(drill_adc_error==DA_FLAGS);++cases;}
 for(unsigned mode=0;mode<10;++mode){fixture();enable(0);assert(drill_adc_capture_start(60));
  switch(mode){case 0:drill_adc_poll(59);break;case 1:drill_adc_poll(1061);break;case 2:adc1.CR&=~ADC_CR_ADSTART;adc1.ISR=ADC_ISR_EOS;drill_adc_poll(260);break;case 3:adc1.CR&=~ADC_CR_ADSTART;adc1.ISR=ADC_ISR_EOC;drill_adc_poll(260);break;case 4:adc1.ISR=ADC_ISR_EOC|ADC_ISR_EOS;drill_adc_poll(260);break;case 5:adc1.DR=4096;adc1.CR&=~ADC_CR_ADSTART;adc1.ISR=ADC_ISR_EOC|ADC_ISR_EOS;drill_adc_poll(260);break;case 6:ga.IDR&=~(1u<<6);drill_adc_poll(61);break;case 7:gf.IDR&=~2u;drill_adc_poll(61);break;case 8:ga.IDR&=~(1u<<12);drill_adc_poll(61);break;case 9:rcc.CFGR|=RCC_CFGR_HPRE_3;drill_adc_poll(61);break;}hard_off();++cases;
 }
 /* Stalled startup/calibration, stale full record, disallowed ownership. */
 for(unsigned mode=0;mode<4;++mode){fixture();if(mode==0){assert(drill_adc_bench_begin(0,true));drill_adc_poll(5001);}if(mode==1){assert(drill_adc_bench_begin(0,true));drill_adc_poll(40);drill_adc_poll(5001);}if(mode==2){enable(0);drill_adc_capture_start(60);for(unsigned ch=0;ch<4;++ch)completed(2048,260+200*ch);da_sample out;memset(&out,0xa5,sizeof out);da_sample before=out;assert(!drill_adc_take(&out,1861)&&!memcmp(&out,&before,sizeof out));}if(mode==3){enable(0);drill_config.state=DC_FAILED;drill_adc_poll(60);}hard_off();++cases;}
 for(unsigned mode=0;mode<4;++mode){fixture();if(mode==0)assert(!drill_adc_bench_begin(0,false));if(mode==1){rcc.AHB2ENR|=RCC_AHB2ENR_ADC12EN;assert(!drill_adc_bench_begin(0,true));}if(mode==2){rcc.AHB2RSTR|=RCC_AHB2RSTR_ADC12RST;assert(!drill_adc_bench_begin(0,true));}if(mode==3){drill_config.state=DC_IDLE;assert(!drill_adc_bench_begin(0,true));}assert(drill_adc_state==DA_IDLE&&(gf.ODR&2u)!=0u);++cases;}
 printf("%u REAL ADC CAPTURE SOURCE MODEL SCENARIOS PASS\n",cases);
}
