diff --git a/as5013-test/nrf52-as5013-interior.png b/as5013-test/nrf52-as5013-interior.png new file mode 100644 index 0000000000000000000000000000000000000000..8144b66cd67228fff89796ceed0ef047336f2a27 Binary files /dev/null and b/as5013-test/nrf52-as5013-interior.png differ diff --git a/as5013-test/nrf52-as5013-layout.png b/as5013-test/nrf52-as5013-layout.png new file mode 100644 index 0000000000000000000000000000000000000000..61da6d7911dbf31cdbd35a5558681448330d0c19 Binary files /dev/null and b/as5013-test/nrf52-as5013-layout.png differ diff --git a/as5013-test/nrf52-as5013-traces.png b/as5013-test/nrf52-as5013-traces.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a1f8a4f493ace3ba6082761a20f338d924a8ad Binary files /dev/null and b/as5013-test/nrf52-as5013-traces.png differ diff --git a/as5013-test/nrf52-as5013.ko b/as5013-test/nrf52-as5013.ko new file mode 100644 index 0000000000000000000000000000000000000000..a8994636505dfd434ff3e470ae5dc2cec36914ba --- /dev/null +++ b/as5013-test/nrf52-as5013.ko @@ -0,0 +1,328 @@ +from koko.lib.pcb import * +from koko.lib.sam import * + + +class R_0805_small(Component): + ''' 0805 Resistor + ''' + _pad_0805 = s2d.rectangle(-.017,.017, -.026, .026) + pins = [Pin(-0.04, 0, _pad_0805), Pin(0.04, 0, _pad_0805)] + prefix = 'R' + vias = [] + +class Button(Component): + ''' SW262CT-ND + ''' + rect = rectangle(-.75/25.4,.75/25.4,-.5/25.4,.5/25.4) + pins = [ + Pin(-2/25.4,.8/25.4,rect), + Pin( 2/25.4,.8/25.4,rect), + Pin(-2/25.4,-.8/25.4,rect), + Pin( 2/25.4,-.8/25.4,rect) + ] + prefix = 'button' + vias = [] + shadow = rectangle(-2.1/25.4,2.1/25.4,-1.4/25.4,1.4/25.4) + +class TagConnectSWD(Component): + ''' + ''' + _pad = s2d.circle(0,0,.5*.031) + _via = s2d.circle(0,0,.5*.039) + pins = [ + Pin(-.05,-.025,_pad,'VCC',label_size=.012), + Pin( .00,-.025,_pad,'TX',label_size=.012), + Pin( .05,-.025,_pad,'RX',label_size=.012), + Pin(-.05,.025,_pad,'GND',label_size=.012), + Pin( .00,.025,_pad,'SWDIO',label_size=.012), + Pin( .05,.025,_pad,'SWDCLK',label_size=.012) + ] + vias = [ + Via(-.1,0,_via), + Via(.1,0.04,_via), + Via(.1,-.04,_via), + + ] + + +class AS5013(Component): + #Austrian Microsystems AS5013 2d linear magnetic encoder + p = .65/25.4 #pitch + pw = .2/25.4 #half pad width + ph = .35/25.4 #half pad height + pe = .4/25.4 #pad extension outwards + pad_1 = s2d.rectangle(-ph-pe,ph,-pw,pw) + pad_2 = s2d.rectangle(-pw,pw,-ph-pe,ph) + pad_3 = s2d.rectangle(-ph,ph+pe,-pw,pw) + pad_4 = s2d.rectangle(-pw,pw,-ph,ph+pe) + w = 3.7/25.4 #side width + labels = [ 'SDA','SCL','RST','INT', + 'TB0','TB1','TB2','TB3', + 'COIL','ADR','VDDp','VDD', + 'VSS','MODE','PCLK','PDIO'] + pins = [Pin(-.5*w, (1.5-i)*p, pad_1, l, label_size=.015) for i,l in enumerate(labels[:4])] + pins += [Pin((-1.5+i)*p, -.5*w,pad_2, l, label_size=.015,label_rot=-90) for i,l in enumerate(labels[4:8])] + pins += [Pin(.5*w, (-1.5+i)*p,pad_3, l, label_size=.015) for i,l in enumerate(labels[8:12])] + pins += [Pin((1.5-i)*p, .5*w,pad_4, l, label_size=.015,label_rot=-90) for i,l in enumerate(labels[12:])] + pins += [Pin(0,0,rectangle(-1.2/25.4,1.2/25.4,-1.2/25.4,1.2/25.4))] + prefix = 'U' + vias = [] + shadow = rectangle(-.5*w,.5*w,-.5*w,.5*w) + +class Regulator_SOT23(Component): + ''' SOT23 voltage regulator + ''' + _pad_SOT23 = s2d.rectangle(-.02,.02,-.012,.012) + pins = [ + Pin(-0.045, -0.0375, _pad_SOT23,'IN'), + Pin(-0.045, 0.0375, _pad_SOT23,'OUT'), + Pin(0.045, 0, _pad_SOT23,'GND') + ] + prefix = 'U' + vias = [] + +class Crystal_FC135(Component): + ''' CRYSTAL 32.7680KHZ 12.5PF SMT + ''' + _pad = s2d.rectangle(-.5/25.4,.5/25.4,-.9/25.4,.9/25.4) + pins = [ + Pin(-1.25/25.4, 0, _pad), + Pin( 1.25/25.4, 0, _pad), + ] + prefix = 'U' + vias = [] + + +class Header_FTDI(Component): + ''' FTDI cable header + ''' + _pad_header = chamfered_rectangle(-0.06, 0.08,-0.025, 0.025,.007) + pins = [ + #Pin(0, -0.25, _pad_header, 'RTS'), + Pin(0, -0.15, _pad_header, 'RX'), + Pin(0, -0.05, _pad_header, 'TX'), + Pin(0, 0.05, _pad_header, 'VCC'), + Pin(0, 0.15, _pad_header, 'CTS'), + Pin(0, 0.25, _pad_header, 'GND') + ] + prefix = 'J' + vias = [] + shadow = s2d.rectangle(-.06,8/25.4,-.3,.3) + #shadow = s2d.rectangle(-.06,8/25.4,-.3,.2) + +class Header_Power(Component): + ''' FTDI cable header + ''' + _pad_header = chamfered_rectangle(-0.06, 0.08,-0.025, 0.025,.007) + pins = [ + Pin(0, 0.05, _pad_header, 'VCC'), + Pin(0, -0.05, _pad_header, 'GND'), + ] + prefix = 'J' + vias = [] + shadow = s2d.rectangle(-.06,.06,-.13,.13) + #shadow = s2d.rectangle(-.06,8/25.4,-.3,.2) + + + +def bot_chamfered_rectangle(x0,x1,y0,y1,c): + r = rectangle(x0,x1,y0,y1) + c1 = triangle(x0,y0,x0,y0+c,x0+c,y0) + c2 = triangle(x1,y1, x1, y1-c, x1-c, y1) + c3 = triangle(x0,y1, x0+c, y1, x0, y1-c) + c4 = triangle(x1,y0, x1-c, y0, x1, y0+c) + return r-c2-c3 + +class CR20XX(Component): + #coin cell battery, e.g. 2032 + pins = [ + Pin(0,0,circle(0,0,5./25.4),'-') + ] + shadow = circle(0,0,10./25.4) + vias = [] + +class AAA(Component): + #AAA battery smd holder + pad = chamfered_rectangle(-.125,.125,-.12,.12,.05) + pins = [ + Pin(1.21-.125,0,pad,'+',label_size=.08), + Pin(-1.21+.125,0,pad,'-',label_size=.08), + ] + shadow = rectangle(-1.07,1.07,-.25,.25) + vias = [ + Via(-1.21+.25,.209,circle(0,0,.039)) + ] + + +class BC832(Component): + #Fanstel BC832 micro nrf52 module + p = 1.1/25.4 + pad_hw = .7/25.4 + pad_hh = .34/25.4 + _pad_lga = circle(0,0,.32/25.4) + _pad = rectangle(-pad_hw,pad_hw,-pad_hh,pad_hh) + c= 3.9/25.4 + start_y = .618/25.4 + y_os = .18 + names = [ + 'GND','DFU','SWDIO','SWDCLK','P18','P13','P11','P12', + 'A1','RESET','XL1','XL2','A0','P27','P26','VDD', + + ] + pins = [Pin(-c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[:8][::-1])] + pins += [Pin(c,start_y+i*p-y_os,_pad,n,label_size=.018) for i,n in enumerate(names[8:16])] + pins += [ + Pin(-c+2.15/25.4,-y_os+.519/25.4,_pad_lga,'P8',label_size=.01), + Pin(-c+2.15/25.4,-y_os+(1.2+.519)/25.4,_pad_lga,'P6',label_size=.01), + #Pin(-c+2.15/25.4,-y_os+(2*1.2+.519)/25.4,_pad_lga,'A2',label_size=.01), + #Pin(-c+2.15/25.4,-y_os+(4*1.2+.519)/25.4,_pad_lga,'A4',label_size=.01), + + #Pin(-c+2.15/25.4,-y_os+(3*1.2+.519)/25.4,_pad_lga,'',label_size=.01), + #Pin(-c+2.15/25.4+1.2/25.4,-y_os+(2*1.2+.519)/25.4,_pad_lga,'',label_size=.01), + #Pin(-c+2.15/25.4+1.2/25.4,-y_os+(3*1.2+.519)/25.4,_pad_lga,'',label_size=.01), + #Pin(-c+2.15/25.4+1.2/25.4,-y_os+(4*1.2+.519)/25.4,_pad_lga,'',label_size=.01), + #Pin(-c+2.15/25.4+2*1.2/25.4,-y_os+(3*1.2+.519)/25.4,_pad_lga,'',label_size=.01), + #Pin(-c+2.15/25.4+3*1.2/25.4,-y_os+(3*1.2+.519)/25.4,_pad_lga,'',label_size=.01) + ] + vias = [] + shadow = rectangle(-c,c,-y_os,8.8/25.4-y_os) + + +class Hole(Component): + pins = [Pin(0,0,circle(0,0,0.01))] + vias = [Via(0,0,circle(0,0,.5*2.2/25.4))] + tap = circle(0,0,.5*1.9/25.5) + + +width = .9 +height = .89 +pcb = PCB(0,0,width,height,chamfer_distance=.07) + + +def connectG(pin,dx,dy,width=.012): + ''' + Convenience function for connecting to ground plane + ''' + pcb.connectD(pin,[pin.x+dx,pin.y+dy],[pin.x+dx-.0001,pin.y+dy],width=width,sides=[0,1,1]) +def connectS(pin,dx,dy,width=.012): + pcb.connectD(pin,[pin.x+dx+.0001,pin.y+dy],width=width) +def connectM(pin1,pin2,dx,width=.012): + pcb.connectD(pin1,[pin1.x+dx,pin1.y],pin2,width=width) + + + + +bc = BC832(width-.25,height-.29,-90,'Fanstel\nBC832\nNRF52') +pcb += bc + +#pow = Header_Power(.2,height-.36,180,'pow') +#pcb += pow +reg = Regulator_SOT23(bc.x-.5,bc.y-.09,-180,'3.3v') +pcb += reg + +#pcb.connectV(pow['GND'],reg['GND'],width=.02) +#pcb.connectD(reg['IN'],[reg['IN'].x-.09,reg['IN'].y+.02],pow['VCC'],width=.02) + +C_in = C_0805(reg.x+.18,reg.y-.05,90,'Cin\n.1uF',label_size=.02) +pcb += C_in +C_out = C_0805(reg.x-.05,reg.y-.09,0,'Cout\n.1uF',label_size=.02) +pcb += C_out +pcb.connectD(C_in[0],reg['IN'],width=.02) +pcb.connectV(reg['OUT'],C_out[0],width=.02) +pcb.connectH(reg['GND'],C_out[1],width=.02) + + + +swd = TagConnectSWD(bc.x-.33,bc.y+.12,0,'swd') +pcb += swd +pcb.connectD(swd['SWDCLK'],[swd['SWDCLK'].x,swd['SWDCLK'].y+.02],[bc['SWDCLK'].x-.02,bc['SWDCLK'].y+.05],bc['SWDCLK'],width=.012) +pcb.connectD(swd['SWDIO'],[swd['SWDIO'].x,swd['SWDIO'].y+.02],[bc['SWDIO'].x-.03,bc['SWDIO'].y+.079],bc['SWDIO'],width=.012) +pcb.connectD(swd['GND'],[swd['GND'].x,swd['GND'].y+.02],[bc['GND'].x-.06,bc['GND'].y+.11],bc['GND'],width=.012) + +pcb.connectD(bc['P6'],[bc['P6'].x,bc['P6'].y+.02],[bc['P6'].x-.07,bc['P6'].y+.035],[swd['RX'].x+.03,swd['RX'].y+.02],swd['RX'],width=.012) +pcb.connectD(bc['P8'],[swd['TX'].x+.07,swd['TX'].y-.05],[swd['TX'].x+.03,swd['TX'].y-.035],swd['TX'],width=.014) + + + +button = Button(swd.x-.2,swd.y-.03,90) +pcb += button + +pcb.connectV(button[3],button[0]) +pcb.connectV(button[1],button[2]) + +C2 = C_0805(C_out.x+.13,C_out.y,-180,'C2\n10uF',label_size=.02) +pcb += C2 +pcb.connectH(C2[1],C_in[1],width=.02) +pcb.connectH(C2[0],C_out[0],width=.02) +pcb.connectD(C2[1],[C2[1].x,reg['GND'].y-.03],reg['GND']) + + +pcb.connectD(swd['GND'],[swd['GND'].x,swd['GND'].y+.05],[button[2].x+.03,button[2].y+.06],button[2]) + +R1 = R_0805(C_in.x+.08,bc['RESET'].y+.01,90,'10k',label_size=.03) +pcb += R1 +pcb.connectH(bc['RESET'],[bc['RESET'].x,bc['RESET'].y+.05],R1[0],width=.012) +pcb.connectD(C2[0],[C2[0].x,C2[0].y-.06],[R1[1].x-.05,C2[0].y-.06],R1[1]) + + +pcb.connectV(swd['VCC'],reg['IN']) + +pcb.connectD(R1[0],[R1[0].x,R1[0].y+.04],[button.x+.1,R1[0].y+.1],button[3]).add_jumper([reg['IN'].x+.075,reg['IN'].y+.06],0,width=.12,thick=.06,height=.055) + + +pcb.connectD(reg['GND'],button[2]) + +#pcb.connectV(reg['OUT'],[reg['OUT'].x-.19,reg['OUT'].y-.11], [width-.02,height-.02], [bc['VDD'].x,bc['VDD'].y-.04], bc['VDD']).cut_corners([(3,.1),(5,.08)]) + + +#mounting holes +w = 25/25.4 +h = .16 + + +hall = AS5013(.5*width,h,-180) +pcb += hall + +#TODO: check bolt holes + +pcb.connectD(hall['SDA'],[hall['SDA'].x+.07,hall['SDA'].y],bc['XL2'],width=.014) +pcb.connectD(hall['SCL'],[hall['SCL'].x+.05,hall['SCL'].y],bc['XL1'],width=.014) + +#pcb.connectH(hall['SCL'],[hall['SCL'].x,hall['SCL'].y+.06],bc['XL1']) +#pcb.connectV(hall['RST'],[C2[0].x,C2[0].y-.06],C2[0]) + +RSDA = R_1206(bc['XL2'].x+.09,bc['XL2'].y-.08,0,'RSDA') +pcb += RSDA +RSCL = R_1206(bc['XL1'].x+.045,RSDA.y-.1,0,'RSCL') +pcb += RSCL +pcb.connectH(RSCL[0],RSDA[0]) +pcb.connectH(RSDA[0],bc['VDD']) + +C_hall = C_1206(hall.x-.21,hall.y-.02,0,'100nF') +pcb += C_hall + +pcb.connectH(hall['VDD'],C_hall[0],width=.014) +pcb.connectH(hall['VDDp'],C_hall[0],width=.014) +pcb.connectH(hall['ADR'],C_hall[0],width=.014) +pcb.connectD(C_hall[1],[C_hall[1].x,C_hall[1].y-.05],[hall['VSS'].x,hall['VSS'].y-.04],hall['VSS']) +pcb.connectD(C_hall[0],[C_hall[0].x,C_hall[0].y+.1],C2[0]) +pcb.connectD(C_hall[1],[C_hall[1].x,C_hall[1].y+.15],C_out[1]) + +pcb.connectV(C_hall[0],[C_hall.x-.15,C_hall.y+.1],[bc['VDD'].x,C_hall.y-.12],bc['VDD']).add_jumper([C_hall[1].x,C_hall.y+.1]) + +#pow = Header_Power(reg.x-.2,reg.y,0,'pow') +#pcb += pow + + +h1 = Hole(.5*width-.5*w,h,0) +h2 = Hole(.5*width+.5*w,h,0) +pcb.custom_cutout = chamfered_rectangle(0,width,0,height,.1) +pcb.custom_cutout += capsule(h1.x-h,h2.x+h,h,h) +pcb += h1 +pcb += h2 + +#TODO: add power for remote operation... doh + +cad.shapes = pcb.layout() +#cad.shape = pcb.traces+(pcb.cutout-pcb.cutout) +#cad.shape = pcb.cutout+(pcb.traces-pcb.traces)