├── .gitignore ├── Makefile ├── README.md ├── TODO ├── arduino_hssp.ino ├── issp_defs.h ├── issp_delays.h ├── issp_driver_routines.cpp ├── issp_errors.h ├── issp_extern.h ├── issp_routines.cpp ├── issp_vectors.h └── stk500_protocol.h /.gitignore: -------------------------------------------------------------------------------- 1 | build-uno 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile 2 | 3 | ARDMK_DIR = /usr/share/arduino 4 | 5 | 6 | # if you have placed the alternate core in your sketchbook directory, then you can just mention the core name alone. 7 | ALTERNATE_CORE = attiny 8 | # If not, you might have to include the full path. 9 | ALTERNATE_CORE_PATH = /usr/share/arduino/hardware/arduino/ 10 | 11 | BOARD_TAG = uno 12 | ISP_PORT = /dev/ttyACM* 13 | 14 | include $(ARDMK_DIR)/Arduino.mk 15 | 16 | # !!! Important. You have to use make ispload to upload when using ISP programmer 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # arduino_hssp 2 | Cypress PSoC® 1 Device hacking using an Arduino 3 | 4 | This is a fork of the [original port](https://github.com/miracoli/arduino_hssp) 5 | of the code found at (AN44168, Revision 6 | 2.30) to the Arduino platform by Dirk Petrautzki. 7 | 8 | Besides implementing the standard commands for flashing a PSoC, it includes the 9 | following extra commands: 10 | * `Cmnd_STK_READ_REG 0x79` 11 | * `Cmnd_STK_WRITE_REG 0x80` 12 | * `Cmnd_STK_READ_MEM 0x81` 13 | * `Cmnd_STK_WRITE_MEM 0x82` 14 | * `Cmnd_STK_EXEC_OPCODES 0x83` 15 | * `Cmnd_STK_RUN_CSUM 0x84` 16 | * `Cmnd_STK_START_CSUM 0x85` 17 | * `Cmnd_STK_READ_SECURITY 0x86` 18 | 19 | Which are very helpful to dump the protected flash of the PSoC. 20 | 21 | ## Usage 22 | 23 | Clone the code into a folder called 'arduino_hssp', run `make && make_upload` 24 | 25 | Connect your PSoC 1 device as follows 26 | (can be changed in issp_defs.h): 27 | 28 | * `SDATA_PIN` -> 9 29 | * `SCLK_PIN` -> 8 30 | * `XRES_PIN` -> 4 31 | * `TARGET_VDD` -> 11 32 | 33 | Run the code and check serial output. 34 | 35 | ## Project status 36 | Tested and working with Arduino Uno and CY8C21434. 37 | 38 | ## Example hack 39 | 40 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - Add support for programming/verifying flash security data 2 | - Clean things up 3 | - Add comments 4 | - Add support for multi bank programming (need a multi bank device first) 5 | -------------------------------------------------------------------------------- /arduino_hssp.ino: -------------------------------------------------------------------------------- 1 | /* Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //---------------------------------------------------------------------------*/ 33 | 34 | /* ############################################################################ 35 | ################### CRITICAL PROJECT CONSTRAINTS ######################## 36 | ############################################################################ 37 | 38 | ISSP programming can only occur within a temperature range of 5C to 50C. 39 | - This project is written without temperature compensation and using 40 | programming pulse-widths that match those used by programmers such as the 41 | Mini-Prog and the ISSP Programmer. 42 | This means that the die temperature of the PSoC device cannot be outside 43 | of the above temperature range. 44 | If a wider temperature range is required, contact your Cypress Semi- 45 | conductor FAE or sales person for assistance. 46 | 47 | The project can be configured to program devices at 5V or at 3.3V. 48 | - Initialization of the device is different for different voltages. The 49 | initialization is hardcoded and can only be set for one voltage range. 50 | The supported voltages ranges are 3.3V (3.0V to 3.6V) and 5V (4.75V to 51 | 5.25V). See the device datasheet for more details. If varying voltage 52 | ranges must be supported, contact your Cypress Semiconductor FAE or sales 53 | person for assistance. 54 | - ISSP programming for the 2.7V range (2.7V to 3.0V) is not supported. 55 | 56 | This program does not support programming all PSoC Devices 57 | - It does not support obsoleted PSoC devices. A list of devices that are 58 | not supported is shown here: 59 | CY8C22x13 - not supported 60 | CY8C24x23 - not supported (CY8C24x23A is supported) 61 | CY8C24x33 - not supported 62 | CY8C25x43 - not supported 63 | CY8C26x43 - not supported 64 | 65 | - Note: There is another application note (AN59389) that supports HSSP programming 66 | for CY8C20xx6, CY8CTMG2xx, CY8CTST2xx. 67 | 68 | - It does not suport devices that have not been released for sale at the 69 | time this version was created. If you need to ISSP program a newly released 70 | device, please contact Cypress Semiconductor Applications, your FAE or 71 | sales person for assistance. 72 | The CY8C20x23 devices are not supported at the time of this release. 73 | 74 | ############################################################################ 75 | ##########################################################################*/ 76 | 77 | 78 | /* This program uses information found in Cypress Semiconductor application 79 | // notes "Programming - In-System Serial Programming Protocol", AN2026. The 80 | // version of this application note that applies to the specific PSoC that is 81 | // being In-System Serial Programmed should be read and and understood when 82 | // using this program. (http://www.cypress.com) 83 | 84 | // This project is included with releases of PSoC Programmer software. It is 85 | // important to confirm that the latest revision of this software is used when 86 | // it is used. The revision of this copy can be found in the Project History 87 | // table below. 88 | */ 89 | 90 | /*///////////////////////////////////////////////////////////////////////////// 91 | // PROJECT HISTORY 92 | // date revision author description 93 | // -------- -------- ------ ----------------------------------------------- 94 | // 95 | // 12/06/10 ?2.30? vvsk 1. Added support for CY8C21x45, CY8C22x45, CY8C23x33 96 | // 97 | // 2. Changed Revision to REV230 98 | // 99 | // xx/xx/10 ?2.20? xch 1. Added support for CY8C20x34, CY8CTST110, CY8CTST120, 100 | // CY8CTMG110, CY8CTMG120, CY8CTMA120, 101 | // 102 | // 2. Aligned the order of parameters for LoadProgramData 103 | // per CDT45137 104 | // 105 | // 3. Changed timing equation since CPU is now at 12MHz 106 | // instead of 24MHz. Equation is now 2x+7 was 1x+3 107 | // 108 | // 4. Changed Revision to REV220 109 | // 110 | // 02/09/09 2.12 fkl 1. Added vectors and constant defs for CY8C28xxx. 111 | // 112 | // 2. Changed constant definitions in files 113 | // issp_directives.h, issp_vectors.h and issp_defs.h. 114 | // 115 | // 3. Changed version number to REV212 116 | // 117 | // 09/23/07 2.11 dkn 1. Added searchable comments for the HSSP app note. 118 | // 119 | // 2. Added new device vectors. 120 | // 121 | // 3. Verified write and erase pulsewidths. 122 | // 123 | // 4. Modified some functions for easier porting to 124 | // other processors. 125 | // 126 | // 09/23/06 2.10 mwl 1. Added #define SECURITY_BYTES_PER_BANK to 127 | // file issp_defs.h. Modified function 128 | // fSecureTargetFlashMain() in issp_routines.c 129 | // to use new #define. Modified function 130 | // fLoadSecurityData() in issp_driver_routines.c 131 | // to accept a bank number. Modified the secure 132 | // data loop in main.c to program multiple banks. 133 | // 134 | // 2. Created function fAccTargetBankChecksum to 135 | // read and add the target bank checksum to the 136 | // referenced accumulator. This allows the 137 | // checksum loop in main.c to function at the 138 | // same level of abstraction as the other 139 | // programming steps. Accordingly, modified the 140 | // checksum loop in main.c. Deleted previous 141 | // function fVerifyTargetChecksum(). 142 | // 143 | // 09/08/06 2.00 mwl 1. Array variable abTargetDataOUT was not 144 | // getting intialized anywhere and compiled as a 145 | // one-byte array. Modified issp_driver_routines.c 146 | // line 44 to initialize with TARGET_DATABUFF_LEN. 147 | // 148 | // 2. Function void LoadProgramData(unsigned char 149 | // bBlockNum) in issp_driver_routines.c had only 150 | // one parameter bBlockNum but was being called 151 | // from function main() with two parameters, 152 | // LoadProgramData(bBankCounter, (unsigned char) 153 | // iBlockCounter). Modified function 154 | // LoadProgramData() to accept both parameters, 155 | // and in turn modified InitTargetTestData() to 156 | // accept and use both as well. 157 | // 158 | // 3. Corrected byte set_bank_number[1] 159 | // inissp_vectors.h. Was 0xF2, correct value is 160 | // 0xE2. 161 | // 162 | // 4. Corrected the logic to send the SET_BANK_NUM 163 | // vectors per the AN2026B flow chart.The previous 164 | // code version was sending once per block, but 165 | // should have been once per bank. Removed the 166 | // conditionally-compiled bank setting code blocks 167 | // from the top of fProgramTargetBlock() and 168 | // fVerifyTargetBlock() int issp_routines.c and 169 | // created a conditionally-compiled subroutine in 170 | // that same file called SetBankNumber(). Two 171 | // conditionally-compiled calls to SetBankNumber() 172 | // were added to main.c(). 173 | // 174 | // 5. Corrected CY8C29x66 NUM_BANKS and 175 | // BLOCKS_PER_BANK definitions in ISSP_Defs.h. 176 | // Was 2 and 256 respectively, correct values are 177 | // 4 and 128. 178 | // 179 | // 6. Modified function fVerifyTargetChecksum() 180 | // in issp_routines.c to read and accumulate multiple 181 | // banks of checksums as required for targets 182 | // CY8C24x94 and CY8C29x66. Would have kept same 183 | // level of abstraction as other multi-bank functions 184 | // in main.c, but this implementation impacted the 185 | // code the least. 186 | // 187 | // 7. Corrected byte checksum_v[26] of 188 | // CHECKSUM_SETUP_24_29 in issp_vectors.h. Was 0x02, 189 | // correct value is 0x04. 190 | // 191 | // 06/30/06 1.10 jvy Added support for 24x94 and 29x66 devices. 192 | // 06/09/06 1.00 jvy Changed CPU Clk to 12MHz (from 24MHz) so the 193 | // host can run from 3.3V. 194 | // Simplified init of security data. 195 | // 06/05/06 0.06 jvy Version #ifdef added to each file to make sure 196 | // all of the file are from the same revision. 197 | // Added flags to prevent multiple includes of H 198 | // files. 199 | // Changed pre-determined data for demo to be 200 | // unique for each block. 201 | // Changed block verify to check all blocks after 202 | // block programming has been completed. 203 | // Added SetSCLKHiZ to explicitly set the Clk to 204 | // HighZ before power cycle acquire. 205 | // Fixed wrong vectors in setting Security. 206 | // Fixed wrong vectors in Block program. 207 | // Added support for pods 208 | // 06/05/06 0.05 jvy Comments from code review. First copy checked 209 | // into perforce. Code has been updated enough to 210 | // compile, by implementing some comments and 211 | // fixing others. 212 | // 06/04/06 0.04 jvy made code more efficient in bReceiveByte(), and 213 | // SendVector() by re-arranging so that local vars 214 | // could be eliminated. 215 | // added defines for the delays used in the code. 216 | // 06/02/06 0.03 jvy added number of Flash block adjustment to 217 | // programming. added power cycle programming 218 | // mode support. This is the version initially 219 | // sent out for peer review. 220 | // 06/02/06 0.02 jvy added framework for multiple chip support from 221 | // one source code set using compiler directives. 222 | // added timeout to high-low trasition detection. 223 | // added multiple error message to allow tracking 224 | // of failures. 225 | // 05/30/06 0.01 jvy initial version, 226 | // created from DBD's issp_27xxx_v3 program. 227 | /////////////////////////////////////////////////////////////////////////////*/ 228 | 229 | /* (((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))) 230 | PSoC In-System Serial Programming (ISSP) Template 231 | This PSoC Project is designed to be used as a template for designs that 232 | require PSoC ISSP Functions. 233 | 234 | This project is based on the AN2026 series of Application Notes. That app 235 | note should be referenced before any modifications to this project are made. 236 | 237 | The subroutines and files were created in such a way as to allow easy cut & 238 | paste as needed. There are no customer-specific functions in this project. 239 | This demo of the code utilizes a PSoC as the Host. 240 | 241 | Some of the subroutines could be merged, or otherwise reduced, but they have 242 | been written as independently as possible so that the specific steps involved 243 | within each function can easily be seen. By merging things, some code-space 244 | savings could be realized. 245 | 246 | As is, and with all features enabled, the project consumes approximately 3500 247 | bytes of code space, and 19-Bytes of RAM (not including stack usage). The 248 | Block-Verify requires a 64-Byte buffer for read-back verification. This same 249 | buffer could be used to hold the (actual) incoming program data. 250 | 251 | Please refer to the compiler-directives file "directives.h" to see the various 252 | features. 253 | 254 | The pin used in this project are assigned as shown below. The HOST pins are 255 | arbitrary and any 3 pins could be used (the masks used to control the pins 256 | must be changed). The TARGET pins cannot be changed, these are fixed function 257 | pins on the PSoC. 258 | The PWR pin is used to provide power to the target device if power cycle 259 | programming mode is used. The compiler directive RESET_MODE in ISSP_directives.h 260 | is used to select the programming mode. This pin could control the enable on 261 | a voltage regulator, or could control the gate of a FET that is used to turn 262 | the power to the PSoC on. 263 | The TP pin is a Test Point pin that can be used signal from the host processor 264 | that the program has completed certain tasks. Predefined test points are 265 | included that can be used to observe the timing for bulk erasing, block 266 | programming and security programming. 267 | 268 | SIGNAL HOST TARGET 269 | --------------------- 270 | SDATA P1.0 P1.0 271 | SCLK P1.1 P1.1 272 | XRES P2.0 XRES 273 | PWR P2.1 Vdd 274 | TP P0.7 n/a 275 | 276 | For test & demonstration, this project generates the program data internally. 277 | It does not take-in the data from an external source such as I2C, UART, SPI, 278 | etc. However, the program was written in such a way to be portable into such 279 | designs. The spirit of this project was to keep it stripped to the minimum 280 | functions required to do the ISSP functions only, thereby making a portable 281 | framework for integration with other projects. 282 | 283 | The high-level functions have been written in C in order to be portable to 284 | other processors. The low-level functions that are processor dependent, such 285 | as toggling pins and implementing specific delays, are all found in the file 286 | ISSP_Drive_Routines.c. These functions must be converted to equivalent 287 | functions for the HOST processor. Care must be taken to meet the timing 288 | requirements when converting to a new processor. ISSP timing information can 289 | be found in Application Note AN2026. All of the sections of this program 290 | that need to be modified for the host processor have "PROCESSOR_SPECIFIC" in 291 | the comments. By performing a "Find in files" using "PROCESSOR_SPECIFIC" these 292 | sections can easily be identified. 293 | 294 | The variables in this project use Hungarian notation. Hungarian prepends a 295 | lower case letter to each variable that identifies the variable type. The 296 | prefixes used in this program are defined below: 297 | b = byte length variable, signed char and unsigned char 298 | i = 2-byte length variable, signed int and unsigned int 299 | f = byte length variable used as a flag (TRUE = 0, FALSE != 0) 300 | ab = an array of byte length variables 301 | 302 | 303 | After this program has been ported to the desired host processor the timing 304 | of the signals must be confirmed. The maximum SCLK frequency must be checked 305 | as well as the timing of the bulk erase, block write and security write 306 | pulses. 307 | 308 | The maximum SCLK frequency for the target device can be found in the device 309 | datasheet under AC Programming Specifications with a Symbol of "Fsclk". 310 | An oscilloscope should be used to make sure that no half-cycles (the high 311 | time or the low time) are shorter than the half-period of the maximum 312 | freqency. In other words, if the maximum SCLK frequency is 8MHz, there can be 313 | no high or low pulses shorter than 1/(2*8MHz), or 62.5 nsec. 314 | 315 | (((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))) */ 316 | 317 | 318 | 319 | /*---------------------------------------------------------------------------- 320 | // C main line 321 | //---------------------------------------------------------------------------- 322 | */ 323 | 324 | #define CY8C21x45 325 | 326 | // ------ Declarations Associated with ISSP Files & Routines ------- 327 | // Add these to your project as needed. 328 | #include "issp_extern.h" 329 | #include "issp_defs.h" 330 | #include "issp_errors.h" 331 | #include "stk500_protocol.h" 332 | 333 | #define HWVER 2 334 | #define SWMAJ 1 335 | #define SWMIN 18 336 | 337 | unsigned char bBankCounter; 338 | unsigned int iBlockCounter; 339 | unsigned int iChecksumData; 340 | unsigned int iChecksumTarget; 341 | 342 | parameter param; 343 | 344 | int error=0; 345 | int pmode=0; 346 | int here; 347 | uint8_t buff[256]; // global block storage 348 | unsigned char bit; 349 | volatile unsigned char *out; 350 | int psocisp(); 351 | 352 | uint8_t getch() { 353 | while(!Serial.available()); 354 | return Serial.read(); 355 | } 356 | 357 | void empty_reply() { 358 | if (Sync_CRC_EOP == getch()) { 359 | Serial.print((char)Resp_STK_INSYNC); 360 | Serial.print((char)Resp_STK_OK); 361 | } else { 362 | error++; 363 | Serial.print((char)Resp_STK_NOSYNC); 364 | } 365 | } 366 | 367 | void breply(uint8_t b) { 368 | if (Sync_CRC_EOP == getch()) { 369 | Serial.print((char)Resp_STK_INSYNC); 370 | Serial.print((char)b); 371 | Serial.print((char)Resp_STK_OK); 372 | } else { 373 | error++; 374 | Serial.print((char)Resp_STK_NOSYNC); 375 | } 376 | } 377 | 378 | void fill(int n) { 379 | for (int x = 0; x < n; x++) { 380 | buff[x] = getch(); 381 | } 382 | } 383 | 384 | void get_parameter(uint8_t c) { 385 | switch(c) { 386 | case Parm_STK_HW_VER: 387 | breply(HWVER); 388 | break; 389 | case Parm_STK_SW_MAJOR: 390 | breply(SWMAJ); 391 | break; 392 | case Parm_STK_SW_MINOR: 393 | breply(SWMIN); 394 | break; 395 | case Parm_STK_PROGMODE: 396 | breply('S'); // serial programmer 397 | break; 398 | case Parm_STK_VTARGET: 399 | breply(50); 400 | default: 401 | breply(0); 402 | } 403 | } 404 | 405 | void set_parameters() { 406 | // call this after reading paramter packet into buff[] 407 | param.prog_mode = (programming_mode) buff[0]; 408 | param.targ_voltage = (target_voltage) buff[1]; 409 | param.chksm_setup = (checksum_setup) buff[2]; 410 | param.prgm_block = (prg_block) buff[3]; 411 | param.multi_bank = (boolean) buff[4]; 412 | } 413 | 414 | void end_pmode() { 415 | ReStartTarget(); 416 | } 417 | 418 | int8_t erase_chip() { 419 | return fEraseTarget(); 420 | } 421 | 422 | // Initialize the Host & Target for ISSP operations 423 | int8_t start_pmode() { 424 | // Acquire the device through reset or power cycle 425 | int8_t result = PASS; 426 | if(param.prog_mode == RESET_MODE) { 427 | fXRESInitializeTargetForISSP(); 428 | } else { 429 | result = fPowerCycleInitializeTargetForISSP(); 430 | } 431 | if (result) 432 | Serial.print((char) Resp_STK_FAILED); 433 | else 434 | Serial.print((char) Resp_STK_OK); 435 | pmode = 1; 436 | return result; 437 | } 438 | 439 | void read_signature() { 440 | if (Sync_CRC_EOP != getch()) { 441 | error++; 442 | Serial.print((char) Resp_STK_NOSYNC); 443 | return; 444 | } 445 | 446 | if(getSiliconID(buff)) { 447 | Serial.print((char) Resp_STK_FAILED); 448 | return; 449 | } 450 | Serial.print((char) Resp_STK_INSYNC); 451 | Serial.print((char) buff[0]); 452 | Serial.print((char) buff[1]); 453 | Serial.print((char) Resp_STK_OK); 454 | } 455 | 456 | char flash_read_page(int length) { 457 | for (uint8_t x = 0; x < length; x++) { 458 | Serial.write(readByte(0x80+x)); 459 | } 460 | return Resp_STK_OK; 461 | } 462 | 463 | void read_mem() { 464 | char result = (char)Resp_STK_FAILED; 465 | int addr = getch(); 466 | if (Sync_CRC_EOP != getch()) { 467 | error++; 468 | Serial.print((char) Resp_STK_NOSYNC); 469 | return; 470 | } 471 | Serial.print((char) Resp_STK_INSYNC); 472 | result = readByte(addr); 473 | Serial.print(result); 474 | Serial.print((char) Resp_STK_OK); 475 | return; 476 | } 477 | 478 | void write_mem() { 479 | int addr = getch(); 480 | int value = getch(); 481 | if (Sync_CRC_EOP != getch()) { 482 | error++; 483 | Serial.print((char) Resp_STK_NOSYNC); 484 | return; 485 | } 486 | writeByte(addr, value); 487 | Serial.print((char) Resp_STK_INSYNC); 488 | Serial.print((char) Resp_STK_OK); 489 | return; 490 | } 491 | 492 | void read_reg() { 493 | char result = (char)Resp_STK_FAILED; 494 | int addr = getch(); 495 | if (Sync_CRC_EOP != getch()) { 496 | error++; 497 | Serial.print((char) Resp_STK_NOSYNC); 498 | return; 499 | } 500 | Serial.print((char) Resp_STK_INSYNC); 501 | result = readReg(addr); 502 | Serial.print(result); 503 | Serial.print((char) Resp_STK_OK); 504 | return; 505 | } 506 | 507 | void write_reg() { 508 | int addr = getch(); 509 | int value = getch(); 510 | if (Sync_CRC_EOP != getch()) { 511 | error++; 512 | Serial.print((char) Resp_STK_NOSYNC); 513 | return; 514 | } 515 | writeReg(addr, value); 516 | Serial.print((char) Resp_STK_INSYNC); 517 | Serial.print((char) Resp_STK_OK); 518 | return; 519 | } 520 | 521 | void exec_opcodes() { 522 | unsigned char opc[3]; 523 | opc[0] = getch(); 524 | opc[1] = getch(); 525 | opc[2] = getch(); 526 | 527 | if (Sync_CRC_EOP != getch()) { 528 | error++; 529 | Serial.print((char) Resp_STK_NOSYNC); 530 | return; 531 | } 532 | Exec(opc); 533 | Serial.print((char) Resp_STK_INSYNC); 534 | Serial.print((char) Resp_STK_OK); 535 | return; 536 | } 537 | 538 | void read_page() { 539 | char result = (char)Resp_STK_FAILED; 540 | int length = 256 * getch(); 541 | length += getch(); 542 | char memtype = getch(); 543 | if (Sync_CRC_EOP != getch()) { 544 | error++; 545 | Serial.print((char) Resp_STK_NOSYNC); 546 | return; 547 | } 548 | Serial.print((char) Resp_STK_INSYNC); 549 | if (memtype == 'F') { 550 | result = flash_read_page(length); 551 | } 552 | Serial.print(result); 553 | return; 554 | } 555 | 556 | uint8_t write_flash_pages(int length) { 557 | for (bTargetDataPtr = 0; bTargetDataPtr < TARGET_DATABUFF_LEN; bTargetDataPtr++) { 558 | abTargetDataOUT[bTargetDataPtr] = buff[bTargetDataPtr]; 559 | } 560 | iLoadTarget(); 561 | fProgramTargetBlock(0, here); 562 | return Resp_STK_OK; 563 | } 564 | 565 | void write_flash(int length) { 566 | fill(length); 567 | if (Sync_CRC_EOP == getch()) { 568 | Serial.print((char) Resp_STK_INSYNC); 569 | Serial.print((char) write_flash_pages(length)); 570 | } else { 571 | error++; 572 | Serial.print((char) Resp_STK_NOSYNC); 573 | } 574 | } 575 | 576 | void program_page() { 577 | int length = 256 * getch(); 578 | length += getch(); 579 | char memtype = getch(); 580 | // flash memory @here, (length) bytes 581 | if (memtype == 'F') { 582 | write_flash(length); 583 | return; 584 | } else { 585 | error++; 586 | Serial.print((char) Resp_STK_NOSYNC); 587 | } 588 | Serial.print((char)Resp_STK_FAILED); 589 | return; 590 | } 591 | 592 | void setup() { 593 | bit = digitalPinToBitMask(SDATA_PIN); 594 | out = portOutputRegister(digitalPinToPort(SDATA_PIN)); 595 | param.prog_mode = RESET_MODE; 596 | param.targ_voltage = TARGET_VOLTAGE_5V; 597 | param.chksm_setup = CHECKSUM_SETUP_21_23_27_TST110_TMG110; 598 | param.prgm_block = PROGRAM_BLOCK_21_22_23_24_28_29_TST_TMG_TMA; 599 | param.multi_bank = false; 600 | Serial.begin(115200); 601 | } 602 | 603 | void loop() { 604 | if (Serial.available()) { 605 | psocisp(); 606 | } 607 | } 608 | 609 | int psocisp() { 610 | uint8_t res, block_count; 611 | uint32_t checksum_delay = 0, ms_delay = 0; 612 | uint8_t ch = getch(); 613 | unsigned int csum = 0; 614 | switch (ch) { 615 | case Cmnd_STK_GET_SYNC: // signon 616 | error = 0; 617 | empty_reply(); 618 | break; 619 | case Cmnd_STK_GET_SIGN_ON: 620 | if (getch() == Sync_CRC_EOP) { 621 | Serial.print((char) Resp_STK_INSYNC); 622 | Serial.print("AVR ISP"); 623 | Serial.print((char) Resp_STK_OK); 624 | } 625 | break; 626 | case Cmnd_STK_GET_PARAMETER: 627 | get_parameter(getch()); 628 | break; 629 | case Cmnd_STK_SET_DEVICE: 630 | fill(5); 631 | set_parameters(); 632 | empty_reply(); 633 | break; 634 | case Cmnd_STK_SET_DEVICE_EXT: // extended parameters - ignore for now 635 | fill(5); 636 | empty_reply(); 637 | break; 638 | case Cmnd_STK_ENTER_PROGMODE: 639 | start_pmode(); 640 | break; 641 | case Cmnd_STK_INIT_PROGMODE: 642 | res = SendInitVectors(); 643 | Serial.print((char) Resp_STK_INSYNC); 644 | Serial.print((char) res); 645 | Serial.print((char) Resp_STK_OK); 646 | break; 647 | case Cmnd_STK_CHIP_ERASE: 648 | erase_chip(); 649 | empty_reply(); 650 | break; 651 | case Cmnd_STK_LOAD_ADDRESS: // set address (word) 652 | here = getch(); 653 | here += 256 * getch(); 654 | here /= 64; 655 | setAddress(0, (here)); // TODO support for multiple banks 656 | empty_reply(); 657 | break; 658 | case Cmnd_STK_PROG_PAGE: 659 | program_page(); 660 | break; 661 | case Cmnd_STK_READ_PAGE: 662 | read_page(); 663 | break; 664 | case Cmnd_STK_READ_MEM: 665 | read_mem(); 666 | break; 667 | case Cmnd_STK_WRITE_MEM: 668 | write_mem(); 669 | break; 670 | case Cmnd_STK_READ_REG: 671 | read_reg(); 672 | break; 673 | case Cmnd_STK_READ_SECURITY: 674 | res = fVerifySecurity(); 675 | Serial.print((char) Resp_STK_INSYNC); 676 | Serial.print((char) res); 677 | Serial.print((char) Resp_STK_OK); 678 | break; 679 | case Cmnd_STK_WRITE_REG: 680 | write_reg(); 681 | break; 682 | case Cmnd_STK_EXEC_OPCODES: 683 | exec_opcodes(); 684 | break; 685 | case Cmnd_STK_RUN_CSUM: 686 | block_count = getch(); 687 | fAccTargetBankChecksum(&csum, block_count); 688 | Serial.print((char) Resp_STK_INSYNC); 689 | Serial.print((char)(csum&0xFF)); 690 | Serial.print((char)((csum>>8)&0xFF)); 691 | Serial.print((char) Resp_STK_OK); 692 | break; 693 | case Cmnd_STK_START_CSUM: 694 | checksum_delay = ((uint32_t)getch())<<24; 695 | checksum_delay |= ((uint32_t)getch())<<16; 696 | checksum_delay |= ((uint32_t)getch())<<8; 697 | checksum_delay |= getch(); 698 | if(checksum_delay > 10000) { 699 | ms_delay = checksum_delay/1000; 700 | checksum_delay = checksum_delay%1000; 701 | } 702 | else { 703 | ms_delay = 0; 704 | } 705 | send_checksum_v(); 706 | if (checksum_delay) 707 | delayMicroseconds(checksum_delay); 708 | delay(ms_delay); 709 | start_pmode(); 710 | break; 711 | case Cmnd_STK_LEAVE_PROGMODE: 712 | error=0; 713 | end_pmode(); 714 | empty_reply(); 715 | break; 716 | case Cmnd_STK_READ_SIGN: 717 | read_signature(); 718 | break; 719 | 720 | // expecting a command, not Sync_CRC_EOP 721 | // this is how we can get back in sync 722 | case Sync_CRC_EOP: 723 | error++; 724 | Serial.print((char) Resp_STK_NOSYNC); 725 | break; 726 | 727 | // anything else we will return Resp_STK_UNKNOWN 728 | default: 729 | error++; 730 | if (Sync_CRC_EOP == getch()) 731 | Serial.print((char)Resp_STK_UNKNOWN); 732 | else 733 | Serial.print((char)Resp_STK_NOSYNC); 734 | } 735 | 736 | return 0; 737 | } 738 | -------------------------------------------------------------------------------- /issp_defs.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //-------------------------------------------------------------------------- 33 | #ifndef INC_ISSP_DEFS 34 | #define INC_ISSP_DEFS 35 | 36 | // Block-Verify Uses 64-Bytes of RAM 37 | #define TARGET_DATABUFF_LEN 64 38 | 39 | // The number of Flash blocks in each part is defined here. This is used in 40 | // main programming loop when programming and verifying the blocks. 41 | 42 | // xch ----------------------------------------------------------------------------------------------------------------------------- 43 | #ifdef CY8CTST110 44 | #define NUM_BANKS 1 45 | #define BLOCKS_PER_BANK 128 46 | #define SECURITY_BYTES_PER_BANK 64 47 | #endif 48 | #ifdef CY8CTST120 49 | #define NUM_BANKS 2 50 | #define BLOCKS_PER_BANK 128 51 | #define SECURITY_BYTES_PER_BANK 32 52 | #endif 53 | #ifdef CY8CTMG110 54 | #define NUM_BANKS 1 55 | #define BLOCKS_PER_BANK 128 56 | #define SECURITY_BYTES_PER_BANK 64 57 | #endif 58 | #ifdef CY8CTMG120 59 | #define NUM_BANKS 2 60 | #define BLOCKS_PER_BANK 128 61 | #define SECURITY_BYTES_PER_BANK 32 62 | #endif 63 | #ifdef CY8CTMA120 64 | #define NUM_BANKS 2 65 | #define BLOCKS_PER_BANK 128 66 | #define SECURITY_BYTES_PER_BANK 32 67 | #endif 68 | // xch ----------------------------------------------------------------------------------------------------------------------------- 69 | 70 | #ifdef CY8C21x23 71 | #define NUM_BANKS 1 72 | #define BLOCKS_PER_BANK 64 73 | #define SECURITY_BYTES_PER_BANK 64 74 | #endif 75 | #ifdef CY8C21x34 76 | #define NUM_BANKS 1 77 | #define BLOCKS_PER_BANK 128 78 | #define SECURITY_BYTES_PER_BANK 64 79 | #endif 80 | #ifdef CY8C21x45 81 | #define NUM_BANKS 1 82 | #define BLOCKS_PER_BANK 128 83 | #define SECURITY_BYTES_PER_BANK 64 84 | #endif 85 | #ifdef CY8C22x45 86 | #define NUM_BANKS 2 87 | #define BLOCKS_PER_BANK 128 88 | #define SECURITY_BYTES_PER_BANK 32 89 | #endif 90 | #ifdef CY8C23x33 91 | #define NUM_BANKS 1 92 | #define BLOCKS_PER_BANK 128 93 | #define SECURITY_BYTES_PER_BANK 64 94 | #endif 95 | #ifdef CY8C24x23A 96 | #define NUM_BANKS 1 97 | #define BLOCKS_PER_BANK 64 98 | #define SECURITY_BYTES_PER_BANK 64 99 | #endif 100 | #ifdef CY8C24x94 101 | #define NUM_BANKS 2 102 | #define BLOCKS_PER_BANK 128 103 | #define SECURITY_BYTES_PER_BANK 32 104 | #endif 105 | #ifdef CY8C27x43 106 | #define NUM_BANKS 1 107 | #define BLOCKS_PER_BANK 256 108 | #define SECURITY_BYTES_PER_BANK 64 109 | #endif 110 | #ifdef CY8C28xxx 111 | #define NUM_BANKS 2 112 | #define BLOCKS_PER_BANK 128 113 | #define SECURITY_BYTES_PER_BANK 32 114 | #endif 115 | #ifdef CY8C29x66 116 | #define NUM_BANKS 4 117 | #define BLOCKS_PER_BANK 128 118 | #define SECURITY_BYTES_PER_BANK 32 119 | #endif 120 | // used for SDATA writing 121 | extern unsigned char bit; 122 | extern volatile unsigned char *out; 123 | // ****************************** PORT BIT MASKS ****************************** 124 | // **************************************************************************** 125 | // **** PROCESSOR SPECIFIC **** 126 | // **************************************************************************** 127 | // **** USER ATTENTION REQUIRED **** 128 | // **************************************************************************** 129 | #define SDATA_PIN 9 130 | #define SCLK_PIN 8 131 | #define XRES_PIN 4 132 | #define TARGET_VDD 11 133 | #define TP_PIN 12 134 | #endif //(INC_ISSP_DEFS) 135 | 136 | -------------------------------------------------------------------------------- /issp_delays.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //----------------------------------------------------------------------------- 33 | #ifndef INC_ISSP_DELAYS 34 | #define INC_ISSP_DELAYS 35 | 36 | // TRANSITION_TIMEOUT is a loop counter for a 100msec timeout when waiting for 37 | // a high-to-low transition. This is used in the polling loop of 38 | // fDetectHiLoTransition(). 39 | #define TRANSITION_TIMEOUT 200 40 | 41 | // XRES_DELAY is the time duration for which XRES is asserted. This defines 42 | // a 63 usec delay. 43 | // The minimum Xres time (from the device datasheet) is 10 usec. 44 | #define XRES_CLK_DELAY 63 45 | 46 | // POWER_CYCLE_DELAY is the time required when power is cycled to the target 47 | // device to create a power reset after programming has been completed. The 48 | // actual time of this delay will vary from system to system depending on the 49 | // bypass capacitor size. A delay of 150 usec is used here. 50 | #define POWER_CYCLE_DELAY 150 51 | 52 | // DELAY_100us delays 100 usec. This is used in fXRESInitializeTargetForISSP to 53 | // time the wait for Vdd to become stable after a power up. A loop runs 10 of 54 | // these for a total delay of 1 msec. 55 | #define DELAY100us 100 56 | 57 | #endif //(INC_ISSP_DELAYS) 58 | 59 | -------------------------------------------------------------------------------- /issp_driver_routines.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 3 | // 4 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 5 | // and is protected by and subject to worldwide patent protection (United 6 | // States and foreign), United States copyright laws and international 7 | // treaty provisions. Cypress hereby grants to licensee a personal, 8 | // non-exclusive, non-transferable license to copy, use, modify, create 9 | // derivative works of, and compile the Cypress Source Code and derivative 10 | // works for the sole purpose of creating custom software in support of 11 | // licensee product to be used only in conjunction with a Cypress integrated 12 | // circuit as specified in the applicable agreement. Any reproduction, 13 | // modification, translation, compilation, or representation of this 14 | // software except as specified above is prohibited without the express 15 | // written permission of Cypress. 16 | // 17 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 18 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 | // Cypress reserves the right to make changes without further notice to the 21 | // materials described herein. Cypress does not assume any liability arising 22 | // out of the application or use of any product or circuit described herein. 23 | // Cypress does not authorize its products for use as critical components in 24 | // life-support systems where a malfunction or failure may reasonably be 25 | // expected to result in significant injury to the user. The inclusion of 26 | // Cypress product in a life-support systems application implies that the 27 | // manufacturer assumes all risk of such use and in doing so indemnifies 28 | // Cypress against all charges. 29 | // 30 | // Use may be limited by and subject to the applicable Cypress software 31 | // license agreement. 32 | // 33 | //-------------------------------------------------------------------------- 34 | 35 | #include "issp_defs.h" 36 | #include "issp_extern.h" 37 | #include "issp_errors.h" 38 | 39 | // ============================================================================ 40 | // LoadArrayWithSecurityData() 41 | // !!!!!!!!!!!!!!!!!!FOR TEST!!!!!!!!!!!!!!!!!!!!!!!!!! 42 | // PROCESSOR_SPECIFIC 43 | // Most likely this data will be fed to the Host by some other means, ie: I2C, 44 | // RS232, etc., or will be fixed in the host. The security data should come 45 | // from the hex file. 46 | // bStart - the starting byte in the array for loading data 47 | // bLength - the number of byte to write into the array 48 | // bType - the security data to write over the range defined by bStart and 49 | // bLength 50 | // ============================================================================ 51 | /*void LoadArrayWithSecurityData(unsigned char bStart, unsigned char bLength, unsigned char bType) 52 | { 53 | // Now, write the desired security-bytes for the range specified 54 | for (bTargetDataPtr = bStart; bTargetDataPtr < bLength; bTargetDataPtr++) { 55 | abTargetDataOUT[bTargetDataPtr] = bType; 56 | } 57 | }*/ 58 | 59 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 60 | // **************************************************************************** 61 | // **** PROCESSOR SPECIFIC **** 62 | // **************************************************************************** 63 | // **** USER ATTENTION REQUIRED **** 64 | // **************************************************************************** 65 | // fLoadSecurityData() 66 | // Load security data from hex file into 64 byte host ram buffer. In a fully 67 | // functional program (not a demo) this routine should do the following: 68 | // 1. Read data from security record in hex file into ram buffer. 69 | // 2. Check host ram buffer + record data (Address, # of bytes) against hex 70 | // record checksum at end of record line 71 | // 3. If error reread security data from file or abort 72 | // 4. Exit this Function and Program block 73 | // In this demo routine, all of the security data is set to unprotected (0x00) 74 | // and it returns. 75 | // This function always returns PASS. The flag return is reserving 76 | // functionality for non-demo versions. 77 | // **************************************************************************** 78 | /*signed char fLoadSecurityData(unsigned char bBankNum) 79 | { 80 | // >>> The following call is for demo use only. <<< 81 | // Function LoadArrayWithSecurityData fills buffer for demo 82 | LoadArrayWithSecurityData(0,SECURITY_BYTES_PER_BANK, 0x00); 83 | 84 | // Note: 85 | // Error checking should be added for the final version as noted above. 86 | // For demo use this function just returns PASS. 87 | return(PASS); 88 | }*/ 89 | 90 | 91 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 92 | // **************************************************************************** 93 | // **** PROCESSOR SPECIFIC **** 94 | // **************************************************************************** 95 | // **** USER ATTENTION REQUIRED **** 96 | // **************************************************************************** 97 | // fSDATACheck() 98 | // Check SDATA pin for high or low logic level and return value to calling 99 | // routine. 100 | // Returns: 101 | // 0 if the pin was low. 102 | // 1 if the pin was high. 103 | // **************************************************************************** 104 | unsigned char fSDATACheck(void) 105 | { 106 | return digitalRead(SDATA_PIN); 107 | } 108 | 109 | 110 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 111 | // **************************************************************************** 112 | // **** PROCESSOR SPECIFIC **** 113 | // **************************************************************************** 114 | // **** USER ATTENTION REQUIRED **** 115 | // **************************************************************************** 116 | // SCLKHigh() 117 | // Set the SCLK pin High 118 | // **************************************************************************** 119 | void SCLKHigh(void) 120 | { 121 | digitalWrite(SCLK_PIN, HIGH); 122 | } 123 | 124 | 125 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 126 | // **************************************************************************** 127 | // **** PROCESSOR SPECIFIC **** 128 | // **************************************************************************** 129 | // **** USER ATTENTION REQUIRED **** 130 | // **************************************************************************** 131 | // SCLKLow() 132 | // Make Clock pin Low 133 | // **************************************************************************** 134 | void SCLKLow(void) 135 | { 136 | digitalWrite(SCLK_PIN, LOW); 137 | } 138 | 139 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 140 | // **************************************************************************** 141 | // **** PROCESSOR SPECIFIC **** 142 | // **************************************************************************** 143 | // **** USER ATTENTION REQUIRED **** 144 | // **************************************************************************** 145 | // SetSCLKHiZ() 146 | // Set SCLK pin to HighZ drive mode. 147 | // **************************************************************************** 148 | void SetSCLKHiZ(void) 149 | { 150 | pinMode(SCLK_PIN, INPUT); 151 | digitalWrite(SCLK_PIN, LOW); 152 | } 153 | 154 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 155 | // **************************************************************************** 156 | // **** PROCESSOR SPECIFIC **** 157 | // **************************************************************************** 158 | // **** USER ATTENTION REQUIRED **** 159 | // **************************************************************************** 160 | // SetSCLKStrong() 161 | // Set SCLK to an output (Strong drive mode) 162 | // **************************************************************************** 163 | void SetSCLKStrong(void) 164 | { 165 | pinMode(SCLK_PIN, OUTPUT); 166 | } 167 | 168 | // Arduinos digitalWrite function is to slow (violates timings), this is a workaround 169 | void digitalWriteSDATA(unsigned char val) { 170 | if (val == LOW) { 171 | *out &= ~bit; 172 | } else { 173 | *out |= bit; 174 | } 175 | } 176 | 177 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 178 | // **************************************************************************** 179 | // **** PROCESSOR SPECIFIC **** 180 | // **************************************************************************** 181 | // **** USER ATTENTION REQUIRED **** 182 | // **************************************************************************** 183 | // SetSDATAHigh() 184 | // Make SDATA pin High 185 | // **************************************************************************** 186 | void SetSDATAHigh(void) 187 | { 188 | digitalWriteSDATA(HIGH); 189 | } 190 | 191 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 192 | // **************************************************************************** 193 | // **** PROCESSOR SPECIFIC **** 194 | // **************************************************************************** 195 | // **** USER ATTENTION REQUIRED **** 196 | // **************************************************************************** 197 | // SetSDATALow() 198 | // Make SDATA pin Low 199 | // **************************************************************************** 200 | void SetSDATALow(void) 201 | { 202 | digitalWriteSDATA(LOW); 203 | } 204 | 205 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 206 | // **************************************************************************** 207 | // **** PROCESSOR SPECIFIC **** 208 | // **************************************************************************** 209 | // **** USER ATTENTION REQUIRED **** 210 | // **************************************************************************** 211 | // SetSDATAHiZ() 212 | // Set SDATA pin to an input (HighZ drive mode). 213 | // **************************************************************************** 214 | void SetSDATAHiZ(void) 215 | { 216 | pinMode(SDATA_PIN, INPUT); 217 | digitalWrite(SDATA_PIN, LOW); 218 | } 219 | 220 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 221 | // **************************************************************************** 222 | // **** PROCESSOR SPECIFIC **** 223 | // **************************************************************************** 224 | // **** USER ATTENTION REQUIRED **** 225 | // **************************************************************************** 226 | // SetSDATAStrong() 227 | // Set SDATA for transmission (Strong drive mode) -- as opposed to being set to 228 | // High Z for receiving data. 229 | // **************************************************************************** 230 | void SetSDATAStrong(void) 231 | { 232 | pinMode(SDATA_PIN, OUTPUT); 233 | } 234 | 235 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 236 | // **************************************************************************** 237 | // **** PROCESSOR SPECIFIC **** 238 | // **************************************************************************** 239 | // **** USER ATTENTION REQUIRED **** 240 | // **************************************************************************** 241 | // SetXRESStrong() 242 | // Set external reset (XRES) to an output (Strong drive mode). 243 | // **************************************************************************** 244 | void SetXRESStrong(void) 245 | { 246 | pinMode(XRES_PIN, OUTPUT); 247 | } 248 | 249 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 250 | // **************************************************************************** 251 | // **** PROCESSOR SPECIFIC **** 252 | // **************************************************************************** 253 | // **** USER ATTENTION REQUIRED **** 254 | // **************************************************************************** 255 | // AssertXRES() 256 | // Set XRES pin High 257 | // **************************************************************************** 258 | void AssertXRES(void) 259 | { 260 | digitalWrite(XRES_PIN, HIGH); 261 | } 262 | 263 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 264 | // **************************************************************************** 265 | // **** PROCESSOR SPECIFIC **** 266 | // **************************************************************************** 267 | // **** USER ATTENTION REQUIRED **** 268 | // **************************************************************************** 269 | // DeassertXRES() 270 | // Set XRES pin low. 271 | // **************************************************************************** 272 | void DeassertXRES(void) 273 | { 274 | digitalWrite(XRES_PIN, LOW); 275 | } 276 | 277 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 278 | // **************************************************************************** 279 | // **** PROCESSOR SPECIFIC **** 280 | // **************************************************************************** 281 | // **** USER ATTENTION REQUIRED **** 282 | // **************************************************************************** 283 | // SetTargetVDDStrong() 284 | // Set VDD pin (PWR) to an output (Strong drive mode). 285 | // **************************************************************************** 286 | void SetTargetVDDStrong(void) 287 | { 288 | pinMode(TARGET_VDD, OUTPUT); 289 | } 290 | 291 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 292 | // **************************************************************************** 293 | // **** PROCESSOR SPECIFIC **** 294 | // **************************************************************************** 295 | // **** USER ATTENTION REQUIRED **** 296 | // **************************************************************************** 297 | // ApplyTargetVDD() 298 | // Provide power to the target PSoC's Vdd pin through a GPIO. 299 | // **************************************************************************** 300 | void ApplyTargetVDD(void) 301 | { 302 | digitalWrite(TARGET_VDD, HIGH); 303 | } 304 | 305 | // ********************* LOW-LEVEL ISSP SUBROUTINE SECTION ******************** 306 | // **************************************************************************** 307 | // **** PROCESSOR SPECIFIC **** 308 | // **************************************************************************** 309 | // **** USER ATTENTION REQUIRED **** 310 | // **************************************************************************** 311 | // RemoveTargetVDD() 312 | // Remove power from the target PSoC's Vdd pin. 313 | // **************************************************************************** 314 | void RemoveTargetVDD(void) 315 | { 316 | digitalWrite(TARGET_VDD, LOW); 317 | } 318 | 319 | -------------------------------------------------------------------------------- /issp_errors.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //-------------------------------------------------------------------------- 33 | #ifndef INC_ISSP_ERRORS 34 | #define INC_ISSP_ERRORS 35 | 36 | // The following are defines for error messages from the ISSP program. 37 | #define PASS 0 38 | // PASS is used to indicate that a function completed successfully. 39 | #define ERROR -1 40 | // ERROR is a generic failure used within lower level functions before the 41 | // error is reported. This should not be seen as an error that is reported 42 | // from main. 43 | #define INIT_ERROR 1 44 | // INIT_ERROR means a step in chip initialization failed. 45 | #define SiID_ERROR 2 46 | // SiID_ERROR means that the Silicon ID check failed. This happens if the 47 | // target part does not match the device type that the ISSP program is 48 | // configured for. 49 | #define ERASE_ERROR 3 50 | // ERASE_ERROR means that the bulk erase step failed. 51 | #define BLOCK_ERROR 4 52 | // BLOCK_ERROR means that a step in programming a Flash block or the verify 53 | // of the block failed. 54 | #define VERIFY_ERROR 5 55 | // VERIFY_ERROR means that the checksum verification failed. 56 | #define SECURITY_ERROR 6 57 | // SECURITY_ERROR means that the write of the security information failed. 58 | 59 | #endif //(INC_ISSP_ERRORS) 60 | 61 | -------------------------------------------------------------------------------- /issp_extern.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //-------------------------------------------------------------------------- 33 | #ifndef INC_ISSP_EXTERN 34 | #define INC_ISSP_EXTERN 35 | 36 | // Block-Verify Uses 64-Bytes of RAM 37 | #define TARGET_DATABUFF_LEN 64 38 | 39 | #include "Arduino.h" 40 | 41 | extern void fXRESInitializeTargetForISSP(void); 42 | extern signed char SendInitVectors(void); 43 | extern signed char fPowerCycleInitializeTargetForISSP(void); 44 | extern signed char fEraseTarget(void); 45 | extern unsigned int iLoadTarget(void); 46 | extern void ReStartTarget(void); 47 | extern int8_t getSiliconID(uint8_t * buff); 48 | extern void setAddress(unsigned char, unsigned char); 49 | extern byte readByte(unsigned char bTargetAddress); 50 | extern byte readReg(unsigned char bTargetReg); 51 | extern int Exec(const unsigned char *opcodes); 52 | extern void writeReg(unsigned char bTargetReg, unsigned char bValue); 53 | extern void writeByte(unsigned char bTargetAddress, unsigned char bValue); 54 | extern signed char fAccTargetBankChecksum(unsigned int*, unsigned char block_count); 55 | extern void send_checksum_v(void); 56 | extern void SetBankNumber(unsigned char); 57 | extern signed char fProgramTargetBlock(unsigned char, unsigned char); 58 | extern signed char fVerifyTargetBlock(unsigned char, unsigned char); 59 | extern signed char fSecureTargetFlash(void); 60 | extern signed char fVerifySecurity(void); 61 | 62 | extern void LoadArrayWithSecurityData(unsigned char, unsigned char, unsigned char); 63 | 64 | extern signed char fLoadSecurityData(unsigned char); 65 | extern unsigned char fSDATACheck(void); 66 | extern void SCLKHigh(void); 67 | extern void SCLKLow(void); 68 | extern void SetSCLKHiZ(void); 69 | extern void SetSCLKStrong(void); 70 | extern void SetSDATAHigh(void); 71 | extern void SetSDATALow(void); 72 | extern void SetSDATAHiZ(void); 73 | extern void SetSDATAStrong(void); 74 | extern void AssertXRES(void); 75 | extern void DeassertXRES(void); 76 | extern void SetXRESStrong(void); 77 | extern void ApplyTargetVDD(void); 78 | extern void RemoveTargetVDD(void); 79 | extern void SetTargetVDDStrong(void); 80 | 81 | extern unsigned char fIsError; 82 | 83 | // This enumeration causes the proper Initialization vector #3 to be sent 84 | // to the Target, based on what the Target Vdd programming voltage will 85 | // be. Either 5V or 3.3V. 86 | enum target_voltage { 87 | TARGET_VOLTAGE_5V, 88 | TARGET_VOLTAGE_3_3V, 89 | } extern targ_voltage; 90 | 91 | // This enumeration selects whether code that uses reset programming mode or code 92 | // that uses power cycle programming is use. Reset programming mode uses the 93 | // external reset pin (XRES) to enter programming mode. Power cycle programming 94 | // mode uses the power-on reset to enter programming mode. 95 | // Applying signals to various pins on the target device must be done in a 96 | // deliberate order when using power cycle mode. Otherwise, high signals to GPIO 97 | // pins on the target will power the PSoC through the protection diodes. 98 | enum programming_mode { 99 | RESET_MODE, 100 | POWER_CYCLE_MODE, 101 | } extern prog_mode; 102 | 103 | // The boolean below is used to control switching banks if the device 104 | // has multiple banks of Flash. 105 | extern bool multi_bank; 106 | 107 | // The enumerations below are used to define various sets of vectors that differ 108 | // for more than one set of PSoC parts. 109 | enum checksum_setup { 110 | CHECKSUM_SETUP_21_23_27_TST110_TMG110, // CY8C21x23, CY8C21x34, CY8C23x33, CY8C27x43, TST110 & TMG110 Checksum Setup Vectors 111 | CHECKSUM_SETUP_22_24_28_29_TST120_TMG120_TMA120, // CY8C21x45,CY8C22x45,CY8C24x94, CY8C28xxx, CY8C29x66, TST120, TMG120, & TMA120 Checksum Setup Vectors 112 | CHECKSUM_SETUP_24_24A // CY8C24x23 & CY8C24x23A Checksum Setup Vectors 113 | } extern chksm_setup; 114 | 115 | enum prg_block { 116 | PROGRAM_BLOCK_21_22_23_24_28_29_TST_TMG_TMA, // CY8C21xxx, CY8C21x45, CY8C22x45, CY8C23x33, CY8C24x23A, CY8C24x94, CY8C28xxx, CY8C29x66, TST1x0, TMG1x0, & TMA120 Program Block Vectors 117 | PROGRAM_BLOCK_27 // CY8C27x43 Program Block Vectors 118 | } extern prgm_block; 119 | 120 | typedef struct { 121 | programming_mode prog_mode; 122 | target_voltage targ_voltage; 123 | bool multi_bank; 124 | checksum_setup chksm_setup; 125 | prg_block prgm_block; 126 | } 127 | parameter; 128 | 129 | 130 | extern parameter param; 131 | 132 | extern unsigned char bTargetDataPtr; 133 | extern unsigned char abTargetDataOUT[TARGET_DATABUFF_LEN]; 134 | 135 | #endif //(INC_ISSP_EXTERN) 136 | 137 | -------------------------------------------------------------------------------- /issp_routines.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //-------------------------------------------------------------------------- 33 | 34 | #include "issp_defs.h" 35 | #include "issp_vectors.h" 36 | #include "issp_extern.h" 37 | #include "issp_errors.h" 38 | #include "issp_delays.h" 39 | 40 | unsigned char bTargetDataIN; 41 | unsigned char abTargetDataOUT[TARGET_DATABUFF_LEN]; 42 | 43 | unsigned char bTargetAddress; 44 | unsigned char bTargetDataPtr = 0; 45 | unsigned char bTargetID[2]; 46 | 47 | unsigned char fIsError; 48 | 49 | /* ((((((((((((((((((((( LOW-LEVEL ISSP SUBROUTINE SECTION )))))))))))))))))))) 50 | (( The subroutines in this section use functions from the C file )) 51 | (( ISSP_Drive_Routines.c. The functions in that file interface to the )) 52 | (( processor specific hardware. So, these functions should work as is, if )) 53 | (( the routines in ISSP_Drive_Routines.c are correctly converted. )) 54 | (((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))*/ 55 | 56 | // ============================================================================ 57 | // RunClock() 58 | // Description: 59 | // Run Clock without sending/receiving bits. Use this when transitioning from 60 | // write to read and read to write "num_cycles" is number of SCLK cycles, not 61 | // number of counter cycles. 62 | // 63 | // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some 64 | // processors may need to have delays added after setting SCLK low and setting 65 | // SCLK high in order to not exceed this specification. The maximum frequency 66 | // of SCLK should be measured as part of validation of the final program 67 | // 68 | // ============================================================================ 69 | void RunClock(unsigned int iNumCycles) 70 | { 71 | unsigned int i; 72 | 73 | for(i=0; i < iNumCycles; i++) { 74 | SCLKLow(); 75 | SCLKHigh(); 76 | } 77 | // function exits with CLK high. 78 | } 79 | 80 | // ============================================================================ 81 | // bReceiveBit() 82 | // Clocks the SCLK pin (high-low-high) and reads the status of the SDATA pin 83 | // after the rising edge. 84 | // 85 | // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some 86 | // processors may need to have delays added after setting SCLK low and setting 87 | // SCLK high in order to not exceed this specification. The maximum frequency 88 | // of SCLK should be measured as part of validation of the final program 89 | // 90 | // Returns: 91 | // 0 if SDATA was low 92 | // 1 if SDATA was high 93 | // ============================================================================ 94 | unsigned char bReceiveBit(void) 95 | { 96 | SCLKLow(); 97 | SCLKHigh(); 98 | if (fSDATACheck()) { 99 | return(1); 100 | } 101 | else { 102 | return(0); 103 | } 104 | } 105 | 106 | // ============================================================================ 107 | // bReceiveByte() 108 | // Calls ReceiveBit 8 times to receive one byte. 109 | // Returns: 110 | // The 8-bit values recieved. 111 | // ============================================================================ 112 | unsigned char bReceiveByte(void) 113 | { 114 | unsigned char b; 115 | unsigned char bCurrByte = 0x00; 116 | 117 | for (b=0; b<8; b++) { 118 | bCurrByte = (bCurrByte<<1) + bReceiveBit(); 119 | } 120 | return(bCurrByte); 121 | } 122 | 123 | 124 | // ============================================================================ 125 | // SendByte() 126 | // This routine sends up to one byte of a vector, one bit at a time. 127 | // bCurrByte the byte that contains the bits to be sent. 128 | // bSize the number of bits to be sent. Valid values are 1 to 8. 129 | // 130 | // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some 131 | // processors may need to have delays added after setting SCLK low and setting 132 | // SCLK high in order to not exceed this specification. The maximum frequency 133 | // of SCLK should be measured as part of validation of the final program 134 | // 135 | // There is no returned value. 136 | // ============================================================================ 137 | void SendByte(unsigned char bCurrByte, unsigned char bSize) 138 | { 139 | unsigned char b = 0; 140 | 141 | for(b=0; b 0) 173 | { 174 | if (iNumBits >= 8) { 175 | SendByte(*(bVect), 8); 176 | iNumBits -= 8; 177 | bVect++; 178 | } 179 | else { 180 | SendByte(*(bVect), iNumBits); 181 | iNumBits = 0; 182 | } 183 | } 184 | SetSDATAHiZ(); 185 | } 186 | 187 | 188 | // ============================================================================ 189 | // fDetectHiLoTransition() 190 | // Waits for transition from SDATA = 1 to SDATA = 0. Has a 100 msec timeout. 191 | // TRANSITION_TIMEOUT is a loop counter for a 100msec timeout when waiting for 192 | // a high-to-low transition. This is used in the polling loop of 193 | // fDetectHiLoTransition(). The timing of the while(1) loops can be calculated 194 | // and the number of loops is counted, using iTimer, to determine when 100 195 | // msec has passed. 196 | // 197 | // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some 198 | // processors may need to have delays added after setting SCLK low and setting 199 | // SCLK high in order to not exceed this specification. The maximum frequency 200 | // of SCLK should be measured as part of validation of the final program 201 | // 202 | // Returns: 203 | // 0 if successful 204 | // -1 if timed out. 205 | // ============================================================================ 206 | signed char fDetectHiLoTransition(void) 207 | { 208 | // nTimer breaks out of the while loops if the wait in the two loops totals 209 | // more than 100 msec. Making this static makes the loop run a faster. 210 | // This is really a processor/compiler dependency and it not needed. 211 | static unsigned int iTimer; 212 | 213 | // NOTE: 214 | // These loops look unconventional, but it is necessary to check SDATA_PIN 215 | // as shown because the transition can be missed otherwise, due to the 216 | // length of the SDATA Low-High-Low after certain commands. 217 | 218 | // Generate clocks for the target to pull SDATA High 219 | iTimer = millis() + TRANSITION_TIMEOUT; 220 | while(1) { 221 | SCLKLow(); 222 | if (fSDATACheck()) // exit once SDATA goes HI 223 | break; 224 | SCLKHigh(); 225 | // If the wait is too long then timeout 226 | if (iTimer < millis()) { 227 | return (ERROR); 228 | } 229 | } 230 | 231 | 232 | // Generate Clocks and wait for Target to pull SDATA Low again 233 | iTimer = millis() + TRANSITION_TIMEOUT; // reset the timeout counter 234 | while(1) { 235 | SCLKLow(); 236 | if (!fSDATACheck()) { // exit once SDATA returns LOW 237 | break; 238 | } 239 | SCLKHigh(); 240 | // If the wait is too long then timeout 241 | if (iTimer < millis()) { 242 | return (ERROR); 243 | } 244 | } 245 | return (PASS); 246 | } 247 | 248 | 249 | /* ((((((((((((((((((((( HIGH-LEVEL ISSP ROUTINE SECTION )))))))))))))))))))))) 250 | (( These functions are mostly made of calls to the low level routines )) 251 | (( above. This should isolate the processor-specific changes so that )) 252 | (( these routines do not need to be modified. )) 253 | (((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))*/ 254 | 255 | // ============================================================================ 256 | // fXRESInitializeTargetForISSP() 257 | // Implements the intialization vectors for the device. 258 | // ============================================================================ 259 | void fXRESInitializeTargetForISSP(void) 260 | { 261 | // Configure the pins for initialization 262 | SetSDATAHiZ(); 263 | SetSCLKStrong(); 264 | SCLKLow(); 265 | SetXRESStrong(); 266 | 267 | // Cycle reset and put the device in programming mode when it exits reset 268 | AssertXRES(); 269 | delayMicroseconds(XRES_CLK_DELAY); 270 | DeassertXRES(); 271 | // 272 | // !!! NOTE: 273 | // The timing spec that requires that the first Init-Vector happen within 274 | // 1 msec after the reset/power up. For this reason, it is not advisable 275 | // to separate the above RESET_MODE or POWER_CYCLE_MODE code from the 276 | // Init-Vector instructions below. Doing so could introduce excess delay 277 | // and cause the target device to exit ISSP Mode. 278 | 279 | // Here we send the magic that transitions into prog mode 280 | SendVector(init0_v, num_bits_init0); 281 | } 282 | 283 | signed char SendInitVectors(void) 284 | { 285 | SendVector(init1_v, num_bits_init1); 286 | if ((fIsError = fDetectHiLoTransition())) { 287 | return(INIT_ERROR); 288 | } 289 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 290 | 291 | // Send Initialize 2 Vector 292 | SendVector(init2_v, num_bits_init2); 293 | if ((fIsError = fDetectHiLoTransition())) { 294 | return(INIT_ERROR); 295 | } 296 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 297 | 298 | // Send Initialize 3 Vector NOTE: the proper vector based on Vdd of target 299 | if(param.targ_voltage == TARGET_VOLTAGE_5V) { 300 | SendVector(init3_5v, num_bits_init3_5v); // Target Vdd = 5v 301 | } else { 302 | SendVector(init3_3v, num_bits_init3_3v); // Target Vdd = 3.3v 303 | } 304 | 305 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 306 | 307 | // NOTE: DO NOT not wait for HiLo on SDATA after vector Init-3 308 | // it does not occur (per spec). 309 | return(PASS); 310 | } 311 | 312 | // ============================================================================ 313 | // fPowerCycleInitializeTargetForISSP() 314 | // Implements the intialization vectors for the device. 315 | // The first time fDetectHiLoTransition is called the Clk pin is highZ because 316 | // the clock is not needed during acquire. 317 | // Returns: 318 | // 0 if successful 319 | // INIT_ERROR if timed out on handshake to the device. 320 | // ============================================================================ 321 | signed char fPowerCycleInitializeTargetForISSP(void) 322 | { 323 | unsigned char n; 324 | 325 | // Set all pins to highZ to avoid back powering the PSoC through the GPIO 326 | // protection diodes. 327 | SetSCLKHiZ(); 328 | SetSDATAHiZ(); 329 | 330 | // Turn on power to the target device before other signals 331 | SetTargetVDDStrong(); 332 | ApplyTargetVDD(); 333 | // wait 1msec for the power to stabilize 334 | 335 | for (n=0; n<10; n++) { 336 | delayMicroseconds(DELAY100us); 337 | } 338 | 339 | // Set SCLK to high Z so there is no clock and wait for a high to low 340 | // transition on SDAT. SCLK is not needed this time. 341 | SetSCLKHiZ(); 342 | if ((fIsError = fDetectHiLoTransition())) { 343 | return(INIT_ERROR); 344 | } 345 | 346 | // Configure the pins for initialization 347 | SetSDATAHiZ(); 348 | SetSCLKStrong(); 349 | SCLKLow(); 350 | 351 | // !!! NOTE: 352 | // The timing spec that requires that the first Init-Vector happen within 353 | // 1 msec after the reset/power up. For this reason, it is not advisable 354 | // to separate the above RESET_MODE or POWER_CYCLE_MODE code from the 355 | // Init-Vector instructions below. Doing so could introduce excess delay 356 | // and cause the target device to exit ISSP Mode. 357 | 358 | // Send Initialization Vectors and detect Hi-Lo transition on SDATA 359 | SendVector(init1_v, num_bits_init1); 360 | if ((fIsError = fDetectHiLoTransition())) { 361 | return(INIT_ERROR); 362 | } 363 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 364 | 365 | // Send Initialize 2 Vector 366 | SendVector(init2_v, num_bits_init2); 367 | if ((fIsError = fDetectHiLoTransition())) { 368 | return(INIT_ERROR); 369 | } 370 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 371 | 372 | // Send Initialize 3 Vector NOTE: the proper vector based on Vdd of target 373 | #ifdef TARGET_VOLTAGE_IS_5V 374 | SendVector(init3_5v, num_bits_init3_5v); // Target Vdd = 5v 375 | #else 376 | SendVector(init3_3v, num_bits_init3_3v); // Target Vdd = 3.3v 377 | #endif 378 | 379 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 380 | 381 | // NOTE: DO NOT not wait for HiLo on SDATA after vector Init-3 382 | // it does not occur (per spec). 383 | return(PASS); 384 | } 385 | 386 | void setAddress(unsigned char bBankNumber, unsigned char bBlockNumber) { 387 | SendVector(set_block_number, 11); 388 | 389 | // Set the drive here because SendByte() does not 390 | SetSDATAStrong(); 391 | SendByte(bBlockNumber,8); 392 | SendByte(set_block_number_end, 3); 393 | 394 | SendVector(verify_setup_v, num_bits_verify_setup); 395 | if ((fIsError = fDetectHiLoTransition())) { 396 | return; 397 | } 398 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 399 | } 400 | 401 | uint8_t readReg(uint8_t bTargetReg) { 402 | //Send Read Byte vector and then get a byte from Target 403 | SendVector(read_reg_v, 3); 404 | // Set the drive here because SendByte() does not 405 | SetSDATAStrong(); 406 | SendByte(bTargetReg, 8); 407 | 408 | RunClock(2); // Run two SCLK cycles between writing and reading 409 | SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA 410 | bTargetDataIN = bReceiveByte(); 411 | 412 | RunClock(1); 413 | SendVector(read_reg_v + 1, 1); // Send the ReadByte Vector End 414 | return bTargetDataIN; 415 | } 416 | 417 | void writeReg(uint8_t bTargetReg, uint8_t bValue) { 418 | SendVector(write_reg_v, 3); 419 | // Set the drive here because SendByte() does not 420 | SetSDATAStrong(); 421 | SendByte(bTargetReg, 8); 422 | SendByte(bValue, 8); 423 | SendVector(write_reg_v+1, 3); 424 | } 425 | 426 | uint8_t readByte(uint8_t bTargetAddress) { 427 | //Send Read Byte vector and then get a byte from Target 428 | SendVector(read_byte_v, 3); 429 | // Set the drive here because SendByte() does not 430 | SetSDATAStrong(); 431 | SendByte(bTargetAddress, 8); 432 | 433 | RunClock(2); // Run two SCLK cycles between writing and reading 434 | SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA 435 | bTargetDataIN = bReceiveByte(); 436 | 437 | RunClock(1); 438 | SendVector(read_byte_v + 1, 1); // Send the ReadByte Vector End 439 | return bTargetDataIN; 440 | } 441 | 442 | void writeByte(uint8_t bTargetAddress, uint8_t bValue) { 443 | // Set the drive here because SendByte() does not 444 | SetSDATAStrong(); 445 | SendByte(write_byte_start, 3); 446 | SendByte(bTargetAddress, 8); 447 | SendByte(bValue, 8); 448 | SendByte(write_byte_end, 3); 449 | 450 | SetSDATAHiZ(); 451 | } 452 | 453 | int8_t getSiliconID(uint8_t * buff) { 454 | // Send ID-Setup vector set 455 | SendVector(id_setup_v, num_bits_id_setup); 456 | if ((fIsError = fDetectHiLoTransition())) { 457 | return(SiID_ERROR); 458 | } 459 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 460 | 461 | //Send Read ID vector and get Target ID 462 | SendVector(read_id_v, 11); // Read-MSB Vector is the first 11-Bits 463 | RunClock(2); // Two SCLK cycles between write & read 464 | buff[0] = bReceiveByte(); 465 | RunClock(1); 466 | SendVector(read_id_v+2, 12); // 12 bits starting from the 3rd character 467 | 468 | RunClock(2); // Read-LSB Command 469 | buff[1] = bReceiveByte(); 470 | 471 | RunClock(1); 472 | SendVector(read_id_v+4, 1); // 1 bit starting from the 5th character 473 | 474 | return 0; 475 | } 476 | 477 | int Exec(const unsigned char *opcodes) 478 | { 479 | /* [DE E0 1C] wrreg CPU_F, 0x00 480 | [DE 80 7C] wrreg F4, 0x03 481 | [DE A0 1C] wrreg F5, 0x00 482 | [DE C1 1C] wrreg F6, 0x08 483 | [DF 0A 3C] wrreg opc0, 0x51 484 | [DF 3F 9C] wrreg opc1, 0xFC 485 | [DF 46 1C] wrreg opc2, 0x30 486 | [DF E2 5C] wrreg CPU_SCR0, 0x12*/ 487 | writeReg(0xF7, 0); 488 | writeReg(0xF4, 0x03); 489 | writeReg(0xF5, 0x00); 490 | writeReg(0xF6, 0x08); 491 | writeReg(0xF8, opcodes[0]); 492 | writeReg(0xF9, opcodes[1]); 493 | writeReg(0xFA, opcodes[2]); 494 | writeReg(0xFF, 0x12); 495 | // Send nop ? 496 | // 497 | SendVector(wait_and_poll_end, 22); 498 | 499 | if ((fIsError = fDetectHiLoTransition())) { 500 | return(INIT_ERROR); 501 | } 502 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 503 | 504 | return PASS; 505 | } 506 | 507 | // ============================================================================ 508 | // fEraseTarget() 509 | // Perform a bulk erase of the target device. 510 | // Returns: 511 | // 0 if successful 512 | // ERASE_ERROR if timed out on handshake to the device. 513 | // ============================================================================ 514 | signed char fEraseTarget(void) 515 | { 516 | SendVector(erase_all_v, num_bits_erase_all); 517 | if ((fIsError = fDetectHiLoTransition())) { 518 | return(ERASE_ERROR); 519 | } 520 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 521 | return(PASS); 522 | } 523 | 524 | 525 | // ============================================================================ 526 | // LoadTarget() 527 | // Transfers data from array in Host to RAM buffer in the target. 528 | // Returns the checksum of the data. 529 | // ============================================================================ 530 | unsigned int iLoadTarget(void) 531 | { 532 | unsigned char bTemp; 533 | unsigned int iChecksumData = 0; 534 | 535 | // Set SDATA to Strong Drive here because SendByte() does not 536 | SetSDATAStrong(); 537 | 538 | // Transfer the temporary RAM array into the target. 539 | // In this section, a 64-Byte array was specified by #define, so the entire 540 | // 64-Bytes are written in this loop. 541 | bTargetAddress = 0x00; 542 | bTargetDataPtr = 0x00; 543 | 544 | while(bTargetDataPtr < TARGET_DATABUFF_LEN) { 545 | bTemp = abTargetDataOUT[bTargetDataPtr]; 546 | iChecksumData += bTemp; 547 | 548 | SendByte(write_byte_start,5); 549 | SendByte(bTargetAddress, 6); 550 | SendByte(bTemp, 8); 551 | SendByte(write_byte_end, 3); 552 | 553 | // !!!NOTE: 554 | // SendByte() uses MSbits, so inc by '4' to put the 0..63 address into 555 | // the six MSBit locations. 556 | // 557 | // This can be confusing, but check the logic: 558 | // The address is only 6-Bits long. The SendByte() subroutine will 559 | // send however-many bits, BUT...always reads them bits from left-to- 560 | // right. So in order to pass a value of 0..63 as the address using 561 | // SendByte(), we have to left justify the address by 2-Bits. 562 | // This can be done easily by incrementing the address each time by 563 | // '4' rather than by '1'. 564 | 565 | bTargetAddress += 4; 566 | bTargetDataPtr++; 567 | } 568 | return(iChecksumData); 569 | } 570 | 571 | // ============================================================================ 572 | // SetBankNumber() 573 | // Set the bank number in the target device. 574 | // Returns: 575 | // none 576 | // ============================================================================ 577 | void SetBankNumber(unsigned char bBankNumber) 578 | { 579 | // Send the bank-select vector. 580 | SendVector(set_bank_number, 33); 581 | 582 | // Set the drive here because SendByte() does not. 583 | SetSDATAStrong(); 584 | SendByte(bBankNumber,8); 585 | SendVector(set_bank_number_end, 25); 586 | } 587 | 588 | // ============================================================================ 589 | // fProgramTargetBlock() 590 | // Program one block with data that has been loaded into a RAM buffer in the 591 | // target device. 592 | // Returns: 593 | // 0 if successful 594 | // BLOCK_ERROR if timed out on handshake to the device. 595 | // ============================================================================ 596 | signed char fProgramTargetBlock(unsigned char bBankNumber, unsigned char bBlockNumber) 597 | { 598 | // Send the block-select vector. 599 | SendVector(set_block_number, 11); 600 | 601 | // Set the drive here because SendByte() does not. 602 | SetSDATAStrong(); 603 | SendByte(bBlockNumber,8); 604 | SendByte(set_block_number_end, 3); 605 | 606 | // Send the program-block vector. 607 | if(param.prgm_block == PROGRAM_BLOCK_21_22_23_24_28_29_TST_TMG_TMA) { 608 | program_block[1] = 0x8A; 609 | program_block[2] = 0x9E; 610 | } else { 611 | program_block[1] = 0x82; 612 | program_block[2] = 0xBE; 613 | } 614 | SendVector(program_block, num_bits_program_block); 615 | // wait for acknowledge from target. 616 | if ((fIsError = fDetectHiLoTransition())) { 617 | return(BLOCK_ERROR); 618 | } 619 | // Send the Wait-For-Poll-End vector 620 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 621 | return(PASS); 622 | } 623 | 624 | 625 | void send_checksum_v(void) 626 | { 627 | checksum_v[17] = 0xF6; 628 | checksum_v[26] = 0x40; 629 | 630 | SendVector(checksum_v, num_bits_checksum); 631 | RunClock(2); 632 | } 633 | 634 | // ============================================================================ 635 | // fAddTargetBankChecksum() 636 | // Reads and adds the target bank checksum to the referenced accumulator. 637 | // Returns: 638 | // 0 if successful 639 | // VERIFY_ERROR if timed out on handshake to the device. 640 | // ============================================================================ 641 | signed char fAccTargetBankChecksum(unsigned int* pAcc, unsigned char block_count) 642 | { 643 | // if(chksm_setup==CHECKSUM_SETUP_22_24_28_29_TST120_TMG120_TMA120) { 644 | checksum_v[17] = 0xF6; 645 | checksum_v[26] = 0x40; 646 | /* } else if(chksm_setup==CHECKSUM_SETUP_24_24A) { 647 | checksum_v[17] = 0xF7; 648 | checksum_v[26] = 0x20; 649 | } else { 650 | checksum_v[17] = 0xF7; 651 | checksum_v[26] = 0x00; 652 | }*/ 653 | 654 | checksum_v[26] = block_count>>1; 655 | checksum_v[27] |= (block_count&1)<<7; 656 | SendVector(checksum_v, num_bits_checksum); 657 | if ((fIsError = fDetectHiLoTransition())) { 658 | return(VERIFY_ERROR); 659 | } 660 | 661 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 662 | 663 | //Send Read Checksum vector and get Target Checksum 664 | SendVector(read_checksum_v, 11); // first 11-bits is ReadCKSum-MSB 665 | RunClock(2); // Two SCLKs between write & read 666 | *pAcc += (int)bReceiveByte() << 8; 667 | RunClock(1); // See Fig. 6 668 | SendVector(read_checksum_v + 2, 12); // 12 bits starting from 3rd character 669 | RunClock(2); // Read-LSB Command 670 | *pAcc += bReceiveByte(); 671 | RunClock(1); 672 | SendVector(read_checksum_v + 3, 1); // Send the final bit of the command 673 | return(PASS); 674 | } 675 | 676 | 677 | // ============================================================================ 678 | // ReStartTarget() 679 | // After programming, the target PSoC must be reset to take it out of 680 | // programming mode. This routine performs a reset. 681 | // ============================================================================ 682 | void ReStartTarget(void) 683 | { 684 | if(param.prog_mode == RESET_MODE) { 685 | // Assert XRES, then release, then disable XRES-Enable 686 | AssertXRES(); 687 | delayMicroseconds(XRES_CLK_DELAY); 688 | DeassertXRES(); 689 | } else { 690 | // Set all pins to highZ to avoid back powering the PSoC through the GPIO 691 | // protection diodes. 692 | SetSCLKHiZ(); 693 | SetSDATAHiZ(); 694 | // Cycle power on the target to cause a reset 695 | RemoveTargetVDD(); 696 | delayMicroseconds(POWER_CYCLE_DELAY); 697 | ApplyTargetVDD(); 698 | } 699 | } 700 | 701 | 702 | // ============================================================================ 703 | // fVerifyTargetBlock() 704 | // Verify the block just written to. This can be done byte-by-byte before the 705 | // protection bits are set. 706 | // Returns: 707 | // 0 if successful 708 | // BLOCK_ERROR if timed out on handshake to the device. 709 | // ============================================================================ 710 | signed char fVerifyTargetBlock(unsigned char bBankNumber, unsigned char bBlockNumber) 711 | { 712 | SendVector(set_block_number, 11); 713 | 714 | // Set the drive here because SendByte() does not 715 | SetSDATAStrong(); 716 | SendByte(bBlockNumber,8); 717 | SendByte(set_block_number_end, 3); 718 | 719 | SendVector(verify_setup_v, num_bits_verify_setup); 720 | if ((fIsError = fDetectHiLoTransition())) { 721 | return(BLOCK_ERROR); 722 | } 723 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 724 | 725 | bTargetAddress = 0; 726 | bTargetDataPtr = 0; 727 | 728 | while(bTargetDataPtr < TARGET_DATABUFF_LEN) { 729 | //Send Read Byte vector and then get a byte from Target 730 | SendVector(read_byte_v, 5); 731 | // Set the drive here because SendByte() does not 732 | SetSDATAStrong(); 733 | SendByte(bTargetAddress,6); 734 | 735 | RunClock(2); // Run two SCLK cycles between writing and reading 736 | SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA 737 | bTargetDataIN = bReceiveByte(); 738 | 739 | RunClock(1); 740 | SendVector(read_byte_v + 1, 1); // Send the ReadByte Vector End 741 | 742 | // Test the Byte that was read from the Target against the original 743 | // value (already in the 64-Byte array "abTargetDataOUT[]"). If it 744 | // matches, then bump the address & pointer,loop-back and continue. 745 | // If it does NOT match abort the loop and return and error. 746 | if (bTargetDataIN != abTargetDataOUT[bTargetDataPtr]) 747 | return(BLOCK_ERROR); 748 | 749 | bTargetDataPtr++; 750 | // Increment the address by four to accomodate 6-Bit addressing 751 | // (puts the 6-bit address into MSBit locations for "SendByte()"). 752 | bTargetAddress += 4; 753 | } 754 | return(PASS); 755 | } 756 | 757 | 758 | // ============================================================================ 759 | // fSecureTargetFlash() 760 | // Before calling, load the array, abTargetDataOUT, with the desired security 761 | // settings using LoadArrayWithSecurityData(StartAddress,Length,SecurityType). 762 | // The can be called multiple times with different SecurityTypes as needed for 763 | // particular Flash Blocks. Or set them all the same using the call below: 764 | // LoadArrayWithSecurityData(0,SECURITY_BYTES_PER_BANK, 0); 765 | // Returns: 766 | // 0 if successful 767 | // SECURITY_ERROR if timed out on handshake to the device. 768 | // ============================================================================ 769 | /*signed char fSecureTargetFlash(void) 770 | { 771 | unsigned char bTemp; 772 | 773 | // Transfer the temporary RAM array into the target 774 | bTargetAddress = 0x00; 775 | bTargetDataPtr = 0x00; 776 | SetSDATAStrong(); 777 | while(bTargetDataPtr < SECURITY_BYTES_PER_BANK) { 778 | bTemp = abTargetDataOUT[bTargetDataPtr]; 779 | SendByte(write_byte_start,5); 780 | SendByte(bTargetAddress, 6); 781 | SendByte(bTemp, 8); 782 | SendByte(write_byte_end, 3); 783 | 784 | // SendBytes() uses MSBits, so increment the address by '4' to put 785 | // the 0..n address into the six MSBit locations 786 | bTargetAddress += 4; 787 | bTargetDataPtr++; 788 | } 789 | 790 | SendVector(security_v, num_bits_security); 791 | if (fIsError = fDetectHiLoTransition()) { 792 | return(SECURITY_ERROR); 793 | } 794 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 795 | return(PASS); 796 | }*/ 797 | 798 | signed char fVerifySecurity(void) 799 | { 800 | //Send the vector to read the security bits 801 | SendVector(securityVerification_v, num_bits_securityVerification); 802 | 803 | //Generate one clock to make M8C core to start executing the instructions 804 | //from the test queue 805 | SCLKHigh(); 806 | SCLKLow(); 807 | 808 | if ((fIsError = fDetectHiLoTransition())) { 809 | return(SECURITY_ERROR); 810 | } 811 | SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); 812 | return PASS; 813 | } 814 | -------------------------------------------------------------------------------- /issp_vectors.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006-2010, Cypress Semiconductor Corporation. 2 | // 3 | // This software is owned by Cypress Semiconductor Corporation (Cypress) 4 | // and is protected by and subject to worldwide patent protection (United 5 | // States and foreign), United States copyright laws and international 6 | // treaty provisions. Cypress hereby grants to licensee a personal, 7 | // non-exclusive, non-transferable license to copy, use, modify, create 8 | // derivative works of, and compile the Cypress Source Code and derivative 9 | // works for the sole purpose of creating custom software in support of 10 | // licensee product to be used only in conjunction with a Cypress integrated 11 | // circuit as specified in the applicable agreement. Any reproduction, 12 | // modification, translation, compilation, or representation of this 13 | // software except as specified above is prohibited without the express 14 | // written permission of Cypress. 15 | // 16 | // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 17 | // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | // Cypress reserves the right to make changes without further notice to the 20 | // materials described herein. Cypress does not assume any liability arising 21 | // out of the application or use of any product or circuit described herein. 22 | // Cypress does not authorize its products for use as critical components in 23 | // life-support systems where a malfunction or failure may reasonably be 24 | // expected to result in significant injury to the user. The inclusion of 25 | // Cypress product in a life-support systems application implies that the 26 | // manufacturer assumes all risk of such use and in doing so indemnifies 27 | // Cypress against all charges. 28 | // 29 | // Use may be limited by and subject to the applicable Cypress software 30 | // license agreement. 31 | // 32 | //----------------------------------------------------------------------------- 33 | #ifndef INC_ISSP_VECTORS 34 | #define INC_ISSP_VECTORS 35 | 36 | // --------------------------- Specialized PSoC Vectors------------------------ 37 | // These Vectors will be altered by code, depending on selected device 38 | const unsigned int num_bits_checksum = 286; 39 | unsigned char checksum_v[] = 40 | { 41 | 0xDE, 0xE0, 0x1F, 0x7B, 0x00, 0x79, 0xF0, 0x75, 42 | 0xE7, 0xC8, 0x1F, 0xDE, 0xA0, 0x1F, 0x7A, 0x01, 43 | 0xF9, 0xF7, 0x01, 0xF7, 0xC9, 0x87, 0xDF, 0x48, 44 | 0x1E, 0x7D, 0x00, 0x7D, 0xE0, 0x0F, 0xF7, 0xC0, 45 | 0x07, 0xDF, 0xE2, 0x5C 46 | }; 47 | 48 | const unsigned int num_bits_program_block = 308; 49 | unsigned char program_block[] = 50 | { 51 | 0x9F, 0x8A, 0x9E, 0x7F, 0x2B, 0x7D, 0xEE, 0x01, 52 | 0xF7, 0xB0, 0x07, 0x9F, 0x07, 0x5E, 0x7C, 0x81, 53 | 0xFD, 0xEA, 0x01, 0xF7, 0xA0, 0x1F, 0x9F, 0x70, 54 | 0x1F, 0x7C, 0x98, 0x7D, 0xF4, 0x81, 0xF7, 0x80, 55 | 0x17, 0xDF, 0x00, 0x1F, 0x7F, 0x89, 0x70 56 | }; 57 | 58 | // ----------------------------- General PSoC Vectors-------------------------- 59 | const unsigned int num_bits_init0 = 132; 60 | const unsigned char init0_v[] = 61 | { 62 | 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00 65 | }; 66 | 67 | const unsigned int num_bits_init1 = 264; 68 | const unsigned char init1_v[] = 69 | { 70 | 0xDE, 0xE0, 0x1F, 0x7B, 0x00, 0x79, 0xF0, 0x75, 71 | 0xE7, 0xC8, 0x1F, 0xDE, 0xA0, 0x1F, 0x7A, 0x01, 72 | 0xF9, 0xF7, 0x01, 0xF7, 0xC9, 0x87, 0xDF, 0x48, 73 | 0x1F, 0x78, 0x04, 0xFD, 0xF0, 0x01, 0xF7, 0xF8, 74 | 0x97 75 | }; 76 | 77 | const unsigned int num_bits_init2 = 288; 78 | const unsigned char init2_v[] = 79 | { 80 | 0xDE, 0xE0, 0x1F, 0x7B, 0x00, 0x79, 0xF0, 0x75, 81 | 0xE7, 0xC8, 0x1F, 0xDE, 0xA0, 0x1F, 0x7A, 0x01, 82 | 0xF9, 0xF7, 0x01, 0xF7, 0xC9, 0x87, 0xDF, 0x48, 83 | 0x1E, 0x7D, 0x00, 0xFD, 0xE0, 0x0D, 0xF7, 0xC0, 84 | 0x07, 0xDF, 0xE2, 0x5C 85 | }; 86 | 87 | const unsigned int num_bits_init3_5v = 836; 88 | const unsigned char init3_5v[] = 89 | { 90 | 0xDE, 0xE0, 0x1F, 0x7A, 0x01, 0xFD, 0xEA, 0x01, 91 | 0xF7, 0xB0, 0x47, 0xDF, 0x0A, 0x3F, 0x7C, 0xFE, 92 | 0x7D, 0xF4, 0x61, 0xF7, 0xF8, 0x97, 0x00, 0x00, 93 | 0x03, 0x7B, 0x80, 0x7D, 0xE8, 0x07, 0xF7, 0xA8, 94 | 0x07, 0xDE, 0xC1, 0x1F, 0x7C, 0x30, 0x7D, 0xF3, 95 | 0xD5, 0xF7, 0xD1, 0x87, 0xDE, 0xE2, 0x1F, 0x7F, 96 | 0x89, 0x70, 0x00, 0x00, 0x37, 0xB8, 0x07, 0xDE, 97 | 0x80, 0x7F, 0x7A, 0x80, 0x7D, 0xEC, 0x11, 0xF7, 98 | 0xC2, 0x8F, 0xDF, 0x3F, 0xBF, 0x7D, 0x18, 0x7D, 99 | 0xFE, 0x25, 0xC0, 0x00, 0x00, 0xDE, 0xE0, 0x1F, 100 | 0x7A, 0x01, 0xFD, 0xEA, 0x01, 0xF7, 0xB0, 0x47, 101 | 0xDF, 0x0C, 0x1F, 0x7C, 0xF4, 0x7D, 0xF4, 0x61, 102 | 0xF7, 0xB8, 0x87, 0xDF, 0xE2, 0x5C, 0x00, 0x00, 103 | 0x00 104 | }; 105 | 106 | const unsigned int num_bits_init3_3v = 840; 107 | const unsigned char init3_3v[] = 108 | { 109 | 0xDE, 0xE0, 0x1F, 0x7A, 0x01, 0xFD, 0xEA, 0x01, 110 | 0xF7, 0xB0, 0x47, 0xDF, 0x0A, 0x3F, 0x7C, 0xFC, 111 | 0x7D, 0xF4, 0x61, 0xF7, 0xF8, 0x97, 0x00, 0x00, 112 | 0x03, 0x7B, 0x80, 0x7D, 0xE8, 0x07, 0xF7, 0xA8, 113 | 0x07, 0xDE, 0xC1, 0x1F, 0x7C, 0x30, 0x7D, 0xF3, 114 | 0xD5, 0xF7, 0xD1, 0x87, 0xDE, 0xE2, 0x1F, 0x7F, 115 | 0x89, 0x70, 0x00, 0x00, 0x37, 0xB8, 0x07, 0xDE, 116 | 0x80, 0x7F, 0x7A, 0x80, 0x7D, 0xEC, 0x11, 0xF7, 117 | 0xC2, 0x8F, 0xDF, 0x3F, 0x3F, 0x7D, 0x18, 0x7D, 118 | 0xFE, 0x25, 0xC0, 0x00, 0x00, 0xDE, 0xE0, 0x1F, 119 | 0x7A, 0x01, 0xFD, 0xEA, 0x01, 0xF7, 0xB0, 0x47, 120 | 0xDF, 0x0C, 0x1F, 0x7C, 0xF4, 0x7D, 0xF4, 0x61, 121 | 0xF7, 0xB8, 0x87, 0xDF, 0xE2, 0x5C, 0x00, 0x00, 122 | 0x00 123 | }; 124 | 125 | const unsigned int num_bits_id_setup = 330; 126 | const unsigned char id_setup_v[] = 127 | { 128 | 0xDE, 0xE2, 0x1F, 0x70, 0x01, 0x7D, 0xEE, 0x01, 129 | 0xF7, 0xB0, 0x07, 0x9F, 0x07, 0x5E, 0x7C, 0x81, 130 | 0xFD, 0xEA, 0x01, 0xF7, 0xA0, 0x1F, 0x9F, 0x70, 131 | 0x1F, 0x7C, 0x98, 0x7D, 0xF4, 0x81, 0xE7, 0xD0, 132 | 0x07, 0xDE, 0x00, 0xDF, 0x7C, 0x00, 0x7D, 0xFE, 133 | 0x25, 0xC0 134 | }; 135 | 136 | const unsigned int num_bits_erase_all = 308; 137 | const unsigned char erase_all_v[] = 138 | { 139 | 0x9F, 0x82, 0xBE, 0x7F, 0x2B, 0x7D, 0xEE, 0x01, 140 | 0xF7, 0xB0, 0x07, 0x9F, 0x07, 0x5E, 0x7C, 0x81, 141 | 0xFD, 0xEA, 0x01, 0xF7, 0xA0, 0x1F, 0x9F, 0x70, 142 | 0x1F, 0x7C, 0x98, 0x7D, 0xF4, 0x81, 0xF7, 0x80, 143 | 0x2F, 0xDF, 0x00, 0x1F, 0x7F, 0x89, 0x70 144 | }; 145 | 146 | const unsigned char read_id_v[] = 147 | { 148 | 0xBF, 0x00, 0xDF, 0x90, 0x00 149 | }; 150 | 151 | const unsigned char write_byte_start = 0x90; 152 | const unsigned char write_byte_end = 0xE0; 153 | 154 | const unsigned char set_block_number[] = {0x9F, 0x40, 0xE0}; 155 | const unsigned char set_block_number_end = 0xE0; 156 | 157 | const unsigned char set_bank_number[] = {0xDE, 0xE2, 0x1F, 0x7D, 0x00}; 158 | const unsigned char set_bank_number_end[] = {0xFB, 0xDC, 0x03, 0x80}; 159 | 160 | const unsigned char num_bits_wait_and_poll_end = 40; 161 | const unsigned char wait_and_poll_end[] = 162 | { 163 | 0x00, 0x00, 0x00, 0x00, 0x00 164 | }; // forty '0's per the spec 165 | 166 | const unsigned char read_checksum_v[] = 167 | { 168 | 0xBF, 0x20, 0xDF, 0x80, 0x80 169 | }; 170 | 171 | const unsigned char read_byte_v[] = 172 | { 173 | 0xB0, 0x80 174 | }; 175 | 176 | const unsigned char read_reg_v[] = 177 | { 178 | 0xE0, 0x80 179 | }; 180 | 181 | const unsigned char write_reg_v[] = 182 | { 183 | 0xC0, 0xE0 184 | }; 185 | 186 | const unsigned int num_bits_verify_setup = 264; 187 | const unsigned char verify_setup_v[] = 188 | { 189 | 0xDE, 0xE0, 0x1F, 0x7B, 0x00, 0x79, 0xF0, 0x75, 190 | 0xE7, 0xC8, 0x1F, 0xDE, 0xA0, 0x1F, 0x7A, 0x01, 191 | 0xF9, 0xF7, 0x01, 0xF7, 0xC9, 0x87, 0xDF, 0x48, 192 | 0x1F, 0x78, 0x00, 0xFD, 0xF0, 0x01, 0xF7, 0xF8, 193 | 0x97 194 | }; 195 | 196 | const unsigned int num_bits_security = 308; 197 | const unsigned char security_v[] = 198 | { 199 | 0x9F, 0x8A, 0x9E, 0x7F, 0x2B, 0x7D, 0xEE, 0x01, 200 | 0xF7, 0xB0, 0x07, 0x9F, 0x07, 0x5E, 0x7C, 0x81, 201 | 0xFD, 0xEA, 0x01, 0xF7, 0xA0, 0x1F, 0x9F, 0x70, 202 | 0x1F, 0x7C, 0x98, 0x7D, 0xF4, 0x81, 0xF7, 0x80, 203 | 0x27, 0xDF, 0x00, 0x1F, 0x7F, 0x89, 0x70 204 | }; 205 | 206 | const unsigned int num_bits_securityVerification = 308; 207 | const unsigned char securityVerification_v[] = 208 | { 209 | 0xDE,0xE0,0x1F,0x7B,0x00,0x79,0xF0,0x75,0xE7,0xC8,0x1F, 210 | 0x9F,0xA0,0x1E,0x7F,0x80,0x7D,0xEA,0x01,0xF7,0xA0,0x1F, 211 | 0x9F,0x70,0x1F,0x7C,0x98,0x7D,0xF4,0x81,0xF7,0x80,0x87, 212 | 0xDF,0x0,0x1F,0x7F,0x89,0x70 213 | 214 | // 0b11011110, 0b11100000, 0b00011111, 0b01111011, 0b00000000, 0b01111001, 0b11110000, 0b01110101, 215 | // 0b11100111, 0b11001000, 0b00011111, 0b10011111, 0b10100000, 0b00011110, 0b01111111, 0b10000000, 216 | // 0b01111101, 0b11101010, 0b00000001, 0b11110111, 0b10100000, 0b00011111, 0b10011111, 0b01110000, 217 | // 0b00011111, 0b01111100, 0b10011000, 0b01111101, 0b11110100, 0b10000001, 0b11110111, 0b10000000, 218 | // 0b10000111, 0b11011111, 0b00000000, 0b00011111, 0b01111111, 0b10001001, 0b01110000 219 | }; 220 | #endif //(INC_ISSP_VECTORS) 221 | 222 | -------------------------------------------------------------------------------- /stk500_protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef _STK500_PROTOCOL_H_ 2 | #define _STK500_PROTOCOL_H_ 3 | 4 | // *****************[ STK Message constants ]*************************** 5 | 6 | #define STK_SIGN_ON_MESSAGE "AVR STK" // Sign on string for Cmnd_STK_GET_SIGN_ON 7 | 8 | // *****************[ STK Response constants ]*************************** 9 | 10 | #define Resp_STK_OK 0x10 // ' ' 11 | #define Resp_STK_FAILED 0x11 // ' ' 12 | #define Resp_STK_UNKNOWN 0x12 // ' ' 13 | #define Resp_STK_NODEVICE 0x13 // ' ' 14 | #define Resp_STK_INSYNC 0x14 // ' ' 15 | #define Resp_STK_NOSYNC 0x15 // ' ' 16 | 17 | #define Resp_ADC_CHANNEL_ERROR 0x16 // ' ' 18 | #define Resp_ADC_MEASURE_OK 0x17 // ' ' 19 | #define Resp_PWM_CHANNEL_ERROR 0x18 // ' ' 20 | #define Resp_PWM_ADJUST_OK 0x19 // ' ' 21 | 22 | // *****************[ STK Special constants ]*************************** 23 | 24 | #define Sync_CRC_EOP 0x20 // 'SPACE' 25 | 26 | // *****************[ STK Command constants ]*************************** 27 | 28 | #define Cmnd_STK_GET_SYNC 0x30 // ' ' 29 | #define Cmnd_STK_GET_SIGN_ON 0x31 // ' ' 30 | 31 | #define Cmnd_STK_SET_PARAMETER 0x40 // ' ' 32 | #define Cmnd_STK_GET_PARAMETER 0x41 // ' ' 33 | #define Cmnd_STK_SET_DEVICE 0x42 // ' ' 34 | #define Cmnd_STK_SET_DEVICE_EXT 0x45 // ' ' 35 | 36 | #define Cmnd_STK_ENTER_PROGMODE 0x49 // ' ' 37 | #define Cmnd_STK_INIT_PROGMODE 0x50 // ' ' 38 | #define Cmnd_STK_LEAVE_PROGMODE 0x51 // ' ' 39 | #define Cmnd_STK_CHIP_ERASE 0x52 // ' ' 40 | #define Cmnd_STK_CHECK_AUTOINC 0x53 // ' ' 41 | #define Cmnd_STK_LOAD_ADDRESS 0x55 // ' ' 42 | #define Cmnd_STK_UNIVERSAL 0x56 // ' ' 43 | #define Cmnd_STK_UNIVERSAL_MULTI 0x57 // ' ' 44 | 45 | #define Cmnd_STK_PROG_FLASH 0x60 // ' ' 46 | #define Cmnd_STK_PROG_DATA 0x61 // ' ' 47 | #define Cmnd_STK_PROG_FUSE 0x62 // ' ' 48 | #define Cmnd_STK_PROG_LOCK 0x63 // ' ' 49 | #define Cmnd_STK_PROG_PAGE 0x64 // ' ' 50 | #define Cmnd_STK_PROG_FUSE_EXT 0x65 // ' ' 51 | 52 | #define Cmnd_STK_READ_FLASH 0x70 // ' ' 53 | #define Cmnd_STK_READ_DATA 0x71 // ' ' 54 | #define Cmnd_STK_READ_FUSE 0x72 // ' ' 55 | #define Cmnd_STK_READ_LOCK 0x73 // ' ' 56 | #define Cmnd_STK_READ_PAGE 0x74 // ' ' 57 | #define Cmnd_STK_READ_SIGN 0x75 // ' ' 58 | #define Cmnd_STK_READ_OSCCAL 0x76 // ' ' 59 | #define Cmnd_STK_READ_FUSE_EXT 0x77 // ' ' 60 | #define Cmnd_STK_READ_OSCCAL_EXT 0x78 // ' ' 61 | #define Cmnd_STK_READ_REG 0x79 // ' ' 62 | #define Cmnd_STK_WRITE_REG 0x80 // ' ' 63 | #define Cmnd_STK_READ_MEM 0x81 // ' ' 64 | #define Cmnd_STK_WRITE_MEM 0x82 // ' ' 65 | #define Cmnd_STK_EXEC_OPCODES 0x83 // ' ' 66 | #define Cmnd_STK_RUN_CSUM 0x84 // ' ' 67 | #define Cmnd_STK_START_CSUM 0x85 // ' ' 68 | #define Cmnd_STK_READ_SECURITY 0x86 // ' ' 69 | 70 | // *****************[ STK Parameter constants ]*************************** 71 | 72 | #define Parm_STK_HW_VER 0x80 // ' ' - R 73 | #define Parm_STK_SW_MAJOR 0x81 // ' ' - R 74 | #define Parm_STK_SW_MINOR 0x82 // ' ' - R 75 | #define Parm_STK_LEDS 0x83 // ' ' - R/W 76 | #define Parm_STK_VTARGET 0x84 // ' ' - R/W 77 | #define Parm_STK_VADJUST 0x85 // ' ' - R/W 78 | #define Parm_STK_OSC_PSCALE 0x86 // ' ' - R/W 79 | #define Parm_STK_OSC_CMATCH 0x87 // ' ' - R/W 80 | #define Parm_STK_RESET_DURATION 0x88 // ' ' - R/W 81 | #define Parm_STK_SCK_DURATION 0x89 // ' ' - R/W 82 | 83 | #define Parm_STK_BUFSIZEL 0x90 // ' ' - R/W, Range {0..255} 84 | #define Parm_STK_BUFSIZEH 0x91 // ' ' - R/W, Range {0..255} 85 | #define Parm_STK_DEVICE 0x92 // ' ' - R/W, Range {0..255} 86 | #define Parm_STK_PROGMODE 0x93 // ' ' - 'P' or 'S' 87 | #define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE 88 | #define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE 89 | #define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE 90 | #define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached 91 | 92 | // *****************[ STK status bit definitions ]*************************** 93 | 94 | #define Stat_STK_INSYNC 0x01 // INSYNC status bit, '1' - INSYNC 95 | #define Stat_STK_PROGMODE 0x02 // Programming mode, '1' - PROGMODE 96 | #define Stat_STK_STANDALONE 0x04 // Standalone mode, '1' - SM mode 97 | #define Stat_STK_RESET 0x08 // RESET button, '1' - Pushed 98 | #define Stat_STK_PROGRAM 0x10 // Program button, ' 1' - Pushed 99 | #define Stat_STK_LEDG 0x20 // Green LED status, '1' - Lit 100 | #define Stat_STK_LEDR 0x40 // Red LED status, '1' - Lit 101 | #define Stat_STK_LEDBLINK 0x80 // LED blink ON/OFF, '1' - Blink 102 | 103 | #endif 104 | --------------------------------------------------------------------------------