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(¶m->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; }
_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; }