Ejemplo n.º 1
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cc1101_process, ev, data)
{

  PROCESS_POLLHANDLER(pollhandler());

  PROCESS_BEGIN();

#if 0
  while(1) {
    static struct etimer et;
    uint8_t rxbytes, txbytes;
    etimer_set(&et, CLOCK_SECOND * 4);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    //    cc1101_rx_interrupt();
    burst_read(CC1101_RXBYTES, &rxbytes, 1);
    burst_read(CC1101_TXBYTES, &txbytes, 1);
    printf("state 0x%02x rxbytes 0x%02x txbytes 0x%02x\n",
     state(), rxbytes, txbytes);
    on();
  }
#endif /* 0 */

  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_EXIT);

  PROCESS_END();
}
Ejemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static uint8_t
read_rxbytes(void)
{
  uint8_t rxbytes1, rxbytes2;

  do {
    burst_read(CC1101_RXBYTES, &rxbytes1, 1);
    burst_read(CC1101_RXBYTES, &rxbytes2, 1);
    if(rxbytes1 + 1 == rxbytes2 || rxbytes1 + 2 == rxbytes2) {
      /* XXX Workaround for slow CPU/SPI */
      return rxbytes2;
    }
  } while(rxbytes1 != rxbytes2);

  return rxbytes1;
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*/
static uint8_t
txbytes(void)
{
  uint8_t txbytes1, txbytes2;

  do {
    burst_read(CC1101_TXBYTES, &txbytes1, 1);
    burst_read(CC1101_TXBYTES, &txbytes2, 1);
    if(txbytes1 - 1 == txbytes2 || txbytes1 - 2 == txbytes2) {
      /* XXX Workaround for slow CPU/SPI */
      return txbytes2;
    }
  } while(txbytes1 != txbytes2);

  return txbytes2;
}
Ejemplo n.º 4
0
/**
 * The CC1101 interrupt handler: called by the hardware interrupt
 * handler, which is defined as part of the cc1101-arch interface.
 */
int
cc1101_rx_interrupt(void)
{
  /* NB: This function may be called both from an rx interrupt and
     from cc1101_process */
  uint8_t rxbytes, s;

  if(radio_on_or_off == OFF) {
    return 0;
  }
#if DEBUG
  printf("-");
#endif /* DEBUG */
  
  if(SPI_IS_LOCKED()) {
#if DEBUG
    printf("/%d", spi_locked);
#endif /* DEBUG */
    process_poll(&cc1101_process);
    return 1;
  }

  LOCK_SPI();
  s = state();
  if(s == CC1101_STATE_RXFIFO_OVERFLOW) {
    burst_read(CC1101_RXBYTES, &rxbytes, 1);
#if DEBUG
    printf("irqflush\n");
    printf("rxbytes 0x%02x\n", rxbytes);
#endif /* DEBUG */
    flushrx();
    RELEASE_SPI();
    return 0;
  }
  if(s == CC1101_STATE_TXFIFO_UNDERFLOW) {
#if DEBUG
    printf("irqflushtx\n");
#endif /* DEBUG */
    strobe(CC1101_SFTX);
    strobe(CC1101_SRX);
    RELEASE_SPI();
    return 0;
  }

  if(is_receiving() && timer_expired(&rxstate.timer)) {
#if DEBUG
    printf("Packet expired, flushing fifo\n");
#endif /* DEBUG */
    flushrx();
    RELEASE_SPI();
    return 0;
  }
#define RX_OVERFLOW 0x80

  /* Read each byte from the RXFIFO and put it into the input_byte()
     function, which takes care of the reception logic. */
  do {
    uint8_t byte;
    int i, numbytes;

    rxbytes = read_rxbytes();

    if(rxbytes & RX_OVERFLOW) {
#if DEBUG
      printf("ovf\n");
      leds_off(LEDS_GREEN;)
#endif /* DEBUG */
      flushrx();
      process_poll(&cc1101_process);
      RELEASE_SPI();
      return 1;
    }
Ejemplo n.º 5
0
static int ec_command_lpc_3(int command, int version,
			  const void *outdata, int outsize,
			  void *indata, int insize)
{
	struct ec_host_request rq;
	struct ec_host_response rs;
	const uint8_t *d;
	int csum = 0;
	int i;

	/* Fail if output size is too big */
	if (outsize + sizeof(rq) > EC_LPC_HOST_PACKET_SIZE)
		return -EC_RES_REQUEST_TRUNCATED;

	/* Fill in request packet */
	/* TODO(crosbug.com/p/23825): This should be common to all protocols */
	rq.struct_version = EC_HOST_REQUEST_VERSION;
	rq.checksum = 0;
	rq.command = command;
	rq.command_version = version;
	rq.reserved = 0;
	rq.data_len = outsize;

	/* Copy data and start checksum */
	burst_write((const uint8_t *)outdata, &csum,
		    EC_LPC_ADDR_HOST_PACKET + sizeof(rq), outsize);

	/* Finish checksum */
	for (i = 0, d = (const uint8_t *)&rq; i < sizeof(rq); i++, d++)
		csum += *d;

	/* Write checksum field so the entire packet sums to 0 */
	rq.checksum = (uint8_t)(-csum);

	/* Copy header */
	burst_write((const uint8_t *)&rq, NULL,
		    EC_LPC_ADDR_HOST_PACKET, sizeof(rq));

	/* Start the command */
	send_byte(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);

	if (wait_for_ec(EC_LPC_ADDR_HOST_CMD, 1000000)) {
		fprintf(stderr, "Timeout waiting for EC response\n");
		return -EC_RES_ERROR;
	}

	/* Check result */
	i = read_byte(EC_LPC_ADDR_HOST_DATA);
	if (i) {
		fprintf(stderr, "EC returned error result code %d\n", i);
		return -EECRESULT - i;
	}

	/* Read back response header and start checksum */
	csum = 0;
	burst_read((uint8_t *)&rs, &csum, EC_LPC_ADDR_HOST_PACKET, sizeof(rs));

	if (rs.struct_version != EC_HOST_RESPONSE_VERSION) {
		fprintf(stderr, "EC response version mismatch\n");
		return -EC_RES_INVALID_RESPONSE;
	}

	if (rs.reserved) {
		fprintf(stderr, "EC response reserved != 0\n");
		return -EC_RES_INVALID_RESPONSE;
	}

	if (rs.data_len > insize) {
		fprintf(stderr, "EC returned too much data\n");
		return -EC_RES_RESPONSE_TOO_BIG;
	}

	/* Read back data and update checksum */
	burst_read((uint8_t *)indata, &csum,
		   EC_LPC_ADDR_HOST_PACKET + sizeof(rs), rs.data_len);

	/* Verify checksum */
	if ((uint8_t)csum) {
		fprintf(stderr, "EC response has invalid checksum\n");
		return -EC_RES_INVALID_CHECKSUM;
	}

	/* Return actual amount of data received */
	return rs.data_len;
}
Ejemplo n.º 6
0
static int ec_command_lpc(int command, int version,
			  const void *outdata, int outsize,
			  void *indata, int insize)
{
	struct ec_lpc_host_args args;
	int csum;
	int i;

	/* Fill in args */
	args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
	args.command_version = version;
	args.data_size = outsize;

	/* Initialize checksum */
	csum = command + args.flags + args.command_version + args.data_size;

	/* Write data and update checksum */
	burst_write((uint8_t *)outdata, &csum, EC_LPC_ADDR_HOST_PARAM, outsize);

	/* Finalize checksum and write args */
	args.checksum = (uint8_t)csum;
	burst_write((const uint8_t *)&args, NULL,
		    EC_LPC_ADDR_HOST_ARGS, sizeof(args));

	send_byte(command, EC_LPC_ADDR_HOST_CMD);

	if (wait_for_ec(EC_LPC_ADDR_HOST_CMD, 1000000)) {
		fprintf(stderr, "Timeout waiting for EC response\n");
		return -EC_RES_ERROR;
	}

	/* Check result */
	i = read_byte(EC_LPC_ADDR_HOST_DATA);
	if (i) {
		fprintf(stderr, "EC returned error result code %d\n", i);
		return -EECRESULT - i;
	}

	/* Read back args */
	burst_read((uint8_t *)&args, NULL, EC_LPC_ADDR_HOST_ARGS, sizeof(args));

	/*
	 * If EC didn't modify args flags, then somehow we sent a new-style
	 * command to an old EC, which means it would have read its params
	 * from the wrong place.
	 */
	if (!(args.flags & EC_HOST_ARGS_FLAG_TO_HOST)) {
		fprintf(stderr, "EC protocol mismatch\n");
		return -EC_RES_INVALID_RESPONSE;
	}

	if (args.data_size > insize) {
		fprintf(stderr, "EC returned too much data\n");
		return -EC_RES_INVALID_RESPONSE;
	}

	/* Start calculating response checksum */
	csum = command + args.flags + args.command_version + args.data_size;

	/* Read response and update checksum */
	burst_read((uint8_t *)indata, &csum,
		   EC_LPC_ADDR_HOST_PARAM, args.data_size);

	/* Verify checksum */
	if (args.checksum != (uint8_t)csum) {
		fprintf(stderr, "EC response has invalid checksum\n");
		return -EC_RES_INVALID_CHECKSUM;
	}

	/* Return actual amount of data received */
	return args.data_size;
}