Пример #1
0
//----------------------------------------------------------------------------
void
spiEepromWritePage(spiEepromDriver * sedp, uint16_t page, const uint8_t * buf)
{	
	uint32_t addr = page << SPIEEPROM_PAGE_SIZE_SHIFT;

	spiStart(sedp->spip, &sedp->cfgp->spicfg);
	spiSelect(sedp->spip);

	spiPolledExchange(sedp->spip, OP_WRITE);
#ifdef SPIEEPROM_24BIT_ADDRESS
	spiPolledExchange(sedp->spip, (addr>>16)&0xff);
#endif
	spiPolledExchange(sedp->spip, (addr>>8)&0xff);
	spiPolledExchange(sedp->spip, addr&0xff);
	for ( uint16_t idx = 0 ; idx < SPIEEPROM_PAGE_SIZE ; ++idx )
		spiPolledExchange(sedp->spip, *buf++);

	spiUnselect(sedp->spip);
}
Пример #2
0
/**
 * @brief   Stops a sequential read gracefully.
 *
 * @param[in] mmcp      pointer to the @p MMCDriver object
 *
 * @return              The operation status.
 * @retval CH_SUCCESS   the operation succeeded.
 * @retval CH_FAILED    the operation failed.
 *
 * @api
 */
bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
  static const uint8_t stopcmd[] = {0x40 | MMCSD_CMD_STOP_TRANSMISSION,
                                    0, 0, 0, 0, 1, 0xFF};

  chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");

  if (mmcp->state != BLK_READING)
    return CH_FAILED;

  spiSend(mmcp->config->spip, sizeof(stopcmd), stopcmd);
/*  result = recvr1(mmcp) != 0x00;*/
  /* Note, ignored r1 response, it can be not zero, unknown issue.*/
  (void) recvr1(mmcp);

  /* Read operation finished.*/
  spiUnselect(mmcp->config->spip);
  mmcp->state = BLK_READY;
  return CH_SUCCESS;
}
Пример #3
0
msg_t Mtd25::spi_read(uint8_t *rxbuf, size_t len,
                      uint8_t *writebuf, size_t preamble_len) {

#if SPI_USE_MUTUAL_EXCLUSION
  spiAcquireBus(this->spip);
#endif

  osalDbgCheck((nullptr != rxbuf) && (0 != len));

  spiSelect(spip);
  spiSend(spip, preamble_len, writebuf);
  spiReceive(spip, len, rxbuf);
  spiUnselect(spip);

#if SPI_USE_MUTUAL_EXCLUSION
  spiReleaseBus(this->spip);
#endif

  return MSG_OK;
}
Пример #4
0
static int cjReadRegister(unsigned char regAddr) {
#if ! EFI_UNIT_TEST
	spiSelect(driver);
	tx_buff[0] = regAddr;
	spiSend(driver, 1, tx_buff);
	// safety?
	chThdSleepMilliseconds(10);
	
	rx_buff[0] = 0;
	spiReceive(driver, 1, rx_buff);
	spiUnselect(driver);

#ifdef CJ125_DEBUG_SPI
	scheduleMsg(logger, "cjReadRegister: addr=%d answer=%d", regAddr, rx_buff[0]);
#endif /* CJ125_DEBUG_SPI */
	return rx_buff[0];
#else /* EFI_UNIT_TEST */
	return 0;
#endif /* EFI_UNIT_TEST */
}
Пример #5
0
void spiInit(void)
{
#warning spi stuff is currently disabled
#if 0
	/* set SS, SCLK and MOSI to output mode, and MISO to input mode */
	writeIO(&DDR_SPI, SPI_ALL, SPI_ALL ^ SPI_MISO);
	writeIO(&PORT_SPI, SPI_SS_NULL, SPI_SS_NULL);
	
	/* ensure that all slave select pins are high */
	spiUnselect();
	
	/* disable power saving for SPI, and enable hardware SPI with interrupts
	 * disabled and master mode enabled */
	writeIO(&PRR0, _BV(PRSPI), 0);
	writeIO(&SPCR, _BV(SPE) | _BV(MSTR), _BV(SPE) | _BV(MSTR));
	
	/* read the status and data registers to clear the state */
	readIO(&SPSR, 0xff);
	readIO(&SPDR, 0xff);
#endif
}
Пример #6
0
static THD_FUNCTION(Thread1, arg) {
  static uint8_t txbuf[5];
  static uint8_t rxbuf[5];

  (void)arg;
  chRegSetThreadName("Blinker");
  while (TRUE) {
    palSetPad(GPIOB, GPIOB_LED);

    /* Send the Manufacturer and Device ID Read command */
    txbuf[0] = 0x9F;

    spiSelect(&SPID1);
    spiExchange(&SPID1, sizeof(txbuf), txbuf, rxbuf);
    spiUnselect(&SPID1);

    chThdSleepMilliseconds(1000);
  }

  return 0;
}
Пример #7
0
/**
 * @brief   Writes a value into a register.
 * @pre     The SPI interface must be initialized and the driver started.
 *
 * @param[in] spip      pointer to the SPI initerface
 * @param[in] reg       register number
 * @param[in] value     the value to be written
 */
void lis302dlWriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value) {

  switch (reg) {
  default:
    /* Reserved register must not be written, according to the datasheet
       this could permanently damage the device.*/
    osalDbgAssert(FALSE, "reserved register");
  case LIS302DL_WHO_AM_I:
  case LIS302DL_HP_FILTER_RESET:
  case LIS302DL_STATUS_REG:
  case LIS302DL_OUTX:
  case LIS302DL_OUTY:
  case LIS302DL_OUTZ:
  case LIS302DL_FF_WU_SRC1:
  case LIS302DL_FF_WU_SRC2:
  case LIS302DL_CLICK_SRC:
    /* Read only registers cannot be written, the command is ignored.*/
    return;
  case LIS302DL_CTRL_REG1:
  case LIS302DL_CTRL_REG2:
  case LIS302DL_CTRL_REG3:
  case LIS302DL_FF_WU_CFG1:
  case LIS302DL_FF_WU_THS1:
  case LIS302DL_FF_WU_DURATION1:
  case LIS302DL_FF_WU_CFG2:
  case LIS302DL_FF_WU_THS2:
  case LIS302DL_FF_WU_DURATION2:
  case LIS302DL_CLICK_CFG:
  case LIS302DL_CLICK_THSY_X:
  case LIS302DL_CLICK_THSZ:
  case LIS302DL_CLICK_TIMELIMIT:
  case LIS302DL_CLICK_LATENCY:
  case LIS302DL_CLICK_WINDOW:
    spiSelect(spip);
    txbuf[0] = reg;
    txbuf[1] = value;
    spiSend(spip, 2, txbuf);
    spiUnselect(spip);
  }
}
/*
 * Application entry point.
 */
void main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * OS initialization.
   */
  chSysInit();

  /*
   * Activates the SPI driver 1 using the driver default configuration.
   */
  spiStart(&SPID1, &spicfg);

  /*
   * Normal main() thread activity.
   */
  while (TRUE) {
    volatile uint8_t b;

    chThdSleepMilliseconds(1000);
    /* Exchanging data, if the pins MISO and MOSI are connected then the
       transmitted data is received back into the buffer. On the
       STM8S-Discovery board the pins are CN2-9 and CN2-10.*/
    spiSelect(&SPID1);
    spiExchange(&SPID1, sizeof(digits), digits, buffer);
    /* Polled transfers test.*/
    b = spiPolledExchange(&SPID1, 0x55);    
    b = spiPolledExchange(&SPID1, 0xAA);    
    spiUnselect(&SPID1);
  }
}
Пример #9
0
msg_t Mtd25::spi_write(const uint8_t *txdata, size_t len,
                       uint8_t *writebuf, size_t preamble_len) {

  memcpy(&writebuf[preamble_len], txdata, len);

  if (MSG_OK != spi_write_enable())
    return MSG_RESET;

#if SPI_USE_MUTUAL_EXCLUSION
  spiAcquireBus(this->spip);
#endif

  spiSelect(spip);
  spiSend(spip, preamble_len + len, writebuf);
  spiUnselect(spip);

#if SPI_USE_MUTUAL_EXCLUSION
  spiReleaseBus(this->spip);
#endif

  return wait_op_complete(cfg.programtime);
}
Пример #10
0
/**
 * @brief   Reads a block within a sequential read operation.
 *
 * @param[in] mmcp      pointer to the @p MMCDriver object
 * @param[out] buffer   pointer to the read buffer
 *
 * @return              The operation status.
 * @retval CH_SUCCESS   the operation succeeded.
 * @retval CH_FAILED    the operation failed.
 *
 * @api
 */
bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
  int i;

  chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");

  if (mmcp->state != BLK_READING)
    return CH_FAILED;

  for (i = 0; i < MMC_WAIT_DATA; i++) {
    spiReceive(mmcp->config->spip, 1, buffer);
    if (buffer[0] == 0xFE) {
      spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);
      /* CRC ignored. */
      spiIgnore(mmcp->config->spip, 2);
      return CH_SUCCESS;
    }
  }
  /* Timeout.*/
  spiUnselect(mmcp->config->spip);
  spiStop(mmcp->config->spip);
  return CH_FAILED;
}
Пример #11
0
msg_t Mtd25::wait_op_complete(systime_t timeout) {

  systime_t start = chVTGetSystemTimeX();
  systime_t end = start + timeout;

  osalThreadSleepMilliseconds(2);

  while (chVTIsSystemTimeWithinX(start, end)) {
    uint8_t tmp;

#if SPI_USE_MUTUAL_EXCLUSION
    spiAcquireBus(this->spip);
#endif

    spiSelect(spip);
    spiPolledExchange(spip, S25_CMD_RDSR1);
    tmp = spiPolledExchange(spip, 0);
    spiUnselect(spip);

#if SPI_USE_MUTUAL_EXCLUSION
    spiReleaseBus(this->spip);
#endif

    if (tmp & S25_SR1_WIP) {
      continue;
    }
    else {
      if (tmp & (S25_SR1_PERR | S25_SR1_EERR))
        return MSG_RESET;
      else
        return MSG_OK;
    }

    osalThreadSleepMilliseconds(10);
  }

  /* time is out */
  return MSG_RESET;
}
Пример #12
0
void sc_spi_exchange(uint8_t spin, uint8_t *tx, uint8_t *rx, size_t bytes)
{
    SPIConfig spi_cfg;

    chDbgAssert(spin < SC_SPI_MAX_CLIENTS, "SPI n outside range", "#3");
    chDbgAssert(spi_conf[spin].spip != NULL, "SPI n not initialized", "#2");

    /* spiStart always to set CS for every call according to SPI client. */
    spi_cfg.end_cb = NULL;
    spi_cfg.ssport = spi_conf[spin].cs_port;
    spi_cfg.sspad = spi_conf[spin].cs_pin;
    spi_cfg.cr1 = spi_conf[spin].cr1;

    spiStart(spi_conf[spin].spip, &spi_cfg);
    spiAcquireBus(spi_conf[spin].spip);
    spiSelect(spi_conf[spin].spip);

    spiExchange(spi_conf[spin].spip, bytes, tx, rx);

    spiUnselect(spi_conf[spin].spip);
    spiReleaseBus(spi_conf[spin].spip);
    spiStop(spi_conf[spin].spip);
}
Пример #13
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 CH_SUCCESS   the operation succeeded.
 * @retval CH_FAILED    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");

  if (mmcp->state != BLK_WRITING)
    return CH_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] & 0x1F) == 0x05) {
    wait(mmcp);
    return CH_SUCCESS;
  }

  /* Error.*/
  spiUnselect(mmcp->config->spip);
  spiStop(mmcp->config->spip);
  return CH_FAILED;
}
Пример #14
0
void sc_spi_send(uint8_t spin, uint8_t *data, size_t bytes)
{
    SPIConfig spi_cfg;

    chDbgAssert(spin < SC_SPI_MAX_CLIENTS, "SPI n outside range", "#4");
    chDbgAssert(spi_conf[spin].spip != NULL, "SPI n not initialized", "#3");

    /* spiStart always to set CS per SPI client. */
    spi_cfg.end_cb = NULL;
    spi_cfg.ssport = spi_conf[spin].cs_port;
    spi_cfg.sspad = spi_conf[spin].cs_pin;
    spi_cfg.cr1 = spi_conf[spin].cr1;

    spiStart(spi_conf[spin].spip, &spi_cfg);
    spiAcquireBus(spi_conf[spin].spip);
    spiSelect(spi_conf[spin].spip);

    spiSend(spi_conf[spin].spip, bytes, data);

    spiUnselect(spi_conf[spin].spip);
    spiReleaseBus(spi_conf[spin].spip);
    spiStop(spi_conf[spin].spip);
}
Пример #15
0
/**
 * @brief   Reads a block within a sequential read operation.
 *
 * @param[in] mmcp      pointer to the @p MMCDriver object
 * @param[out] buffer   pointer to the read buffer
 *
 * @return              The operation status.
 * @retval HAL_SUCCESS   the operation succeeded.
 * @retval HAL_FAILED    the operation failed.
 *
 * @api
 */
bool mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
  unsigned i;

  osalDbgCheck((mmcp != NULL) && (buffer != NULL));

  if (mmcp->state != BLK_READING) {
    return HAL_FAILED;
  }

  for (i = 0; i < MMC_WAIT_DATA; i++) {
    spiReceive(mmcp->config->spip, 1, buffer);
    if (buffer[0] == 0xFEU) {
      spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);
      /* CRC ignored. */
      spiIgnore(mmcp->config->spip, 2);
      return HAL_SUCCESS;
    }
  }
  /* Timeout.*/
  spiUnselect(mmcp->config->spip);
  spiStop(mmcp->config->spip);
  mmcp->state = BLK_READY;
  return HAL_FAILED;
}
Пример #16
0
/**
 * @brief   Stops a sequential write 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 mmcStopSequentialWrite(MMCDriver *mmcp) {
  static const uint8_t stop[] = {0xFD, 0xFF};

  chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");

  chSysLock();
  if (mmcp->state != MMC_WRITING) {
    chSysUnlock();
    return TRUE;
  }
  chSysUnlock();

  spiSend(mmcp->spip, sizeof(stop), stop);
  spiUnselect(mmcp->spip);

  chSysLock();
  if (mmcp->state == MMC_WRITING) {
    mmcp->state = MMC_READY;
    chSysUnlock();
    return FALSE;
  }
  chSysUnlock();
  return TRUE;
}
LLDSPEC bool_t gdisp_lld_init(GDisplay *g)
{
    unsigned char j;
    // No private area for this controller
    g->priv = 0;
    
    // Initialise the board interface
    init_board(g);
    
    // Hardware reset
    spiUnselect(&DISP_SPI_PORT);
    CLR_RS;
    setpin_reset(g, TRUE);
    delayms(10);
    setpin_reset(g, FALSE);
    delayms(10);
    SET_RS;
    spiSelect(&DISP_SPI_PORT);
    
    for (j = 0; j < 134; j++) {
        write_cmd(g, initData[j]);
    }
    
    delayms(10);
    spiUnselect(&DISP_SPI_PORT);
    
    delayms(10);
    
    spiSelect(&DISP_SPI_PORT);
    
    write_cmd(g, 0xf0);
    write_cmd(g, 0x81);
    write_cmd(g, 0xf4);
    write_cmd(g, 0xb3);
    write_cmd(g, 0xa0);
    
    write_cmd(g, 0xf0);
    write_cmd(g, 0x06);
    write_cmd(g, 0x10);
    write_cmd(g, 0x20);
    write_cmd(g, 0x30);
    write_cmd(g, 0xf5);
    write_cmd(g, 0x0f);
    write_cmd(g, 0x1c);
    write_cmd(g, 0x2f);
    write_cmd(g, 0x34);
    
    write_cmd(g, 0xf4);
    write_cmd(g, 0x94);
    write_cmd(g, 0xb3);
    write_cmd(g, 0xa2);
    write_cmd(g, 0xd0);
    
    spiUnselect(&DISP_SPI_PORT);
    CLR_RS;
    
    spiStop(&DISP_SPI_PORT);
    spiStart(&DISP_SPI_PORT, &spi2cfg2);
    
    /* Initialise the GDISP structure to match */
    g->g.Width = GDISP_SCREEN_WIDTH;
    g->g.Height = GDISP_SCREEN_HEIGHT;
    g->g.Orientation = GDISP_ROTATE_0;
    g->g.Powermode = powerOn;
    g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
    g->g.Contrast = GDISP_INITIAL_CONTRAST;
    return TRUE;
}
Пример #18
0
void spiEnd(void)
{
	spiUnselect();
}
Пример #19
0
static THD_FUNCTION(Thread1, arg) {
  static int8_t xbuf[4], ybuf[4];   /* Last accelerometer data.*/
  systime_t time;                   /* Next deadline.*/

  (void)arg;
  chRegSetThreadName("reader");

  /* LIS302DL initialization.*/
  lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG1, 0x43);
  lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG2, 0x00);
  lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG3, 0x00);

  /* Reader thread loop.*/
  time = chVTGetSystemTime();
  while (TRUE) {
    int32_t x, y;
    unsigned i;

    /* Keeping an history of the latest four accelerometer readings.*/
    for (i = 3; i > 0; i--) {
      xbuf[i] = xbuf[i - 1];
      ybuf[i] = ybuf[i - 1];
    }

    /* Reading MEMS accelerometer X and Y registers.*/
    xbuf[0] = (int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTX);
    ybuf[0] = (int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTY);

    /* Transmitting accelerometer the data over SPI2.*/
    spiSelect(&SPID2);
    spiSend(&SPID2, 4, xbuf);
    spiSend(&SPID2, 4, ybuf);
    spiUnselect(&SPID2);

    /* Calculating average of the latest four accelerometer readings.*/
    x = ((int32_t)xbuf[0] + (int32_t)xbuf[1] +
         (int32_t)xbuf[2] + (int32_t)xbuf[3]) / 4;
    y = ((int32_t)ybuf[0] + (int32_t)ybuf[1] +
         (int32_t)ybuf[2] + (int32_t)ybuf[3]) / 4;

    /* Reprogramming the four PWM channels using the accelerometer data.*/
    if (y < 0) {
      pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)-y);
      pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)0);
    }
    else {
      pwmEnableChannel(&PWMD4, 2, (pwmcnt_t)y);
      pwmEnableChannel(&PWMD4, 0, (pwmcnt_t)0);
    }
    if (x < 0) {
      pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)-x);
      pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)0);
    }
    else {
      pwmEnableChannel(&PWMD4, 3, (pwmcnt_t)x);
      pwmEnableChannel(&PWMD4, 1, (pwmcnt_t)0);
    }

    /* Waiting until the next 250 milliseconds time interval.*/
    chThdSleepUntil(time += MS2ST(100));
  }
}
Пример #20
0
void frontend_configure(void)
{
  spiStart(&FRONTEND_SPI, &spi_config);
  spiAcquireBus(&FRONTEND_SPI);
  spiSelect(&FRONTEND_SPI);

  for (u8 i = 0; i < 2; ++i) {
    spi_write(2, 0x03);
    spi_write(3, 0x01);
    spi_write(4, 0x03);
    spi_write(5, 0x00);
    spi_write(6, 0x1F);
    spi_write(9, 0x00);
    spi_write(11, 0x08);
    spi_write(12, 0x1C);
    spi_write(13, 0x03);
    spi_write(14, 0x69);
    spi_write(15, 0x2B);
    spi_write(16, 0x74);
    spi_write(17, 0xF1);
    spi_write(18, 0xEA);
    spi_write(19, 0x0B);
    spi_write(20, 0x01);
    spi_write(21, 0x28);
    spi_write(22, 0x2B);
    spi_write(23, 0x74);
    spi_write(24, 0xF1);
    spi_write(25, 0xEA);
    spi_write(26, 0x0B);
    spi_write(27, 0x01);
    spi_write(28, 0x28);
    spi_write(29, 0x2B);
    spi_write(30, 0x74);
    spi_write(31, 0xF1);
    spi_write(32, 0xEA);
    spi_write(33, 0x0B);
    spi_write(34, 0x03);
    spi_write(35, 0x7F);
    spi_write(36, 0x2B);
    spi_write(37, 0x74);
    spi_write(38, 0xF1);
    spi_write(39, 0xEA);
    spi_write(40, 0x0B);
    spi_write(41, 0x03);
    spi_write(42, 0x4F);
    spi_write(43, 0x89);
    spi_write(45, 0x01);
    spi_write(46, 0x7B);
    spi_write(47, 0x91);
    spi_write(49, 0xBD);
    spi_write(50, 0x0C);
    spi_write(51, 0x64);
    spi_write(52, 0xA8);
    spi_write(53, 0x5B);
    spi_write(54, 0xE5);
    spi_write(55, 0x57);
    spi_write(56, 0xE4);
    spi_write(57, 0xDD);
    spi_write(58, 0x0C);
    spi_write(59, 0x64);
    spi_write(60, 0xA8);
    spi_write(61, 0xC5);
    spi_write(62, 0x6D);
    spi_write(63, 0x57);
    spi_write(64, 0x71);
    spi_write(65, 0x7F);
    spi_write(66, 0x00);
    spi_write(67, 0xC9);
    spi_write(68, 0x86);
    spi_write(69, 0x7E);
    spi_write(70, 0x0F);
    spi_write(71, 0x11);
    spi_write(72, 0x00);
    spi_write(73, 0x00);
    spi_write(74, 0xFF);
    spi_write(75, 0x1C);
    spi_write(76, 0xCD);
    spi_write(77, 0x99);
    spi_write(78, 0x0B);
    spi_write(79, 0x40);
    spi_write(80, 0x08);
    spi_write(81, 0x30);
    spi_write(82, 0xFF);
    spi_write(83, 0x1C);
    spi_write(84, 0xCD);
    spi_write(85, 0x99);
    spi_write(86, 0x0B);
    spi_write(87, 0x40);
    spi_write(88, 0x08);
    spi_write(89, 0x30);
    spi_write(90, 0xFF);
    spi_write(91, 0x0C);
    spi_write(92, 0xCD);
    spi_write(93, 0x99);
    spi_write(94, 0x0B);
    spi_write(95, 0x40);
    spi_write(96, 0x08);
    spi_write(97, 0x30);
    spi_write(98, 0xFF);
    spi_write(99, 0x0C);
    spi_write(100, 0xCD);
    spi_write(101, 0x99);
    spi_write(102, 0x0B);
    spi_write(103, 0x40);
    spi_write(104, 0x08);
    spi_write(105, 0x30);
  }

  spi_write(15, 0x0B);
  spi_write(22, 0x0B);
  spi_write(29, 0x0B);
  spi_write(36, 0x0B);

  spiUnselect(&FRONTEND_SPI);
  spiReleaseBus(&FRONTEND_SPI);
}
Пример #21
0
__attribute__((noreturn)) msg_t InstrumentThread(void *arg) {
  size_t rval; 
#ifndef RELEASE
  size_t wval;
#endif
//  uint16_t aCheckSum = 0;
  uint16_t aCheckSum = 2056; //Ryan checksum check
#ifdef _TEST_BBI2C
  uint8_t status;
  static uint8_t txbuf[32];
  static uint8_t rxbuf[32];
#endif // _TEST_BBI2C
  ChipDriverStatus_t chipStatus = SUCCESS;
  // volatile int32_t dly = 0, dmmy = 0;
  // int j,k;
  // uint8_t bit, pldata;
  
  (void)arg;
  chRegSetThreadName("Instrument");


  /* Reader thread loop.*/
  while (!USBconfigured) chThdSleep(100); //Wait here until USB hw is configured

  RED_OFF;
  while (TRUE) {
    bzero(&pktInBuf,sizeof(usb_packet_t));//Zeros out the mem location to store pktInBuf

    rval=readPacket(&pktInBuf,0);//Reads in a new packet
    
    // Command Dispatcher Requirements:
    // See usbcmdio.h for structures 
    //   defining each kind of message
    //   and payload
    //
    //   Recognize 9 commands:  ACK, NAK, RESET, ID, WRITE, READ, ECHO, SHADOW, ADC

    // DB1_HI;
    switch (pktInBuf.type) {
    case CMD_ACK:
      pktInBuf.length = 4;
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
#ifdef RELEASE
      writePacket(&pktInBuf,0);
#else
      wval=writePacket(&pktInBuf,0);
      dprintf("ACK sent %u \r\n",wval);
#endif
      break;
    case CMD_NAK:
      pktInBuf.length = 4;
      pktInBuf.type = CMD_ACK;        // all packet's ACK unless error
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
#ifdef RELEASE
      writePacket(&pktInBuf,0);
#else
      wval=writePacket(&pktInBuf,0);
      dprintf("NAK sent %u\r\n",wval);
#endif
      break;
    case CMD_RESET:

      pktInBuf.length = 4;
      if (chipStatus == SUCCESS) 
        pktInBuf.type = CMD_ACK;        // all packet's ACK unless error
      else
        pktInBuf.type = CMD_NAK; 
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
#ifdef RELEASE
      writePacket(&pktInBuf,0);
#else
      wval=writePacket(&pktInBuf,0);
      dprintf("RESET sent %u\r\n",wval);
#endif
      break;
    case CMD_ID:
      dprintf("ID \r\n");
      get_instrument_ID(&pktInBuf); // my_id;
      // pktInBuf.length=4+sizeof(payload_id_response_t);
      if (chipStatus == SUCCESS) 
        pktInBuf.type = CMD_ACK;        // all packet's ACK unless error
      else
        pktInBuf.type = CMD_NAK; 
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
#ifdef RELEASE
      writePacket(&pktInBuf,0);
#else
      wval=writePacket(&pktInBuf,0);
      dprintf("ID sent %u \r\n",wval);
#endif
      break;
    case CMD_ECHO:
      dprintf("ECHO \r\n");
      pktInBuf.type = CMD_ACK;        // all packet's ACK unless error
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
      if (rval > 0) {                 // echo the incoming packet, if non-zero
#ifdef RELEASE
        writePacket(&pktInBuf,0);
#else
        wval=writePacket(&pktInBuf,0);
        dprintf("ECHO sent %d\r\n",wval);
#endif
      }
      break;
    case CMD_SSN:
      dprintf("SSN \r\n");
      get_instrument_SSN(&pktInBuf);
      if (chipStatus == SUCCESS) 
        pktInBuf.type = CMD_ACK;
      else
        pktInBuf.type = CMD_NAK; 
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
      writePacket(&pktInBuf,0);
      break;
    case CMD_UID:
      dprintf("UID \r\n");
      get_instrument_UID(&pktInBuf);
      if (chipStatus == SUCCESS) 
        pktInBuf.type = CMD_ACK;
      else
        pktInBuf.type = CMD_NAK; 
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
      writePacket(&pktInBuf,0);
      break;
    case CMD_ADC:
      dprintf("ADC \r\n");
      palTogglePad(GPIOD, 12); //Debug check: Green LED
      get_instrument_ADC(&pktInBuf);
      if (chipStatus == SUCCESS) 
        pktInBuf.type = CMD_ACK;
      else
        pktInBuf.type = CMD_NAK; 
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
      writePacket(&pktInBuf,0);
      break;
    case CMD_ADC_ALL:
//    dprintf("ADC ALL \r\n");
      palTogglePad(GPIOD, 12); //Debug check: Green LED
      if(!cake.empty) {
//	      while(!cake.empty){ //seems to run into a race condition
	int k=0;
	      while(k<22){
	      	      get_instrument_ADC_ALL(&pktInBuf);
         	      pktInBuf.type = CMD_ACK;
		      pktInBuf.checksum = aCheckSum; 
		      writePacket(&pktInBuf,0);	
		      k++;
	      }
      } else {
		//TODO:fill a packet with zero and send it
		pktInBuf.type = CMD_NAK; 
		pktInBuf.length = 9;
		pktInBuf.checksum = aCheckSum;
		pktInBuf.payload.adc_resp.current =0;
		pktInBuf.payload.adc_resp.voltage =0;
		pktInBuf.payload.adc_resp.DUTstate =0;
		writePacket(&pktInBuf,0);	
      }
      break;
    case CMD_ADC_TEST2:
//    dprintf("ADC ALL \r\n");
      palTogglePad(GPIOD, 12); //Debug check: Green LED
      if(!cake.empty) {
      	      get_instrument_ADC_TEST(&pktInBuf);//Put 2 readings in a packet
	      if (chipStatus == SUCCESS) 
		pktInBuf.type = CMD_ACK;
	      else
		pktInBuf.type = CMD_NAK; 
	        pktInBuf.checksum = aCheckSum;
	        writePacket(&pktInBuf,0);	
      } else {
	pktInBuf.length = 4;
      pktInBuf.type = CMD_NAK;        // packet's NAK on empty
      pktInBuf.checksum = aCheckSum;  
      writePacket(&pktInBuf,0);		//send empty packet NAK

      }
      break;
    default:
      dprintf("ERROR: unrecognized command: %u\r\n",pktInBuf.type);
      pktInBuf.length = 4;
      pktInBuf.type = CMD_NAK;        // packet's NAK on error
      // aCheckSum = compute_fletch(&pktInBuf);
      pktInBuf.checksum = aCheckSum;  // TODO: compute FLETCH
      writePacket(&pktInBuf,0);
      break;
    }

#ifdef _SPI_TEST
    spiSelect(&SPID2);
    spiSend(&SPID2, 8, txbuf);
    spiUnselect(&SPID2);
#endif // _SPI_TEST

#ifdef _TEST_BBI2C
#ifdef _BBI2C_INCLUDED
    bzero(txbuf,32);
    bzero(rxbuf,32);
    status = bbI2C_bufio(i2c_addr<<1, 0x80, txbuf, 0, rxbuf, 1);
    dprintf("Global reg 0x%x     status: %d\r\n",rxbuf[0],status);
    status = bbI2C_bufio(i2c_addr<<1, 0x0, txbuf, 12, rxbuf, 0);
    dprintf("Clear reg A chan 0 status: %d\r\n",status);
    status = bbI2C_bufio(i2c_addr<<1, 0x20, txbuf, 12, rxbuf, 0);
    dprintf("Clear reg B chan 0 status: %d\r\n",status);
    status = bbI2C_bufio(i2c_addr<<1, 0x40, txbuf, 12, rxbuf, 0);
    dprintf("Clear reg A chan 1 status: %d\r\n",status);
    status = bbI2C_bufio(i2c_addr<<1, 0x60, txbuf, 12, rxbuf, 0);
    dprintf("Clear reg B chan 1 status: %d\r\n",status);
#endif // _BBI2C_INCLUDED
#endif // _TEST_BBI2C

    //Blink the LED
    RED_ON;
    
    //Here's how to printf out the USB debug shell port
    //chprintf(shell_cfg1.sc_channel,".");
  }
}
Пример #22
0
void eeprom_unselect(void){
    spiUnselect(&EEPROM_SPI_BUS);       /* Slave Select de-assertion.*/
    spiReleaseBus(&EEPROM_SPI_BUS);     /* Ownership release.*/

}
Пример #23
0
/*
 * Application entry point.
 */
int main(void) {

   /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */

  uint32_t tempR, tempP, tempY;
  float Roll,Pitch,Yaw;  


  halInit();
  chSysInit();
  i2c_setup();

  palSetPadMode(IOPORT1, 8, PAL_MODE_INPUT);      // PA8 - RADIO INPUT
 
  palSetPadMode(IOPORT2, 13, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);     /* SCK. */
  palSetPadMode(IOPORT2, 14, PAL_MODE_STM32_ALTERNATE_PUSHPULL);     /* MISO.*/
  palSetPadMode(IOPORT2, 15, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);     /* MOSI.*/
  palSetPadMode(IOPORT2, 12, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);

  palSetPadMode(IOPORT3, 11, PAL_MODE_OUTPUT_PUSHPULL);
  
  chMtxInit(&mtx_imu);
  chMtxInit(&mutex_motors);

  palClearPad(IOPORT3,10);
  //palClearPad(IOPORT3,11);
  /*
   * Activates the USB driver and then the USB bus pull-up on D+.
   */
  sduObjectInit(&SDU1);
  sduStart(&SDU1, &serusbcfg);
  usbConnectBus(serusbcfg.usbp);
  //palClearPad(GPIOC, GPIOC_USB_DISC);
  
  icuStart(&ICUD1, &icucfg);
  icuEnable(&ICUD1);
  
  chThdSleepSeconds(1);
  
  chThdCreateStatic(waThread1, sizeof(waThread1), HIGHPRIO, Thread1, NULL);

  //chThdCreateStatic(waMotorsThread, sizeof(waMotorsThread), NORMALPRIO, MotorsThread, NULL);

 
  spiAcquireBus(&SPID2);                        /* Acquire ownership of the bus.    */
  spiStart(&SPID2, &ls_spicfg);                 /* Setup transfer parameters.       */
  spiSelect(&SPID2);


  KP = 1;
  KI = 1;
  KD = 0;

  while (TRUE) {

	while(!(SPID2.spi->SR & SPI_SR_RXNE)); 
	 	
  		spiReceive(&SPID2,24,rxbuf_16bit);

//	Floating point calculation of Roll/Pitch/Yaw inside the microcontroller. Decomment next 6 lines if you want to implement
//	the control Law.

	tempR = (uint32_t)((rxbuf_16bit[0] << 31) | (rxbuf_16bit[1] << 23) | (rxbuf_16bit[2] << 11) | rxbuf_16bit[3]);
	tempP = (uint32_t)((rxbuf_16bit[4] << 31) | (rxbuf_16bit[5] << 23) | (rxbuf_16bit[6] << 11) | rxbuf_16bit[7]);
	tempY = (uint32_t)((rxbuf_16bit[8] << 31) | (rxbuf_16bit[9] << 23) | (rxbuf_16bit[10] << 11) | rxbuf_16bit[11]);
		
	Roll = (*(float*)&tempR);
	Pitch = (*(float*)&tempP); 					
	Yaw = (*(float*)&tempY);
	
	// CONTROL LAW HERE
	//++ (ROLL,PITCH,YAW ERRORS) -----> [CONTROLLER] -----> (MOTORS INPUT)
	

	// PID Control Law
	
	roll_error = 0 - Roll;
        pitch_error = 0 - Pitch;
        yaw_error = 0 - Yaw;

        roll_I = roll_I + roll_error*0.01;
        pitch_I = pitch_I + pitch_error*0.01;

        roll_D = (roll_error - roll_prev_error)/0.01;
        pitch_D = (pitch_error - pitch_prev_error)/0.01;

        roll_controller_output = (int8_t)(KP*roll_error + KI*roll_I + KD*roll_D);
        pitch_controller_output = (int8_t)(KP*pitch_error + KI*pitch_I + KD*pitch_D);

        //roll_controller_output = (int8_t)roll_error;
        //pitch_controller_output = (int8_t)pitch_error;


        roll_prev_error = roll_error;
        pitch_prev_error = pitch_error;


	//-------------------------------------------------------------------

	blctrl20_set_velocity();


	palSetPad(IOPORT3,11);


/*	SPI FLOATING POINT TEST PACKET (sending 5.6F)	
	rxbuf_16bit[0] = 0;
	rxbuf_16bit[1] = 129;
	rxbuf_16bit[2] = 1638;
	rxbuf_16bit[3] = 819;
	rxbuf_16bit[4] = 0;
	rxbuf_16bit[5] = 129;
	rxbuf_16bit[6] = 1638;
	rxbuf_16bit[7] = 819;
	rxbuf_16bit[8] = 1;
	rxbuf_16bit[9] = 129;
	rxbuf_16bit[10] = 1638;
	rxbuf_16bit[11] = 819;
*/	



	if(SDU1.config->usbp->state==USB_ACTIVE)
	{
//		chprintf((BaseChannel *)&SDU1,"S:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:%6d:E\r\n",rxbuf_16bit[0],rxbuf_16bit[1],rxbuf_16bit[2],rxbuf_16bit[3],rxbuf_16bit[4],rxbuf_16bit[5],rxbuf_16bit[6],rxbuf_16bit[7],rxbuf_16bit[8],rxbuf_16bit[9],rxbuf_16bit[10],rxbuf_16bit[11]);
		chprintf((BaseChannel *)&SDU1, "S:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:%6D:E\r\n",rxbuf_16bit[0],rxbuf_16bit[1],rxbuf_16bit[2],rxbuf_16bit[3],rxbuf_16bit[4],rxbuf_16bit[5],rxbuf_16bit[6],rxbuf_16bit[7],rxbuf_16bit[8],rxbuf_16bit[9],rxbuf_16bit[10],rxbuf_16bit[11],(int8_t)Roll,(int8_t)Pitch,(int8_t)Yaw,icu_ch[3],icu_ch[4],roll_controller_output,pitch_controller_output,yaw_controller_output);

	}

    	chThdSleepMilliseconds(10);
  }
  spiUnselect(&SPID2);
  spiReleaseBus(&SPID2);                        /* Ownership release.               */


}
Пример #24
0
/// called every 10ms from clock.c - check all temp sensors that are ready for checking
void temp_sensor_tick() {
	temp_sensor_t i = 0;
	for (; i < NUM_TEMP_SENSORS; i++) {
		if (temp_sensors_runtime[i].next_read_time) {
			temp_sensors_runtime[i].next_read_time--;
		}
		else {
			uint16_t	temp = 0;
			#ifdef	TEMP_MAX31855
			uint32_t value = 0;
			struct max31855_plat_data *max31855;
			#endif
			//time to deal with this temp sensor
			switch(temp_sensors[i].temp_type) {
				#ifdef	TEMP_MAX31855
				case TT_MAX31855:
				#ifdef __arm__
				        max31855 = (struct max31855_plat_data*)temp_sensors[i].plat_data;
					spiAcquireBus(max31855->bus);
					spiStart(max31855->bus, max31855->config);
					spiSelect(max31855->bus);
					spiReceive(max31855->bus, 4, &value);
					spiUnselect(max31855->bus);
					spiReleaseBus(max31855->bus);

					value = SWAP_UINT32(value);

					temp_sensors_runtime[i].temp_flags = 0;
					if (value & (1 << 16)) {
                                        #ifdef HALT_ON_TERMOCOUPLE_FAILURE
						emergency_stop();
                                        #endif
					}
					else {
						temp = value >> 18;
						if (temp & (1 << 13))
							temp = 0;
					}
				#else
					temp = 0;
				#endif

					break;
				#endif
				#ifdef	TEMP_MAX6675
				case TT_MAX6675:
					#ifdef	PRR
						PRR &= ~MASK(PRSPI);
					#elif defined PRR0
						PRR0 &= ~MASK(PRSPI);
					#endif

					SPCR = MASK(MSTR) | MASK(SPE) | MASK(SPR0);

					// enable TT_MAX6675
					WRITE(SS, 0);

					// No delay required, see
					// https://github.com/triffid/Teacup_Firmware/issues/22

					// read MSB
					SPDR = 0;
					for (;(SPSR & MASK(SPIF)) == 0;);
					temp = SPDR;
					temp <<= 8;

					// read LSB
					SPDR = 0;
					for (;(SPSR & MASK(SPIF)) == 0;);
					temp |= SPDR;

					// disable TT_MAX6675
					WRITE(SS, 1);

					temp_sensors_runtime[i].temp_flags = 0;
					if ((temp & 0x8002) == 0) {
						// got "device id"
						temp_sensors_runtime[i].temp_flags |= PRESENT;
						if (temp & 4) {
							// thermocouple open
							temp_sensors_runtime[i].temp_flags |= TCOPEN;
						}
						else {
							temp = temp >> 3;
						}
					}

					// this number depends on how frequently temp_sensor_tick is called. the MAX6675 can give a reading every 0.22s, so set this to about 250ms
					temp_sensors_runtime[i].next_read_time = 25;

					break;
				#endif	/* TEMP_MAX6675	*/

				#ifdef	TEMP_THERMISTOR
				case TT_THERMISTOR:
					do {
						uint8_t j, table_num;
						//Read current temperature
						temp = analog_read(i);
						// for thermistors the thermistor table number is in the additional field
						table_num = temp_sensors[i].additional;

						//Calculate real temperature based on lookup table
						for (j = 1; j < NUMTEMPS; j++) {
							if (pgm_read_word(&(temptable[table_num][j][0])) > temp) {
								// Thermistor table is already in 14.2 fixed point
								#ifndef	EXTRUDER
								if (DEBUG_PID && (debug_flags & DEBUG_PID))
									sersendf_P(PSTR("pin:%d Raw ADC:%d table entry: %d"),temp_sensors[i].temp_pin,temp,j);
								#endif
								// Linear interpolating temperature value
								// y = ((x - x₀)y₁ + (x₁-x)y₀ ) / (x₁ - x₀)
								// y = temp
								// x = ADC reading
								// x₀= temptable[j-1][0]
								// x₁= temptable[j][0]
								// y₀= temptable[j-1][1]
								// y₁= temptable[j][1]
								// y =
								// Wikipedia's example linear interpolation formula.
								temp = (
								//     ((x - x₀)y₁
									((uint32_t)temp - pgm_read_word(&(temptable[table_num][j-1][0]))) * pgm_read_word(&(temptable[table_num][j][1]))
								//                 +
									+
								//                   (x₁-x)
									(pgm_read_word(&(temptable[table_num][j][0])) - (uint32_t)temp)
								//                         y₀ )
									* pgm_read_word(&(temptable[table_num][j-1][1])))
								//                              /
									/
								//                                (x₁ - x₀)
									(pgm_read_word(&(temptable[table_num][j][0])) - pgm_read_word(&(temptable[table_num][j-1][0])));
								#ifndef	EXTRUDER
								if (DEBUG_PID && (debug_flags & DEBUG_PID))
									sersendf_P(PSTR(" temp:%d.%d"),temp/4,(temp%4)*25);
								#endif
								break;
							}
						}
						#ifndef	EXTRUDER
						if (DEBUG_PID && (debug_flags & DEBUG_PID))
							sersendf_P(PSTR(" Sensor:%d\n"),i);
						#endif


						//Clamp for overflows
						if (j == NUMTEMPS)
							temp = temptable[table_num][NUMTEMPS-1][1];

						temp_sensors_runtime[i].next_read_time = 0;
					} while (0);
					break;
				#endif	/* TEMP_THERMISTOR */

				#ifdef	TEMP_AD595
				case TT_AD595:
					temp = analog_read(i);

					// convert
					// >>8 instead of >>10 because internal temp is stored as 14.2 fixed point
					temp = (temp * 500L) >> 8;

					temp_sensors_runtime[i].next_read_time = 0;

					break;
				#endif	/* TEMP_AD595 */

				#ifdef	TEMP_PT100
				case TT_PT100:
					#warning TODO: PT100 code
					break
				#endif	/* TEMP_PT100 */

				#ifdef	TEMP_INTERCOM
				case TT_INTERCOM:
					temp = read_temperature(temp_sensors[i].temp_pin);

					temp_sensors_runtime[i].next_read_time = 25;

					break;
				#endif	/* TEMP_INTERCOM */

				#ifdef	TEMP_DUMMY
				case TT_DUMMY:
					temp = temp_sensors_runtime[i].last_read_temp;

					if (temp_sensors_runtime[i].target_temp > temp)
						temp++;
					else if (temp_sensors_runtime[i].target_temp < temp)
						temp--;

					temp_sensors_runtime[i].next_read_time = 0;

					break;
				#endif	/* TEMP_DUMMY */

				default: /* prevent compiler warning */
					break;
			}
			/* Exponentially Weighted Moving Average alpha constant for smoothing
			   noisy sensors. Instrument Engineer's Handbook, 4th ed, Vol 2 p126
			   says values of 0.05 to 0.1 for TEMP_EWMA are typical. */
			#ifndef TEMP_EWMA
				#define TEMP_EWMA 1.0
			#endif
			#define EWMA_SCALE  1024L
			#define EWMA_ALPHA  ((long) (TEMP_EWMA * EWMA_SCALE))
			temp_sensors_runtime[i].last_read_temp = (uint16_t) ((EWMA_ALPHA * temp +
			  (EWMA_SCALE-EWMA_ALPHA) * temp_sensors_runtime[i].last_read_temp
			                                         ) / EWMA_SCALE);
		}
		if (labs((int16_t)(temp_sensors_runtime[i].last_read_temp - temp_sensors_runtime[i].target_temp)) < (TEMP_HYSTERESIS*4)) {
			if (temp_sensors_runtime[i].temp_residency < (TEMP_RESIDENCY_TIME*120))
				temp_sensors_runtime[i].temp_residency++;
		}
		else {
			// Deal with flakey sensors which occasionally report a wrong value
			// by setting residency back, but not entirely to zero.
			if (temp_sensors_runtime[i].temp_residency > 10)
				temp_sensors_runtime[i].temp_residency -= 10;
			else
				temp_sensors_runtime[i].temp_residency = 0;
		}

		if (temp_sensors[i].heater < NUM_HEATERS) {
			heater_tick(temp_sensors[i].heater, temp_sensors[i].temp_type, temp_sensors_runtime[i].last_read_temp, temp_sensors_runtime[i].target_temp);
		}

    if (DEBUG_PID && (debug_flags & DEBUG_PID))
      sersendf_P(PSTR("DU temp: {%d %d %d.%d}"), i,
                 temp_sensors_runtime[i].last_read_temp,
                 temp_sensors_runtime[i].last_read_temp / 4,
                 (temp_sensors_runtime[i].last_read_temp & 0x03) * 25);
	}
Пример #25
0
//==============================================================================
// SdSpiCard member functions
//------------------------------------------------------------------------------
bool SdSpiCard::begin(SdSpiDriver* spi, uint8_t csPin, SPISettings settings) {
  m_spiActive = false;
  m_errorCode = SD_CARD_ERROR_NONE;
  m_type = 0;
  m_spiDriver = spi;
  uint16_t t0 = curTimeMS();
  uint32_t arg;

  m_spiDriver->begin(csPin);
  m_spiDriver->setSpiSettings(SD_SCK_HZ(250000));
  spiStart();

  // must supply min of 74 clock cycles with CS high.
  spiUnselect();
  for (uint8_t i = 0; i < 10; i++) {
    spiSend(0XFF);
  }
  spiSelect();
  // command to go idle in SPI mode
  while (cardCommand(CMD0, 0) != R1_IDLE_STATE) {
    if (isTimedOut(t0, SD_INIT_TIMEOUT)) {
      error(SD_CARD_ERROR_CMD0);
      goto fail;
    }
  }
#if USE_SD_CRC
  if (cardCommand(CMD59, 1) != R1_IDLE_STATE) {
    error(SD_CARD_ERROR_CMD59);
    goto fail;
  }
#endif  // USE_SD_CRC
  // check SD version
  while (1) {
    if (cardCommand(CMD8, 0x1AA) == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE)) {
      type(SD_CARD_TYPE_SD1);
      break;
    }
    for (uint8_t i = 0; i < 4; i++) {
      m_status = spiReceive();
    }
    if (m_status == 0XAA) {
      type(SD_CARD_TYPE_SD2);
      break;
    }
    if (isTimedOut(t0, SD_INIT_TIMEOUT)) {
      error(SD_CARD_ERROR_CMD8);
      goto fail;
    }
  }
  // initialize card and send host supports SDHC if SD2
  arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;

  while (cardAcmd(ACMD41, arg) != R1_READY_STATE) {
    // check for timeout
    if (isTimedOut(t0, SD_INIT_TIMEOUT)) {
      error(SD_CARD_ERROR_ACMD41);
      goto fail;
    }
  }
  // if SD2 read OCR register to check for SDHC card
  if (type() == SD_CARD_TYPE_SD2) {
    if (cardCommand(CMD58, 0)) {
      error(SD_CARD_ERROR_CMD58);
      goto fail;
    }
    if ((spiReceive() & 0XC0) == 0XC0) {
      type(SD_CARD_TYPE_SDHC);
    }
    // Discard rest of ocr - contains allowed voltage range.
    for (uint8_t i = 0; i < 3; i++) {
      spiReceive();
    }
  }
  spiStop();
  m_spiDriver->setSpiSettings(settings);
  return true;

fail:
  spiStop();
  return false;
}
Пример #26
0
static flash_error_t program(void *instance, flash_address_t addr,
                             const uint8_t *pp, size_t n) {
  N25Q128Driver *devp = (N25Q128Driver *)instance;
  SPIDriver *spip = devp->config->spip;
  flash_error_t err;

  osalDbgAssert(devp->state == FLASH_READY, "invalid state");

#if N25Q128_SHARED_SPI == TRUE
  spiAcquireBus(spip);
  spiStart(spip, devp->config->spicfg);
#endif
  devp->state = FLASH_ACTIVE;

  while (n > 0U) {
    uint8_t sts;

    /* Data size that can be written in a single program page operation.*/
    size_t chunk = (size_t)(((addr | PAGE_MASK) + 1U) - addr);
    if (chunk > n) {
      chunk = n;
    }

    /* Enabling write operation.*/
    spiSelect(spip);
    spi_send_cmd(devp, N25Q128_CMD_WRITE_ENABLE);
    spiUnselect(spip);
    (void) spiPolledExchange(spip, 0xFF);   /* One frame delay.*/

    /* Page program command.*/
    spiSelect(spip);
    spi_send_cmd_addr(devp, N25Q128_CMD_PAGE_PROGRAM, addr);
    spiSend(spip, chunk, pp);
    spiUnselect(spip);
    (void) spiPolledExchange(spip, 0xFF);   /* One frame delay.*/

    /* Operation end waiting.*/
    do {
#if N25Q128_NICE_WAITING == TRUE
      osalThreadSleepMilliseconds(1);
#endif
      /* Read status command.*/
      spiSelect(spip);
      spi_send_cmd(devp, N25Q128_CMD_READ_STATUS_REGISTER);
      spiReceive(spip, 1, &sts);
      spiUnselect(spip);
    } while ((sts & N25Q128_STS_BUSY) != 0U);

    /* Checking for errors.*/
    if ((sts & N25Q128_STS_ALL_ERRORS) != 0U) {
      /* Clearing status register.*/
      (void) spiPolledExchange(spip, 0xFF);   /* One frame delay.*/
      spiSelect(spip);
      spi_send_cmd(devp, N25Q128_CMD_CLEAR_FLAG_STATUS_REGISTER);
      spiUnselect(spip);

      /* Program operation failed.*/
      err = FLASH_PROGRAM_FAILURE;
      goto exit_error;
    }

    /* Next page.*/
    addr += chunk;
    pp   += chunk;
    n    -= chunk;
  }

  /* Program operation succeeded.*/
  err = FLASH_NO_ERROR;

  /* Common exit path for this function.*/
exit_error:
  devp->state = FLASH_READY;
#if N25Q128_SHARED_SPI == TRUE
  spiReleaseBus(spip);
#endif
  return err;
}
Пример #27
0
/**
 * @brief End a SPI transaction.
 */
static int end_spi(void)
{
    spiUnselect(SPI_SX);
    spiReleaseBus(SPI_SX);
    return 0;
}
Пример #28
0
void Rf24ChibiosIo::unselect() {
    spiUnselect(driver);
}