/// <summary> /// Enter ICSP mode. /// </summary> public void EnterICSP() { // // get the size of the internal buffer // CommResponse rsp = this.comm.SendCommand(JappCommand.GET_BUFFER_LEN); Debug.Assert(rsp.Data.Length == 1); this.internalBufferSize = rsp.Data[0]; // // initialize programmer state to known values // this.comm.SendCommand(JappCommand.PP_CMD_INIT); // // set Vpp to Vss for about 100ms, then send a 500us pulse on Vpp and // start clocking in the ENTER ICSP sequence and pull Vpp to Vdd. // // The PP_CMD_HOLD_IN_RESET command is used to pull Vpp down, then // we use PP_CMD_PULSE_VPP_US command to send the 500us pulse through // Vpp (the argument is the # of uSecs in unsigned 16-bit little-endian // format). Then we use PP_CMD_RELEASE_FROM_RESET command to pull Vpp // to Vdd. The timing of the 100ms delay is not important so we can just // use .Net's Thread.Sleep method. // this.comm.SendCommand(JappCommand.HOLD_ON_RESET); Thread.Sleep(100); this.comm.SendCommand(JappCommand.PULSE_VPP, 0xF4, 0x01); // // a 1us minimun delay is required before clocking the ICSP sequence, communications // delay may take care of this but since there's no maximun where just going to wait // 1ms before sending the command // Thread.Sleep(1); this.comm.SendCommand(JappCommand.WRITE, 0x4D, 0x43, 0x48, 0x51); this.comm.SendCommand(JappCommand.RELEASE_FROM_RESET); // // wait at least 25ms before presenting data on PGD // Thread.Sleep(25); // // send 5 clock cycles on PGC before 1st SIX instruction // this.comm.SendCommand(JappCommand.PP_CMD_SEND_PGD_CYCLES, 0x05); // // set the IsICSP mode property // this.IsICSPMode = true; }
/// <summary> /// Sends a command with arguments to the programmer. /// </summary> /// <param name="command">The command to send.</param> /// <param name="arguments">The command argumments or data.</param> /// <returns></returns> public CommResponse SendCommand(JappCommand command, params byte[] arguments) { byte len; CommResponse response = new CommResponse(); try { if (arguments.Count() > 0) { // // make sure the command is not too big // Debug.Assert(arguments.Count() <= 0xFFU - 0x2U); // // prepare the command // byte[] cmd = new byte[arguments.Count() + 2]; cmd[0] = (byte)((int)command); cmd[1] = (byte)arguments.Count(); for (int i = 0; i < arguments.Count(); i++) { cmd[i + 2] = arguments[i]; } // // discard input buffer // //this.serialPort.DiscardInBuffer(); // // send the command // this.serialPort.Write(cmd, 0, cmd.Count()); //for (int i = 0; i < cmd.Count(); i++) // this.serialPort.Write(new byte[] { cmd[i] }, 0, 1); } else { // // send the command without arguments // this.serialPort.Write(new byte[] { (byte)((int)command) }, 0, 1); } //Thread.Sleep(1); // // wait for the response // while (this.serialPort.BytesToRead == 0) { ; } response.Response = (JappResponse)this.serialPort.ReadByte(); // // get the 2nd byte of the response. This byte indicates the length // of the rest of the message so we also initialize response.Data to // an array of this length // len = (byte)this.serialPort.ReadByte(); response.Data = new byte[len]; // // if there's any data in the response then copy it to the // Data array // for (int i = 0; i < len; i++) { while (this.serialPort.BytesToRead == 0) { ; // spin cpu until we got bytes to read } response.Data[i] = (byte)this.serialPort.ReadByte(); } // // discard any data left in buffer // this.serialPort.DiscardInBuffer(); } catch (TimeoutException) { throw new CommTimeoutException(); } catch (ThreadAbortException) { throw; } catch (Exception ex) { throw new CommException(ex); } finally { } // // return the response // return(response); }
protected override byte[] ReadProgramMemoryICSP(uint address, uint length) { int i = 0; byte[] pwords = new byte[length * 3]; // // while there's more than 4 words of memory left to read // we'll read them 1 word at a time. // while (length > 4) { // // ; copy 1st LSW to VISI // // mov w0, VISI // 883C20 // nop // 000000 // this.ExecuteInstructions ( // // ;exit reset vector // 0x040200, // goto 0x200 // 040200 0x040200, // goto 0x200 // 040200 0x000000, // nop // 000000 // // ;initialize pointers // 0x200000 | ((address >> 16) << 4), // mov devid<23:16>, w0 // 200xx0 0x880190, // mov w0, TBLPAG // 880190 0x200006 | ((address & 0x0000FFFF) << 4), // mov DEVID<16:0>, w6 // 2xxxx6 0xEB0380, // clr w7 // EB0380 0x000000, // nop // 000000 // // ;ready program memory and pack it into registers w0:w6 // 0xBA1B96, // tblrdl [w6], [w7++] // BA1B96 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBADBB6, // tblrdh.b [w6++], [w7++] // BADBB6 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBADBD6, // tblrdh.b [++w6], [w7++] // BADBD6 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBA1BB6, // tblrdl [w6++], [w7++] // BA1BB6 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBA1B96, // tblrdl [w6], [w7++] // BA1B96 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBADBB6, // tblrdh.b [w6++], [w7++] // BADBB6 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBADBD6, // tblrdh.b [++w6], [w7++] // BADBD6 0x000000, // nop // 000000 0x000000, // nop // 000000 0xBA0BB6, // tblrdl [w6++], [w7] // BA0BB6 0x000000, // nop // 000000 0x000000, // nop // 000000 // // ; copy 1st LSW to VISI // 0x883C20, // mov w0, VISI // 883C20 0x000000 // nop // 000000 ); // // read VISI // this.ReadVISIToBuffer(); // // ;copy w1 to VISI // this.ExecuteInstructions ( 0x000000, // nop // 000000 0x883C21, // mov w1, VISI // 883C21 0x000000, // nop // 000000 0x000000 // nop ;padding // 000000 ); // // read visi // this.ReadVISIToBuffer(); // // copy w2 to visi // this.ExecuteInstructions ( 0x000000, // nop // 000000 0x883C22, // mov w2, VISI // 883C22 0x000000, // nop // 000000 0x000000 // nop ;padding // 000000 ); // // read VISI // this.ReadVISIToBuffer(); // // copy w3 to VISI // this.ExecuteInstructions ( 0x000000, // nop // 000000 0x883C23, // mov w3, VISI // 883C23 0x000000, // nop // 000000 0x000000 // nop ;padding // 000000 ); // // read VISI // this.ReadVISIToBuffer(); // // copy w4 to visi // this.ExecuteInstructions ( 0x000000, // nop // 000000 0x883C24, // mov w4, VISI // 883C24 0x000000, // nop // 000000 0x000000 // nop ;padding // 000000 ); // // read visi // this.ReadVISIToBuffer(); // // copy w5 to VISI // this.ExecuteInstructions ( 0x000000, // nop // 000000 0x883C25, // mov w5, VISI // 883C25 0x000000, // nop // 000000 0x000000 // nop ;padding // 000000 ); // // read VISI // this.ReadVISIToBuffer(); // // send commmand to read buffer // CommResponse rsp = this.comm.SendCommand(JappCommand.READ_BUFFER); Debug.Assert(rsp.Response == JappResponse.ACK && rsp.Data.Length == 12); // // read the instructions // pwords[(i * 4 * 3) + 00] = rsp.Data[00]; pwords[(i * 4 * 3) + 01] = rsp.Data[01]; pwords[(i * 4 * 3) + 02] = rsp.Data[02]; pwords[(i * 4 * 3) + 05] = rsp.Data[03]; pwords[(i * 4 * 3) + 03] = rsp.Data[04]; pwords[(i * 4 * 3) + 04] = rsp.Data[05]; pwords[(i * 4 * 3) + 06] = rsp.Data[06]; pwords[(i * 4 * 3) + 07] = rsp.Data[07]; pwords[(i * 4 * 3) + 08] = rsp.Data[08]; pwords[(i * 4 * 3) + 11] = rsp.Data[09]; pwords[(i * 4 * 3) + 09] = rsp.Data[10]; pwords[(i * 4 * 3) + 10] = rsp.Data[11]; // // increase the address by 4 words and the "round counter" by 1 // address += (4 * 2); length -= 4; i++; } // // convert i to a byte index; // i = i * 4 * 3; // // if we still got any words left to read we'll read them one by one // while (length > 0) { // // read the next word // byte[] pword = this.ReadProgramWord(address); // // copy it's bytes // pwords[i++] = pword[0]; pwords[i++] = pword[1]; pwords[i++] = pword[2]; // // decrement length and increment address // length--; address++; } // // return program memory buffer // return(pwords); }