Beispiel #1
0
void
SMoHVSP::EnterProgmode()
{
#ifdef DEBUG_HVSP
    SMoDebugInit();
#endif

    // const uint8_t   stabDelay   = SMoCommand::gBody[1];
    // const uint8_t   cmdexeDelay = SMoCommand::gBody[2];
    const uint8_t   syncCycles  = SMoCommand::gBody[3];
    // const uint8_t   latchCycles = SMoCommand::gBody[4];
    // const uint8_t   toggleVtg   = SMoCommand::gBody[5];
    const uint8_t   powoffDelay = SMoCommand::gBody[6];
    const uint8_t   resetDelay1 = SMoCommand::gBody[7];
    const uint8_t   resetDelay2 = SMoCommand::gBody[8];
    
    pinMode(HVSP_VCC, OUTPUT);
    digitalWrite(HVSP_VCC, LOW);
    digitalWrite(HVSP_RESET, HIGH); // Set BEFORE pinMode, so we don't glitch LOW
    pinMode(HVSP_RESET, OUTPUT);
    pinMode(HVSP_SCI, OUTPUT);
    digitalWrite(HVSP_SCI, LOW);
    pinMode(HVSP_SDI, OUTPUT);
    digitalWrite(HVSP_SDI, LOW);
    pinMode(HVSP_SII, OUTPUT);
    digitalWrite(HVSP_SII, LOW);
    pinMode(HVSP_SDO, OUTPUT);       // progEnable[2] on tinyX5
    digitalWrite(HVSP_SDO, LOW);

    delay(powoffDelay);
    digitalWrite(HVSP_VCC, HIGH);
    delayMicroseconds(80);
    for (uint8_t i=0; i<syncCycles; ++i) {
        digitalWrite(HVSP_SCI, HIGH);
        delayMicroseconds(10);
        digitalWrite(HVSP_SCI, LOW);
    }
    digitalWrite(HVSP_RESET, LOW);
    delayMicroseconds(1);
    pinMode(HVSP_SDO, INPUT);
    
    SMoCommand::SendResponse();
}
Beispiel #2
0
void
SMoISP::EnterProgmode()
{
#ifdef DEBUG_ISP
    SMoDebugInit();
    // SMoDebug.print("Pin layout ");
    // SMoDebug.print(SMO_LAYOUT);
    SMoDebug.print(" RESET ");
    SMoDebug.println(ISP_RESET);
#endif
    // const uint8_t   timeOut     =   SMoCommand::gBody[1];
    const uint8_t   stabDelay   =   SMoCommand::gBody[2];
    // const uint8_t   cmdexeDelay =   SMoCommand::gBody[3];
    // const uint8_t   synchLoops  =   SMoCommand::gBody[4];
    // const uint8_t   byteDelay   =   SMoCommand::gBody[5];
    const uint8_t   pollValue   =   SMoCommand::gBody[6];
    const uint8_t   pollIndex   =   SMoCommand::gBody[7];
    const uint8_t * command     =  &SMoCommand::gBody[8];

    //
    // Set up SPI
    //
#if SMO_LAYOUT==SMO_LAYOUT_HVPROG2
    // make sure that 12V regulator is shutdown 
    digitalWrite(SMO_HVENABLE, LOW);
    pinMode(SMO_HVENABLE, OUTPUT);
#endif
    // to avoid glitch in SCK and MOSI we must set CPOL before SPI.begin()
    SPCR &= ~_BV(CPOL) & ~_BV(CPHA); // idle LOW for SPI_MODE0
    //
    SPI.begin();
    SPI.beginTransaction(SMoGeneral::gSCKDuration > 2 ? ISPSPISetting[2] : ISPSPISetting[SMoGeneral::gSCKDuration]);
    ISPAssertReset();
    pinMode(ISP_RESET, OUTPUT);
    delay(stabDelay);

    //
    // Set up clock generator on OC1A (OC2A or OC2 if HVPROG2)
    //
    pinMode(MCU_CLOCK, OUTPUT);
#if SMO_LAYOUT==SMO_LAYOUT_HVPROG2
#ifdef TCCR2
    TCCR2  = _BV(COM20) | _BV(WGM21);  // Stop Timer 2
    TCNT2  = 0xFF;                     // Initialize counter value
    OCR2   = SMoGeneral::gClockMatch;  // Set compare match value
    // CTC mode, Toggle OC2 on Compare Match. Set timer operation mode and prescaler
    TCCR2  = _BV(COM20) | _BV(WGM21) | (0x07 & SMoGeneral::gPrescale);
#else
    TCCR2B = 0;                        // Stop Timer 2
    TCCR2A = _BV(COM2A0) | _BV(WGM21); // CTC mode, Toggle OC2A on Compare Match
    TCNT2  = 0xFF;                     // Initialize counter value
    OCR2A  = SMoGeneral::gClockMatch;  // Set compare match value
    TCCR2B = 0x07 & SMoGeneral::gPrescale;// Set timer operation mode and prescaler
#endif
#else
    TCCR1B = 0;                        // Stop clock generator
    TCCR1A = _BV(COM1A0);              // CTC mode, toggle OC1A on comparison with OCR1A
    OCR1A  = 0;                        // F(OC1A) = 16MHz / (2*8*(1+0)) == 1MHz
    TIMSK1 = 0;
    TCCR1B = _BV(WGM12) | _BV(CS11);   // Prescale by 8
    TCNT1  = 0;
#endif
    
    //
    // Now issue the programming mode instruction
    //
    digitalWrite(SCK, LOW);

    uint8_t response = SPITransaction(command, pollIndex-1);
    if (response != pollValue) {
        //
        // Ooops, that's bad. Try again in limp mode
        //
        SPI.endTransaction();
        SPI.end();       
        sSPILimpMode = 2;   // Start at 16µs, 60kHz bit clock
        pinMode(MOSI, OUTPUT);
        pinMode(SCK, OUTPUT);
        pinMode(MISO, INPUT);
        
        do {
#ifdef DEBUG_ISP
            SMoDebug.print("Retrying in limp mode ");
            SMoDebug.print(sSPILimpMode);
            SMoDebug.print(" (");
            SMoDebug.print(1000.0 / (4 << sSPILimpMode));
            SMoDebug.println("kHz).");
#endif
            ISPDeassertReset();
            digitalWrite(SCK, LOW);
            delay(50);
            ISPAssertReset();
            delay(50);
            response     = SPITransaction(command, pollIndex-1);
        } while (response != pollValue && sSPILimpMode++ < kMaxLimp);
    }
    SMoCommand::SendResponse(response==pollValue ? STATUS_CMD_OK : STATUS_CMD_FAILED);
}