· 

seeeduino XIAOでPICライターを作る 1

seeeduno XIAOでPIC12F1840用のライターを作ってみます。 PICkit3のバッタもんも安く手に入るのに、、、 e電子工房さんのPICerFT(ファームウェア不要USB接続ライタ)っていう素晴らしいものもあるのに、、、
まぁ、やってみたいだけです。
参考資料はPIC16F/LF1847/PIC12F/LF1840 Memory Programming Specificationです。
$ V_{PP} $はデータシートによると8V~9Vで、LT1054のデータシートによると
$ V_{IN} = 3.5V\ to\ 15V $
$ V_{OUT} \approx 2V_{IN} – \left(V_L + 2V_{DIODE}\right)$
$ V_L = LT1054\ VOLTAGE\ LOSS$
で$V_{IN}=5V$, $V_{DIODE}=0.6V$, $V_L=0.35V$なので$V_{OUT}=8.45V$でまぁまぁイケてるでしょ。

で、参考資料によるとseeeduinoXIAO-->PICではPICが立下りでデータを取得(なので立ち上がりでデータセット)、PIC-->seeeduinoXIAOでは立ち上がりでデータを取得なのかなーと思って作ったけどうまく動かないので、先人の成果物を参考にする。ということで、PICerFTを急遽作って(というかseeeduinoXIAOをAE-UM232Rをつなぎ変えて)波形を観測すると、コマンド時はICSPCLKがH時にずっとICSPDATをキープしている。データ送信時は、ICSPCLKがLの時にICSPDATをキープしている。さらに、PROGRAMMING MODEに入ってから数10ms待っている。で、そっくりそのまま真似てみる。とりあえずMPLAB+picKit3で書き込んだEEPROMを読み込みます。

スピードではPICerFTにかないませんが、ちゃんと動いているようです。まずは動くことが大事です♡

  1. #define MCLR (0) //HIGH=ON, LOW=OFF
  2. #define VDD (1)//LOW=ON, HIGH=OFF
  3. #define ICSPDAT (10)
  4. #define ICSPCLK (8)
  5. #define TENTS 10
  6. #define TENTH 10
  7. #define TEXIT 10
  8. #define CLOCK_HHOLD 1
  9. #define CLOCK_LHOLD 1
  10. #define TDLY 10
  11. void picSendCommandH(){
  12.   digitalWrite(ICSPCLK,LOW);
  13.   digitalWrite(ICSPDAT,HIGH);
  14.   delayMicroseconds(CLOCK_LHOLD);
  15.   digitalWrite(ICSPCLK,HIGH);
  16.   delayMicroseconds(CLOCK_HHOLD);
  17.   digitalWrite(ICSPCLK,LOW);
  18.   delayMicroseconds(CLOCK_LHOLD);
  19. }
  20. void picSendCommandL(){
  21.   digitalWrite(ICSPCLK,LOW);
  22.   digitalWrite(ICSPDAT,LOW);
  23.   delayMicroseconds(CLOCK_LHOLD);
  24.   digitalWrite(ICSPCLK,HIGH);
  25.   delayMicroseconds(CLOCK_HHOLD);
  26.   digitalWrite(ICSPCLK,LOW);
  27.   delayMicroseconds(CLOCK_LHOLD);
  28. }
  29. void picSendDataH(){
  30.   digitalWrite(ICSPCLK,HIGH);
  31.   delayMicroseconds(CLOCK_HHOLD);
  32.   digitalWrite(ICSPDAT,HIGH);
  33.   delayMicroseconds(CLOCK_HHOLD);
  34.   digitalWrite(ICSPCLK,LOW);
  35.   delayMicroseconds(CLOCK_LHOLD);
  36. }
  37. void picSendDataL(){
  38.   digitalWrite(ICSPCLK,HIGH);
  39.   delayMicroseconds(CLOCK_HHOLD);
  40.   digitalWrite(ICSPDAT,LOW);
  41.   delayMicroseconds(CLOCK_HHOLD);
  42.   digitalWrite(ICSPCLK,LOW);
  43.   delayMicroseconds(CLOCK_LHOLD);
  44. }
  45. void (*func[32])(void);
  46. void dummy(){
  47.   delayMicroseconds(1);
  48. }
  49. void picSendCommand(uint8_t sendData){
  50.   pinMode(ICSPDAT,OUTPUT);
  51.   pinMode(ICSPCLK,OUTPUT);
  52.   for(int i=0;i<6;i++){
  53.     if(sendData&0x01){
  54.       func[i]=picSendCommandH;
  55.     }else{
  56.       func[i]=picSendCommandL;
  57.     }
  58.     sendData=sendData>>1;
  59.   }
  60.   for(int i=0;i<6;i++){
  61.     (*func[i])();
  62.   }
  63.   digitalWrite(ICSPDAT,LOW);
  64. }
  65. void picSendData(uint16_t sendData,uint8_t bit_length_to_send){
  66.   pinMode(ICSPDAT,OUTPUT);
  67.   pinMode(ICSPCLK,OUTPUT);
  68.   for(int i=0;i<bit_length_to_send;i++){
  69.     if(sendData&0x01){
  70.       func[i]=picSendDataH;
  71.     }else{
  72.       func[i]=picSendDataL;
  73.     }
  74.     sendData=sendData>>1;
  75.   }
  76.   for(int i=0;i<bit_length_to_send;i++){
  77.     (*func[i])();
  78.   }
  79.   digitalWrite(ICSPDAT,LOW);
  80. }
  81. uint16_t picRecv(uint8_t bit_length_to_receive){
  82.   uint16_t rcv;
  83.   pinMode(ICSPDAT,INPUT);
  84.   pinMode(ICSPCLK,OUTPUT);
  85.   rcv=0x0000;
  86.   for(int i=0;i<bit_length_to_receive;i++){
  87.     rcv=rcv<<1;
  88.     digitalWrite(ICSPCLK,HIGH);
  89.     delayMicroseconds(CLOCK_HHOLD);
  90.     digitalWrite(ICSPCLK,LOW);
  91.     if(digitalRead(ICSPDAT)){
  92.       rcv|=0x01;
  93.     }else{
  94.       rcv&=0xFE;
  95.     }
  96.     delayMicroseconds(CLOCK_LHOLD);
  97.   }
  98.   return rcv;
  99. }
  100.   
  101. void LOAD_CONFIGURATION(){
  102.   picSendCommand(0x00);
  103.   delayMicroseconds(TDLY);
  104.   picSendData(0x7FFE,16);
  105.   delayMicroseconds(TDLY);
  106. }
  107. uint16_t READ_DATA_FROM_PROGRAM_MEMORY(){
  108.   picSendCommand(0x04);
  109.   delayMicroseconds(TDLY);
  110.   return picRecv(16);
  111. }
  112. uint16_t READ_DATA_FROM_DATA_MEMORY(){
  113.   picSendCommand(0x05);
  114.   delayMicroseconds(TDLY);
  115.   return picRecv(16);
  116. }
  117. void INCREMENT_ADDRESS(){
  118.   picSendCommand(0x06);
  119.   delayMicroseconds(TDLY);
  120. }
  121. void PROGRAMMING_MODE_ENTRY_VDD_FIRST(){
  122.   pinMode(ICSPDAT,OUTPUT);
  123.   pinMode(ICSPCLK,OUTPUT);
  124.   pinMode(MCLR,OUTPUT);
  125.   pinMode(VDD,OUTPUT);
  126.   digitalWrite(ICSPDAT,LOW);
  127.   digitalWrite(ICSPCLK,LOW);
  128.   digitalWrite(MCLR,LOW);
  129.   digitalWrite(VDD,LOW);
  130.   delayMicroseconds(TENTS);
  131.   digitalWrite(MCLR,HIGH);
  132.   delayMicroseconds(TENTH);
  133. }
  134. void PROGRAMMING_MODE_ENTRY_VPP_FIRST(){
  135.   pinMode(ICSPDAT,OUTPUT);
  136.   pinMode(ICSPCLK,OUTPUT);
  137.   pinMode(MCLR,OUTPUT);
  138.   pinMode(VDD,OUTPUT);
  139.   digitalWrite(ICSPDAT,LOW);
  140.   digitalWrite(ICSPCLK,LOW);
  141.   digitalWrite(MCLR,LOW);
  142.   digitalWrite(VDD,HIGH);
  143.   delayMicroseconds(100);
  144.   digitalWrite(MCLR,HIGH);
  145.   delayMicroseconds(TENTS);
  146.   digitalWrite(VDD,LOW);
  147.   delayMicroseconds(TENTH);
  148. }
  149. void PROGRAMMING_MODE_EXIT_VDD_FIRST(){
  150.   pinMode(ICSPDAT,OUTPUT);
  151.   pinMode(ICSPCLK,OUTPUT);
  152.   pinMode(MCLR,OUTPUT);
  153.   digitalWrite(ICSPDAT,LOW);
  154.   digitalWrite(ICSPCLK,LOW);
  155.   digitalWrite(MCLR,LOW);
  156.   delayMicroseconds(TEXIT);
  157. }
  158. void PROGRAMMING_MODE_EXIT_VPP_FIRST(){
  159.   pinMode(ICSPDAT,OUTPUT);
  160.   pinMode(ICSPCLK,OUTPUT);
  161.   pinMode(VDD,OUTPUT);
  162.   pinMode(MCLR,OUTPUT);
  163.   digitalWrite(ICSPDAT,LOW);
  164.   digitalWrite(ICSPCLK,LOW);
  165.   digitalWrite(VDD,HIGH);
  166.   delayMicroseconds(TEXIT);
  167.   digitalWrite(MCLR,LOW);
  168. }
  169. void setup() {
  170.   for(int i=0;i<32;i++){
  171.     func[i]=dummy;
  172.   }
  173.   pinMode(VDD,OUTPUT);
  174.   digitalWrite(VDD,HIGH);
  175.   delay(200);
  176.   PROGRAMMING_MODE_ENTRY_VDD_FIRST();
  177.   delay(20);
  178.   LOAD_CONFIGURATION();
  179.   READ_DATA_FROM_DATA_MEMORY();
  180.   for(int i=0;i<16;i++){
  181.     INCREMENT_ADDRESS();
  182.     READ_DATA_FROM_DATA_MEMORY();
  183.   }
  184.   PROGRAMMING_MODE_EXIT_VDD_FIRST();
  185.   pinMode(VDD,OUTPUT);
  186.   digitalWrite(VDD,HIGH);
  187.   pinMode(ICSPDAT,INPUT);
  188.   pinMode(ICSPCLK,INPUT);
  189. }
  190. void loop() {
  191. }

あいかわらず、コメントなしの不親切なコードです。まぁプロじゃないので。