Beispiel #1
0
/*
** ===================================================================
**     Method      :  EE241_ReadBlock (component 24AA_EEPROM)
**     Description :
**         Read a block of memory.
**     Parameters  :
**         NAME            - DESCRIPTION
**         addr            - Address where to read the memory
**       * data            - Pointer to a buffer where to store the
**                           data
**         dataSize        - Size of buffer the data pointer
**                           is pointing to
**     Returns     :
**         ---             - Error code, possible values
**                           ERR_OK - OK
**                           otherwise it can return an error code of
**                           the underlying communication protocol.
** ===================================================================
*/
byte EE241_ReadBlock(EE241_Address addr, byte *data, word dataSize)
{
  uint8_t res;
  #if EE241_DEVICE_ID==EE241_DEVICE_ID_8
    uint8_t addr8;
    addr8 = (uint8_t)(addr&0xff);
  #else  
    uint8_t addr16[2];                  /* big endian address on I2C bus needs to be 16bit */
    addr16[0] = (uint8_t)(addr>>8); /* 16 bit address must be in big endian format */
    addr16[1] = (uint8_t)(addr&0xff);
  #endif

  res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr));
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  #if EE241_DEVICE_ID==EE241_DEVICE_ID_8
    res = GI2C1_WriteBlock(&addr8, 1, GI2C1_DO_NOT_SEND_STOP); /* send 8bit address */
  #else
    res = GI2C1_WriteBlock(addr16, 2, GI2C1_DO_NOT_SEND_STOP); /* send 16bit address */
  #endif
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_ReadBlock(data, dataSize, GI2C1_SEND_STOP);
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  return GI2C1_UnselectSlave();
}
Beispiel #2
0
/* Single Write DAC Input Register (EEPROM not updated) */
uint8_t MCP4728_FastWriteDAC(uint8_t channel, uint16_t val) {
  uint8_t res;
  uint8_t data[3];

  /* 01000|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */
  if (channel>3) {
    return ERR_FAILED; /* only channel 0-3 allowed */
  }
  data[0] = 0x40|((channel&0x3)<<1); /* UDAC zero */
  data[1] = (uint8_t)((val>>8)&0x0F); /* VREF, PD1, PD2 and Gx zero */
  data[2] = (uint8_t)(val&0xff); /* low byte */
  res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS);
  if (res!=ERR_OK) {
    return res;
  }
  res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP);
  if (res!=ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_UnselectSlave();
  if (res!=ERR_OK) {
    return res;
  }
  return ERR_OK;
}
Beispiel #3
0
/* Single Write DAC Input Register and EEPROM */
uint8_t MCP4728_WriteDACandEE(uint8_t channel, uint16_t val) {
  uint8_t res;
  uint8_t data[3];

  /* 01011|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */
  if (channel>3) {
    return ERR_FAILED; /* only channel 0-3 allowed */
  }
  data[0] = 0x58|((channel&0x3)<<1); /* UDAC zero */
  data[1] = (uint8_t)((val>>8)&0x0F); /* VREF, PD1, PD2 and Gx zero */
  data[2] = (uint8_t)(val&0xff); /* low byte */
  res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS);
  if (res!=ERR_OK) {
    return res;
  }
  res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP);
  if (res!=ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_UnselectSlave();
  if (res!=ERR_OK) {
    return res;
  }
#if PL_CONFIG_HAS_MCP4728_RDY
  while(MCP4728_IsBusy()) {
    WAIT1_WaitOSms(10); /* wait until data is written */
  }
#else
  WAIT1_WaitOSms(500); /* give EEPROM time to write data */
#endif
  return ERR_OK;
}
Beispiel #4
0
/* Fast Mode Write: updates all 4 channels, but does not update EEPROM */
uint8_t MCP4728_FastWriteAllDAC(uint16_t dac[4], size_t dacSize, uint8_t pd[4], size_t pdSize) {
  uint8_t res;
  uint8_t data[4*2], *p;
  int i;

  /* DAC contains PD1|PD0|D11..D0 */
  if (dacSize!=4*sizeof(uint16_t) || pdSize!=4) {
    return ERR_FAILED;
  }
  p = &data[0];
  for(i=0;i<4;i++) {
    *p = (pd[i]&0x3)<<4;
    *p |= (dac[i]>>8)&0x0F;
    p++;
    *p = (uint8_t)(dac[i]&0xFF);
    p++;
  }
  res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS);
  if (res!=ERR_OK) {
    return res;
  }
  res = GI2C1_WriteBlock(data, sizeof(data), GI2C1_SEND_STOP);
  if (res!=ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_UnselectSlave();
  if (res!=ERR_OK) {
    return res;
  }
  return ERR_OK;
}
Beispiel #5
0
/*
** ===================================================================
**     Method      :  EE241_WriteByte (component 24AA_EEPROM)
**     Description :
**         Writes a single byte to specified address
**     Parameters  :
**         NAME            - DESCRIPTION
**         addr            - The address inside the EEPROM
**         data            - The data value to write
**     Returns     :
**         ---             - Error code, possible values
**                           ERR_OK - OK
**                           otherwise it can return an error code of
**                           the underlying communication protocol.
** ===================================================================
*/
byte EE241_WriteByte(EE241_Address addr, byte data)
{
  uint8_t res, block[3];

  res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr));
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  #if EE241_DEVICE_ID==EE241_DEVICE_ID_8  
    block[0] = (uint8_t)(addr&0xff);    /* low byte of address */
    block[1] = data; /* switch to read mode */
    res = GI2C1_WriteBlock(block, 2, GI2C1_SEND_STOP); /* send address and data */
  #else
    block[0] = (uint8_t)(addr>>8);      /* high byte of address */
    block[1] = (uint8_t)(addr&0xff);    /* low byte of address */
    block[2] = data; /* switch to read mode */
    res = GI2C1_WriteBlock(block, sizeof(block), GI2C1_SEND_STOP); /* send address and data */
  #endif
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
#if EE241_DO_ACKNOWLEDGE_POLLING
  /* do acknowledge polling */
  block[0] = 0xff; /* dummy value */
  do {
    WAIT1_WaitOSms(EE241_PAGE_WRITE_TIME_MS);
    res = GI2C1_ProbeACK(block, 1, GI2C1_SEND_STOP, EE241_ACK_POLLING_TIME_US); /* send address and data */
  } while(res!=ERR_OK); /* wait until we get an ACK */
#endif /* EE241_DO_ACKNOWLEDGE_POLLING */
  if (res != ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  return GI2C1_UnselectSlave();
}
Beispiel #6
0
/*!
 * \brief General Call to reset, wake-up, sofware update or read address bits.
 */
static uint8_t MCP4728_GeneralCall(uint8_t cmd) {
  uint8_t res;

  res = GI2C1_SelectSlave(MCP4728_I2C_ADDRESS);
  if (res!=ERR_OK) {
    return res;
  }
  res = GI2C1_WriteBlock(&cmd, sizeof(cmd), GI2C1_SEND_STOP);
  if (res!=ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_UnselectSlave();
  if (res!=ERR_OK) {
    return res;
  }
  return ERR_OK;
}
Beispiel #7
0
uint8_t MPC4728_SingleWrite(uint8_t channel, uint16_t val) {
  uint8_t res;
  uint8_t data[3];
  
  /* 01011|DAC1|DAC0|UDAC VREF|PD1|PD0|Gx|D11-D0 */
  data[0] = 0xB0|((channel&0x3)<<1);
  data[1] = (uint8_t)(val>>8);
  data[2] = (uint8_t)(val&0xff);
  res = GI2C1_SelectSlave(MPC4728_I2C_ADDRESS);
  if (res!=ERR_OK) {
    return res;
  }
  res = GI2C1_WriteBlock(&data[0], sizeof(data), GI2C1_SEND_STOP);
  if (res!=ERR_OK) {
    (void)GI2C1_UnselectSlave();
    return res;
  }
  res = GI2C1_UnselectSlave();
  if (res!=ERR_OK) {
    return res;
  }
  return ERR_OK;
}
Beispiel #8
0
byte EE241_WriteBlockPage(EE241_Address addr, byte *data, word dataSize)
{
  uint8_t res, i, *p, block[EE241_BLOCK_BUF_SIZE+2]; /* additional 2 bytes for the address */
  uint16_t eepromPage = (uint16_t)(addr/EE241_PAGE_SIZE);
  uint8_t offset = (uint8_t)(addr%EE241_PAGE_SIZE);

  if (dataSize==0 || dataSize>EE241_BLOCK_BUF_SIZE) {
    return ERR_OVERFLOW;                /* you may increase the buffer size in the properties? */
  }
  if (dataSize>EE241_PAGE_SIZE) {
    uint16_t size;

    size = (uint16_t)(EE241_PAGE_SIZE-offset);
    if (size!=0) {
      res = EE241_WriteBlock(addr, data, size); /* first page write */
      if (res != ERR_OK) {
        return res;
      }
      data += size; /* increment data pointer */
      addr += size; /* increment address */
      dataSize -= size; /* reduce size */
    }
    /* write multiple block of PAGE_SIZE */
    while (dataSize>EE241_PAGE_SIZE) {
      res = EE241_WriteBlock(addr, data, EE241_PAGE_SIZE);
      if (res != ERR_OK) {
        return res;
      }
      data += EE241_PAGE_SIZE; /* increment data pointer */
      addr += EE241_PAGE_SIZE; /* increment address */
      dataSize -= EE241_PAGE_SIZE; /* reduce size */
    }
    /* write remainder (if any) */
    if (dataSize>0) {
      return EE241_WriteBlock(addr, data, dataSize);
    }
    return ERR_OK;
  }
  if (offset+dataSize <= EE241_PAGE_SIZE) { /* no page boundary crossing */
    res = GI2C1_SelectSlave(EE241_DEVICE_ADDR(addr));
    if (res != ERR_OK) {
      (void)GI2C1_UnselectSlave();
      return res;
    }
    #if EE241_DEVICE_ID==EE241_DEVICE_ID_8 
      /* 8 bit address byte, high byte of address have been place in SelectSlave(addr) */
      block[0] = (uint8_t)(addr&0xff);  /* low byte of address */
      p = &block[1]; i = (uint8_t)dataSize;
    #else /* 16 bit address byte */
      block[0] = (uint8_t)(addr>>8);    /* high byte of address */
      block[1] = (uint8_t)(addr&0xff);  /* low byte of address */
      p = &block[2]; i = (uint8_t)dataSize;
    #endif

    /* copy block */
    while(i>0) {
      *p++ = *data++;
      i--;
    }
    res = GI2C1_WriteBlock(block, 
        dataSize+((EE241_DEVICE_ID==EE241_DEVICE_ID_8)? 1:2), GI2C1_SEND_STOP); /* send address and data */
    if (res != ERR_OK) {
      (void)GI2C1_UnselectSlave();
      return res;
    }
#if EE241_DO_ACKNOWLEDGE_POLLING
    /* do acknowledge polling */
    block[0] = 0xff; /* dummy value */
    do {
      WAIT1_WaitOSms(EE241_PAGE_WRITE_TIME_MS);
      res = GI2C1_ProbeACK(block, 1, GI2C1_SEND_STOP, EE241_ACK_POLLING_TIME_US); /* send address and data */
    } while(res!=ERR_OK); /* wait until we get an ACK */
    if (res != ERR_OK) {
      (void)GI2C1_UnselectSlave();
      return res;
    }
#endif /* EE241_DO_ACKNOWLEDGE_POLLING */
    return GI2C1_UnselectSlave();
  } else { /* crossing page boundaries: make two page writes */