//------------------------------------------------------------------------------ // send command and return error code. Return zero for OK uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { // select card chipSelectLow(); // wait up to 300 ms if busy waitNotBusy(300); // send command spiSend(cmd | 0x40); // send argument for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); // send CRC uint8_t crc = 0XFF; if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA spiSend(crc); // skip stuff byte for stop read if (cmd == CMD12) spiRec(); // wait for response for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++) { /* Intentionally left empty */ } return status_; }
/** * @brief Writes a block within a sequential write operation. * * @param[in] mmcp pointer to the @p MMCDriver object * @param[out] buffer pointer to the write buffer * * @return The operation status. * @retval HAL_SUCCESS the operation succeeded. * @retval HAL_FAILED the operation failed. * * @api */ bool mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { static const uint8_t start[] = {0xFF, 0xFC}; uint8_t b[1]; osalDbgCheck((mmcp != NULL) && (buffer != NULL)); if (mmcp->state != BLK_WRITING) { return HAL_FAILED; } spiSend(mmcp->config->spip, sizeof(start), start); /* Data prologue. */ spiSend(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);/* Data. */ spiIgnore(mmcp->config->spip, 2); /* CRC ignored. */ spiReceive(mmcp->config->spip, 1, b); if ((b[0] & 0x1FU) == 0x05U) { wait(mmcp); return HAL_SUCCESS; } /* Error.*/ spiUnselect(mmcp->config->spip); spiStop(mmcp->config->spip); mmcp->state = BLK_READY; return HAL_FAILED; }
//------------------------------------------------------------------------------ // send one block of data for write block or write multiple blocks uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { #ifdef SPI_DMA dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS, (uint8_t *)src, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT | DMA_TRNS_ERR)); dma_attach_interrupt(DMA1, DMA_CH3, DMAEvent); dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH); dma_set_num_transfers(DMA1, DMA_CH3, 512); dmaActive = true; dma_enable(DMA1, DMA_CH3); while(dmaActive) delayMicroseconds(1); dma_disable(DMA1, DMA_CH3); #else // SPI_DMA spiSend(token); for (uint16_t i = 0; i < 512; i++) { spiSend(src[i]); } #endif // OPTIMIZE_HARDWARE_SPI spiSend(0xff); // dummy crc spiSend(0xff); // dummy crc status_ = spiRec(); if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { error(SD_CARD_ERROR_WRITE); chipSelectHigh(); Serial.println("Error: Write"); Serial.println("Error: Sd2Card::writeData()"); return false; } return true; }
//------------------------------------------------------------------------------ // send command to card uint8_t SdReader::cardCommand(uint8_t cmd, uint32_t arg) { uint8_t r1; // end read if in partialBlockRead mode readEnd(); // select card spiSSLow(); // wait up to 300 ms if busy waitNotBusy(300); // send command spiSend(cmd | 0x40); // send argument for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); // send CRC uint8_t crc = 0XFF; if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA spiSend(crc); // wait for response for (uint8_t retry = 0; ((r1 = spiRec()) & 0X80) && retry != 0XFF; retry++); return r1; }
//------------------------------------------------------------------------------ // send one block of data for write block or write multiple blocks uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { #ifdef OPTIMIZE_HARDWARE_SPI // send data - optimized loop SPDR = token; // send two byte per iteration for (uint16_t i = 0; i < 512; i += 2) { while (!(SPSR & (1 << SPIF))); SPDR = src[i]; while (!(SPSR & (1 << SPIF))); SPDR = src[i+1]; } // wait for last data byte while (!(SPSR & (1 << SPIF))); #else // OPTIMIZE_HARDWARE_SPI spiSend(token); for (uint16_t i = 0; i < 512; i++) { spiSend(src[i]); } #endif // OPTIMIZE_HARDWARE_SPI spiSend(0xff); // dummy crc spiSend(0xff); // dummy crc status_ = spiRec(); if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { error(SD_CARD_ERROR_WRITE); chipSelectHigh(); return false; } return true; }
/** * @brief Writes a block within a sequential write operation. * * @param[in] mmcp pointer to the @p MMCDriver object * @param[out] buffer pointer to the write buffer * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. * * @api */ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { static const uint8_t start[] = {0xFF, 0xFC}; uint8_t b[1]; chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite"); chSysLock(); if (mmcp->state != MMC_WRITING) { chSysUnlock(); return TRUE; } chSysUnlock(); spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */ spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */ spiIgnore(mmcp->spip, 2); /* CRC ignored. */ spiReceive(mmcp->spip, 1, b); if ((b[0] & 0x1F) == 0x05) { wait(mmcp); return FALSE; } /* Error.*/ spiUnselect(mmcp->spip); chSysLock(); if (mmcp->state == MMC_WRITING) mmcp->state = MMC_READY; chSysUnlock(); return TRUE; }
//------------------------------------------------------------------------------ // send command and return error code. Return zero for OK uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) { // end read if in partialBlockRead mode readEnd(); // select card chipSelectLow(); // wait up to 300 ms if busy waitNotBusy(300); // send command spiSend(cmd | 0x40); // send argument for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); // send CRC uint8_t crc = 0XFF; if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0 if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA spiSend(crc); // wait for response for (unsigned int i = 0; ((status_ = spiRec()) & 0X80) && i != 0xFFF; i++); return status_; }
static void cmd_write(BaseSequentialStream *chp, int argc, char *argv[]) { (void)argc; (void)argv; acquire_bus(); write_index(0x00); chprintf(chp,"Device ID %x\r\n",read_data()); release_bus(); //chprintf(chp,"GRAM %x\r\n",gdispReadReg(0x22)); /*gdispClear(White); chThdSleepMilliseconds(3000); gdispClear(Red); chThdSleepMilliseconds(3000); gdispClear(Blue); chThdSleepMilliseconds(3000); gdispClear(Green);*/ #if 0 uint8_t c = 0xAA; uint8_t d = 0x55; spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */ spiStart(&SPID1, &spicfg); /* Setup transfer parameters. */ spiSelect(&SPID1); /* Slave Select assertion. */ spiSend(&SPID1, 1, &c); spiSend(&SPID1, 1, &d); spiUnselect(&SPID1); /* Slave Select de-assertion. */ spiReleaseBus(&SPID1); /* Ownership release. */ #endif }
uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { switch(msg) { case U8G_COM_MSG_STOP: break; case U8G_COM_MSG_INIT: u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_CS, 1); u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_A0, 1); u8g_SetPIOutput_DUE_hw_spi(u8g, U8G_PI_CS); u8g_SetPIOutput_DUE_hw_spi(u8g, U8G_PI_A0); u8g_Delay(5); spiBegin(); #ifndef SPI_SPEED #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card #endif spiInit(2); break; case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_A0, arg_val); break; case U8G_COM_MSG_CHIP_SELECT: u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_CS, (arg_val ? 0 : 1)); break; case U8G_COM_MSG_RESET: break; case U8G_COM_MSG_WRITE_BYTE: spiSend((uint8_t)arg_val); break; case U8G_COM_MSG_WRITE_SEQ: { uint8_t *ptr = (uint8_t*) arg_ptr; while (arg_val > 0) { spiSend(*ptr++); arg_val--; } } break; case U8G_COM_MSG_WRITE_SEQ_P: { uint8_t *ptr = (uint8_t*) arg_ptr; while (arg_val > 0) { spiSend(*ptr++); arg_val--; } } break; } return 1; }
void spiSendBlock(uint8_t token, const uint8_t* buf) { spiSend (token); for (uint16_t i = 0; i < 512; i += 2) { spiSend (buf[i]); spiSend (buf[i+1]); } }
void SPI_Write(unsigned int addr,unsigned char data) { enablewiz(); // Activate the CS pin spiSend(WIZNET_WRITE_OPCODE); // Send Wiznet W5100 Write OpCode spiSend(addr >>8); // Send Wiznet W5100 Address High Byte spiSend(addr & 0x00FF); // Send Wiznet W5100 Address Low Byte spiSend(data); // Send the data byte disablewiz(); // make CS pin not active }
void _writeBuffer(uint16_t len, uint8_t *data) { uint8_t tx[] = { WRITE_BUF_MEM }; spiSelect(_spip); spiSend(_spip, 1, tx); spiSend(_spip, len, data); spiUnselect(_spip); }
/** * @brief Writes a value into a generic register using SPI. * @pre The SPI interface must be initialized and the driver started. * * @param[in] spip pointer to the SPI interface * @param[in] reg starting register address * @param[in] n number of adjacent registers to write * @param[in] b pointer to a buffer of values. */ static void l3gd20SPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n, uint8_t* b) { uint8_t cmd; (n == 1) ? (cmd = reg) : (cmd = reg | L3GD20_MS); spiSelect(spip); spiSend(spip, 1, &cmd); spiSend(spip, n, b); spiUnselect(spip); }
void adxl362_write_register (uint16_t address, uint8_t data) { uint8_t command = 0x0A; spiStart(&SPID1, &adxl362_cfg); /* Setup transfer parameters. */ spiSelect(&SPID1); /* Slave Select assertion. */ spiSend(&SPID1, 1, &command); /* Write Command */ spiSend(&SPID1, 1, &address); /* Address */ spiSend(&SPID1, 1, &data); /* Data */ spiUnselect(&SPID1); /* Slave Select de-assertion. */ }
void gyro_write_register (uint8_t address, uint8_t data) { address = address & (~0x80); /* Clear the write bit (bit 7) */ spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */ spiStart(&SPID1, &gyro_cfg); /* Setup transfer parameters. */ spiSelect(&SPID1); /* Slave Select assertion. */ spiSend(&SPID1, 1, &address); /* Send the address byte */ spiSend(&SPID1, 1, &data); spiUnselect(&SPID1); /* Slave Select de-assertion. */ spiReleaseBus(&SPID1); /* Ownership release. */ }
unsigned char SPI_Read(unsigned int addr) { unsigned char value; //data returned from spi transmission enablewiz(); // Activate the CS pin spiSend(WIZNET_READ_OPCODE); //Send Wiznet W5100 Write OpCode spiSend(addr >>8); // Send Wiznet W5100 Address High Byte spiSend(addr & 0x00FF); // Send Wiznet W5100 Address Low Byte value=spixfer(0xff); // Send Dummy transmission to read the data disablewiz(); // make CS pin inactive return(value); }
uint8_t adxl362_read_register (uint8_t address) { uint8_t command = 0x0B; uint8_t dummy = 0x00; uint8_t receive_data; spiStart(&SPID1, &adxl362_cfg); /* Setup transfer parameters. */ spiSelect(&SPID1); /* Slave Select assertion. */ spiSend(&SPID1, 1, &command); /* Transmit Read Command */ spiSend(&SPID1, 1, &address); /* Read Command */ spiReceive(&SPID1, 1, &receive_data); /* Read the data that is returned */ spiUnselect(&SPID1); /* Slave Select de-assertion. */ return (receive_data); }
void RFM70::selectBank(uint8_t bank) { uint8_t tmp = readRegVal(0x07) & 0x80; if (bank) { if (!tmp) { spiSend(0, (uint8_t *) RFM70_cmd_switch_cfg, NELEMS(RFM70_cmd_switch_cfg)); } } else { if (tmp) { spiSend(0, (uint8_t *) RFM70_cmd_switch_cfg, NELEMS(RFM70_cmd_switch_cfg)); } } }
static void send_cmd(uint8_t cmd, uint32_t addr, const uint8_t* cmd_tx_buf, uint32_t cmd_tx_len, uint8_t* cmd_rx_buf, uint32_t cmd_rx_len) { xflash_txn_begin(); spiSend(SPI_FLASH, 1, &cmd); if (addr != NO_ADDR) { uint8_t addr_buf[3]; addr_buf[0] = addr >> 16; addr_buf[1] = addr >> 8; addr_buf[2] = addr; spiSend(SPI_FLASH, 3, addr_buf); }
//------------------------------------------------------------------------------ static uint8_t cardCommand(uint8_t cmd, uint32_t arg) { uint8_t r1; // some cards need extra clocks after transaction to go to ready state // easiest to put extra clocks before next transaction spiSSLow(); spiRec(); spiSend(cmd | 0x40); for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s); spiSend(cmd == CMD0 ? 0x95 : 0XFF);//must send valid CRC for CMD0 //wait for not busy for (uint8_t retry = 0; (r1 = spiRec()) == 0xFF && retry != 0XFF; retry++); return r1; }
static uint32_t spiRec32(uint8_t wishboneSlot) { spiSend(0XFF); spiSend(0XFF); spiSend(0XFF); spiSend(0XFF); // Serial.print(USPIDATA&0xff); // Serial.print(" "); //return USPIDATA&0xff; //return USPIDATA; //return SPI.transfer32(0xFFFFFFFF); //REGISTER(IO_SLOT(12),5) = 0xFFFFFFFF; return REGISTER(IO_SLOT(wishboneSlot),1); //return SPI.transfer32(0xFFFFFFFF); }
static void M25P16WritePage(uint32_t Address, uint8_t * Buffer) { uint8_t Command[] = { M25P16_PAGE_PROGRAM, (Address >> 16) & 0xFF, (Address >> 8) & 0xFF, Address & 0xFF}; M25P16SetWriteEnable(); spiStart(&FLASH_SPI, &HSSpiConfig); /* Setup transfer parameters. */ spiSelect(&FLASH_SPI); /* Slave Select assertion. */ spiSend(&FLASH_SPI, 4, Command); /* Send command */ spiSend(&FLASH_SPI, 256, Buffer); spiUnselect(&FLASH_SPI); /* Slave Select de-assertion. */ spiStop(&FLASH_SPI); while(M25P16ReadStatus() & 0x1) chThdSleepMicroseconds(100); }
void eeprom_read(uint8_t address, uint8_t *data, uint32_t length){ eeprom_select(); uint8_t header [2] = {0x03, address}; spiSend(&EEPROM_SPI_BUS, 2, header); spiReceive(&EEPROM_SPI_BUS, length, data); eeprom_unselect(); }
//------------------------------------------------------------------------------ // send one block of data for write block or write multiple blocks uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) { spiSend(token); for (uint16_t i = 0; i < 512; i++) { spiSend(src[i]); } spiSend(0xff); // dummy crc spiSend(0xff); // dummy crc status_ = spiRec(); if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) { error(SD_CARD_ERROR_WRITE); chipSelectHigh(); return false; } return true; }
/** Set Slave Select high */ inline void spiSSHigh(void) { //digitalWrite(SS, HIGH); sbi(PORTB, SS); // insure SD data out is high Z spiSend(0XFF); }
/** * @brief Stops a sequential read gracefully. * * @param[in] mmcp pointer to the @p MMCDriver object * @return The operation status. * @retval FALSE the operation succeeded. * @retval TRUE the operation failed. * * @api */ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { static const uint8_t stopcmd[] = {0x40 | MMC_CMDSTOP, 0, 0, 0, 0, 1, 0xFF}; bool_t result; chDbgCheck(mmcp != NULL, "mmcStopSequentialRead"); chSysLock(); if (mmcp->state != MMC_READING) { chSysUnlock(); return TRUE; } chSysUnlock(); spiSend(mmcp->spip, sizeof(stopcmd), stopcmd); /* result = recvr1(mmcp) != 0x00;*/ /* Note, ignored r1 response, it can be not zero, unknown issue.*/ recvr1(mmcp); result = FALSE; spiUnselect(mmcp->spip); chSysLock(); if (mmcp->state == MMC_READING) mmcp->state = MMC_READY; chSysUnlock(); return result; }
/** SPI send multiple bytes */ static void spiSend(const uint8_t* output, size_t len) { // clear any data in RX FIFO SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); // use 16 bit frame to avoid TD delay between frames // send one byte if len is odd if (len & 1) { spiSend(*output++); len--; } // initial number of words to push into TX FIFO int nf = len/2 < SPI_INITIAL_FIFO_DEPTH ? len/2 : SPI_INITIAL_FIFO_DEPTH; // limit for pushing data into TX fifo const uint8_t* limit = output + len; for (int i = 0; i < nf; i++) { uint16_t w = (*output++) << 8; w |= *output++; SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; } // write data to TX FIFO while (output < limit) { uint16_t w = *output++ << 8; w |= *output++; while (!(SPI0_SR & SPI_SR_RXCTR)) {} SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; SPI0_POPR; } // wait for data to be sent while (nf) { while (!(SPI0_SR & SPI_SR_RXCTR)) {} SPI0_POPR; nf--; } }
/** * Initialize a SD flash memory card. * * \param[in] slow Set SPI Frequency F_CPU/4 if true else F_CPU/2. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. * */ uint8_t SdCard::init(uint8_t slow) { pinMode(SS, OUTPUT); spiSSHigh(); pinMode(MOSI, OUTPUT); pinMode(SCK, OUTPUT); //Enable SPI, Master, clock rate F_CPU/128 SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); //must supply min of 74 clock cycles with CS high. for (uint8_t i = 0; i < 10; i++) spiSend(0XFF); spiSSLow(); // next line prevent re-init hang by some cards (not sure why this works) for (uint16_t i = 0; i <= 512; i++) spiRec(); uint8_t r = cardCommand(CMD0, 0); for (uint16_t retry = 0; r != R1_IDLE_STATE; retry++){ if (retry == 10000) { error(SD_ERROR_CMD0, r); return false; } r = spiRec(); } for (uint16_t retry = 0; ; retry++) { cardCommand(CMD55, 0); if ((r = cardCommand(ACMD41, 0)) == R1_READY_STATE)break; if (retry == 1000) { error(SD_ERROR_ACMD41, r); return false; } } // set SPI frequency SPCR &= ~((1 << SPR1) | (1 << SPR0)); // F_CPU/4 if (!slow) SPSR |= (1 << SPI2X); // Doubled Clock Frequency to F_CPU/2 spiSSHigh(); return true; }
void MD_MAX72XX::flushBufferAll() // Only one data byte is sent to a device, so if there are many changes, it is more // efficient to send a data byte all devices at the same time, substantially cutting // the number of communication messages required. { for (uint8_t i=0; i<ROW_SIZE; i++) // all data rows { bool bChange = false; // set to true if we detected a change spiClearBuffer(); for (uint8_t dev = FIRST_BUFFER; dev <= LAST_BUFFER; dev++) // all devices { if (bitRead(_matrix[dev].changed, i)) { // put our device data into the buffer _spiData[SPI_OFFSET(dev, 0)] = OP_DIGIT0+i; _spiData[SPI_OFFSET(dev, 1)] = _matrix[dev].dig[i]; bChange = true; } } if (bChange) spiSend(); } // mark everything as cleared for (uint8_t dev = FIRST_BUFFER; dev <= LAST_BUFFER; dev++) _matrix[dev].changed = ALL_CLEAR; }
void MD_MAX72XX::flushBuffer(uint8_t buf) // Use this function when the changes are limited to one device only. // Address passed is a buffer address { PRINT("\nflushBuf: ", buf); PRINTS(" r"); if (buf > LAST_BUFFER) return; for (uint8_t i = 0; i < ROW_SIZE; i++) { if (bitRead(_matrix[buf].changed, i)) { PRINT("", i); spiClearBuffer(); // put our device data into the buffer _spiData[SPI_OFFSET(buf, 0)] = OP_DIGIT0+i; _spiData[SPI_OFFSET(buf, 1)] = _matrix[buf].dig[i]; spiSend(); } } _matrix[buf].changed = ALL_CLEAR; }