Exemple #1
0
int serial_get_event(struct wl_input_event *ev)
{
	if (BUFFER_EMPTY(console_write, console_read, console_buffer))
		return 0;

//	msg(MSG_INFO, " OUT. %d %d    %p %p\n", console_read, console_write,
//		ev, &ev->type);

	ev->type = WL_INPUT_EV_TYPE_KEYBOARD;
	if (0x7f == console_buffer[console_read]) {
		console_buffer[console_read] = 0x08;
	}
	ev->key_event.keycode = console_buffer[console_read];
	ev->key_event.value = 1;
	BUFFER_NEXT(console_read, console_buffer);

	/* Override for scrolling... */
	if ((ev->key_event.keycode == WL_KEY_PLUS) || (ev->key_event.keycode == WL_KEY_DOWN)) {
		ev->type = WL_INPUT_EV_TYPE_CURSOR;
		ev->key_event.keycode = WL_INPUT_KEY_CURSOR_DOWN;
	}
	else if ((ev->key_event.keycode == WL_KEY_MINUS) || (ev->key_event.keycode == WL_KEY_UP)) {
		ev->type = WL_INPUT_EV_TYPE_CURSOR;
		ev->key_event.keycode = WL_INPUT_KEY_CURSOR_UP;
	}

	return 1;
}
Exemple #2
0
/**************************************************************************
DOES:    Queues a message for transmission. Gathers data from two memory
         areas and stores sequentially in buffer.
RETURNS: TRUE if message was queued, FALSE if there was an error
**************************************************************************/
UNSIGNED8 SerialProtocol_PushMessage (
  UNSIGNED8 length1, // length of data chunk 1
  UNSIGNED8 *pTx1,   // pointer to data chunk 1
  UNSIGNED8 length2, // length of data chunk 2
  UNSIGNED8 *pTx2    // pointer to data chunk 2
  )
{
  int b;

  // store data in transmit buffer - it will be transmitted by the
  // state machine when all currently buffered messages have been
  // transmitted
  txbuffer.nextwrite->dlc = length1 + length2;
  for (b = 0; b < length1; b++)
  {
    txbuffer.nextwrite->data[b] = *(pTx1 + b);
  }
  for (b = 0; b < length2; b++)
  {
    txbuffer.nextwrite->data[b + length1] = *(pTx2 + b);
  }
  BUFFER_INCWRITE(txbuffer);
  // if overflow lose oldest packet
  if (BUFFER_EMPTY(txbuffer))
  {
    BUFFER_INCREAD(txbuffer);
  }

  return TRUE;
}
Exemple #3
0
void *speaker_thread(void* ptr){
  audiobuffer* buf = ((spk_pcm_package*)ptr)->buffer; //cast pointer, get buffer struct
  snd_pcm_t* speaker_handle = ((spk_pcm_package*)ptr)->pcm_handle; //cast pointer, get device pointer
  free(ptr); //free message memory
    
  snd_pcm_nonblock(speaker_handle, SND_PCM_NONBLOCK); //set in nonblocking mode
    
  char started = 0;  //track when to start reading data
  while(!global_kill && !speaker_kill_flag) { //loop until program stops us
    //wait until adequate buffer is achieved and can be written
    if((!started && BUFFER_SIZE(*buf) < (MIN_BUFFER)) \
        || BUFFER_EMPTY(*buf) \
        || !snd_pcm_avail_update(speaker_handle)) {
      //printf("Speaker Waiting\n");
      usleep(PERIOD_UTIME*2); //wait to reduce CPU usage
      continue;     //don't start yet
    } else {
      if(!started) snd_pcm_prepare(speaker_handle); //reset speaker
      started = 1; //indicate that we've startd
    }
    
    //write data to speaker buffer, check responses
    int write_count = MIN(BUFFER_SIZE(*buf), snd_pcm_avail_update(speaker_handle)/(buf->period));
    
#ifdef DEBUG_MODE
    printf("Writing %d packets to speaker\n", write_count);
#endif

    //loop over avaliable buffer entries
    while(write_count-- > 0 && started){
      /* Note: This call performs a syscall to copy data to kernel space 
          so it would be better to write multiple entries in one operation, 
          but using the audiobuffer without the abstraction was something 
          I didn't want to do at the time of writing. */
      int rc = snd_pcm_writei(speaker_handle, GET_QUEUE_HEAD(*buf), buf->period);      
      INC_QUEUE_HEAD(*buf);
      if (rc == -EPIPE){ //Catch underruns (not enough data)
        fprintf(stderr, "underrun occurred\n");
        started = 0;  //stop and wait for buffer to buildup
      } else if (rc < 0) fprintf(stderr, "error from writei: %s\n", snd_strerror(rc)); //other errors
      else if (rc != (int)buf->period) fprintf(stderr, "short write, write %d frames\n", rc);
      //else fprintf(stderr, "audio written correctly\n");
      //snd_pcm_wait(speaker_handle, 1000); //wait for IO to be ready
    }
    
#ifdef DEBUG_MODE
    printf("%d unwritten\n", write_count);
#endif    
  }
  
  // notify kernel to empty/close the speakers
  snd_pcm_drain(speaker_handle);  //finish transferring the audio
  snd_pcm_close(speaker_handle);  //close the device
  printf("Audio Controller: Speaker Thread shutdown\n");
  
  pthread_exit(NULL); //exit thread safetly
}
Exemple #4
0
/**************************************************************************
DOES:    Transmits all packets in transmit buffer
RETURNS: Nothing
**************************************************************************/
void SerialProtocol_CompleteTransmits (
  void
  )
{
  while (!BUFFER_EMPTY(txbuffer))
  {
    SerialProtocol_ProcessTransmit();
  }

  COM_Flush();
}
Exemple #5
0
bool CTP_get(int *x, int *y, bool *pressed, unsigned long *ticks)
{
    if (BUFFER_EMPTY(CTPwrite, CTPread, CTPbuffer)) {
        return false;
    }

    *x = CTPbuffer[CTPread].x;
    *y = CTPbuffer[CTPread].y;
    *pressed = CTPbuffer[CTPread].pressed;
    *ticks = CTPbuffer[CTPread].ticks;
    BUFFER_NEXT(CTPread, CTPbuffer);
    return true;
}
Exemple #6
0
/**************************************************************************
DOES:    Gets the next message from the receive buffer
RETURNS: Number of data bytes copied or zero if no messages
**************************************************************************/
UNSIGNED8 SerialProtocol_PullMessage (
  UNSIGNED8 *pRx    // pointer to location to store data
  )
{
  int b;
  UNSIGNED8 length = 0;

  if (!BUFFER_EMPTY(rxbuffer))
  {
    length = rxbuffer.nextread->dlc;
    for (b = 0; b < length; b++)
    {
      *(pRx + b) = rxbuffer.nextread->data[b];
    }
    BUFFER_INCREAD(rxbuffer);

    if (pRx[0] == 'W')
    {
      num = ((UNSIGNED16)pRx[5] << 8) | pRx[4];
    }
  }

  return length;
}
Exemple #7
0
/**************************************************************************
DOES:    Processes packet transmission
RETURNS: TRUE, if an error occured during transmission
GLOBALS: SerialProtocol_Out, SerialProtocol_TransmitErrorCounter
**************************************************************************/
static UNSIGNED8 SerialProtocol_ProcessTransmit (
  void
  )
{
  UNSIGNED8 return_val = FALSE;
  static UNSIGNED16 crc;

  // Depending on the state, send the next byte from the transmit buffer.
  switch ( mSerialProtocol_SendState.send_state )
  {
    case SENDSTATE_IDLE:

      // If there is something to send, start
      if (!BUFFER_EMPTY(txbuffer))
      {
        mSerialProtocol_SendState.send_state = SENDSTATE_START;
      }
      break;

    // The first byte is the start-of-header
    case SENDSTATE_START:

      if (COM_SendByte(PROT_SOH))
      {
        // Initialize CRC calculator
        crc = CRC_Init();

        // Next byte is the length
        mSerialProtocol_SendState.send_state = SENDSTATE_LENGTH;
      }
      break;


    // Send the length
    case SENDSTATE_LENGTH:

      if (COM_SendByte(txbuffer.nextread->dlc))
      {
        // Add to CRC
        CRC_Add(txbuffer.nextread->dlc, &crc);

        if (txbuffer.nextread->dlc == 0)
        { // No data: Next state is the low checksum bytes
          mSerialProtocol_SendState.send_state = SENDSTATE_CHECKL;
        }
        else
        { // Next state is the field of data bytes
          mSerialProtocol_SendState.send_state = SENDSTATE_DATA;
        }
      }
      break;


    // Send data
    case SENDSTATE_DATA:

      if (COM_SendByte(txbuffer.nextread->data[mSerialProtocol_SendState.num_bytes]))
      {
        // Add to CRC
        CRC_Add(txbuffer.nextread->data[mSerialProtocol_SendState.num_bytes], &crc);

        mSerialProtocol_SendState.num_bytes++;

        if (mSerialProtocol_SendState.num_bytes == txbuffer.nextread->dlc)
        { // All data bytes sent: Now checksum
          mSerialProtocol_SendState.send_state  = SENDSTATE_CHECKL;
        }
        else
        { // Otherwise stay here
          mSerialProtocol_SendState.send_state  = SENDSTATE_DATA;
        }
      }
      break;

    // Send checksum low byte
    case SENDSTATE_CHECKL:

      mSerialProtocol_SendState.checksum = crc;

      // Send low byte
      if(COM_SendByte((UNSIGNED8)(mSerialProtocol_SendState.checksum & 0x00FFU)))
      {
        // Now send high byte of checksum
        mSerialProtocol_SendState.send_state  = SENDSTATE_CHECKH;
      }
      break;


    // End-of-packet: Send high byte of checksum
    case SENDSTATE_CHECKH:

      // Send high byte
      if(COM_SendByte((UNSIGNED8)(mSerialProtocol_SendState.checksum >> 8)))
      {
        // finished sending packet
        // Now we are ready for the next packet
        SerialProtocol_ResetTransmitHandler();
        BUFFER_INCREAD(txbuffer);
      }
      break;

    default:  // never be here, if we get here by error, reset state machine
      SerialProtocol_ResetTransmitHandler();
      break;
  }

  return (return_val);
}
Exemple #8
0
/**************************************************************************
DOES:    Processes received bytes. Handles synchronization packets
         autonomously.
RETURNS: TRUE, if a complete, correct command was received and
         'SerialProtocol_In' contains the command.
GLOBALS: SerialProtocol_In, SerialProtocol_ReceiveErrorCounter
**************************************************************************/
static UNSIGNED8 SerialProtocol_ProcessReceive (
  void
  )
{
  UNSIGNED8 return_val = FALSE;
  UNSIGNED8 byte;
  static UNSIGNED16 mycrc;

  // Only process receive packets if not currently sending
  if (mSerialProtocol_SendState.send_state == SENDSTATE_IDLE)
  { 
    // Get the next byte from the receive buffer, if available, and process.
    if (COM_GetByte(&byte))
    {
      // Arm the timer for receiving the next byte
      mByteTimeout = MCOHW_GetTime() + SERIALPROTOCOL_NEXTBYTETIMEOUT;

      switch ( mSerialProtocol_ParseState.parse_state )
      {
        // The first byte is the start-of-header
        case PARSESTATE_START:

          // Test if start-of-header was received
          if (byte == PROT_SOH)
          {
            // Initialize CRC calculator
            mycrc = CRC_Init();

            // Packet reception started - now monitor subsequent bytes
            mSerialProtocol_ParseState.wait_next   = TRUE;

            // Next byte is the length
            mSerialProtocol_ParseState.parse_state = PARSESTATE_LENGTH;
          }
          else
          { // otherwise ignore byte and stay in this state
            ;
          }
          break;


        // Get the length
        case PARSESTATE_LENGTH:

          // Add to CRC
          CRC_Add(byte, &mycrc);

          mSerialProtocol_ParseState.dlc = byte;  // Memorize number of data bytes

          if (byte > MAX_PACKET_DATA)
          { // If this packet is too long: Error
            mSerialProtocol_ParseState.err = TRUE;
          }
          if (byte == 0)
          { // No data: Next state is the low checksum bytes
            mSerialProtocol_ParseState.parse_state = PARSESTATE_CHECKL;
          }
          else
          { // Next state is the field of data bytes
            mSerialProtocol_ParseState.parse_state = PARSESTATE_DATA;
          }
          break;


        // Get data
        case PARSESTATE_DATA:

          // Add to CRC
          CRC_Add(byte, &mycrc);

          // Only receive data if no error, packet is for us, and not too long
          if ( !mSerialProtocol_ParseState.err       &&
               !mSerialProtocol_ParseState.ignore      &&
               (mSerialProtocol_ParseState.num_bytes < MAX_PACKET_DATA) )
          { // If possible, save data in buffer
            rxbuffer.nextwrite->data[mSerialProtocol_ParseState.num_bytes] = byte;
          }

          // Increment counter for received data bytes
          mSerialProtocol_ParseState.num_bytes++;

          if (mSerialProtocol_ParseState.num_bytes == mSerialProtocol_ParseState.dlc)
          { // All data bytes received: Now checksum
            mSerialProtocol_ParseState.parse_state  = PARSESTATE_CHECKL;
          }
          else
          { // Otherwise stay here
            mSerialProtocol_ParseState.parse_state  = PARSESTATE_DATA;
          }
          break;

        // Get checksum low byte
        case PARSESTATE_CHECKL:

          // Memorize low byte
          mSerialProtocol_ParseState.crc = (UNSIGNED16)byte;

          // Now get high byte of checksum
          mSerialProtocol_ParseState.parse_state  = PARSESTATE_CHECKH;
          break;


        // End-of-packet: Get checksum and compare with the calculated one
        case PARSESTATE_CHECKH:

          // If this packet is not for us, don't do anything (just keep on parsing)
          if (!mSerialProtocol_ParseState.ignore)
          {
            // Add high byte of received checksum
            mSerialProtocol_ParseState.crc |= (UNSIGNED16)byte << 8;

            if (mSerialProtocol_ParseState.crc != mycrc)
            {
              mSerialProtocol_ParseState.err = TRUE;
            }

            // if packet received correct then store in receive buffer
            if (!mSerialProtocol_ParseState.err)
            {
              rxbuffer.nextwrite->dlc = mSerialProtocol_ParseState.dlc;
              BUFFER_INCWRITE(rxbuffer);
              // if overflow then lose oldest packet
              if (BUFFER_EMPTY(rxbuffer))
              {
                BUFFER_INCREAD(rxbuffer);
              }
              return_val = TRUE;
            }
          }

          // Now we are ready for the next packet
          mSerialProtocol_ParseState.wait_next = FALSE;
          SerialProtocol_ResetReceiveHandler();
          break;

        default:  // never be here, reset
          mSerialProtocol_ParseState.wait_next = FALSE;
          SerialProtocol_ResetReceiveHandler();
          break;
      }
    }
    else
    {
      // If no byte has been received, monitor timeout if we are in-packet
      if ( mSerialProtocol_ParseState.wait_next &&
           MCOHW_IsTimeExpired(mByteTimeout)
         )
      {
        // In-packet bytes have to arrive in time. After timeout resort to
        // the ground state to be ready for the next packet reception.
        mSerialProtocol_ParseState.wait_next = FALSE;
        SerialProtocol_ResetReceiveHandler();
        SerialProtocol_ReceiveErrorCounter++;
      }
    }
  }

  return (return_val);
}
Exemple #9
0
int main() {
  kill_flag = 0;  //not killed yet

  // Open PCM device for playback, check for errors
  snd_pcm_t *speaker_handle; //handler struct
  int rc = snd_pcm_open(&speaker_handle, "default",SND_PCM_STREAM_PLAYBACK, 0);
  if (rc < 0) {
    fprintf(stderr,"unable to open pcm device: %s\n",snd_strerror(rc));
    exit(1);
  }

  /* Allocate a hardware parameters object. */
  snd_pcm_hw_params_t *params;
  snd_pcm_hw_params_alloca(&params);

  /* Fill it in with default values. */
  snd_pcm_hw_params_any(speaker_handle, params);

  /* Set the desired hardware parameters. */

  /* Interleaved mode */
  snd_pcm_hw_params_set_access(speaker_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

  /* Signed 16-bit little-endian format */
  snd_pcm_hw_params_set_format(speaker_handle, params, SND_PCM_FORMAT_S16_LE);

  /* Two channels (stereo) */
  snd_pcm_hw_params_set_channels(speaker_handle, params, 2);

  /* 44100 bits/second sampling rate (CD quality) */
  unsigned int val = SAMPLE_RATE; //assign value
  int dir; //direction (input/output)
  snd_pcm_hw_params_set_rate_near(speaker_handle, params, &val, &dir); //get closest match
  printf("rate is %d\n",val);

  /* Set period size to the constant frames. */
  size_t frames = PERIOD;
  snd_pcm_hw_params_set_period_size_near(speaker_handle, params, &frames, &dir);

  /* Write the parameters to the driver */
  rc = snd_pcm_hw_params(speaker_handle, params);
  if (rc < 0) {
    fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));
    exit(1);
  }

  /* Allocate stream buffer and input buffer */
  snd_pcm_hw_params_get_period_size(params, &frames, &dir);
  printf("Actual frames: %d\n",(int)frames);
  frame_size = frames * 4; /* 2 bytes/sample, 2 channels */
  input_buffer = (char*) malloc(frame_size * MAX_BUFFER);  //allocate buffer for network input
  in_buff_start = 0; in_buff_end = 0; //setup the queue
  
  /* create a server socket and thread to handle input */
  pthread_t thread;
  int flags = 0;
  rc = pthread_create(&thread, NULL, reciever_thread, (void*)&flags);
  if (rc){
     printf("ERROR; return code from pthread_create() is %d\n", rc);
     exit(-1);
  }

  char started = 0;  //track when to start reading data
  while(!kill_flag) { //loop until broken
    //rc = read(0, speaker_buffer, size); //read values in from console
    //wait for some buffer before starting, stop if empty
    if((!started && BUFFER_SIZE(in_buff_start,in_buff_end) < (MAX_BUFFER/2)) \
          || BUFFER_EMPTY(in_buff_start, in_buff_end)){
      //printf("Skipped (%d,%d)\n",BUFFER_SIZE(in_buff_start,in_buff_end),BUFFER_EMPTY(in_buff_start,in_buff_end));
      //if(started) printf("stopping\n");
      started = 0;
      continue; 
    }
    else {
      //if(!started) printf("starting\n");
      started = 1; //indicate that we've startd
    }
    
    //write data to speaker buffer, check responses
    rc = snd_pcm_writei(speaker_handle, input_buffer+(frame_size*in_buff_start), frames);
    //printf("wrote data to speakers\n");
    in_buff_start = (in_buff_start+1)%MAX_BUFFER;
    if (rc == -EPIPE){ /* EPIPE means underrun */
      fprintf(stderr, "underrun occurred\n");
      snd_pcm_prepare(speaker_handle);
    } else if (rc < 0) fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
    else if (rc != (int)frames) fprintf(stderr, "short write, write %d frames\n", rc);
  }

  // notify kernel to empty/close the buffers
  snd_pcm_drain(speaker_handle);
  snd_pcm_close(speaker_handle);

  free(input_buffer); //free our buffers

  kill_flag = 1;  //signal that threads should die
  pthread_exit(NULL); //exit without killing children
  return 0;
}
Exemple #10
0
bool CTP_available(void)
{
    return !BUFFER_EMPTY(CTPwrite, CTPread, CTPbuffer);
}