uint8_t MCP_rx_status(){ toggle_cs(0); SPI_send(MCP_RX_STATUS); // send read rx status code: 0b10110000 uint8_t data = SPI_receive(); toggle_cs(1); return data; }
void MCP_write(uint8_t address, uint8_t data){ toggle_cs(0); SPI_send(MCP_WRITE); //Send write command 0b00000010 SPI_send(address); SPI_send(data); toggle_cs(1); }
void MCP_bit_modify(uint8_t address, uint8_t mask, uint8_t data){ toggle_cs(0); SPI_send(MCP_BITMOD); // send bit modify command: 0b00000101 SPI_send(address); SPI_send(mask); SPI_send(data); toggle_cs(1); }
uint8_t MCP_read(uint8_t address){ toggle_cs(0); SPI_send(MCP_READ); //Send read command 0b00000011 SPI_send(address); uint8_t data = SPI_receive(); toggle_cs(1); return data; }
static int spi_flash_read_status(FlashOps *me) { int ret = -1; SpiFlash *flash = container_of(me, SpiFlash, ops); uint8_t command; if (flash->spi->start(flash->spi)) { printf("%s: Failed to start transaction.\n", __func__); return ret; } if (toggle_cs(flash, "RDSTATUS") != 0) goto fail; command = ReadSr1Command; if (flash->spi->transfer(flash->spi, NULL, &command, sizeof(command))) { printf("%s: Failed to send register read command.\n", __func__); goto fail; } if (flash->spi->transfer(flash->spi, &command, NULL, sizeof(command))) { printf("%s: Failed to read status.\n", __func__); goto fail; } ret = command; fail: if (flash->spi->stop(flash->spi)) { printf("%s: Failed to stop.\n", __func__); ret = -1; } return ret; }
void MCP_rts(uint8_t buffer){ toggle_cs(0); switch(buffer%4){ //Select buffer to use, 3 = all case 0: SPI_send(MCP_RTS_TX0); break; case 1: SPI_send(MCP_RTS_TX1); break; case 2: SPI_send(MCP_RTS_TX2); break; case 3: SPI_send(MCP_RTS_ALL); break; default: break; } toggle_cs(1); }
static int spi_flash_write_status(FlashOps *me, uint8_t status) { int ret = -1; SpiFlash *flash = container_of(me, SpiFlash, ops); uint8_t command_bytes[2]; if (flash->spi->start(flash->spi)) { printf("%s: Failed to start transaction.\n", __func__); return ret; } command_bytes[0] = WriteEnableCommand; if (flash->spi->transfer(flash->spi, NULL, &command_bytes, 1)) { printf("%s: Failed to send write enable command.\n", __func__); goto fail; } if (operation_failed(flash, "WREN") != 0) goto fail; /* * CS needs to be deasserted before any other command can be * issued after WREN. */ if (toggle_cs(flash, "WREN")) goto fail; command_bytes[0] = WriteStatus; command_bytes[1] = status; if (flash->spi->transfer(flash->spi, NULL, &command_bytes, 2)) { printf("%s: Failed to send write status command.\n", __func__); goto fail; } if (operation_failed(flash, "WRSTATUS") == 0) ret = 0; fail: if (flash->spi->stop(flash->spi)) { printf("%s: Failed to stop.\n", __func__); ret = -1; } return ret; }
/* * Poll device status register until write/erase operation has completed or * timed out. Returns zero on success. */ static int operation_failed(SpiFlash *flash, const char *opname) { uint8_t value; int i = 0; if (toggle_cs(flash, opname)) return -1; value = ReadSr1Command; if (flash->spi->transfer(flash->spi, NULL, &value, sizeof(value))) { printf("%s: Failed to send register read command.\n", __func__); return -1; } while (i++ < MAX_POLL_CYCLES) { if (flash->spi->transfer(flash->spi, &value, NULL, sizeof(value))) { printf("%s: Failed to read status after %d cycles.\n", __func__, i); return -1; } if (!(value & SPI_FLASH_STATUS_WIP)) { if (check_error(flash, value)) { printf("%s: status %#x after %d cycles.\n", __func__, value, i); return -1; } return 0; } udelay(POLL_INTERVAL_US); } printf("%s: timeout waiting for %s completion\n", __func__, opname); return -1; }
/* * Write or erase the flash. To write, pass a buffer and size; to erase, * pass null for the buffer. * This function is guaranteed to be invoked with data not spanning across * writeable/erasable boundaries (page size/block size). */ static int spi_flash_modify(SpiFlash *flash, const void *buffer, uint32_t offset, uint32_t size, uint8_t opcode, const char *opname) { union { uint8_t bytes[4]; // We're using 3 byte addresses. uint32_t whole; } command; int stop_needed = 0; uint32_t rv = -1; do { /* Each write or erase command requires a 'write enable' (WREN) * first. */ if (flash->spi->start(flash->spi)) { printf("%s: Failed to start WREN transaction.\n", __func__); break; } command.bytes[0] = WriteEnableCommand; if (flash->spi->transfer(flash->spi, NULL, &command, 1)) { printf("%s: Failed to send write enable command.\n", __func__); stop_needed = 1; break; } /* * CS needs to be deasserted before any other command can be * issued after WREN. */ if (toggle_cs(flash, "WREN")) break; stop_needed = 1; command.whole = swap_bytes32((opcode << 24) | offset); if (flash->spi->transfer(flash->spi, NULL, &command, 4)) { printf("%s: Failed to send %s command.\n", __func__, opname); break; } if (buffer && flash->spi->transfer(flash->spi, NULL, buffer, size)) { printf("%s: Failed to write data.\n", __func__); break; } stop_needed = 1; if (!operation_failed(flash, opname)) rv = size; } while(0); if (stop_needed && flash->spi->stop(flash->spi)) printf("%s: Failed to stop.\n", __func__); return rv; }
void MCP_reset(){ toggle_cs(0); //CS low SPI_transmit(MCP_RESET); // sen reset command 0b11000000 toggle_cs(1); //CS high }