static BT_ERROR spiSetBaudrate(BT_HANDLE hSpi, BT_u32 ulBaudrate) { volatile LPC17xx_SPI_REGS *pRegs = hSpi->pRegs; const BT_RESOURCE *pResource = BT_GetIntegratedResource(hSpi->pDevice, BT_RESOURCE_ENUM, 0); BT_u32 ulInputClk = BT_LPC17xx_GetPeripheralClock(g_SPI_PERIPHERAL[pResource->ulStart]); if (pResource->ulStart == 0) { BT_u32 ulDivider = ulInputClk / ulBaudrate; if (ulDivider < 8) ulDivider = 8; if (ulDivider % 2) ulDivider++; pRegs->CCR = ulDivider; } else { pRegs->CR0 &= ~LPC17xx_SPI_CR0_SCR_MASK; BT_u32 ulDivider = (ulInputClk / ulBaudrate) / 256; if (ulDivider < 2) ulDivider = 2; if (ulDivider % 2) ulDivider++; pRegs->CPSR = ulDivider; pRegs->CR0 |= ((ulInputClk / (ulBaudrate * ulDivider)-1) << 8) & LPC17xx_SPI_CR0_SCR_MASK; } spiEnable(hSpi); return BT_ERR_NONE; }
uint8_t readStatus() { uint8_t status; spiEnable(); spiReadWriteByte(SPICMD_RDSR); status = spiReadWriteByte(0); spiDisable(); return status; }
usbMsgLen_t readMemory(uint16_t startAddr, uint16_t size) { spiEnable(); spiReadWriteByte(SPICMD_READ); spiReadWriteByte(startAddr >> 8); spiReadWriteByte(startAddr); readBytesRemaining = size; reading = 1; return USB_NO_MSG; }
usbMsgLen_t erasePage(uint8_t page) { if (page > 31) { return 0; } if (!waitForReady()) { return 0; } if (!enableWrite()) { return 0; } spiEnable(); spiReadWriteByte(SPICMD_ERASEPAGE); spiReadWriteByte(page); spiDisable(); waitWenIsCleared(); return 0; }
bool enableWrite() { uint8_t status; uint8_t attempts; for (attempts = 0; attempts < 10; ++attempts) { // set wren spiEnable(); spiReadWriteByte(SPICMD_WREN); spiDisable(); // then check that it's set status = readStatus(); if (status & FSR_WEN) { return true; } _delay_ms(2); } return false; }
uint8_t usbFunctionWrite(uint8_t *data, uint8_t len) { uint8_t i; uint16_t startAddr; if (reading) { return 1; } if (len > writeBytesRemaining) { len = writeBytesRemaining; } if (wrote == 0) { if (!enableWrite()) { return 0; } spiEnable(); spiReadWriteByte(SPICMD_ERASEPAGE); spiReadWriteByte(currentPage); spiDisable(); // wait WEN flag is cleared and flash is ready if (!waitWenIsCleared()) { return 0; } // enable WEN flag if (!enableWrite()) { return 0; } startAddr = currentPage * 512; // start writing spiEnable(); spiReadWriteByte(SPICMD_PROGRAM); spiReadWriteByte(startAddr >> 8); spiReadWriteByte(startAddr); } for (i = 0; i < len; i++) { spiReadWriteByte(data[i]); wrote++; } writeBytesRemaining -= len; if (wrote == 512 || writeBytesRemaining == 0) { wrote = 0; spiDisable(); waitWenIsCleared(); ++currentPage; } if (writeBytesRemaining == 0) { return 1; } return 0; }