Exemplo n.º 1
0
//------------------------------------------------------------------------------
// 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_;
}
Exemplo n.º 2
0
/**
 * @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;
}
Exemplo n.º 4
0
//------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 6
0
/**
 * @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;
}
Exemplo n.º 7
0
//------------------------------------------------------------------------------
// 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_;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 10
0
  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]);
  }

}
Exemplo n.º 11
0
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
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
/**
 * @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);
}
Exemplo n.º 14
0
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. */
}
Exemplo n.º 15
0
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.               */
}
Exemplo n.º 16
0
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);
}
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
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));
		}
	}
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
0
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);
  }
Exemplo n.º 23
0
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();
}
Exemplo n.º 24
0
//------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 25
0
/** Set Slave Select high */
inline void spiSSHigh(void) {
   //digitalWrite(SS, HIGH);
   sbi(PORTB, SS);

   // insure SD data out is high Z
   spiSend(0XFF);
}
Exemplo n.º 26
0
/**
 * @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;
}
Exemplo n.º 27
0
/** 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;
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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;
}