// ============================================================================ // SendVector() // This routine sends the vector specifed. All vectors constant strings found // in ISSP_Vectors.h. The data line is returned to HiZ after the vector is // sent. // bVect a pointer to the vector to be sent. // nNumBits the number of bits to be sent. // bCurrByte scratch var to keep the byte to be sent. // // There is no returned value. // ============================================================================ void SendVector(const unsigned char *bVect, unsigned int iNumBits) { SetSDATAStrong(); while (iNumBits > 0) { if (iNumBits >= 8) { SendByte(*(bVect), 8); iNumBits -= 8; bVect++; } else { SendByte(*(bVect), iNumBits); iNumBits = 0; } } SetSDATALow(); // issp_test_20100709 add SetSDATAHiZ(); }
/* ============================================================================ SendByte() This routine sends up to one byte of a vector, one bit at a time. bCurrByte the byte that contains the bits to be sent. bSize the number of bits to be sent. Valid values are 1 to 8. SCLK cannot run faster than the specified maximum frequency of 8MHz. Some processors may need to have delays added after setting SCLK low and setting SCLK high in order to not exceed this specification. The maximum frequency of SCLK should be measured as part of validation of the final program There is no returned value. ============================================================================ */ void SendByte(unsigned char bCurrByte, unsigned char bSize) { unsigned char b = 0; for (b = 0; b < bSize; b++) { if (bCurrByte & 0x80) { SetSDATAHigh(); SCLKHigh(); SCLKLow(); } else { SetSDATALow(); SCLKHigh(); SCLKLow(); } bCurrByte = bCurrByte << 1; } }
/* ============================================================================ // fPowerCycleInitializeTargetForISSP() // Implements the intialization vectors for the device. // The first time fDetectHiLoTransition is called the Clk pin is highZ because // the clock is not needed during acquire. // Returns: // 0 if successful // INIT_ERROR if timed out on handshake to the device. ============================================================================*/ signed char fPowerCycleInitializeTargetForISSP(void) { unsigned char n; SetSDATALow(); SCLKLow(); RemoveTargetVDD(); mdelay(500); SetSCLKHiZ(); SetSDATAHiZ(); /* Set all pins to highZ to avoid back powering the PSoC through the GPIO // protection diodes. */ /* Turn on power to the target device before other signals */ SetTargetVDDStrong(); ApplyTargetVDD(); /* wait 1msec for the power to stabilize */ for (n = 0; n < 10; n++) udelay(DELAY100us); /* Set SCLK to high Z so there is no clock and wait for a high to low // transition on SDAT. SCLK is not needed this time. */ SetSCLKHiZ(); mdelay(10); /* //fIsError = fDetectHiLoTransition(); //if (fIsError ) { //printk("wly: fDetectHiLoTransition 11111 failed!\n"); //return(INIT_ERROR); //} */ /* Configure the pins for initialization */ SetSDATAHiZ(); SetSCLKStrong(); SCLKLow(); /* DO NOT SET A BREAKPOINT HERE AND EXPECT SILICON ID TO PASS! */ /* !!! NOTE: // The timing spec that requires that the first Init-Vector happen within // 1 msec after the reset/power up. For this reason, it is not advisable // to separate the above RESET_MODE or POWER_CYCLE_MODE code from the // Init-Vector instructions below. Doing so could introduce excess delay // and cause the target device to exit ISSP Mode. */ SendVector(id_setup_1, num_bits_id_setup_1); fIsError = fDetectHiLoTransition(); if (fIsError) { pr_info("wly: fDetectHiLoTransition 222222 failed!\n"); return INIT_ERROR; } SendVector(wait_and_poll_end, num_bits_wait_and_poll_end); /* NOTE: DO NOT not wait for HiLo on SDATA after vector Init-3 // it does not occur (per spec). */ return PASS; }
/* ============================================================================ // fDetectHiLoTransition() // Waits for transition from SDATA = 1 to SDATA = 0. Has a 100 msec timeout. // TRANSITION_TIMEOUT is a loop counter for a 100msec timeout when waiting for // a high-to-low transition. This is used in the polling loop of // fDetectHiLoTransition(). The timing of the while(1) loops can be calculated // and the number of loops is counted, using iTimer, to determine when 100 // msec has passed. // // SCLK cannot run faster than the specified maximum frequency of 8MHz. Some // processors may need to have delays added after setting SCLK low and setting // SCLK high in order to not exceed this specification. The maximum frequency // of SCLK should be measured as part of validation of the final program // // Returns: // 0 if successful // -1 if timed out. ============================================================================*/ signed char fDetectHiLoTransition(void) { /* nTimer breaks out of the while loops if the wait in the two loops totals // more than 100 msec. Making this static makes the loop run a faster. // This is really a processor/compiler dependency and it not needed. */ static unsigned int iTimer; /* NOTE: // These loops look unconventional, but it is necessary to check SDATA_PIN // as shown because the transition can be missed otherwise, due to the // length of the SDATA Low-High-Low after certain commands. */ /* Generate clocks for the target to pull SDATA High */ iTimer = 40000; /*TRANSITION_TIMEOUT; */ while (1) { int ret; SCLKLow(); ret = fSDATACheck(); if (ret) /* exit once SDATA goes HI */ break; SCLKHigh(); /* If the wait is too long then timeout */ if (iTimer-- == 0) return ERROR; } /* Generate Clocks and wait for Target to pull SDATA Low again */ #if 0 /* wly */ iTimer = 40000;/* TRANSITION_TIMEOUT; */ while (1) { int ret; SCLKLow(); ret = fSDATACheck(); /* pr_info("wly while 2, ret=%d\n", ret); */ if (!ret) { /* exit once SDATA returns LOW */ break; } /* SCLKHigh(); // If the wait is too long then timeout */ if (iTimer-- == 0) { #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif return ERROR; } } #else SCLKHigh(); SetSDATALow(); SCLKLow(); if (!fSDATACheck()) /* exit once SDATA returns LOW */ SetSDATAHiZ(); mdelay(20); #endif #ifdef USE_TP SetTPHigh(); /* Only used of Test Points are enabled */ #endif return PASS; }