ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
27 ноября
931203 Топик полностью
SciFi (03.07.2019 17:06, просмотров: 120) ответил Ксения на Может быть, у кого-то готовый код есть (желательно под STM32), как в эту флешку читать/писать? Лично меня смущает, что по даташиту она "Dual/Quad I/O SPI", тогда как у меня обычный 8-битный SPI.
вот #include "spiflash.h" #include "systime.h" #include "stm32f4xx.h" #include <string.h> static bool busy = false; static uint8_t volatile dmabuf[260]; static int addr_delayed, len_delayed; static const uint8_t* src_delayed; static void cs_assert(void) { GPIOD->BSRR = 1 << (2 + 16); } static void cs_deassert(void) { GPIOD->BSRR = 1 << 2; systime_delay(SYSTIME_TPS / 10000000); } void spiflash_init(void) { // configure SCK, MOSI, MISO GPIOC->AFR[1] |= (6 << ((10 - 8) * 4)) | (6 << ((11 - 8) * 4)) | (6 << ((12 - 8) * 4)); GPIOC->MODER |= GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1; // configure NSS cs_deassert(); GPIOD->MODER |= GPIO_MODER_MODER2_0; SPI3->CR2 = SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI3->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE | SPI_CR1_MSTR; } static void transfer(int len) { static DMA_TypeDef* const dma = DMA1; static DMA_Stream_TypeDef* const rx_stream = DMA1_Stream0; static DMA_Stream_TypeDef* const tx_stream = DMA1_Stream7; rx_stream->M0AR = (int)dmabuf; tx_stream->M0AR = (int)dmabuf; rx_stream->PAR = (int)&SPI3->DR; tx_stream->PAR = (int)&SPI3->DR; rx_stream->NDTR = len; tx_stream->NDTR = len; rx_stream->CR = (0 * DMA_SxCR_CHSEL_0) // select channel | DMA_SxCR_MINC; // memory increment mode rx_stream->CR |= DMA_SxCR_EN; // enable stream tx_stream->CR = (0 * DMA_SxCR_CHSEL_0) // select channel | DMA_SxCR_DIR_0 // memory to peripheral | DMA_SxCR_MINC; // memory increment mode tx_stream->CR |= DMA_SxCR_EN; // enable stream while ((dma->LISR & DMA_LISR_TCIF0) == 0) ; // wait for Rx DMA transfer complete rx_stream->CR = 0; tx_stream->CR = 0; while (rx_stream->CR || tx_stream->CR) ; // wait for stream disable dma->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0; dma->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CHTIF7 | DMA_HIFCR_CTEIF7; } static void unlock(void) { cs_assert(); dmabuf[0] = 6; transfer(1); cs_deassert(); } bool spiflash_busy(void) { cs_assert(); dmabuf[0] = 5; transfer(2); cs_deassert(); return dmabuf[1] & 1; } static void wait_ready(void) { if (busy) { while (spiflash_busy()) ; // wait busy = false; } } static void opcode_addr(int addr, int opcode) { dmabuf[0] = opcode; dmabuf[1] = addr >> 16; dmabuf[2] = addr >> 8; dmabuf[3] = addr; } void spiflash_read(int addr, void* dst, int len) { wait_ready(); cs_assert(); opcode_addr(addr, 0x03); int header = 4; while (len > 0) { int n = len > (sizeof dmabuf - header) ? (sizeof dmabuf - header) : len; transfer(header + n); memcpy(dst, (void*)(dmabuf + header), n); dst = n + (uint8_t*)dst; len -= n; header = 0; } cs_deassert(); } void spiflash_write_start(int addr, const void* src, int len) { addr_delayed = addr; src_delayed = src; len_delayed = len; } bool spiflash_writing(void) { return len_delayed > 0; } bool spiflash_write_done(void) { if (spiflash_writing()) { int len = 256 - (addr_delayed & 0xFF); len = (len > len_delayed ? len_delayed : len); wait_ready(); unlock(); cs_assert(); opcode_addr(addr_delayed, 0x02); memcpy((void*)(dmabuf + 4), src_delayed, len); transfer(4 + len); cs_deassert(); busy = true; addr_delayed += len; src_delayed += len; len_delayed -= len; return !spiflash_writing(); } else { return true; } } void spiflash_write(int addr, const void* src, int len) { while (!spiflash_write_done()); spiflash_write_start(addr, src, len); while (!spiflash_write_done()); } void spiflash_erase4k(int addr) { wait_ready(); unlock(); cs_assert(); opcode_addr(addr, 0x20); transfer(4); cs_deassert(); busy = true; } void spiflash_erase64k(int addr) { wait_ready(); unlock(); cs_assert(); opcode_addr(addr, 0xD8); transfer(4); cs_deassert(); busy = true; } void spiflash_unprotect64k(int addr) { wait_ready(); unlock(); cs_assert(); opcode_addr(addr, 0x39); transfer(4); cs_deassert(); }
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้