int32_t DRV_SPI_MasterRMReceive8BitISR( struct DRV_SPI_DRIVER_OBJECT * pDrvInstance ) { register SPI_MODULE_ID spiId = pDrvInstance->spiId; register DRV_SPI_JOB_OBJECT * currentJob = pDrvInstance->currentJob; if (currentJob == NULL) { return 0; } if (PLIB_SPI_ReceiverBufferIsFull(spiId)) { /* We have data waiting in the SPI buffer */ if (currentJob->dataLeftToRx != 0) { /* Receive the data and updates the count */ currentJob->rxBuffer[currentJob->dataRxed] = PLIB_SPI_BufferRead(spiId); currentJob->dataRxed++; currentJob->dataLeftToRx --; } else { /* No Data but dummy data: Note: We cannot just clear the buffer because we have to keep track of how many symbols/units we have received, and the number may have increased since we checked how full the buffer is.*/ PLIB_SPI_BufferRead(spiId); //SYS_CONSOLE_MESSAGE("Rd "); currentJob->dummyLeftToRx--; } /* No longer have a symbol in progress */ pDrvInstance->symbolsInProgress = 0; } return 0; }
/************************************************************************ * Function: void SST25ReadArray(DWORD address, BYTE* pData, nCount) * * Overview: this function reads data into buffer specified * * Input: flash memory address, pointer to the data buffer, data number * ************************************************************************/ void SST25ReadArray(uint32_t address, uint8_t *pData, uint16_t nCount) { SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_READ); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>16); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>8); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address); PLIB_SPI_BufferRead(spiInitData.spiId); while(nCount--) { SPIPut(spiInitData.spiId, 0); *pData++ = PLIB_SPI_BufferRead(spiInitData.spiId); } SST25CSHigh(); }
/************************************************************************ * Function: void SST25SectorErase(DWORD address) * * Overview: this function erases a 4Kb sector * * Input: address within sector to be erased * * Output: none * ************************************************************************/ void SST25SectorErase(uint32_t address) { SST25WriteEnable(); // while(!SPILock(spiInitData.spiId)); SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_SER); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>16); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>8); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); // SPIUnLock(spiInitData.spiId); // Wait for write end while(SST25IsWriteBusy()); }
/************************************************************************ * Function: BYTE SST25ReadByte(DWORD address) * * Overview: this function reads a byte from the address specified * * Input: address * * Output: data read * ************************************************************************/ uint8_t SST25ReadByte(uint32_t address) { uint8_t temp; SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_READ); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>16); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>8); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, 0); temp = PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); return (temp); }
/************************************************************************ * Function: void SST25WriteByte(BYTE data, DWORD address) * * Overview: this function writes a byte to the address specified * * Input: data to be written and address * * Output: none * ************************************************************************/ void SST25WriteByte(uint8_t data, uint32_t address) { SST25WriteEnable(); SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_WRITE); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>16); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address>>8); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, address); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, data); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); // Wait for write end while(SST25IsWriteBusy()); }
int32_t DRV_SPI_MasterEBMReceive8BitISR( struct DRV_SPI_DRIVER_OBJECT * pDrvInstance ) { register SPI_MODULE_ID spiId = pDrvInstance->spiId; register DRV_SPI_JOB_OBJECT * currentJob = pDrvInstance->currentJob; /* Figure out how many bytes are waiting to be received."*/ uint8_t bufferBytes = PLIB_SPI_FIFOCountGet(spiId, SPI_FIFO_TYPE_RECEIVE); /* Calculate the maximum number of data bytes that can be received*/ size_t dataUnits = MIN(currentJob->dataLeftToRx, bufferBytes); size_t counter; if (dataUnits != 0) { bufferBytes -= dataUnits; currentJob->dataLeftToRx -= dataUnits; /* Set the buffer location to receive bytes from the SPI to*/ uint8_t *bufferLoc = &(currentJob->rxBuffer[currentJob->dataRxed]); for (counter = 0; counter < dataUnits; counter++) { /* Receive the data from the SPI */ bufferLoc[counter] = PLIB_SPI_BufferRead(spiId); } /* Adjust the amount of data that has been received */ currentJob->dataRxed += dataUnits; /* Update the symbols in progress so we can send more units later */ pDrvInstance->symbolsInProgress -= dataUnits; } /* Figure out the maximum number of dummy data to be received */ size_t dummyUnits = MIN(currentJob->dummyLeftToRx, bufferBytes); if (dummyUnits != 0) { /* Lower the number of dummy bytes to be received */ currentJob->dummyLeftToRx -= dummyUnits; pDrvInstance->symbolsInProgress -= dummyUnits; for (counter = 0; counter < dummyUnits; counter++) { /* Receive and throw away the byte. Note: We cannot just clear the buffer because we have to keep track of how many symbols/units we have received, and the number may have increased since we checked how full the buffer is.*/ PLIB_SPI_BufferRead(spiId); } } /* Figure out how many bytes are left to be received */ size_t bytesLeft = currentJob->dataLeftToRx + currentJob->dummyLeftToRx; /* If the bytes left are smaller than the HW mark we have to change the interrupt mode */ if (bytesLeft < PLIB_SPI_RX_8BIT_HW_MARK(spiId)) { PLIB_SPI_FIFOInterruptModeSelect(spiId, SPI_FIFO_INTERRUPT_WHEN_RECEIVE_BUFFER_IS_NOT_EMPTY); } return 0; }
/************************************************************************ * Function: void SST25ResetWriteProtection() * * Overview: this function reset write protection bits * * Input: none * * Output: none * ************************************************************************/ void SST25ResetWriteProtection(void) { #if defined(USE_M25P80) uint8_t status; #endif // while(!SPILock(spiInitData.spiId)); SST25CSLow(); // send write enable command SPIPut(spiInitData.spiId, SST25_CMD_EWSR); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); #if defined(USE_M25P80) SST25CSLow(); // verify if the WEL bit is set high while(1) { SPIPut(spiInitData.spiId, SST25_CMD_RDSR); SPIGet(spiInitData.spiId); status = 0xFF; while((status & SST25_STATUS_MASK) > 0) { SPIPut(spiInitData.spiId, 0); status = SPIGet(spiInitData.spiId); } if ((status & SST25_WEL_STATUS) == SST25_WEL_STATUS) break; } SST25CSHigh(); #endif SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_WRSR); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, 0); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); // SPIUnLock(spiInitData.spiId); // Wait for write end while(SST25IsWriteBusy()); }
/************************************************************************ * Function: BYTE SST25IsWriteBusy(void) * * Overview: this function reads status register and chek BUSY bit for write operation * * Input: none * * Output: non zero if busy * ************************************************************************/ uint8_t SST25IsWriteBusy(void) { uint8_t temp; SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_RDSR); PLIB_SPI_BufferRead(spiInitData.spiId); SPIPut(spiInitData.spiId, 0); temp = PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); return (temp & 0x01); }
int32_t DRV_SPI0_BufferAddWriteRead(const void * txBuffer, void * rxBuffer, uint32_t size) { bool continueLoop; int32_t txcounter = 0; int32_t rxcounter = 0; uint8_t unitsTxed = 0; const uint8_t maxUnits = 16; do { continueLoop = false; unitsTxed = 0; if (PLIB_SPI_TransmitBufferIsEmpty(SPI_ID_4)) { while (!PLIB_SPI_TransmitBufferIsFull(SPI_ID_4) && (txcounter < size) && unitsTxed != maxUnits) { PLIB_SPI_BufferWrite(SPI_ID_4, ((uint8_t*)txBuffer)[txcounter]); txcounter++; continueLoop = true; unitsTxed++; } } while (txcounter != rxcounter) { while (PLIB_SPI_ReceiverFIFOIsEmpty(SPI_ID_4)); ((uint8_t*)rxBuffer)[rxcounter] = PLIB_SPI_BufferRead(SPI_ID_4); rxcounter++; continueLoop = true; } if (txcounter > rxcounter) { continueLoop = true; } }while(continueLoop); return txcounter; }
int32_t DRV_SPI1_BufferAddWriteRead(const void * txBuffer, void * rxBuffer, uint32_t size) { bool continueLoop; int32_t txcounter = 0; int32_t rxcounter = 0; do { continueLoop = false; if(!PLIB_SPI_TransmitBufferIsFull(SPI_ID_2) && txcounter < size) { PLIB_SPI_BufferWrite(SPI_ID_2, ((uint8_t*)txBuffer)[txcounter]); txcounter++; continueLoop = true; } while (txcounter != rxcounter) { while(!PLIB_SPI_ReceiverBufferIsFull(SPI_ID_2)); ((uint8_t*)rxBuffer)[rxcounter] = PLIB_SPI_BufferRead(SPI_ID_2); rxcounter++; continueLoop = true; } if (txcounter > rxcounter) { continueLoop = true; } }while(continueLoop); return txcounter; }
/************************************************************************ * Function: SST25WriteEnable() * * Overview: this function allows write/erase SST25. Must be called * before every write/erase command. * * Input: none * * Output: none * ************************************************************************/ void SST25WriteEnable(void) { SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_WREN); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); }
/************************************************************************ * Function: void SST25ChipErase(void) * * Overview: chip erase * * Input: none * ************************************************************************/ void SST25ChipErase(void) { #if defined(USE_M25P80) uint8_t status; #endif #if defined(USE_SST25VF016) SST25WriteEnable(); #endif // while(!SPILock(spiInitData.spiId)); SST25CSLow(); #if defined(USE_M25P80) // send write enable command SPIPut(spiInitData.spiId, SST25_CMD_EWSR); SPIGet(spiInitData.spiId); SST25CSHigh(); Nop(); SST25CSLow(); // verify if the WEL bit is set high while(1) { SPIPut(spiInitData.spiId, SST25_CMD_RDSR); SPIGet(spiInitData.spiId); status = 0xFF; while((status & SST25_STATUS_MASK) > 0) { SPIPut(spiInitData.spiId, 0); status = SPIGet(spiInitData.spiId); } if ((status & SST25_WEL_STATUS) == SST25_WEL_STATUS) break; } SST25CSHigh(); #endif SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_ERASE); PLIB_SPI_BufferRead(spiInitData.spiId); SST25CSHigh(); #if defined (USE_M25P80) // wait for BULK ERASE to be done SST25CSLow(); SPIPut(spiInitData.spiId, SST25_CMD_RDSR); SPIGet(spiInitData.spiId); while(1) { SPIPut(spiInitData.spiId, 0); status = (SPIGet(spiInitData.spiId)& SST25_WIP_STATUS); if ((status & SST25_WIP_STATUS) == 0) break; } SST25CSHigh(); #endif // SPIUnLock(spiInitData.spiId); // Wait for write end while(SST25IsWriteBusy()); }