uint    ispMulti(stkMultiIsp_t *param, stkMultiIspResult_t *result)
{
uchar   cnt1, i, *p;

    cnt1 = param->numTx;
    if(cnt1 > param->rxStartAddr)
        cnt1 = param->rxStartAddr;
    ispBlockTransfer(param->txData, cnt1);

    p = result->rxData;
    for(i = 0; i < param->numTx - cnt1; i++){
        uchar b = ispBlockTransfer(&param->txData[cnt1] + i, 1);
        if(i < param->numRx)
            *p++ = b;
        wdt_reset();
    }
    
    for(; i < param->numRx; i++){
        cmdBuffer[0] = 0;
        *p++ = ispBlockTransfer(cmdBuffer, 1);
        wdt_reset();
    }
    *p = result->status1 = STK_STATUS_CMD_OK;
    return (uint)param->numRx + 2;
}
uchar   ispReadFuse(stkReadFuseIsp_t *param)
{
uchar   rval;

    rval = ispBlockTransfer(param->cmd, param->retAddr);
    if(param->retAddr < 4)
        ispBlockTransfer(param->cmd + param->retAddr, 4 - param->retAddr);
    return rval;
}
uint    ispReadMemory(stkReadFlashIsp_t *param, stkReadFlashIspResult_t *result, uchar isEeprom)
{
utilWord_t  numBytes;
uchar       *p, cmd0;
uint        i;

    cmdBuffer[3] = 0;
    if(!isEeprom && stkAddress.bytes[3] & 0x80){
        cmdBuffer[0] = 0x4d;    /* load extended address */
        cmdBuffer[1] = 0x00;
        cmdBuffer[2] = stkAddress.bytes[2];
        ispBlockTransfer(cmdBuffer, 4);
    }
    numBytes.bytes[1] = param->numBytes[0];
    numBytes.bytes[0] = param->numBytes[1];
    p = result->data;
    result->status1 = STK_STATUS_CMD_OK;
    cmd0 = param->cmd;
    for(i = 0; i < numBytes.word; i++){
        wdt_reset();
        cmdBuffer[1] = stkAddress.bytes[1];
        cmdBuffer[2] = stkAddress.bytes[0];
        if(!isEeprom){
            if((uchar)i & 1){
                cmd0 |= 0x08;
                stkIncrementAddress();
            }else{
                cmd0 &= ~0x08;
            }
        }else{
            stkIncrementAddress();
        }
        cmdBuffer[0] = cmd0;
        *p++ = ispBlockTransfer(cmdBuffer, 4);
    }
    *p = STK_STATUS_CMD_OK; /* status2 */
    return numBytes.word + 2;
}
Beispiel #4
0
_u8   ispEnterProgmode(stkEnterProgIsp_t *param)
{
    _u8   i, rval;
    ispAttachToDevice(stkParam.s.sckDuration, param->stabDelay);
    delay(param->cmdExeDelay);
    /* we want for(i = param->synchLoops; i--;), but avrdude sends synchLoops == 0 */
    for(i = 32; i--;){
        wdt_reset();
        rval = ispBlockTransfer(param->cmd, param->pollIndex);
        if(param->pollIndex < 4)
            ispBlockTransfer(param->cmd + param->pollIndex, 4 - param->pollIndex);
        if(rval == param->pollValue){   /* success: we are in sync */
            return STK_STATUS_CMD_OK;
        }
        /* insert one clock pulse and try again: */
        DIGITAL_WRITE(ISP_SCK, HIGH);
        timerTicksDelay(ispClockDelay);
        DIGITAL_WRITE(ISP_SCK, LOW);
        timerTicksDelay(ispClockDelay);
    }
    ispDetachFromDevice();
    return STK_STATUS_CMD_FAILED;   /* failure */
}
uchar   ispChipErase(stkChipEraseIsp_t *param)
{
uchar   maxDelay = param->eraseDelay;
uchar   rval = STK_STATUS_CMD_OK;

    ispBlockTransfer(param->cmd, 4);
    if(param->pollMethod != 0){
        if(maxDelay < 10)   /* allow at least 10 ms */
            maxDelay = 10;
        rval = waitUntilReady(maxDelay);
    }else{
        timerMsDelay(maxDelay);
    }
    return rval;
}
uchar   ispProgramFuse(stkProgramFuseIsp_t *param)
{
    ispBlockTransfer(param->cmd, 4);
    return STK_STATUS_CMD_OK;
}
uchar   ispProgramMemory(stkProgramFlashIsp_t *param, uchar isEeprom)
{
utilWord_t  numBytes;
uchar       rval = STK_STATUS_CMD_OK;
uchar       valuePollingMask, rdyPollingMask;
uint        i;

    numBytes.bytes[1] = param->numBytes[0];
    numBytes.bytes[0] = param->numBytes[1];
    if(param->mode & 1){    /* page mode */
        valuePollingMask = 0x20;
        rdyPollingMask = 0x40;
    }else{                  /* word mode */
        valuePollingMask = 4;
        rdyPollingMask = 8;
    }
    if(!isEeprom && stkAddress.bytes[3] & 0x80){
        cmdBuffer[0] = 0x4d;    /* load extended address */
        cmdBuffer[1] = 0x00;
        cmdBuffer[2] = stkAddress.bytes[2];
        cmdBuffer[3] = 0x00;
        ispBlockTransfer(cmdBuffer, 4);
    }
    for(i = 0; rval == STK_STATUS_CMD_OK && i < numBytes.word; i++){
        uchar x;
        wdt_reset();
        cmdBuffer[1] = stkAddress.bytes[1];
        cmdBuffer[2] = stkAddress.bytes[0];
        cmdBuffer[3] = param->data[i];
        x = param->cmd[0];
        if(!isEeprom){
            x &= ~0x08;
            if((uchar)i & 1){
                x |= 0x08;
                stkIncrementAddress();
            }
        }else{
            stkIncrementAddress();
        }
        cmdBuffer[0] = x;
#if 0   /* does not work this way... */
        if(cmdBuffer[3] == 0xff && !(param->mode & 1) && !isEeprom)   /* skip 0xff in word mode */
            continue;
#endif
        ispBlockTransfer(cmdBuffer, 4);
        if(param->mode & 1){            /* is page mode */
            if(i < numBytes.word - 1 || !(param->mode & 0x80))
                continue;               /* not last byte written */
            cmdBuffer[0] = param->cmd[1];     /* write program memory page */
            ispBlockTransfer(cmdBuffer, 4);
        }
        /* poll for ready after each byte (word mode) or page (page mode) */
        if(param->mode & valuePollingMask){ /* value polling */
            uchar d = param->data[i];
            if(d == param->poll[0] || d == param->poll[1]){ /* must use timed polling */
                timerMsDelay(param->delay);
            }else{
                uchar x = param->cmd[2];     /* read flash */
                x &= ~0x08;
                if((uchar)i & 1){
                    x |= 0x08;
                }
                cmdBuffer[0] = x;
                timerSetupTimeout(param->delay);
                while(ispBlockTransfer(cmdBuffer, 4) != d){
                    if(timerTimeoutOccurred()){
                        rval = STK_STATUS_CMD_TOUT;
                        break;
                    }
                }
            }
        }else if(param->mode & rdyPollingMask){ /* rdy/bsy polling */
            rval = waitUntilReady(param->delay);
        }else{                          /* must be timed delay */
            timerMsDelay(param->delay);
        }
    }
    return rval;
}
static uchar    deviceIsBusy(void)
{
    cmdBuffer[0] = 0xf0;
    cmdBuffer[1] = 0;
    return ispBlockTransfer(cmdBuffer, 4) & 1;
}