Esempio n. 1
0
/*
 * Release Deep Power Down. We do NOT read the Electronic Signature
 */
void
m25p16_res() {
  select();
  bit_bang_write(M25P16_I_RES);
  deselect();
  /* a few usec between RES and standby */
  while(M25P16_WIP());
}
Esempio n. 2
0
/**
 * Release Deep Power Down. Read and return the Electronic Signature
 * must return 0x14
 *
 * \return The old style Electronic Signature. This must be 0x14
 */
uint8_t
m25p16_res_res() {
  uint8_t rv;

  select();
  bit_bang_write(M25P16_I_RES);
  bit_bang_write(M25P16_DUMMY_BYTE);
  bit_bang_write(M25P16_DUMMY_BYTE);
  bit_bang_write(M25P16_DUMMY_BYTE);

  rv = bit_bang_read();

  deselect();

  /* a few usec between RES and standby */
  while(M25P16_WIP());
  return rv;
}
Esempio n. 3
0
File: disco.c Progetto: 1uk3/contiki
/*---------------------------------------------------------------------------*/
static void
timer_handler(void *p)
{
  uint8_t *s = p;
  uint8_t wip;

  PRINTF("Disco: @ %lu, s: %u\n", clock_seconds(), *s);

  if(*s == DISCO_STATE_PREPARING) {
    n740_analog_deactivate();
    wip = M25P16_WIP();
    n740_analog_activate();

    if(wip) {
      restart_timer(DISCO_TIMEOUT_PREPARE);
    } else {
      PRINTF("Disco: Erased %u\n", sector);
      if((sector & 1) == 0) {
        sector++;
        PRINTF("Disco: Next %u\n", sector);
        n740_analog_deactivate();
        m25p16_se(sector);
        n740_analog_activate();
        restart_timer(DISCO_TIMEOUT_PREPARE);
      } else {
        PRINTF("Disco: Ready\n");
        *s = DISCO_STATE_READY;
        resp.status = DISCO_CMD_INIT;
        restart_timer(DISCO_TIMEOUT_ABORT);
        server_conn->rport = seed.port;
        uip_ipaddr_copy(&server_conn->ripaddr, &seed.addr);
        uip_udp_packet_send(server_conn, &resp, DISCO_RESP_LEN_INIT);

        /* Restore server connection to allow data from any node */
        uip_create_unspecified(&server_conn->ripaddr);
        server_conn->rport = 0;
      }
    }
  } else if(*s == DISCO_STATE_READY) {
    abort();
  } else if(*s == DISCO_STATE_REBOOTING) {
    watchdog_reboot();
  }
}
Esempio n. 4
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_flash_process, ev, data)
{
  static struct etimer et;
  uint8_t i;

  PROCESS_BEGIN();

  PRINTF("Start\n");

  memset(r_addr, 0, 3);
  r_addr[0] = USE_SECTOR;
  counter = 1;

  while(1) {

    /* Delay */
    etimer_set(&et, CLOCK_SECOND * 2);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

    leds_on(LEDS_GREEN);

    if(counter == 0) {
      n740_analog_deactivate();
      rv = m25p16_rdsr();
      n740_analog_activate();
      /* If counter==0, we started Bulk Erasing earlier. Check if we still are */
      if(rv & M25P16_SR_WIP) {
        PRINTF("Yield [%02x]\n", rv);
      } else {
        counter = 1;
      }
    }
    if(counter) {
      /*
       * Take us out of Deep Power Down - On first power-on, the device will
       * go to stand by mode (which is not DP). However, we drop to DP at the
       * end of every loop. RES must be 0x14. This is the old style signature
       * and is only still there for backward compatibility.
       */
      n740_analog_deactivate();
      rv = m25p16_res_res();
      n740_analog_activate();

      PRINTF(" RES: 0x%02x\n", rv);

      n740_analog_deactivate();
      rv = M25P16_WIP();
      n740_analog_activate();

      PRINTF("========\n");
      memset(d_buf, 0, MAX_READ_CHUNK);


      /*
       * Read Device ID: Return values must be:
       *   man_id: 0x20 (Numonyx)
       * mem_type: 0x20
       * mem_size: 0x15 (2 ^ 0x15 bytes = 2MB)
       *  uid_len: number of bytes in UID
       *      uid: Either all zeroes or a customized factory data content
       * */
      rdid();

      /* Check the value of our Status Register (SR) */
      rdsr();

      /* Enable Write: Set Bit 1 in the SR to 1 (bit WEL) */
      PRINTF("WREN\n");
      n740_analog_deactivate();
      m25p16_wren();
      n740_analog_activate();

      /* Confirm: SR & 0x02 must be 1 */
      rdsr();

      /* Disable the WEL bit */
      PRINTF("WRDI\n");
      n740_analog_deactivate();
      m25p16_wrdi();
      n740_analog_activate();

      /* Confirm: SR & 0x02 must be 0 */
      rdsr();

      /* Write something to the SR. We don't need to explicitly set WEL, wrsr()
       * will do it for us. When the cycle ends, WEL will go low */
      PRINTF("WRSR\n");
      n740_analog_deactivate();

      /* For instance, let's protect sector 31 (that's the highest one) */
      m25p16_wrsr(M25P16_SR_BP0);

      /*
       * While this is running, WEL should remain high and WIP (bit 0) should
       * also be high. When this ends, WIP and WEL will go low.
       *
       * While the write is in ongoing, we can still read the SR to check the
       * cycle's progress
       */
      while(M25P16_WIP());

      n740_analog_activate();

      /* Confirm: SR & 0x02 must be 0 */
      rdsr();

      /* Read MAX_READ_CHUNK bytes from Page 0x000000 */
      memset(d_buf, 0, MAX_READ_CHUNK);
      n740_analog_deactivate();
      m25p16_read(r_addr, d_buf, MAX_READ_CHUNK);
      n740_analog_activate();

      PRINTF("READ:");
      for(i = 0; i < MAX_READ_CHUNK; i++) {
        PRINTF(" %02x", d_buf[i]);
      }
      PRINTF("\n");

      /* Write MAX_READ_CHUNK bytes to the same Page */
      PRINTF("WRITE\n");
      for(i = 0; i < MAX_READ_CHUNK; i++) {
        d_buf[i] = i;
      }
      n740_analog_deactivate();

      /* We don't need to wren() explicitly, pp() will do that for us */
      m25p16_pp(r_addr, d_buf, MAX_READ_CHUNK);

      /* Wait for the cycle */
      while(M25P16_WIP());

      /* Trash our data buffer */
      memset(d_buf, 0, MAX_READ_CHUNK);

      PRINTF("ERASE\n");
      n740_analog_deactivate();

      /* Bulk erase every 4 loops, sector erase otherwise */

      /* Bulk Erase: This takes a few seconds so we can't really block on it.
       * It'd be a bad thing to do and the watchdog would bark anyway.
       * Bulk Erase will only be accepted if all SR_BP[2:0] == 0 */
      if((counter % 4) == 0) {
        m25p16_wrsr(0);
        while(M25P16_WIP());
        m25p16_be();
        counter = 0;
      } else {
        m25p16_se(USE_SECTOR);
        while(M25P16_WIP());
        /* Drop to Deep Power Down */
        m25p16_dp();
        counter ++;
      }
      n740_analog_activate();
    }
    leds_off(LEDS_GREEN);
  }

  PROCESS_END();
}
Esempio n. 5
0
/*---------------------------------------------------------------------------*/
void
batmon_log(uint8_t trigger)
{
  uint32_t next;

  /* Only continue if the process (us) is running */
  if(!process_is_running(&batmon_process)) {
    return;
  }

  next = f.a;
  next |= (((uint32_t) f.p) << 8);
  next |= (((uint32_t) f.s) << 16);

  memcpy(r.magic, magic, sizeof(magic));
  r.trigger = trigger;
  r.c = clock_seconds();

  /* Read VDD and use as ADC reference */
  r.v = s->value(ADC_SENSOR_TYPE_VDD);

  /* And then carry on with battery */
  r.b = s->value(ADC_SENSOR_TYPE_BATTERY);

#if ENERGEST_CONF_ON
  /* ENERGEST values */
  r.mcu = energest_type_time(ENERGEST_TYPE_CPU);
  r.lpm = energest_type_time(ENERGEST_TYPE_LPM);
  r.irq = energest_type_time(ENERGEST_TYPE_IRQ);
  r.tx = energest_type_time(ENERGEST_TYPE_TRANSMIT);
  r.rx = energest_type_time(ENERGEST_TYPE_LISTEN);
  r.f_write = energest_type_time(ENERGEST_TYPE_FLASH_WRITE);
  r.f_read = energest_type_time(ENERGEST_TYPE_FLASH_READ);
#endif

  n740_analog_deactivate();
  /* Make sure we're on */
  if(M25P16_WIP()) {
    m25p16_res();
  }
  m25p16_pp((uint8_t *)&f, (uint8_t *)&r, sizeof(r));
  n740_analog_activate();

  PRINTF("BatMon: @%lu [%u] ", r.c, r.trigger);
  PRINTF("BatMon: 0x%02x%02x%02x\n", f.s, f.p, f.a);

  next += RECORD_SIZE;

  if(next >= FLASH_END_ADDR) {
    abort();
    return;
  }

  f.s = ((next & 0xFF0000) >> 16);
  f.p = ((next & 0xFF00) >> 8);
  f.a = next & 0xFF;

  if(trigger == LOG_TRIGGER_PERIODIC) {
    etimer_reset(&et);
  }
}