#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_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;
static unsigned stream_race;
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(rcc.AHB1RSTR&RCC_AHB1RSTR_DMA1RST){memset(&dma,0,sizeof dma);memset(&dma_channel,0,sizeof dma_channel);}
 if(rcc.AHB1RSTR&RCC_AHB1RSTR_DMAMUX1RST){memset(&mux,0,sizeof mux);memset(&mux_status,0,sizeof mux_status);}
 if(dma.IFCR){if(dma.IFCR&DMA_IFCR_CGIF1)dma.ISR&=~15u;else dma.ISR&=~dma.IFCR;dma.IFCR=0;}
 if(mux_status.CFR){mux_status.CSR&=~mux_status.CFR;mux_status.CFR=0;}
 if(stream_race){unsigned kind=stream_race;stream_race=0;if(kind==1)--dma_channel.CNDTR;if(kind==2)timer2.CNT+=31;if(kind==3)dma.ISR|=DMA_ISR_TEIF1;if(kind==4)adc2.ISR|=ADC_ISR_OVR;if(kind==5)timer2.CNT+=2;}
if(timer.EGR&TIM_EGR_UG){timer.CNT=0;timer.EGR=0;}if(adc2.ISR==ADC_ISR_ADRDY || adc2.ISR==(ADC_ISR_EOC|ADC_ISR_EOS|ADC_ISR_EOSMP))adc2.ISR=0;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){
 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);
 memset(&dma,0,sizeof dma);memset(&dma_channel,0,sizeof dma_channel);memset(&mux,0,sizeof mux);memset(&mux_status,0,sizeof mux_status);ds_owned=ds_pending=false;stream_race=0;
 owned=sampling_owned=timebase_owned=false;state=UNINITIALIZED;drill_config=(dc_runtime){0};drill_adc_state=DA_IDLE;drill_dual_state=DU_IDLE;drill_dual_error=0;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 poll(uint32_t now){timer2.CNT=now;drill_config_service(now);drill_dual_poll(now);}
static void ready(uint32_t n){
 drill_config.last=n;
 assert(drill_dual_bench_begin(n,true));assert(drill_dual_state==DU_REG&&adc1.CR==ADC_CR_ADVREGEN&&adc2.CR==ADC_CR_ADVREGEN);
 assert(adc_common.CCR==0x30006&&adc1.CFGR==0x540&&adc2.CFGR==0&&adc1.SQR1==0x40&&adc2.SQR1==0x80&&adc1.SMPR1==0x10&&adc2.SMPR1==0x80);
 assert(timer.CR2==0x700000&&timer.CCR4==200&&timer.CCER==0&&!(timer.BDTR&TIM_BDTR_MOE)&&!(timer.CR1&TIM_CR1_CEN));
 poll(n+39);assert(drill_dual_state==DU_REG);poll(n+40);assert(drill_dual_state==DU_CAL&&(adc1.CR&ADC_CR_ADCAL)&&(adc2.CR&ADC_CR_ADCAL));
 adc1.CR&=~ADC_CR_ADCAL;poll(n+49);assert(drill_dual_state==DU_CAL);adc2.CR&=~ADC_CR_ADCAL;poll(n+50);assert(drill_dual_state==DU_GAP);poll(n+51);assert(!(adc1.CR&ADC_CR_ADEN));poll(n+52);assert(drill_dual_state==DU_ENABLE);
 adc1.ISR=ADC_ISR_ADRDY;poll(n+53);assert(drill_dual_state==DU_ENABLE);adc2.ISR=ADC_ISR_ADRDY;poll(n+55);assert(drill_dual_state==DU_READY&&drill_spi_available());
}
static void off(void){assert(drill_dual_state==DU_FAILED&&drill_config.state==DC_FAILED&&!sampling_owned);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_dual_bench_begin(10000,true));}
static void streaming(uint32_t n){fixture();ready(n);timer2.CNT=n+60;assert(drill_dual_stream_start(n+60));assert(drill_dual_state==DU_STREAM&&dma_channel.CNDTR==2&&dma_channel.CCR==0x2aa1&&mux.CCR==5&&adc_common.CCR==0x3a006&&timer.CCER==0&&!(timer.BDTR&TIM_BDTR_MOE));}
static void transfer(uint32_t raw){unsigned index=(2u-dma_channel.CNDTR)&1u;ds_ring[index]=raw;if(dma_channel.CNDTR<=1){dma_channel.CNDTR=2;dma.ISR|=DMA_ISR_TCIF1;}else{--dma_channel.CNDTR;if(dma_channel.CNDTR==1)dma.ISR|=DMA_ISR_HTIF1;}}
static void stream_off(void){off();assert(!ds_owned&&!ds_pending&&!(rcc.AHB1ENR&(RCC_AHB1ENR_DMA1EN|RCC_AHB1ENR_DMAMUX1EN)));assert(!(dma_channel.CCR&DMA_CCR_EN));}
static void dump(const char *name,const void *v,size_t n){FILE *f=fopen(name,"wb");assert(f);assert(fwrite(v,1,n,f)==n);fclose(f);}
int main(void){streaming(0);dump("performance_model/RCC.bin",&rcc,sizeof rcc);dump("performance_model/GPIOA.bin",&ga,sizeof ga);dump("performance_model/GPIOB.bin",&gb,sizeof gb);dump("performance_model/GPIOF.bin",&gf,sizeof gf);dump("performance_model/TIM1.bin",&timer,sizeof timer);dump("performance_model/TIM2.bin",&timer2,sizeof timer2);dump("performance_model/SPI2.bin",&spi,sizeof spi);dump("performance_model/ADC1.bin",&adc1,sizeof adc1);dump("performance_model/ADC2.bin",&adc2,sizeof adc2);dump("performance_model/ADC_COMMON.bin",&adc_common,sizeof adc_common);dump("performance_model/FLASH.bin",&flash,sizeof flash);dump("performance_model/PWR.bin",&pwr,sizeof pwr);dump("performance_model/DMA.bin",&dma,sizeof dma);dump("performance_model/DMA_CHANNEL.bin",&dma_channel,sizeof dma_channel);dump("performance_model/MUX.bin",&mux,sizeof mux);dump("performance_model/MUX_STATUS.bin",&mux_status,sizeof mux_status);dump("performance_model/SYSTICK.bin",&systick,sizeof systick);return 0;}
