2010年10月31日日曜日

DDR2 SDRAM controller

ようやくDDR2 SDRAM controllerのcore module のRTLが出来た。
作成しているcontrollerは以下のような構造になっている。







←この部分がcore moduleになる。

clock domain はbf_clk (bus i/f clock)、wr_clk系、rd_clk系の3つだ。
CMD QUEUE, WDT QUEUEは非同期FIFOでここでclockの乗換も兼ねている。非同期FIFOの為同期損が発生し、同期式の場合と比べてlatencyが増加してしまうが反面bus i/f側と異なる周波数に出来るので全体的な設計は容易になると考えている。また、非同期FIFOはPHY_DPにも存在する。これはread data用である。
BCはbank controllerだ。本設計ではbank単位でpage管理を行おうと考えているので4つある。CPはcommand path controllerでBCからのaccess要求を調停して勝者の要求を実効する。各BCからCPへの要求信号はhreqとlreqがあり、Bank ActiveやPrecharge等の要求はhreqに、readやwriteの要求はlreqに出す。信号名からも自明なようにhreqの方が優先度は高く、CPはhreqの方を優先して処理する。
また、単にmodule構成の話ではあるが、wr_clk, rd_clkを作るDCM部はcore module内に持つことにした。その構成は今のところ以下の方針でいこうと考えている。



dcm_srcで周波数を作り、dcm_wr, dcm_rdで位相を作る。
dcm_srcのfeed back pathはSpartan3A Starter KitではLOOP_OUTとLOOP_INというそれ用と思われる配線があるのでその経路を使うことにした。(Starter Kitのdemoの設計資料は回路図とUCFファイル以外は参照していない。)

まだ実機動作はおろか合成すらしていないのでもしかしたら修正になるかも知れないが。。。




Micronのweb siteからsimulation modelを入手してsimulationにも着手した。

これはbank0,1,2,3へのwriteが連続する場合だ。各bankのpageは閉じている状態から始めている。上述の通りBCからCPへの要求はhreqが優先されるため、各bankのactiveが連続して実行され、その後writeが連続して実行される。SD_DQ, SD_DMの初めの部分に不定がのっている(赤くなっている)のは非同期FIFO内のRAMの初期値が不定の為であり、設計不良によるものではない。


これは同一bankへの連続writeの場合だ。本設計の用途はframe bufferとしてのものなので上記のような各bankへのaccessが連続するよりも左のような単一bankへのaccessが連続する方がより現実的だろう。もちろん論理addressをDRAMのaddressにどう対応づけるかにもよるが。。。また、波形から、write latencyは12だ。(bank activeから始まる場合、bank がactiveな状態ではもっと少なくなる。)Command queueが同期FIFOであれば2cycle程度は減る筈だが上述のような理由のためやむを得ない。

これは同一bankからの連続readの場合だ。bankがactiveの状態で開始しているのでread latencyは最小の場合だ。波形から17だ。
readではCommand queue部の同期損にPHY_DP部の非同期FIFOの同期損が加わるためlatencyは悪化してしまう。また、上述のlatency値はcore moduleのみの値であるがaccessを要求する側から見れば、MULTI PORT I/F部のlatencyも加味されることになる。

2010年10月29日金曜日

神のBIN2BCD

BIN2BCDについてネットで検索していたら凄いのを見つけてしまった。
このサイトだ。  (※. リンク先のサイトが存在しなくなっていたのでリンクを削除しました。 2016.09.19)
ここに引用しておく。

~~ 引用ここから ~~
module bin2bcd_m16
(
 input  wire  [15:0] bin_in,   // binary number in
 output wire  [15:0] bcd_out   // BCD digits out
);

   reg [3:0] ones, tens, huns, thous;
   integer   i;  

   assign    bcd_out[3:0]   = ones;
   assign    bcd_out[7:4]   = tens;
   assign    bcd_out[11:8]  = huns;
   assign    bcd_out[15:12] = thous;

   always @(*) begin
      thous = 0;
      huns  = 0;
      tens  = 0;
      ones  = 0;
      for(i=15; i>=0; i=i-1) begin
         {thous, huns, tens, ones} = {thous[2:0],huns,tens,ones,bin_in[i]};
         if(ones  >= 5 && i > 0)  ones  = ones  + 3;
         if(tens  >= 5 && i > 0)  tens  = tens  + 3;
         if(huns  >= 5 && i > 0)  huns  = huns  + 3;
         if(thous >= 5 && i > 0)  thous = thous + 3;
      end 
   end 

endmodule
~~ 引用ここまで ~~

なんと、これでBinaryからBCDへの変換が出来るようだ。
コーディングの仕方は教科書では決して推奨されないスタイルだけれども凄い。
こんなんでちゃんと合成できるんだろうか?
ISEで合成してみた。。


















ちゃんと合成できた。
シミュレーションをしてみた。
テストベンチは以下のようにした。
RTLとP&R後のネットリストの両方に同じ値を入力して、テストベンチ内部で生成した期待値と両者の出力が一致するかを見ている。


`timescale 1ns/1ps
module tb; 


reg  clk;
reg  [15:0] bin_in;
wire [15:0] bcd_rtl,bcd_map;
reg  [3:0] d3,d2,d1,d0;
integer r,err;


bin2bcd_m16 i_rtl     ( .bin_in (bin_in), .bcd_out(bcd_rtl));
bin2bcd_m16_map i_map ( .bin_in (bin_in), .bcd_out(bcd_map));

initial begin
   clk = 0;
   forever clk = #5 ~clk;
end


initial begin
  bin_in = 0;
  err = 0;
  wait (!glbl.GSR);
  @(posedge clk); #1; 
  @(posedge clk); #1; 
  for (bin_in = 0; bin_in < 10000; bin_in = bin_in + 1)
  begin
    @(posedge clk); #1; 
    d3 = bin_in / 1000;
    r = bin_in % 1000;
    d2 = r / 100;
    r = r % 100;
    d1 = r / 10; 
    d0 = r % 10; 
    if ((bcd_rtl !== {d3,d2,d1,d0}) || 
      (bcd_map !== {d3,d2,d1,d0}) || 
       (bcd_map !== bcd_rtl)) begin
      $display("ERROR!!! in=%d,exp=%x->rtl=%x,map=%x", 
      bin_in,{d3,d2,d1,d0}, bcd_rtl, bcd_map);
      err = err+1;
    end else begin
      $display("O  K !!! in=%d,exp=%x->rtl=%x,map=%x", 
      bin_in,{d3,d2,d1,d0}, bcd_rtl, bcd_map);
    end 
  end 
  if (err == 0)
    $display("END OF SIMULATION WITH NO ERROR");
  else
    $display("END OF SIMULATION WITH %d ERROR(S)", err);


  $finish;
end
endmodule


icarus verilogでsimulationした。


















エラーなし!! 凄い!!
こういうアルゴリズムをサクッと創造できるようになりたいもんだ。
私にとってみると正に神のBIN2BCDだ。

すげ~、凄い、凄すぎます。きゃ~~興奮しちゃう。

私もDRAMCの作成を頑張ろう。

2010年10月27日水曜日

BIN2BCD

ブログFPGAの部屋の今日の記事は2進数からBCDへの変換回路だった。
おもしろそうなので、私も検討してみた。
私の場合はこうするかな?

module bin2bcd (clk, bin, bcd);
input           clk;
input   [ 9:0]  bin;
output  [15:0]  bcd;

wire    [13:0]  k3; 
reg     [13:0]  k3b;
reg     [ 3:0]  d32;
reg     [ 3:0]  d31;
reg     [ 3:0]  d30;
wire    [13:0]  k2; 
reg     [13:0]  k2b;
reg     [ 3:0]  d21;
reg     [ 3:0]  d20;
wire    [13:0]  k1; 
reg     [ 3:0]  d10;
reg     [ 3:0]  d00;

assign  k3 = bin + bin[9:6] + bin[9:7] + bin[9] + 1'b1;
always @(posedge clk) d32 <= k3[13:10];
always @(posedge clk) k3b <= bin - (k3[13:10] * 1000);

assign  k2 = k3b * 10 + k3b[13:2];
always @(posedge clk) d21 <= k2[13:10];
always @(posedge clk) k2b <= k3b - (k2[13:10] * 100);
always @(posedge clk) d31 <= d32;

assign  k1 = k2b * 102 + k2b[13:1];
always @(posedge clk) d00 <= k2b - (k1[13:10] * 10);
always @(posedge clk) d10 <= k1[13:10];
always @(posedge clk) d20 <= d21;
always @(posedge clk) d30 <= d31;

assign  bcd = {d30,d20,d10,d00};
endmodule

パイプライン式でLatencyは3だけど乗算部が5つもある。
y = -ax+b , y = a x+b部を1つにしてステートマシンで回すようにすればもう少しコンパクトにできるかも知れないな。

2010年10月26日火曜日

PHY部の検討

DDR2 SDRAM CONTROLLERのPHY部に検討を行っている。
Spartan3AはIDELAYを持っているが、IOB内部のF/Fを使用する場合は4tapしか使えず自由度が低い。Spartan3Aではread dataの取り込みはDQSの位相をずらして使用するのではなく、DCMでCapture用のclockを生成して使うのが作法のようだ。その作法に則って設計することにしよう。

Write系のData pathは以下のようにした。


//--------------------------------------------------------------------------------
// circuit description
//--------------------------------------------------------------------------------
OBUF i_obuf_dm [(PHYDMW/2)-1:0] (
        .O( DM  ),
        .I( dmo )
);


IOBUF   i_iobuf_dq [(PHYDW/2)-1:0] (
        .IO( DQ ),
        .O ( dqi),
        .I ( dqo),
        .T ( oen)
);


IOBUFDS i_iobufds_dqs [(PHYDW/16)-1:0] (
        .IO ( DQS_P),
        .IOB( DQS_N),
        .O  ( dqsi ),
        .I  ( dqso ),
        .T  ( oen  )
) ;


//--------------------------------------------------------------------------------
// write
//--------------------------------------------------------------------------------


/*********************************************************************************


 tx_clk_270 ~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|_
 tx_clk_180 |___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___
 tx_clk_90  __|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~
 tx_clk  ___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 dp_ten  ____/~~~~~~~~~~~~~~~~\_________________________________
 dp_ten_1d __________/~~~~~~~~~~~~~~~~\_________________________
 ten_pd    __________________/~~~~~~~~~~~~~~~~\_________________
 ten_nd    ________________/~~~~~~~~~~~~~~~~\___________________
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 oen       __________/~~~~~~~~~~~~~~~~~~~~~~~~\_________________
 dqso_en   __________/~~~~~~~~~~~~~~~~~~~~~~\___________________
 DQS       ----------_______|~~~|___|~~~|_____------------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 tx_clk_90  __|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~~~|___|~
          ___ _______ _______ _______ _______ _______ _______ __
 dp_wd    ___X__Va___X__Vb___X_______X_______X_______X_______X__
           ______ _______ _______ _______ _______ _______ ______
 wd_180    ______X__Va___X__Vb___X_______X_______X_______X______
           ____ _______ _______ _______ _______ _______ _______ 
 wd_90     ____X_______X___Va__X__Vb___X_______X_______X_______X
                           ___ ___ ___ ___              
 DQ       -----------#####X_a_X_a_X_b_X_b_X####-----------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
                           ___ ___ ___ ___              
 DQ       -----------#####X_a_X_a_X_b_X_b_X####-----------------
            : : : : : : : : : : : : : : : : : : : : : : : : : : 
 DQS       ----------_______|~~~|___|~~~|_____------------------


 latency = 2
*********************************************************************************/


FDC i_ten_1d (.C(tx_clk    ),.D(dp_ten   ),.Q(dp_ten_1d),.CLR(tx_rst));
FDC i_ten_pd (.C(tx_clk    ),.D(dp_ten_1d),.Q(ten_pd   ),.CLR(tx_rst));
FDC i_ten_nd (.C(tx_clk_270),.D(dp_ten_1d),.Q(ten_nd   ),.CLR(tx_rst));


NOR2 i_nor_oen     (.I0(ten_pd), .I1(dp_ten_1d), .O(oen    ));
NOR2 i_nor_dqso_en (.I0(ten_nd), .I1(dp_ten_1d), .O(dqso_en));
OR2  i_or_dqo_en   (.I0(ten_nd), .I1(dp_ten_1d), .O(dqo_en));


ODDR2 #(
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_oddr_dqso [(PHYDW/16)-1:0] (
    .CE           ( 1'b1        ),
    .R            ( dqso_en     ),
    .S            ( 1'b0        ),
    .Q            ( dqso        ),
    .C0           ( tx_clk_180  ),
    .C1           ( tx_clk      ),
    .D1           ( 1'b1        ),
    .D0           ( 1'b0        )
);


FD i_fd_wd_180  [PHYDW-1 :0] (.C(tx_clk_180), .D(dp_wd  ), .Q(wd_180 ));
FD i_fd_wdm_180 [PHYDMW-1:0] (.C(tx_clk_180), .D(dp_wdm ), .Q(wdm_180));
FD i_fd_wd_90   [PHYDW-1 :0] (.C(tx_clk_90 ), .D(wd_180 ), .Q(wd_90  ));
FD i_fd_wdm_90  [PHYDMW-1:0] (.C(tx_clk_90 ), .D(wdm_180), .Q(wdm_90 ));


ODDR2 # (
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_dqo_ddr[(PHYDW/2)-1:0] (
    .CE           ( dqo_en      ),
    .R            ( 1'b0        ),
    .S            ( 1'b0        ),
    .Q            ( dqo         ),
    .C0           ( tx_clk_270  ),
    .D0           ( wd_90[ 7:0] ),
    .C1           ( tx_clk_90   ),
    .D1           ( wd_90[15:8] )
) ;

ODDR2 # (
    .DDR_ALIGNMENT( "NONE"      ),
    .INIT         ( 1'b0        ),
    .SRTYPE       ( "ASYNC"     )
) i_dmo_ddr [(PHYDMW/2)-1:0] (
    .CE           ( dqo_en      ),
    .R            ( 1'b0        ),
    .S            ( 1'b0        ),
    .Q            ( dmo         ),
    .C0           ( tx_clk_270  ),
    .C1           ( tx_clk_90   ),
    .D1           ( wdm_90[1]   ),
    .D0           ( wdm_90[0]   )
) ;

また、Read系は以下だ。



//--------------------------------------------------------------------------------
// read
//--------------------------------------------------------------------------------
IDDR2 #(
    .DDR_ALIGNMENT( "NONE"      ),
    .SRTYPE       ( "ASYNC"     ),
    .INIT_Q0      ( 1'b0        ),
    .INIT_Q1      ( 1'b0        )
)
i_ddr [(PHYDW/2)-1:0] (
    .C0           ( rx_clk_180  ),
    .C1           ( rx_clk      ),
    .D            ( dqi         ),
    .Q1           ( dqip        ),
    .Q0           ( dqin        ),
    .CE           ( 1'b1        ),
    .S            ( 1'b0        ),
    .R            ( 1'b0        )
);


wire dp_ren_dly;


FDC i_ren_dly1 (.C (rx_clk),.D(dp_ren),.Q(dp_ren_dly),.CLR(rx_rst));
FDC i_ren_dly2 (.C (rx_clk),.D(dp_ren_dly),.Q(af_wen),.CLR(rx_rst));


afifo #(.DW(PHYDW), .AW(3)) i_asq (
        .wclk   (rx_clk     ),
        .wrst   (tx_rst     ),
        .full   (/* open */ ),
        .amfull (/* open */ ),
        .wen    (af_wen     ),
        .wdt    ({dqin,dqip}),


        .rclk   (bf_clk     ),
        .rrst   (bf_rst     ),
        .empty  (asq_empty  ),
        .ren    (dp_rd_rdy  ),
        .rdt    (pd_rd      )
);


INV i_vld (.I(asq_empty),.O(pd_rd_vld));


Icarus Verilogでsimulationを行った。


Write系


Read系は上記Write dataを折り返して確認した。





































2010年10月21日木曜日

色味の調整3

カメラの画が白っぽく見えるのはGAMSW(ガンマ補正か?)が効いているためのようだ。


←はテストパターンでは無く実写データの場合だ。GAMSWはOFFにしており、GAMSW以外の
レジスタ設定はディフォルトのままになっている。











←はGAMSWをONにした場合で全体的に底が持ち上がっている。GAMSWのディフォルト値はONなので、白っぽく見えていたのはこのためだろう。









全画面分を表示させるためのフレームバッファが欲しいので、今後はDRAMコントローラの製作に移ろうと思う。

2010年10月20日水曜日

調整用プログラム

調整用プログラムをwxWidgetsで作った。


カラーバーの画面を見ながら各スライダーを動かして最適ポイントに合わせようというスンポウだ。






が、中々最適ポイントにならない。
←は一見ばらつきも少なくいい感じのように見えるが、FPGA内部で生成したパターンよりも振幅が大きくサチってる感じだ。










カメラのテストパターンをRamp2にして見ると左の通りでやはり飽和していた。

2010年10月19日火曜日

色味の調整2

R,G,B各成分の振幅をグラフ表示するようにしてみた。






← 横一直線に並んでいるのはFPGAで生成したカラーバーのもの。上下に散らばっているのはカメラのカラーバーだ。









この画面を見ながらカメラのレジスタ値を調整していけば判りやすいのではないかと考えているが。。。旨くいくかな?

2010年10月18日月曜日

色味の調整

色味の調整を試行している。
TCM8230MDはテストパターンの出力機能を内蔵していて、0x1E番地のレジスタのTESPIC, PICSELビットで機能のON/OFFと出力パターンの選択が出来る。出力パターンとしてはColorbar、Ramp1、Ramp2の3パターンだ。この中からカラーバーを出力するようにして、FPGA内部で生成したカラーバーとの色味を比べながら調整できないか試してみている。
dvi_encの出力サイズをVGAにし、カメラデータを切取る矩形サイズを512x27にして容易に比較できるようにした。








←この部分がカメラから取り込んだカラーバーだ。
微妙にというべきかかなりと言うべきか、色味が違う。
色境界部の変色も気になるが、とりあえずここでは置いておく。











0x18番地のSATU (SATURATION か?)レジスタの値を初期値の0x27から0x4Eにしてみた。















次に0x13にしてみた。
黄色は近くなったけど他は逆に遠ざかってしまった。。








次にVHUE (0x13), UHUE(0x14), VGAIN(0x15), UGAIN(0x16)レジスタの値も振ってみよう。これらのレジスタの設定値はGAMSW (0x0D) をOFFにしないと有効にならないようだ。

何れにしても今のやり方だと効率が悪いので、もっと簡単に調整できるよう工夫が必要だな。

2010年10月17日日曜日

動き始めたぞっと

ハンダ付け作業も一通り終わり、動作確認に着手した。
まずは起動直後のレジスタ値を読んでみた。














0x00, 0x01, 0x2B, 0x2D, 0x32, 0x33, 0x34, 0x36, 0x37の値がデータシートと異なっているが、これらがどういうレジスタなのかは現時点では不明。
次にいよいよ撮像確認だが、このカメラのフレームレートは30fpsであるため例えディスプレイ出力をVGAモードにしたとしてもカメラのデータをスルーして出力することは出来ない。フレームバッファを介する必要がある。現状まだSDRAMコントローラの実装はしていないため、FPGAの内部RAMをフレームバッファとして使うことにした。容量の制約から128x110分とし、カメラの撮像データを切り出して格納・表示するようにした。




























←撮影対象













撮像データのフォーマットはRGB565、CODEはNormalにしている。
撮影対象の写真と比べると色が薄いというか白っぽい。
レジスタで調整できるのかなぁ?
それっぽい名前のレジスタの設定を色々変えてみようか。
YUV422も試してみよう。

現状のレジスタ設定はデータフォーマットや出力コード設定等のみで、
画質に関わるようなレジスタは触っていない。

現在の設定
  
main()
{
   fpga_open();

   reg_wrt(0x02,0x40,0);//FPS:30fps, ACF:60Hz, DCLKP:NORMAL, ACFDET:AUTO
   reg_wrt(0x03,0x02,0);//DOUTSW:ON, DATA:OUT, PICSIZ:VGA, 
                                                            PICFMT:RGB565, CM:COLOR
   reg_wrt(0x1e,0x68,0);//D_MASK:01, CODESW:OUT, CODESEL:NORMAL, 
                  // HSYNCSEL:NORMAL, TESPIC:Not out, PICSEL:Colorbar

   fpga_close();

}


2010年10月14日木曜日

ハンダ付けが終わった

ハンダ付け作業が終わった。
















25MHzの信号を伝送するのでStarter Kitとの接続はツイストペア線(片側GND)で接続した。
結線チェックは明日行うことにしよう。

2010年10月13日水曜日

注文したカメラが届いた

カメラが届いたのでリード線のハンダ付けをした。
















また剥離すると悲しいのでホットなんちゃらで固めよう。。

2010年10月11日月曜日

UARTとI2C モジュールの作成

カメラは再度購入することにした。
カメラコントローラのデバッグ時にI2Cコントローラが必要になる。また、その制御は最初のうちはUART経由でPCから行うことになる。そこで、物が入手できるまでこれらコントローラの作成を行うことにした。

- 通信フレーム
  PC - FPGA間の通信は以下のような通信フレームで行う。
  FPGAはcommand frameに対してACK(受信成功時), NAK(受信失敗時)応答を返す。


   // UART I/F
   //
   // [frame format]
   // 
   // *command frame (PC -> FPGA)
   //   +---+---+---+---+---+---+---+---+
   //   |STX|CMD| B3| B2| B1| B0|ETX|SUM|
   //   +---+---+---+---+---+---+---+---+
   // 
   //   command_frame := {STX, CMD, B3, B2,
   //                         B1, B0, ETX, SUM}
   //   STX   := 0x02
   //   CMD   := {cmd_rw, cmd_addr[6:0]}
   //   B3    := cmd_data[31:24] 
   //   B2    := cmd_data[23:16] 
   //   B1    := cmd_data[15: 8] 
   //   B0    := cmd_data[ 7: 0] 
   //   ETX   := 0x03
   //   SUM   := sum[7:0]
   //            sum = STX + CMD + B3 + B2
   //                           + B1 + B0 + ETX
   //
   // *response data (FPGA -> PC)


   //   response := ACK | NAK
   //   ACK   := 0x06
   //   NAK   := 0x15
   //
   // *readback frame (FPGA -> PC)

   //   +---+---+---+---+---+---+---+---+
   //   |STX|TYP| B3| B2| B1| B0|ETX|SUM|
   //   +---+---+---+---+---+---+---+---+
   // 
   //   response_frame := {STX, TYP, B3, B2,
   //                          B1, B0, ETX, SUM}
   //   STX   := 0x02
   //   TYPE  := rd_typ[7:0]
   //   B3    := rd_data[31:24] 
   //   B2    := rd_data[23:16] 
   //   B1    := rd_data[15: 8] 
   //   B0    := rd_data[ 7: 0] 
   //   ETX   := 0x03
   //   SUM   := sum[7:0]
   //            sum = STX + CMD + B3 + B2
   //                           + B1 + B0 + ETX
   // 


I2Cコントローラはシングルアクセスのみサポートとしたが、連続アクセスにも容易に変更できる構造にした。
出来上がったUART, I2Cコントローラと以下のプログラムでSpartan3A Starter Kitの電源IC  LP3906のレジスタ(LDO1VCR, LDO2VCR)をリードしてみた。
Starter Kitの回路図によればLDO1は3.3V(レジスタ値はデータシートによれば0x17), LDO2は1.8V(同0x08)なので、正しくリードできている。
(今回作成したI2CとUARTモジュールはここで公開している。)















2010年10月9日土曜日

作業開始!!

さあ、作業開始だ。

リード線のハンダ付けは肉眼で見ながら行うのは困難なため、ルーペを見ながら行っている。このルーペは古道具屋さんで買ったステージ用の照明器具を改造したものだ。













このカメラモジュールの裏側にパッドがあるが、外周にもパッドへの接続用のviaが配置されている。但しviaの中央から基板をカットしているのでviaは半分(半円)のみ残っている。リード線のハンダ付けはこのvia部分に行っている。













オーマイガッ!!
ようやくリード線のハンダ付けが終わったと思ったのも床の間、いや、束の間、リード線の反対側の接続作業を行おうとしたらviaの銅箔ごと剥離してしまった。













予備を買っとくんだった。。 (;_;)
なんとかならんかなぁ~










ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...