Example #1
0
// Setup reader to card connection
//
// The setup consists of a three way handshake:
//  - Receive initialisation vector 7 bits
//  - Transmit card type 6 bits
//  - Receive Acknowledge 6 bits
static int32_t setup_phase(legic_card_select_t *p_card) {
  uint8_t len = 0;

  // init coordination timestamp
  last_frame_end = GetCountSspClk();

  // reset prng
  legic_prng_init(0);

  // wait for iv
  int32_t iv = rx_frame(&len);
  if((len != 7) || (iv < 0)) {
    return -1;
  }

  // configure prng
  legic_prng_init(iv);

  // reply with card type
  switch(p_card->tagtype) {
    case 0:
      tx_frame(0x0D, 6);
      break;
    case 1:
      tx_frame(0x1D, 6);
      break;
    case 2:
      tx_frame(0x3D, 6);
      break;
  }

  // wait for ack
  int32_t ack = rx_frame(&len);
  if((len != 6) || (ack < 0)) {
    return -1;
  }

  // validate data
  switch(p_card->tagtype) {
    case 0:
      if(ack != 0x19) return -1;
      break;
    case 1:
      if(ack != 0x39) return -1;
      break;
    case 2:
      if(ack != 0x39) return -1;
      break;
  }

  // During rx the prng is clocked using the variable reader period.
  // Since rx_frame detects end of frame by detecting a code violation,
  // the prng is off by one bit period after each rx phase. Hence, tx
  // code advances the prng by (TAG_FRAME_WAIT/TAG_BIT_PERIOD - 1).
  // This is not possible for back to back rx, so this quirk reduces
  // the gap by one period.
  last_frame_end += TAG_BIT_PERIOD;

  return 0;
}
Example #2
0
/**
 * \brief Handles software-controlled CSMA.
 *
 * \param csma_mode     CSMA Mode; eg. ED or CS
 * \param retransmit    true if frame re-transmission is requested
 */
static inline void sw_controlled_csma(csma_mode_t csma_mode, bool retransmit)
{
	if (retransmit) {
		number_of_tx_retries = 0; /* actual number of retries */
	} else {
		/* no further retries */
		number_of_tx_retries = tal_pib.MaxFrameRetries;
	}

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
		}
	}

	if ((csma_mode == NO_CSMA_WITH_IFS) || (csma_mode == NO_CSMA_NO_IFS)) {
		tx_frame();
	} else {
		csma_start();
	}
}
Example #3
0
void send_mesg_test_mode()
{
   	lcd_init();
	init_push_buttons();

	usart_init();
	txq_init();
	usart_drain_rx();

	lcd_puts("Send Mesg Test Mode");
	wait_ms(1000);
	lcd_clear();

	char echo_mesg[] = "foobar";  // Assumed to be less than DATA_FRAME_MAX_LEN.
 
	while (true)
	{
		switch (wait_button("Select Message")) {
		case mesg_ping:

			txq_enqueue(signal_start);
			txq_enqueue(mesg_ping);
			txq_enqueue(signal_stop);
			txq_drain();
			break;

		case mesg_echo:

			txq_enqueue(signal_start);
			txq_enqueue(mesg_echo);

			// Copy the echo message into the `control`:
			strcpy(control.data, echo_mesg);
			control.data_len = strlen(echo_mesg);

			// Enqueue the frame. No more frames coming.
			tx_frame(false);

			txq_enqueue(signal_start);
			txq_drain();
			break;

		default:
			wait_button("Invalid selection.");
			break;
		}
	}
}
Example #4
0
/*
 * \brief handling of CCA result.
 */
void cca_done_handling(void)
{
	set_trx_state(CMD_PLL_ON); /* leave RX_ON */
	/* Restore IRQ handling */
	trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE); /* Enable frame reception.
	                                         **/

	/* Check if channel was idle or busy */
	if (trx_bit_read(SR_CCA_STATUS) == CCA_STATUS_CHANNEL_IS_IDLE) {
		tx_frame();
	} else {
		tal_state = TAL_CSMA_CONTINUE;
	}
}
Example #5
0
static int32_t connected_phase(legic_card_select_t *p_card) {
  uint8_t len = 0;

  // wait for command
  int32_t cmd = rx_frame(&len);
  if(cmd < 0) {
    return -1;
  }

  // check if command is LEGIC_READ
  if(len == p_card->cmdsize) {
    // prepare data
    uint8_t byte = legic_mem[cmd >> 1];
    uint8_t crc = calc_crc4(cmd, p_card->cmdsize, byte);

    // transmit data
    tx_frame((crc << 8) | byte, 12);

    return 0;
  }
Example #6
0
//Handler for OI, moved from control.
void oi_system()
{
	movement_data_t movement_data;
	rotation_data_t rotation_data;
	
	enum {
		oi_command_init = 0,
		oi_command_move = 1,
		oi_command_rotate = 2,
		oi_command_play_song = 3,
		oi_command_dump = 4,
		oi_command_end_sequence = 5
	} oi_command = usart_rx();

	txq_enqueue(oi_command);

	switch (oi_command) {

		case oi_command_init:
			oi_init(&(control.oi_state));
			break;

		case oi_command_move:
	
			if(rx_frame()) {
				r_error(error_frame,"Move should not have multiple frames.");
			}

			struct {
				uint16_t speed;
				uint16_t dist;
				bool stream;
			} *move_data = (void *) &control.data;
			
			struct {
				uint16_t dist;
				uint8_t flag;
			} *response_move = (void *) &control.data;

			#warning "Stream functionality to be implemented later."
			//Stream returns the distance traveled
			//lcd_puts  ("In OI subsystem"); //debug
			movement_data = move_dist(&(control.oi_state), move_data->dist, move_data->speed);
			
			response_move->dist = movement_data.travelled;
			response_move->flag = movement_data.flag;
			
			if (movement_data.flag != 0) {
				movement_data = move_dist(&(control.oi_state), -20, move_data->speed);
				response_move->dist += movement_data.travelled;
			}

			control.data_len = 3;
			tx_frame(false);
			break;

		case oi_command_rotate:

			if (rx_frame()) {
				r_error(error_bad_message, "Rotate should only have one data frame.");
			}

			int16_t *angle = &(control.data[0]); // TODO: test if this is the right number of bytes

			if (control.data_len != 2/*sizeof(*angle)*/) { // TODO: hardcoding to debug
				r_error(error_bad_message, "Received too much data with rotate "
																	   "message.");
			}

			struct {
				uint16_t rotation;
			} *response_rotation = (void *) &control.data;

			rotation_data = turn(&(control.oi_state), *angle);
			response_rotation->rotation = rotation_data.rotated;
			control.data_len = 2;
			tx_frame(false);
			break;
			
			//Sing me a song.
		case oi_command_play_song:
			
			#warning "oi_command_play_song is deprecated"
			
			;
			//assuming that we get two data frames, the first containing the notes and the second containing the durations.
			int j;
				struct {
					uint8_t n; //The number of notes present in the song
					//char data[n];
					uint8_t index;
				} *song_data = (void *) &control.data;
		
			//	int j;
		 
			while(rx_frame()) { //this should happen twice please
				char tmp_notes[song_data->n];
				char tmp_durs[song_data->n];
			
				for(j =0; j<song_data->n; j++) {
					//tmp_notes[n]; TODO: broken
					#warning "oi_command_play_song not implemented"
				}

			}
		
			break;

		case oi_command_dump:
			//copies all of the data from OI_UPDATE and transmits to Control.
			oi_update(&(control.oi_state));
			memcpy(control.data, &control.oi_state, sizeof(control.oi_state));
			control.data_len = sizeof(control.oi_state);
			tx_frame(false);
			break;
		
		case oi_command_end_sequence:
			#warning "oi_command_end_sequence not implemented"
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED to orange
			oi_set_leds(1, 1, 170, 255);
			
			wait_ms(50);
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED to yellow
			oi_set_leds(1, 1, 70, 255);
			
			wait_ms(50);
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED back to default state (from oi_init())
			oi_set_leds(1, 1, 7, 255);
			
			// Play song
			songs_load(RICK_ROLL);
			
			break;
		
		default:
			r_error(error_bad_message, "Bad OI Command");
			break;
	}
}
Example #7
0
int meshd_write_mgmt(char *buf, int framelen, void *cookie)
{
    tx_frame(&nlcfg, (unsigned char *) buf, framelen);
    return framelen;
}