Exemple #1
0
/*---------------------------------------------------------------------------*/
static void
pa_table_write(uint8_t val)
{
  uint8_t table[8];
  int i;

  for(i = 0; i < sizeof(table); i++) {
    table[i] = val;
  }

  burst_write(CC1101_PATABLE, table, 8);
}
Exemple #2
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;
}
Exemple #3
0
/*---------------------------------------------------------------------------*/
static void
write_txfifo(uint8_t *data, uint8_t len)
{
#define BURST_BIT 0x40
  uint8_t status;
  int i;
#define CC1101_STATUS_STATE_MASK             0x70
#define CC1101_STATUS_STATE_TXFIFO_UNDERFLOW 0x70

  /* ensure FIFO is empty before tx */
  strobe(CC1101_SIDLE);
  strobe(CC1101_SFTX);
  is_transmitting = 1;

  LOCK_SPI();
  burst_write(CC1101_TXFIFO, &len, 1);

#define FIRST_TX 60 /* Must not be 62 or above! */
  i = MIN(len, FIRST_TX);
  burst_write(CC1101_TXFIFO, data, i);


  strobe(CC1101_STX);

  if(len > i) {
    cc1101_arch_enable();
    cc1101_arch_write_command(CC1101_TXFIFO | BURST_BIT);
    for(; i < len; i++) {

      status = cc1101_arch_write_data(data[i]);

      if((status & CC1101_STATUS_STATE_MASK) ==
         CC1101_STATUS_STATE_TXFIFO_UNDERFLOW) {
        cc1101_arch_disable();
        /* TX FIFO underflow, acknowledge it with an SFTX (else the
           CC1101 becomes completely unresponsive) followed by an SRX,
           and break the transmission. */
        strobe(CC1101_SFTX);
        strobe(CC1101_SRX);
        break;
#define MIN_TXFIFO_AVAILABLE 2
      } else if((status & 0x0f) < MIN_TXFIFO_AVAILABLE) {
        cc1101_arch_disable();
        BUSYWAIT_UNTIL(txbytes() < 60 || (txbytes() & 0x80) != 0,
                       RTIMER_SECOND / 10);
        if(txbytes() & 0x80) {
/*          printf("TxUF2\n");*/
          /* TX FIFO underflow. */
          strobe(CC1101_SFTX);
          strobe(CC1101_SRX);
          break;
        }
        /* If there are more bytes to write, we should issue another
           TXFIFO write command. */
        if(i < len - 1) {
          cc1101_arch_enable();
          cc1101_arch_write_command(CC1101_TXFIFO | BURST_BIT);
        }
      }
    }
    cc1101_arch_disable();
  }
  RELEASE_SPI();

  is_transmitting = 0;
}
Exemple #4
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;
}