* SPICE netlist
L1 N004 N005 120m Rser=20
M1 N001 N003 N004 N004 Si4850EY
V1 period 0 PULSE(0 1 0 10n 10n {MIN_ON} {PERIOD})
V2 N001 0 14
R2 N002 N003 50
D2 0 N004 MURS320
Rsense N005 0 0.5
E1 N002 N004 pwm 0 5
A1 period pwmres 0 0 0 0 pwm 0 SRFLOP td=10n
B2 Icoil 0 V=V(Vsense)*2
B3 error 0 V=V(target)-V(Icoil)
B5 pid 0 V={K1}*V(error) + V(i_error)
B6 pid_clamp 0 V=limit({MIN_DUTY}, V(pid), {MAX_DUTY})
V3 target 0 PULSE(0.2 0.4 0 10n 20n 40m 80m)
B7 pwmres 0 V=delay(V(period),V(pwm_val)*{PERIOD})
R1 Vsense N005 10k
C1 Vsense 0 100n
B1 i_error 0 V=idt({K2}*V(elim)/{PERIOD})
S1 error elim N008 0 SW1
R3 elim 0 1k
B9 N006 0 V=IF( (V(i_error)>{INT_MIN} & V(i_error) < {INT_MAX}) , 1, 0)
B8 N007 0 V=IF( (V(i_error)<={INT_MIN} & V(error) > 0 ), 1, 0)
B10 N009 0 V=IF( (V(i_error)>={INT_MAX} & V(error) < 0) , 1, 0)
A2 N009 0 N007 0 N006 0 N008 0 OR
B4 pwm_val 0 V=int(V(pid_clamp)*PWM_RES+0.5)/PWM_RES
.tran 0 80m 0 {MIN_TSTEP}
.param PERIOD=100u
.param MIN_DUTY=0.01
.param MAX_DUTY=1-2*MIN_DUTY
.param MIN_ON=MIN_DUTY*PERIOD
.param PWM_RES=256
.param MIN_TSTEP=0.2*PERIOD*MIN(MIN_DUTY,1/PWM_RES)
.param K1=25
.param K2=0.5
.param INT_MIN=-0.1
.param INT_MAX=1

* LTspice schematic (.asc)
Version 4
SHEET 1 1488 1552
WIRE 488 -392 488 -488
WIRE 488 -712 488 -776
WIRE 488 -776 712 -776
WIRE 712 -776 712 -744
WIRE 712 -664 712 -632
WIRE 440 -632 328 -632
WIRE -712 -584 -712 -472
WIRE -712 -344 -712 -392
WIRE 488 -488 488 -616
WIRE 248 -632 120 -632
WIRE 488 -312 488 -248
WIRE 728 -104 488 -104
WIRE 488 -104 488 -88
WIRE 488 -488 728 -488
WIRE 728 -488 728 -344
WIRE 488 -136 488 -104
WIRE 728 -280 728 -104
WIRE 488 -248 424 -248
WIRE 488 -248 488 -216
WIRE 120 -488 488 -488
WIRE 120 -600 120 -632
WIRE 120 -520 120 -488
WIRE 72 -536 72 -504
WIRE 72 -584 -72 -584
WIRE -712 -584 -680 -584
WIRE -680 -584 -344 -584
WIRE -72 -584 -248 -584
WIRE -344 -536 -472 -536
WIRE -728 136 -728 88
WIRE -728 88 -648 88
WIRE -728 216 -728 248
WIRE -424 136 -424 88
WIRE -424 88 -360 88
WIRE -424 216 -424 248
WIRE -744 472 -744 504
WIRE -744 392 -744 344
WIRE -744 344 -680 344
WIRE -744 744 -744 776
WIRE -744 664 -744 616
WIRE -744 616 -664 616
WIRE -728 -200 -728 -152
WIRE -728 -40 -728 -72
WIRE -728 -200 -696 -200
WIRE -520 -408 -520 -344
WIRE -520 -488 -520 -536
WIRE -472 -536 -520 -536
WIRE 344 -248 296 -248
WIRE 296 -200 296 -248
WIRE 296 -248 264 -248
WIRE 296 -136 296 -88
WIRE 504 216 504 168
WIRE 504 168 568 168
WIRE 504 296 504 328
WIRE 296 200 296 168
WIRE 296 168 184 168
WIRE 296 280 296 328
WIRE 168 216 168 456
WIRE 120 216 120 248
WIRE 104 168 40 168
WIRE 40 168 8 168
WIRE 296 168 344 168
WIRE 344 168 392 168
WIRE 744 520 744 552
WIRE 600 616 600 648
WIRE 440 696 440 728
WIRE 248 456 168 456
WIRE 312 408 744 408
WIRE 312 440 600 440
WIRE 600 440 600 536
WIRE 440 616 440 472
WIRE 440 472 312 472
WIRE 744 408 744 440
WIRE -248 728 -248 776
WIRE -248 648 -248 600
WIRE -248 600 -184 600
FLAG 712 -632 0
FLAG 488 -88 0
FLAG 264 -248 Vsense
IOPIN -112 416 Out
FLAG -680 -584 period
FLAG 72 -504 0
FLAG -72 -584 pwm
FLAG -712 -344 0
FLAG -728 248 0
FLAG -648 88 Icoil
IOPIN -1024 752 Out
FLAG -424 248 0
FLAG -360 88 error
IOPIN -736 752 Out
FLAG -744 504 0
FLAG -680 344 pid
IOPIN -1056 1008 Out
FLAG -744 776 0
FLAG -664 616 pid_clamp
IOPIN -1040 1280 Out
FLAG -696 -200 target
IOPIN -1072 464 Out
FLAG -728 -40 0
FLAG -520 -344 0
FLAG -472 -536 pwmres
FLAG 296 -88 0
FLAG 504 328 0
FLAG 568 168 i_error
IOPIN 192 832 Out
FLAG 296 328 0
FLAG 120 248 0
FLAG 40 168 error
FLAG 344 168 elim
FLAG 744 552 0
FLAG 600 648 0
FLAG 440 728 0
FLAG -248 776 0
FLAG -184 600 pwm_val
IOPIN -560 1264 Out
SYMBOL ind2 472 -408 R0
SYMATTR SpiceLine Rser=20
SYMATTR InstName L1
SYMATTR Value 120m
SYMATTR Type ind
SYMBOL nmos 440 -712 R0
SYMATTR InstName M1
SYMATTR Value Si4850EY
SYMBOL voltage -712 -488 R0
SYMATTR Value PULSE(0 1 0 10n 10n {MIN_ON} {PERIOD})
SYMATTR InstName V1
SYMBOL voltage 712 -760 R0
SYMATTR InstName V2
SYMATTR Value 14
SYMBOL res 232 -616 R270
SYMATTR InstName R2
SYMATTR Value 50
SYMBOL schottky 744 -280 R180
SYMATTR InstName D2
SYMATTR Value MURS320
SYMATTR Description Diode
SYMATTR Type diode
SYMBOL res 472 -232 R0
SYMATTR InstName Rsense
SYMATTR Value 0.5
SYMBOL e 120 -616 R0
SYMATTR InstName E1
SYMATTR Value 5
SYMBOL Digital\\srflop -296 -632 R0
SYMATTR Value td=10n
SYMATTR InstName A1
SYMBOL bv -728 120 R0
SYMATTR InstName B2
SYMATTR Value V=V(Vsense)*2
SYMBOL bv -424 120 R0
SYMATTR InstName B3
SYMATTR Value V=V(target)-V(Icoil)
SYMBOL bv -744 376 R0
SYMATTR InstName B5
SYMATTR Value V={K1}*V(error) + V(i_error)
SYMBOL bv -744 648 R0
SYMATTR InstName B6
SYMATTR Value V=limit({MIN_DUTY}, V(pid), {MAX_DUTY})
SYMBOL voltage -728 -168 R0
SYMATTR Value PULSE(0.2 0.4 0 10n 20n 40m 80m)
SYMATTR InstName V3
SYMBOL bv -520 -504 R0
SYMATTR InstName B7
SYMATTR Value V=delay(V(period),V(pwm_val)*{PERIOD})
SYMBOL res 328 -232 R270
SYMATTR InstName R1
SYMATTR Value 10k
SYMBOL cap 280 -200 R0
SYMATTR InstName C1
SYMATTR Value 100n
SYMBOL bv 504 200 R0
SYMATTR InstName B1
SYMATTR Value V=idt({K2}*V(elim)/{PERIOD})
SYMBOL sw 88 168 R270
SYMATTR InstName S1
SYMATTR Value SW1
SYMBOL res 280 184 R0
SYMATTR InstName R3
SYMATTR Value 1k
SYMBOL bv 744 424 R0
SYMATTR InstName B9
SYMATTR Value V=IF( (V(i_error)>{INT_MIN} & V(i_error) < {INT_MAX}) , 1, 0)
SYMBOL bv 600 520 R0
SYMATTR InstName B8
SYMATTR Value V=IF( (V(i_error)<={INT_MIN} & V(error) > 0 ), 1, 0)
SYMBOL bv 440 600 R0
SYMATTR InstName B10
SYMATTR Value V=IF( (V(i_error)>={INT_MAX} & V(error) < 0) , 1, 0)
SYMBOL Digital\\or 280 504 R180
SYMATTR InstName A2
SYMBOL bv -248 632 R0
SYMATTR InstName B4
SYMATTR Value V=int(V(pid_clamp)*PWM_RES+0.5)/PWM_RES