summaryrefslogtreecommitdiffstats
path: root/libtoprammer/chips
diff options
context:
space:
mode:
authorPavel Štemberk <stemberk@gmail.com>2012-10-16 19:23:58 +0200
committerMichael Buesch <m@bues.ch>2012-10-16 19:23:58 +0200
commit36bb738db5a08c9d83b0c741993082defb46075d (patch)
tree29a329dc0d053ce136ceedee05e5113c72335846 /libtoprammer/chips
parentae9fd6f14ee487d43c4cc070b6d051ae5d2611f8 (diff)
downloadtoprammer-36bb738db5a08c9d83b0c741993082defb46075d.tar.xz
toprammer-36bb738db5a08c9d83b0c741993082defb46075d.zip
Add PIC10F20X support
Signed-off-by: Michael Buesch <m@bues.ch>
Diffstat (limited to 'libtoprammer/chips')
-rw-r--r--libtoprammer/chips/__init__.py7
-rw-r--r--libtoprammer/chips/microchip_common.py353
-rw-r--r--libtoprammer/chips/pic10f200dip8.py60
-rw-r--r--libtoprammer/chips/pic10f202dip8.py59
4 files changed, 477 insertions, 2 deletions
diff --git a/libtoprammer/chips/__init__.py b/libtoprammer/chips/__init__.py
index e43bd7c..a90351b 100644
--- a/libtoprammer/chips/__init__.py
+++ b/libtoprammer/chips/__init__.py
@@ -1,14 +1,17 @@
-# Import all chip modules in alphabetical order
+# Import all chip modules in **ALPHABETICAL** order
+
from _27cxxx import *
from _74hc4094 import *
from at89c2051dip20 import *
from atmega32dip40 import *
-from atmega8dip28 import *
from atmega88dip28 import *
+from atmega8dip28 import *
from attiny13dip8 import *
from attiny26dip20 import *
from hm62256dip28 import *
from m24cxxdip8 import *
from m8cissp import *
+from pic10f200dip8 import *
+from pic10f202dip8 import *
from unitest import *
from w29ee011dip32 import *
diff --git a/libtoprammer/chips/microchip_common.py b/libtoprammer/chips/microchip_common.py
new file mode 100644
index 0000000..db05cb8
--- /dev/null
+++ b/libtoprammer/chips/microchip_common.py
@@ -0,0 +1,353 @@
+"""
+# TOP2049 Open Source programming suite
+#
+# Microchip common
+#
+# Copyright (c) 2012 Pavel Stemberk <stemberk@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""
+
+from libtoprammer.chip import *
+
+class Chip_Microchip_common(Chip):
+ CMD_LOAD_DATA_FOR_PGM = 0x02
+ CMD_READ_DATA_FROM_PGM = 0x04
+ CMD_INCREMENT_ADDRESS = 0x06
+ CMD_BEGIN_PROGRAMMING = 0x08
+ CMD_END_PROGRAMMING = 0x0E
+ CMD_BULK_ERASE_PGM = 0x09
+
+ PROGCMD_SENDINSTR = 1
+ PROGCMD_SENDDATA = 2
+ PROGCMD_READDATA = 3
+
+ STAT_BUSY= 0x01
+ STAT_SDIO = 0x02
+
+ def __init__(self,
+ chipPackage, chipPinVCC, chipPinsVPP, chipPinGND,
+ signature,
+ flashPageSize, flashPages,
+ eepromPageSize, eepromPages,
+ fuseBytes
+ ):
+ Chip.__init__(self,
+ chipPackage = chipPackage,
+ chipPinVCC = chipPinVCC,
+ chipPinsVPP = chipPinsVPP,
+ chipPinGND = chipPinGND)
+ self.signature = signature
+ self.flashPageSize = flashPageSize # Flash page size, in words
+ self.flashPages = flashPages # Nr of flash pages
+ self.eepromPageSize = eepromPageSize # EEPROM page size, in bytes
+ self.eepromPages = eepromPages # Nr of EEPROM pages
+ self.fuseBytes = fuseBytes # Nr of fuse bytes
+ self.PC=0
+
+
+ def readSignature(self):
+ self.progressMeterInit("Reading signature", 0)
+ signature = self.__readSignature()
+ self.progressMeterFinish()
+ return signature
+
+ def erase(self):
+ self.__erase()
+
+ def __erase(self, keepConfigWord=False):
+ OSCCAL = 0xfff
+ if(keepConfigWord):
+ self.progressMeterInit("Reading ConfigWord for backup", 0)
+ CW = self.__getConfigWord()
+ self.progressMeterFinish()
+ self.__enterPM()
+ self.progressMeterInit("Reading OSCCAL)", 0)
+ self.__setPC(self.osccalAddr)
+ self.__sendReadFlashInstr()
+ self.top.cmdDelay(0.00005)
+ self.__readSDOBufferLow()
+ self.__readSDOBufferHigh()
+ OSCCAL=self.top.cmdReadBufferReg16()
+ self.progressMeterFinish()
+ if(OSCCAL == 0xfff):
+ self.progressMeterInit("OSCCAL value lost, restoring from backup location ...", 0)
+ self.__setPC(self.osccalBackupAddr-self.osccalAddr)
+ self.__sendReadFlashInstr()
+ self.top.cmdDelay(0.00005)
+ self.__readSDOBufferLow()
+ self.__readSDOBufferHigh()
+ OSCCAL=self.top.cmdReadBufferReg16()
+ self.progressMeterFinish()
+ #print ("osccal: %x\n" % OSCCAL)
+ self.progressMeterInit("Erasing chip", 0)
+ self.__sendInstr(self.CMD_BULK_ERASE_PGM)
+ self.top.hostDelay(0.01) #Tera
+ self.progressMeterFinish()
+ #OSCCAL=0xC18
+ if(OSCCAL != 0xfff):
+ self.__enterPM()
+ self.progressMeterInit("Writing osccal, value %x" % OSCCAL, 0)
+ self.__setPC(self.osccalAddr)
+ self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM)
+ self.__setSDI(OSCCAL)
+ self.top.hostDelay(0.000005)
+ self.__sendWriteFlashInstr()
+ self.progressMeterFinish()
+ if(keepConfigWord):
+ self.progressMeterInit("Write read ConfigWord, value %x" % CW, 0)
+ self.__writeConfigWord(CW)
+ self.progressMeterFinish()
+
+
+ def readProgmem(self):
+ nrWords = self.flashPages * self.flashPageSize
+ image = ""
+ self.__enterPM()
+ self.progressMeterInit("Reading flash", nrWords)
+ bufferedBytes = 0
+ for word in range(0, nrWords):
+ self.__incrementPC(1)
+ self.__sendReadFlashInstr()
+ #self.__busyWait()
+ self.top.cmdDelay(0.00002) #20us wait - inconsistent data if skipped
+ self.__readSDOBufferLow()
+ bufferedBytes += 1
+ self.__readSDOBufferHigh()
+ bufferedBytes += 1
+ if bufferedBytes == self.top.getBufferRegSize():
+ image += self.top.cmdReadBufferReg(bufferedBytes)
+ self.progressMeter(word)
+ bufferedBytes = 0
+ image += self.top.cmdReadBufferReg(bufferedBytes)
+ self.progressMeterFinish()
+ return image
+
+ def writeProgmem(self, image):
+ nrWords = self.flashPages * self.flashPageSize
+ if len(image) > nrWords * 2 or len(image) % 2 != 0:
+ self.throwError("Invalid flash image size %d (expected <=%d and word aligned)" %\
+ (len(image), nrWords * 2))
+ self.__enterPM()
+ self.progressMeterInit("Writing flash", len(image) // 2)
+ for word in range(0, len(image) // 2):
+ self.progressMeter(word)
+ #do not swap following two lines
+ self.__incrementPC(1)
+ self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM)
+ WD = (byte2int(image[word * 2 + 1])<<8) | byte2int(image[word * 2 + 0])
+ if(WD != 0xfff):
+ self.__setSDI(WD)
+ self.top.hostDelay(0.00002)
+ self.__sendWriteFlashInstr()
+
+ self.progressMeterFinish()
+
+ def readFuse(self):
+ fuses = []
+ self.progressMeterInit("Reading fuses (configuration word)", 0)
+ CW = self.__getConfigWord()
+ fuses.append(int2byte(CW & 0x00ff))
+ fuses.append(int2byte((CW >> 8) & 0x00ff))
+ self.progressMeterFinish()
+ return b"".join(fuses)
+
+ def __getConfigWord(self):
+ self.__enterPM()
+ self.__setPC(self.configWordAddr)
+ self.__sendReadFlashInstr()
+ self.top.cmdDelay(0.00002)
+ self.__readSDOBufferLow()
+ self.__readSDOBufferHigh()
+ return self.top.cmdReadBufferReg16()
+
+ def writeFuse(self, image):
+ if len(image) != 2:
+ self.throwError("Invalid Fuses image size %d (expected %d)" %\
+ (len(image), 2))
+ self.progressMeterInit("Writing fuses", 0)
+ #print "image1:%x,,%x,,%x" % (byte2int(image[0]),byte2int(image[1]),byte2int(image[1])<<8)
+ self.__writeConfigWord((byte2int(image[1])<<8) | byte2int(image[0]))
+ self.progressMeterFinish()
+
+ def __writeConfigWord(self, configWord16):
+ self.__enterPM()
+ self.__setPC(self.configWordAddr)
+ self.__sendInstr(self.CMD_LOAD_DATA_FOR_PGM)
+ self.__setSDI(configWord16)
+ self.top.hostDelay(0.00002)
+ self.__sendWriteFlashInstr()
+
+ def __readSignature(self):
+ self.__enterPM()
+ self.__incrementPC(self.userIDLocationAddr)
+ for i in range(0, self.userIDLocationSize):
+ self.__incrementPC(1)
+ self.__sendReadFlashInstr()
+ self.top.hostDelay(0.00002)
+ self.__readSDOBufferLow()
+ self.__readSDOBufferHigh()
+ return self.top.cmdReadBufferReg()[0:2*self.userIDLocationSize-1]
+
+ def __enterPM(self):
+ self.PC = self.logicalFlashSize - 1
+ "Enter HV programming mode. Vdd first entry mode"
+ self.applyVCC(False)
+ self.applyVPP(False)
+ self.applyGND(False)
+ self.__setPins(0,0)
+ self.top.cmdSetVCCVoltage(self.voltageVDD)
+ self.top.cmdSetVPPVoltage(self.voltageVPP)
+ #self.top.cmdEnableZifPullups(True)
+ self.applyGND(True)
+
+ self.applyVCC(True)
+ self.top.cmdDelay(0.000005)
+
+ for i in range(0,2):
+ self.applyVPP(True)
+ self.top.cmdDelay(0.000005)
+ self.applyVPP(False)
+ self.top.cmdDelay(0.000031)
+ self.applyVPP(True)
+ #self.top.cmdEnableZifPullups(True)
+
+ self.top.cmdDelay(0.000005) #least 5us is required to reach Vdd first entry PM
+
+ def __checkSignature(self):
+ signature = self.__readSignature()
+ if signature != self.signature:
+ msg = "Unexpected device signature. " +\
+ "Want %02X%02X%02X, but got %02X%02X%02X" % \
+ (byte2int(self.signature[0]), byte2int(self.signature[1]),
+ byte2int(self.signature[2]),
+ byte2int(signature[0]), byte2int(signature[1]),
+ byte2int(signature[2]))
+ if self.top.getForceLevel() >= 1:
+ self.printWarning(msg)
+ else:
+ self.throwError(msg)
+
+ def __exitPM(self):
+ "Exit HV programming mode. Vdd last exit mode"
+ self.__setPins(0,0)
+ self.applyVPP(False)
+ self.applyGND(False)
+ self.top.hostDelay(0.000005)
+ self.applyVCC(False)
+
+ def __sendReadFlashInstr(self):
+ '''
+ '''
+ self.__sendInstr(self.CMD_READ_DATA_FROM_PGM)
+ self.__loadCommand(self.PROGCMD_READDATA)
+
+ def __sendWriteFlashInstr(self):
+ '''
+ '''
+ self.__loadCommand(self.PROGCMD_SENDDATA)
+ self.top.hostDelay(0.000005)
+ self.__sendInstr(self.CMD_BEGIN_PROGRAMMING)
+ self.top.hostDelay(0.001)#025) #Tprog
+ self.__sendInstr(self.CMD_END_PROGRAMMING)
+ self.top.hostDelay(0.0001) #Tdis
+
+ def __sendInstr(self, SDI):
+ '''
+ see __loadCommand for availabla commands
+ '''
+ self.top.cmdFPGAWrite(0x13, SDI & 0xFF)
+ self.__loadCommand(self.PROGCMD_SENDINSTR)
+ # We do not poll the busy flag, because that would result
+ # in a significant slowdown. We delay long enough for the
+ # command to finish execution, instead.
+ #self.top.hostDelay(0.001)
+ self.top.hostDelay(0.000005)
+
+ def __setSDI(self, sdi):
+ '''
+ set 14 bit sdi value
+ '''
+ self.top.cmdFPGAWrite(0x13, sdi & 0xFF)
+ self.top.cmdFPGAWrite(0x14, (sdi>>8) & 0x0F)
+
+ def __loadCommand(self, command):
+ '''
+ `define CMD_SENDINSTR 1
+ `define CMD_SENDDATA 2
+ `define CMD_READDATA 3
+ '''
+ self.top.cmdFPGAWrite(0x12, command & 0xFF)
+
+ def __runCommandSync(self, command):
+ self.__loadCommand(command)
+ self.__busyWait()
+
+ def __setPC(self, address):
+ while(self.PC!=address):
+ self.__incrementPC(1)
+
+ def __incrementPC(self, count):
+ for address in range(0, count):
+ self.__sendInstr(self.CMD_INCREMENT_ADDRESS)
+ self.PC += 1
+ if (self.PC == self.logicalFlashSize):
+ self.PC = 0
+
+ def __setPins(self, ICSPCLK=0, SDIODRIVEN=0, SDIOVALUE=0):
+ '''
+ setPins
+ '''
+ data = 0
+ if ICSPCLK:
+ data |= 1
+ if SDIODRIVEN:
+ data |= 2
+ if SDIOVALUE:
+ data |= 4
+ self.top.cmdFPGAWrite(0x15, data)
+
+ def __getStatusFlags(self):
+ '''
+ '''
+ self.top.cmdFPGARead(0x12)
+ stat = self.top.cmdReadBufferReg()
+ return byte2int(stat[0])
+
+ def __readSDOBufferHigh(self):
+ self.top.cmdFPGARead(0x10)
+
+ def __readSDOBufferLow(self):
+ self.top.cmdFPGARead(0x13)
+
+ def __rawSDIOState(self):
+ return bool(self.__getStatusFlags() & self.STAT_SDIO)
+
+ def __busy(self):
+ return bool(self.__getStatusFlags() & self.STAT_BUSY)
+
+ def __busyWait(self):
+ for i in range(0, 100):
+ if not self.__busy():
+ return
+ self.top.hostDelay(0.01)
+ self.throwError("Timeout in busywait.")
+
+ def __waitHighSDIO(self):
+ for i in range(0, 100):
+ if self.__rawSDOState():
+ return
+ self.top.hostDelay(0.01)
+ self.throwError("Timeout waiting for SDO.")
diff --git a/libtoprammer/chips/pic10f200dip8.py b/libtoprammer/chips/pic10f200dip8.py
new file mode 100644
index 0000000..1b434ee
--- /dev/null
+++ b/libtoprammer/chips/pic10f200dip8.py
@@ -0,0 +1,60 @@
+"""
+# TOP2049 Open Source programming suite
+#
+# Microchip PIC10F200, PIC10F204 and PI10f220 DIP8
+#
+# Copyright (c) 2012 Pavel Stemberk <stemberk@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""
+
+from microchip_common import *
+
+
+class Chip_Pic18F200dip8(Chip_Microchip_common):
+ voltageVDD = 5
+ voltageVPP =13
+ #CONFIGURATION WORD FOR PIC10F200/202/204/206
+ #X X X X X X X MCLRE /CP WDT X X
+ logicalFlashSize = 0x200
+ userIDLocationSize = 4
+
+ def __init__(self):
+ Chip_Microchip_common.__init__(self,
+ chipPackage = "DIP8",
+ chipPinVCC = 2,
+ chipPinsVPP = 8,
+ chipPinGND = 7,
+ signature = "\x09\x18\x24\x35",
+ flashPageSize = 0x100,
+ flashPages = 1,
+ eepromPageSize = 0,
+ eepromPages = 0,
+ fuseBytes = 2
+ )
+ self.configWordAddr = self.logicalFlashSize-1
+ self.osccalAddr = self.flashPageSize-1
+ self.userIDLocationAddr = self.flashPageSize
+ self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize
+
+ChipDescription(
+ Chip_Pic18F200dip8,
+ bitfile = "pic10fXXXdip8",
+ chipID = "pic10f200dip8",
+ runtimeID = (0x0001, 0x01),
+ chipVendors = "Microchip",
+ description = "PIC10F200, PIC10F204, PIC10F220",
+ packages = ( ("DIP8", ""), ),
+)
diff --git a/libtoprammer/chips/pic10f202dip8.py b/libtoprammer/chips/pic10f202dip8.py
new file mode 100644
index 0000000..88e1672
--- /dev/null
+++ b/libtoprammer/chips/pic10f202dip8.py
@@ -0,0 +1,59 @@
+"""
+# TOP2049 Open Source programming suite
+#
+# Microchip PIC10F202, PIC10F206 and PIC10f222 DIP8
+#
+# Copyright (c) 2012 Pavel Stemberk <stemberk@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""
+
+from microchip_common import *
+
+class Chip_Pic18F202dip8(Chip_Microchip_common):
+ voltageVDD = 5
+ voltageVPP = 13
+ #CONFIGURATION WORD FOR PIC10F200/202/204/206
+ #X X X X X X X MCLRE /CP WDT X X
+ logicalFlashSize = 0x400
+ userIDLocationSize = 4
+
+ def __init__(self):
+ Chip_Microchip_common.__init__(self,
+ chipPackage="DIP8",
+ chipPinVCC=2,
+ chipPinsVPP=8,
+ chipPinGND=7,
+ signature="\x09\x18\x24\x35",
+ flashPageSize=0x200,
+ flashPages=1,
+ eepromPageSize=0,
+ eepromPages=0,
+ fuseBytes=2
+ )
+ self.configWordAddr = self.logicalFlashSize - 1
+ self.osccalAddr = self.flashPageSize - 1
+ self.userIDLocationAddr = self.flashPageSize
+ self.osccalBackupAddr = self.userIDLocationAddr + self.userIDLocationSize
+
+ChipDescription(
+ Chip_Pic18F202dip8,
+ bitfile="pic10fXXXdip8",
+ chipID = "pic10f202dip8",
+ runtimeID=(0x0001, 0x01),
+ chipVendors="Microchip",
+ description="PIC10F202, PIC10F206, PIC10F222",
+ packages=(("DIP8", ""),),
+)
bues.ch cgit interface