/*---------------------------------------------------------------------------*/ 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(); }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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; }
/** * 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; }
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; }
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; }