aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/cypressbln/issp_routines.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard/cypressbln/issp_routines.c')
-rw-r--r--drivers/input/keyboard/cypressbln/issp_routines.c1044
1 files changed, 1044 insertions, 0 deletions
diff --git a/drivers/input/keyboard/cypressbln/issp_routines.c b/drivers/input/keyboard/cypressbln/issp_routines.c
new file mode 100644
index 0000000..0186e2b
--- /dev/null
+++ b/drivers/input/keyboard/cypressbln/issp_routines.c
@@ -0,0 +1,1044 @@
+// filename: ISSP_Routines.c
+#include "issp_revision.h"
+#ifdef PROJECT_REV_304
+/* Copyright 2006-2007, Cypress Semiconductor Corporation.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONRTACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,
+ WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ Cypress reserves the right to make changes without further notice to the
+ materials described herein. Cypress does not assume any liability arising
+ out of the application or use of any product or circuit described herein.
+ Cypress does not authorize its products for use as critical components in
+ life-support systems where a malfunction or failure may reasonably be
+ expected to result in significant injury to the user. The inclusion of
+ Cypressï¿?product in a life-support systems application implies that the
+ manufacturer assumes all risk of such use and in doing so indemnifies
+ Cypress against all charges.
+
+ Use may be limited by and subject to the applicable Cypress software
+ license agreement.
+
+--------------------------------------------------------------------------*/
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+#include <asm/gpio.h>
+#include <linux/miscdevice.h>
+#include <asm/uaccess.h>
+#include <linux/earlysuspend.h>
+#include <asm/io.h>
+#include <linux/hrtimer.h>
+//mhsong #include <m8c.h> // part specific constants and macros
+//mhsong #include "PSoCAPI.h" // PSoC API definitions for all User Modules
+#include "issp_defs.h"
+#include "issp_vectors.h"
+#include "issp_extern.h"
+#include "issp_errors.h"
+#include "issp_directives.h"
+#include "issp_delays.h"
+
+unsigned char bTargetDataIN;
+unsigned char abTargetDataOUT[TARGET_DATABUFF_LEN];
+
+unsigned char bTargetAddress;
+unsigned char bTargetDataPtr = 0;
+unsigned char bTargetID[10];
+unsigned char bTargetStatus[10]; //PTJ: created to support READ-STATUS in fReadStatus()
+
+unsigned char fIsError;
+
+/* ((((((((((((((((((((( LOW-LEVEL ISSP SUBROUTINE SECTION ))))))))))))))))))))
+ (( The subroutines in this section use functions from the C file ))
+ (( ISSP_Drive_Routines.c. The functions in that file interface to the ))
+ (( processor specific hardware. So, these functions should work as is, if ))
+ (( the routines in ISSP_Drive_Routines.c are correctly converted. ))
+ (((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))*/
+
+// ============================================================================
+// RunClock()
+// Description:
+// Run Clock without sending/receiving bits. Use this when transitioning from
+// write to read and read to write "num_cycles" is number of SCLK cycles, not
+// number of counter cycles.
+//
+// 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
+//
+// ============================================================================
+void RunClock(unsigned int iNumCycles)
+{
+ int i;
+
+ for (i = 0; i < iNumCycles; i++) {
+ SCLKLow();
+ SCLKHigh();
+ }
+ // function exits with CLK high.
+}
+
+// ============================================================================
+// bReceiveBit()
+// Clocks the SCLK pin (high-low-high) and reads the status of the SDATA pin
+// after the rising edge.
+//
+// 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 SDATA was low
+// 1 if SDATA was high
+// ============================================================================
+unsigned char bReceiveBit(void)
+{
+ SCLKLow();
+ SCLKHigh();
+ if (fSDATACheck()) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+// ============================================================================
+// bReceiveByte()
+// Calls ReceiveBit 8 times to receive one byte.
+// Returns:
+// The 8-bit values recieved.
+// ============================================================================
+unsigned char bReceiveByte(void)
+{
+ unsigned char b;
+ unsigned char bCurrByte = 0x00;
+
+ for (b = 0; b < 8; b++) {
+ bCurrByte = (bCurrByte << 1) + bReceiveBit();
+ }
+ return (bCurrByte);
+}
+
+// ============================================================================
+// 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) {
+ // Send a '1'
+ SetSDATAHigh();
+ SCLKHigh();
+ SCLKLow();
+ } else {
+ // Send a '0'
+ SetSDATALow();
+ SCLKHigh();
+ SCLKLow();
+ }
+ bCurrByte = bCurrByte << 1;
+ }
+}
+
+// ============================================================================
+// 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();
+}
+
+// ============================================================================
+// 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
+ //dog_kick();
+ iTimer = TRANSITION_TIMEOUT;
+ printk(KERN_DEBUG
+ "Generate clocks for the target to pull SDATA High\n");
+ while (1) {
+ SCLKLow();
+ if (fSDATACheck()) // exit once SDATA goes HI
+ break;
+ SCLKHigh();
+ // If the wait is too long then timeout
+ if (iTimer-- == 0) {
+ return (ERROR);
+ }
+ }
+ //dog_kick();
+ // Generate Clocks and wait for Target to pull SDATA Low again
+ iTimer = TRANSITION_TIMEOUT; // reset the timeout counter
+ printk(KERN_DEBUG
+ "Generate Clocks and wait for Target to pull SDATA Low again\n");
+ while (1) {
+ SCLKLow(); //issp_test_20100709 unblock
+ if (!fSDATACheck()) { // exit once SDATA returns LOW
+ break;
+ }
+ SCLKHigh(); //issp_test_20100709 unblock
+ // If the wait is too long then timeout
+ if (iTimer-- == 0) {
+ return (ERROR);
+ }
+ }
+ printk("fDetectHiLoTransition OUT!!!!\n");
+ return (PASS);
+}
+
+/* ((((((((((((((((((((( HIGH-LEVEL ISSP ROUTINE SECTION ))))))))))))))))))))))
+ (( These functions are mostly made of calls to the low level routines ))
+ (( above. This should isolate the processor-specific changes so that ))
+ (( these routines do not need to be modified. ))
+ (((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))*/
+
+#ifdef RESET_MODE
+// ============================================================================
+// fXRESInitializeTargetForISSP()
+// Implements the intialization vectors for the device.
+// Returns:
+// 0 if successful
+// INIT_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fXRESInitializeTargetForISSP(void)
+{
+ // Configure the pins for initialization
+ SetSDATAHiZ();
+ SetSCLKStrong();
+ SCLKLow();
+ // Cycle reset and put the device in programming mode when it exits reset
+ AssertXRES();
+ DeassertXRES();
+ // !!! 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.
+
+ //PTJ: Send id_setup_1 instead of init1_v
+ //PTJ: both send CA Test Key and do a Calibrate1 SROM function
+ SendVector(id_setup_1, num_bits_id_setup_1);
+ if (fIsError = fDetectHiLoTransition()) {
+// TX8SW_CPutString("\r\n fDetectHiLoTransition Error");
+ printk("\r\n fDetectHiLoTransition Error\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);
+}
+#else //else = the part is power cycle programmed
+
+// ============================================================================
+// 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;
+
+ // Set all pins to highZ to avoid back powering the PSoC through the GPIO
+ // protection diodes.
+ SetSCLKHiZ();
+ SetSDATAHiZ();
+
+ // Turn on power to the target device before other signals
+ SetTargetVDDStrong();
+ ApplyTargetVDD();
+ // wait 1msec for the power to stabilize
+#if 0
+ for (n = 0; n < 10; n++) {
+ Delay(DELAY100us);
+ }
+#endif
+ // 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();
+// printk(KERN_DEBUG "fDetectHiLoTransition\n");
+ if ((fIsError = fDetectHiLoTransition())) {
+ return (INIT_ERROR);
+ }
+ // Configure the pins for initialization
+// SetSDATAHiZ(); // issp_test_20100709 block
+ SetSCLKStrong();
+ SCLKLow(); //PTJ: 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(wait_and_poll_end, num_bits_wait_and_poll_end); //PTJ: rev308, added to match spec
+// printk("SendVector(id_setup_1)\n",0,0,0);
+ SendVector(id_setup_1, num_bits_id_setup_1);
+ if ((fIsError = fDetectHiLoTransition())) {
+ 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);
+}
+#endif
+
+// ============================================================================
+// fVerifySiliconID()
+// Returns:
+// 0 if successful
+// Si_ID_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fVerifySiliconID(void)
+{
+ SendVector(id_setup_2, num_bits_id_setup_2);
+ printk("fVerifySiliconID: SendVector id_stup2 END\n");
+
+ if ((fIsError = fDetectHiLoTransition())) {
+ printk("fVerifySiliconID(): fDetectHiLoTransition Error\n");
+ return (SiID_ERROR);
+ }
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+ SendVector(tsync_enable, num_bits_tsync_enable);
+ printk
+ ("fVerifySiliconID: SendVector(wait_and_poll_end) (tsync_enable) END\n");
+
+ //Send Read ID vector and get Target ID
+ SendVector(read_id_v, 11); // Read-MSB Vector is the first 11-Bits
+ RunClock(2); // Two SCLK cycles between write & read
+ bTargetID[0] = bReceiveByte();
+ RunClock(1);
+ SendVector(read_id_v + 2, 12); // 1+11 bits starting from the 3rd byte
+
+ RunClock(2); // Read-LSB Command
+ bTargetID[1] = bReceiveByte();
+
+ RunClock(1);
+ SendVector(read_id_v + 4, 1); // 1 bit starting from the 5th byte
+
+ //read Revision ID from Accumulator A and Accumulator X
+ SendVector(read_id_v + 5, 11); //11 bits starting from the 6th byte
+ RunClock(2);
+ bTargetID[2] = bReceiveByte(); //Read from Acc.X
+ RunClock(1);
+ SendVector(read_id_v + 7, 12); //1+11 bits starting from the 8th byte
+
+ RunClock(2);
+ bTargetID[3] = bReceiveByte(); //Read from Acc.A
+
+ RunClock(1);
+ SendVector(read_id_v + 4, 1); //1bit starting from the 5th byte,
+
+ SendVector(tsync_disable, num_bits_tsync_disable);
+
+ // Print READ-ID
+ /*
+ TX8SW_CPutString("\r\n Silicon-ID : ");
+ TX8SW_PutChar(' ');
+ TX8SW_PutSHexByte(bTargetID[0]);
+ TX8SW_PutChar(' ');
+ TX8SW_PutSHexByte(bTargetID[1]);
+ TX8SW_PutChar(' ');
+ TX8SW_PutSHexByte(bTargetID[2]);
+ TX8SW_PutChar(' ');
+ TX8SW_PutSHexByte(bTargetID[3]);
+ TX8SW_PutChar(' ');
+ */
+#if 0 // issp_test_20100709 block
+ printk("issp_routines.c: ID0:0x%X, ID1:0x%X, ID2: 0x%X, ID2: 0x%X\n",
+ bTargetID[0], bTargetID[1], bTargetID[2], bTargetID[3]);
+
+ if ((bTargetID[0] != target_id_v[0]) || (bTargetID[1] != target_id_v[1])
+ || (bTargetID[2] != target_id_v[2])
+ || (bTargetID[3] != target_id_v[3])) {
+ return (SiID_ERROR);
+ } else {
+ return (PASS);
+ }
+#else
+ return (PASS);
+
+#endif
+}
+
+// PTJ: =======================================================================
+// fReadStatus()
+// Returns:
+// 0 if successful
+// _____ if timed out on handshake to the device.
+// ============================================================================
+signed char fReadStatus(void)
+{
+ SendVector(tsync_enable, num_bits_tsync_enable); //PTJ:
+
+ //Send Read ID vector and get Target ID
+ SendVector(read_id_v, 11); // Read-MSB Vector is the first 11-Bits
+ RunClock(2); // Two SCLK cycles between write & read
+ bTargetStatus[0] = bReceiveByte();
+ RunClock(1);
+ //SendVector(read_id_v+2, 12); // 12 bits starting from the 3rd character
+
+ //RunClock(2); // Read-LSB Command
+ //bTargetStatus[1] = bReceiveByte();
+
+ //RunClock(1);
+ SendVector(read_id_v + 4, 1); // 1 bit starting from the 5th character
+
+ SendVector(tsync_disable, num_bits_tsync_disable);
+
+ if (bTargetStatus[0] == target_status00_v) {
+ return (PASS); //PTJ: Status = 00 means Success, the SROM function did what it was supposed to
+ }
+ if (bTargetStatus[0] == target_status01_v) {
+ return (STATUS_ERROR); //PTJ: Status = 01 means that function is not allowed because of block level protection, for test with verify_setup (VERIFY-SETUP)
+ }
+ if (bTargetStatus[0] == target_status03_v) {
+ return (STATUS_ERROR); //PTJ: Status = 03 is fatal error, SROM halted
+ }
+ if (bTargetStatus[0] == target_status04_v) {
+ return (STATUS_ERROR); //PTJ: Status = 04 means there was a checksum faliure with either the smart write code checksum, or the smart write paramters checksum, for test with PROGRAM-AND-VERIFY
+ }
+ if (bTargetStatus[0] == target_status06_v) {
+ return (STATUS_ERROR); //PTJ: Status = 06 means that Calibrate1 failed, for test with id_setup_1 (ID-SETUP-1)
+ } else {
+ return (STATUS_ERROR);
+ }
+}
+
+// PTJ: =======================================================================
+// fReadCalRegisters()
+// PTJ: use this to read some cal registers that should be loaded by Calibrate1 in id_setup_1
+// Returns:
+// 0 if successful
+// _____ if timed out on handshake to the device.
+// ============================================================================
+signed char fReadCalRegisters(void)
+{
+ SendVector(tsync_enable, num_bits_tsync_enable);
+
+ SendVector(Switch_Bank1, 22);
+
+ SendVector(read_IMOtrim, 11); // Read-MSB Vector is the first 11-Bits
+ RunClock(2); // Two SCLK cycles between write & read
+ bTargetStatus[0] = bReceiveByte();
+ RunClock(1);
+ // Set SDATA to Strong Drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(read_reg_end, 1);
+
+ SendVector(read_SPCtrim, 11); // Read-MSB Vector is the first 11-Bits
+ RunClock(2); // Two SCLK cycles between write & read
+ bTargetStatus[1] = bReceiveByte();
+ RunClock(1);
+ // Set SDATA to Strong Drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(read_reg_end, 1);
+
+ SendVector(read_VBGfinetrim, 11); // Read-MSB Vector is the first 11-Bits
+ RunClock(2); // Two SCLK cycles between write & read
+ bTargetStatus[2] = bReceiveByte();
+ RunClock(1);
+ // Set SDATA to Strong Drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(read_reg_end, 1);
+
+ SendVector(Switch_Bank0, 22);
+
+ SendVector(tsync_disable, num_bits_tsync_disable);
+
+ if (bTargetStatus[0] == target_status00_v) {
+ return (PASS); //PTJ: Status = 00 means Success, the SROM function did what it was supposed to
+ }
+ return PASS;
+}
+
+// PTJ: =======================================================================
+// fReadWriteSetup()
+// PTJ: The READ-WRITE-SETUP vector will enable TSYNC and switches the device
+// to SRAM bank1 for PROGRAM-AND-VERIFY, SECURE and VERIFY-SETUP.
+// Returns:
+// 0 if successful
+// _____ if timed out on handshake to the device.
+// ============================================================================
+signed char fReadWriteSetup(void)
+{
+ SendVector(read_write_setup, num_bits_read_write_setup);
+ return (PASS); //PTJ: is there anything else that should be done?
+}
+
+// PTJ: =======================================================================
+// fSyncEnable()
+// PTJ: The SYNC-ENABLE vector will enable TSYNC
+//
+// Returns:
+// 0 if successful
+// _____ if timed out on handshake to the device.
+// ============================================================================
+signed char fSyncEnable(void)
+{
+ SendVector(tsync_enable, num_bits_tsync_enable); //PTJ: 307 for tsync enable testing
+ return (PASS); //PTJ: is there anything else that should be done?
+}
+
+// PTJ: =======================================================================
+// fSyncDisable()
+// PTJ: The SYNC-ENABLE vector will enable TSYNC
+//
+// Returns:
+// 0 if successful
+// _____ if timed out on handshake to the device.
+// ============================================================================
+signed char fSyncDisable(void)
+{
+ SendVector(tsync_disable, num_bits_tsync_disable); //PTJ: 307 for tsync enable testing
+ return (PASS);
+}
+
+// ============================================================================
+// fEraseTarget()
+// Perform a bulk erase of the target device.
+// Returns:
+// 0 if successful
+// ERASE_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fEraseTarget(void)
+{
+ SendVector(erase, num_bits_erase);
+ if ((fIsError = fDetectHiLoTransition())) {
+// TX8SW_CPutString("\r\n fDetectHiLoTransition");
+ //printk("\r\n fDetectHiLoTransition\n"); // issp_test_2010 block
+ return (ERASE_ERROR);
+ }
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+ return (PASS);
+}
+
+extern unsigned int iBlockCounter;
+// ============================================================================
+// LoadTarget()
+// Transfers data from array in Host to RAM buffer in the target.
+// Returns the checksum of the data.
+// ============================================================================
+unsigned int iLoadTarget(void)
+{
+ unsigned char bTemp;
+ unsigned int iChecksumData = 0;
+
+ // Set SDATA to Strong Drive here because SendByte() does not
+ SetSDATAStrong();
+
+ // Transfer the temporary RAM array into the target.
+ // In this section, a 128-Byte array was specified by #define, so the entire
+ // 128-Bytes are written in this loop.
+ bTargetAddress = 0x00;
+ bTargetDataPtr = 0x00;
+
+ while (bTargetDataPtr < TARGET_DATABUFF_LEN) {
+ bTemp = abTargetDataOUT[bTargetDataPtr];
+ iChecksumData += bTemp;
+
+ SendByte(write_byte_start, 4); //PTJ: we need to be able to write 128 bytes from address 0x80 to 0xFF
+ SendByte(bTargetAddress, 7); //PTJ: we need to be able to write 128 bytes from address 0x80 to 0xFF
+ SendByte(bTemp, 8);
+ SendByte(write_byte_end, 3);
+
+ // !!!NOTE:
+ // SendByte() uses MSbits, so inc by '2' to put the 0..128 address into
+ // the seven MSBit locations.
+ //
+ // This can be confusing, but check the logic:
+ // The address is only 7-Bits long. The SendByte() subroutine will
+ // send however-many bits, BUT...always reads them bits from left-to-
+ // right. So in order to pass a value of 0..128 as the address using
+ // SendByte(), we have to left justify the address by 1-Bit.
+ // This can be done easily by incrementing the address each time by
+ // '2' rather than by '1'.
+
+ bTargetAddress += 2; //PTJ: inc by 2 in order to support a 128 byte address space, MSB~1 for address
+ bTargetDataPtr++;
+ }
+
+ return (iChecksumData);
+}
+
+#ifdef MULTI_BANK
+// ============================================================================
+// SetBankNumber()
+// Set the bank number in the target device.
+// Returns:
+// none
+// ============================================================================
+void SetBankNumber(unsigned char bBankNumber)
+{
+ // Send the bank-select vector.
+ SendVector(set_bank_number, 33);
+
+ // Set the drive here because SendByte() does not.
+ SetSDATAStrong();
+ SendByte(bBankNumber, 8);
+ SendVector(set_bank_number_end, 25);
+}
+#endif
+
+// ============================================================================
+// fProgramTargetBlock()
+// Program one block with data that has been loaded into a RAM buffer in the
+// target device.
+// Returns:
+// 0 if successful
+// BLOCK_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fProgramTargetBlock(unsigned char bBankNumber,
+ unsigned char bBlockNumber)
+{
+
+ SendVector(tsync_enable, num_bits_tsync_enable);
+
+ SendVector(set_block_num, num_bits_set_block_num);
+
+ // Set the drive here because SendByte() does not.
+ SetSDATAStrong();
+ SendByte(bBlockNumber, 8);
+ SendByte(set_block_num_end, 3);
+
+ SendVector(tsync_disable, num_bits_tsync_disable); //PTJ:
+
+ // Send the program-block vector.
+ SendVector(program_and_verify, num_bits_program_and_verify); //PTJ: PROGRAM-AND-VERIFY
+ // wait for acknowledge from target.
+ if ((fIsError = fDetectHiLoTransition())) {
+ return (BLOCK_ERROR);
+ }
+ // Send the Wait-For-Poll-End vector
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+ return (PASS);
+
+ //PTJ: Don't do READ-STATUS here because that will
+ //PTJ: require that we return multiple error values, if error occurs
+}
+
+// ============================================================================
+// fAddTargetBankChecksum()
+// Reads and adds the target bank checksum to the referenced accumulator.
+// Returns:
+// 0 if successful
+// VERIFY_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fAccTargetBankChecksum(unsigned int *pAcc)
+{
+ unsigned int wCheckSumData;
+
+ SendVector(checksum_setup, num_bits_checksum_setup); //PTJ:CHECKSUM-SETUP, it is taking 100ms > time > 200ms to complete the checksum
+ if ((fIsError = fDetectHiLoTransition())) { //100ms is default
+ return (VERIFY_ERROR);
+ }
+
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+
+ SendVector(tsync_enable, num_bits_tsync_enable);
+
+ //Send Read Checksum vector and get Target Checksum
+ SendVector(read_checksum_v, 11); // first 11-bits is ReadCKSum-MSB
+ RunClock(2); // Two SCLKs between write & read
+ bTargetDataIN = bReceiveByte();
+ wCheckSumData = bTargetDataIN << 8;
+
+ RunClock(1); // See Fig. 6
+ SendVector(read_checksum_v + 2, 12); // 12 bits starting from 3rd character
+ RunClock(2); // Read-LSB Command
+ bTargetDataIN = bReceiveByte();
+ wCheckSumData |= (bTargetDataIN & 0xFF);
+ RunClock(1);
+ SendVector(read_checksum_v + 3, 1); // Send the final bit of the command //PTJ: read_checksum_v may have to change if TSYNC needs to be enabled
+
+ SendVector(tsync_disable, num_bits_tsync_disable);
+
+ *pAcc = wCheckSumData;
+
+ return (PASS);
+}
+
+// ============================================================================
+// ReStartTarget()
+// After programming, the target PSoC must be reset to take it out of
+// programming mode. This routine performs a reset.
+// ============================================================================
+void ReStartTarget(void)
+{
+#ifdef RESET_MODE
+ // Assert XRES, then release, then disable XRES-Enable
+ AssertXRES();
+ Delay(XRES_CLK_DELAY);
+ DeassertXRES();
+#else
+ // Set all pins to highZ to avoid back powering the PSoC through the GPIO
+ // protection diodes.
+ SetSCLKHiZ();
+ SetSDATAHiZ();
+ // Cycle power on the target to cause a reset
+ RemoveTargetVDD();
+ mdelay(300);
+ ApplyTargetVDD();
+#endif
+}
+
+// ============================================================================
+// fVerifySetup()
+// Verify the block just written to. This can be done byte-by-byte before the
+// protection bits are set.
+// Returns:
+// 0 if successful
+// BLOCK_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fVerifySetup(unsigned char bBankNumber, unsigned char bBlockNumber)
+{
+ SendVector(tsync_enable, num_bits_tsync_enable);
+
+ SendVector(set_block_num, num_bits_set_block_num);
+
+ //Set the drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(bBlockNumber, 8);
+ SendByte(set_block_num_end, 3); //PTJ:
+
+ SendVector(tsync_disable, num_bits_tsync_disable); //PTJ:
+
+ SendVector(verify_setup, num_bits_my_verify_setup); //PTJ:
+ if ((fIsError = fDetectHiLoTransition())) {
+ return (BLOCK_ERROR);
+ }
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+
+ return (PASS);
+}
+
+// ============================================================================
+// fReadByteLoop()
+// Reads the data back from Target SRAM and compares it to expected data in
+// Host SRAM
+// Returns:
+// 0 if successful
+// BLOCK_ERROR if timed out on handshake to the device.
+// ============================================================================
+
+signed char fReadByteLoop(void)
+{
+ bTargetAddress = 0;
+ bTargetDataPtr = 0;
+
+ while (bTargetDataPtr < TARGET_DATABUFF_LEN) {
+ //Send Read Byte vector and then get a byte from Target
+ SendVector(read_byte_v, 4);
+ // Set the drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(bTargetAddress, 7);
+
+ RunClock(2); // Run two SCLK cycles between writing and reading
+ SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA
+ bTargetDataIN = bReceiveByte();
+
+ RunClock(1);
+ SendVector(read_byte_v + 1, 1); // Send the ReadByte Vector End
+
+ // Test the Byte that was read from the Target against the original
+ // value (already in the 128-Byte array "abTargetDataOUT[]"). If it
+ // matches, then bump the address & pointer,loop-back and continue.
+ // If it does NOT match abort the loop and return and error.
+ if (bTargetDataIN != abTargetDataOUT[bTargetDataPtr]) {
+#ifdef TX_ON
+ UART_PutCRLF();
+ UART_CPutString("bTargetDataIN : ");
+ UART_PutHexByte(bTargetDataIN);
+ UART_CPutString(" abTargetDataOUT : ");
+ UART_PutHexByte(abTargetDataOUT[bTargetDataPtr]);
+#endif
+ return (BLOCK_ERROR);
+ }
+
+ bTargetDataPtr++;
+ // Increment the address by 2 to accomodate 7-Bit addressing
+ // (puts the 7-bit address into MSBit locations for "SendByte()").
+ bTargetAddress += 2;
+
+ }
+
+ return (PASS);
+}
+
+// ============================================================================
+// fVerifyTargetBlock()
+// Verify the block just written to. This can be done byte-by-byte before the
+// protection bits are set.
+// Returns:
+// 0 if successful
+// BLOCK_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fVerifyTargetBlock(unsigned char bBankNumber,
+ unsigned char bBlockNumber)
+{
+ SendVector(set_block_number, 11);
+
+ //Set the drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(bBlockNumber, 8);
+ SendByte(set_block_number_end, 3);
+
+ SendVector(verify_setup_v, num_bits_verify_setup);
+ if ((fIsError = fDetectHiLoTransition())) {
+ return (BLOCK_ERROR);
+ }
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+
+ bTargetAddress = 0;
+ bTargetDataPtr = 0;
+
+ while (bTargetDataPtr < TARGET_DATABUFF_LEN) {
+ //Send Read Byte vector and then get a byte from Target
+ SendVector(read_byte_v, 4); //PTJ 308: this was changed from sending the first 5 bits to sending the first 4
+ // Set the drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(bTargetAddress, 6);
+
+ RunClock(2); // Run two SCLK cycles between writing and reading
+ SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA
+ bTargetDataIN = bReceiveByte();
+
+ RunClock(1);
+ SendVector(read_byte_v + 1, 1); // Send the ReadByte Vector End
+
+ // Test the Byte that was read from the Target against the original
+ // value (already in the 128-Byte array "abTargetDataOUT[]"). If it
+ // matches, then bump the address & pointer,loop-back and continue.
+ // If it does NOT match abort the loop and return an error.
+ if (bTargetDataIN != abTargetDataOUT[bTargetDataPtr])
+ return (BLOCK_ERROR);
+
+ bTargetDataPtr++;
+ // Increment the address by four to accomodate 6-Bit addressing
+ // (puts the 6-bit address into MSBit locations for "SendByte()").
+ bTargetAddress += 4;
+ }
+ return (PASS);
+}
+
+// ============================================================================
+// fSecureTargetFlash()
+// Before calling, load the array, abTargetDataOUT, with the desired security
+// settings using LoadArrayWithSecurityData(StartAddress,Length,SecurityType).
+// The can be called multiple times with different SecurityTypes as needed for
+// particular Flash Blocks. Or set them all the same using the call below:
+// LoadArrayWithSecurityData(0,SECURITY_BYTES_PER_BANK, 0);
+// Returns:
+// 0 if successful
+// SECURITY_ERROR if timed out on handshake to the device.
+// ============================================================================
+signed char fSecureTargetFlash(void)
+{
+ unsigned char bTemp;
+
+ // Transfer the temporary RAM array into the target
+ bTargetAddress = 0x00;
+ bTargetDataPtr = 0x00;
+
+ SetSDATAStrong();
+ while (bTargetDataPtr < SECURITY_BYTES_PER_BANK) {
+ bTemp = abTargetDataOUT[bTargetDataPtr];
+ SendByte(write_byte_start, 4);
+ SendByte(bTargetAddress, 7);
+ SendByte(bTemp, 8);
+ SendByte(write_byte_end, 3);
+
+ // SendBytes() uses MSBits, so increment the address by '2' to put
+ // the 0..n address into the seven MSBit locations
+ bTargetAddress += 2; //PTJ: inc by 2 in order to support a 128 byte address space
+ bTargetDataPtr++;
+ }
+
+ SendVector(secure, num_bits_secure); //PTJ:
+ if ((fIsError = fDetectHiLoTransition())) {
+ return (SECURITY_ERROR);
+ }
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+ return (PASS);
+}
+
+// ============================================================================
+// PTJ: fReadSecurity()
+// This reads from SM0 with Read Supervisory SPC command.
+// Need to have SPC Test Mode enabled before using these commands?
+// Returns:
+// 0 if successful
+// __________ if timed out on handshake to the device.
+// ============================================================================
+signed char fReadSecurity(void)
+{
+ SendVector(ReadSecuritySetup, num_bits_ReadSecuritySetup);
+// SendVector(SPCTestMode_enable, num_bits_SPCTestMode_enable);
+
+ bTargetAddress = 0x00;
+ while (bTargetAddress < (SECURITY_BYTES_PER_BANK * 2)) { //PTJ: we do SECURITY_BYTES_PER_BANK * 2 because we bTargetAddress += 2
+
+ //PTJ: TSYNC Enable
+ SendVector(tsync_enable, num_bits_tsync_enable);
+
+ SendVector(read_security_pt1, num_bits_read_security_pt1); //PTJ:
+ // Set the drive here because SendByte() does not.
+ SetSDATAStrong();
+ SendByte(bTargetAddress, 7); //PTJ: hardcode MSb of address as 0 in bit stream
+ SendVector(read_security_pt1_end,
+ num_bits_read_security_pt1_end);
+
+ //PTJ: TSYNC Disable
+ SendVector(tsync_disable, num_bits_tsync_disable);
+
+ SendVector(read_security_pt2, num_bits_read_security_pt2);
+
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+
+ SendVector(read_security_pt3, num_bits_read_security_pt3);
+
+ SetSDATAStrong();
+ SendByte(bTargetAddress, 7);
+
+ SendVector(read_security_pt3_end,
+ num_bits_read_security_pt3_end);
+
+ SendVector(wait_and_poll_end, num_bits_wait_and_poll_end);
+
+ bTargetAddress += 2;
+ }
+
+ bTargetAddress = 0x00;
+ bTargetDataPtr = 0x00;
+
+ SendVector(tsync_enable, num_bits_tsync_enable); //PTJ: 307, added for tsync testing
+ while (bTargetAddress < (SECURITY_BYTES_PER_BANK * 2)) { //PTJ: we do SECURITY_BYTES_PER_BANK * 2 because we bTargetAddress += 2
+
+ //Send Read Byte vector and then get a byte from Target
+ SendVector(read_byte_v, 4);
+ // Set the drive here because SendByte() does not
+ SetSDATAStrong();
+ SendByte(bTargetAddress, 7);
+
+ RunClock(2); // Run two SCLK cycles between writing and reading
+ SetSDATAHiZ(); // Set to HiZ so Target can drive SDATA
+ bTargetDataIN = bReceiveByte();
+
+ RunClock(1);
+ SendVector(read_byte_v + 1, 1); // Send the ReadByte Vector End
+
+ // Test the Byte that was read from the Target against the original
+ // value (already in the 128-Byte array "abTargetDataOUT[]"). If it
+ // matches, then bump the address & pointer,loop-back and continue.
+ // If it does NOT match abort the loop and return and error.
+ if (bTargetDataIN != abTargetDataOUT[bTargetDataPtr])
+// return(BLOCK_ERROR);
+
+ // Increment the address by two to accomodate 7-Bit addressing
+ // (puts the 7-bit address into MSBit locations for "SendByte()").
+ bTargetDataPtr++;
+ bTargetAddress += 2;
+ }
+
+ SendVector(tsync_disable, num_bits_tsync_disable); //PTJ: 307, added for tsync testing
+ return (PASS);
+}
+
+#endif //(PROJECT_REV_)
+// end of file ISSP_Routines.c