Example #1
0
void hal_uart_send_async(hal_uart_port port, uint8_t size){
    assert(port >= HAL_UART_PORT_1 && port <= HAL_UART_NUMBER_OF_PORTS );
    /* select the respective output buffer */
    struct txbuffer_struct* tx_buffer = get_tx_buffer(port);
    tx_buffer->nbytes = size;
    tx_buffer->counter = 0;
    UART_MODULE uart = logic_uart2phy_uart(port);
    INTClearFlag(INT_SOURCE_UART_TX(uart));
    INTEnable(INT_SOURCE_UART_TX(uart), INT_ENABLED);
}
Example #2
0
// TODO: Maybe sanity check buffer not empty
void hal_uart_send_buffer_async(hal_uart_port port, uint8_t* buffer,
        uint8_t size){
    assert(port >= HAL_UART_PORT_1 && port <= HAL_UART_NUMBER_OF_PORTS );
    assert(size > 0 && size < HAL_UART_BUFFER_SIZE );
    assert(buffer != NULL);
    /* select the respective output buffer */
    struct txbuffer_struct* tx_buffer = get_tx_buffer(port);
    /* buffer should be empty before sending a new frame */
    assert(tx_buffer->nbytes == 0);
    /* copy buffer into output buffer */
    memcpy(tx_buffer->buffer, buffer, size);
   /* enable the tx interrupt. It starts the augomagically data transmision
    * from tx_buffer.
    */
    /* copy the size of the buffer.*/
    tx_buffer->nbytes = size;
    /* set the framecounter at null */
    tx_buffer->counter = 0;

    UART_MODULE uart = logic_uart2phy_uart(port);
    INTClearFlag(INT_SOURCE_UART_TX(uart));
    INTEnable(INT_SOURCE_UART_TX(uart), INT_ENABLED);
}
Example #3
0
//return IR_PACKET_SUCCESS if success, IR_PACKET_TX_BUSY if busy
u8 ir_send_packet(struct sIRPacket *ir_packet)
{
  if (ir_comm_get_tx_flag() == 0)
  {
    get_tx_buffer()[0] = IR_PACKET_START_BYTE;

    get_tx_buffer()[1] = ir_packet->id>>8;
    get_tx_buffer()[2] = ir_packet->id&0xff;
    get_tx_buffer()[3] = ir_packet->type>>8;
    get_tx_buffer()[4] = ir_packet->type&0xff;

    u32 i;
    for (i = 0; i < IR_PACKET_PAYLOAD_SIZE; i++)
      get_tx_buffer()[5 + i] = ir_packet->payload[i];

    get_tx_buffer()[IR_COMM_BUFFER_SIZE-1] = ir_packet_crc(get_tx_buffer(), IR_COMM_BUFFER_SIZE-1);

    ir_comm_start_tx();
    return IR_PACKET_SUCCESS;
  }
Example #4
0
uint8_t hal_uart_get_tx_buffer(hal_uart_port port, uint8_t** buffer){
    assert(port >= HAL_UART_PORT_1 && port <= HAL_UART_NUMBER_OF_PORTS );
    struct txbuffer_struct* obuffer = get_tx_buffer(port);
    *buffer = obuffer->buffer;
    return HAL_UART_BUFFER_SIZE;
}
Example #5
0
void hal_uart_interrupt_handler(hal_uart_port port) {
    UART_MODULE uart = logic_uart2phy_uart(port);
    assert(port >= HAL_UART_PORT_1 && port <= HAL_UART_NUMBER_OF_PORTS );
    /* get the txbuffer to send */
    struct txbuffer_struct *buffer = get_tx_buffer(port);
    /* If the source of interrupt is the TXInterrupt, start
     * transmitting the data in output queue. */
    if (INTGetFlag(INT_SOURCE_UART_TX(uart))) {
        /* Clear interrupt to prevent reentry */
        INTClearFlag(INT_SOURCE_UART_TX(uart));
        /* if queue is not empty, send tx data to uart while available. */
        while (buffer->nbytes > 0) {
            if (UARTTransmitterIsReady(uart)) {
                UARTSendDataByte(uart, buffer->buffer[buffer->counter++]);
                /* decrement buffer count after byte was transmitted */
                buffer->nbytes --;
            } else {
                break;
            }
        }
        /* if queue is empty, disable tx interrupt. */
        if (buffer->nbytes <= 0) {
            INTEnable(INT_SOURCE_UART_TX(uart), INT_DISABLED);
            if(on_data_sent[port]!=NULL)
                on_data_sent[port](port);
        }
    }

    /* detect uart rx errors */
    if(INTGetFlag(INT_SOURCE_UART_ERROR(uart))){
        uint8_t in_byte = 0x00;
        hal_uart_error error = HAL_UART_ERR_NONE;
        volatile UART_LINE_STATUS  lineStatus = UARTGetLineStatus(uart);
        /* detect framming error. (break)*/
        /* Framing error are only valid if data is available in buffer. */
        if(UART_FRAMING_ERROR & lineStatus){
            /* trigger an on_data_received_callback */
            error = HAL_UART_ERR_FRAMMING;
        }
        /* detect uart overrun errors. */
        if(UART_OVERRUN_ERROR & lineStatus)
        {
            error = HAL_UART_ERR_OVERRUN;
            /* TODO: Not sure what to do if buffer overruns (it means data
             * arrives faster than we are able to process. So just
             * clear error and continue with our lives as nothing happened.
             */
            UARTClearOverrunError(uart);
        }
        if(UART_PARITY_ERROR & lineStatus){
            error = HAL_UART_ERR_PARITY;
        }
        if(UARTReceivedDataIsAvailable(uart)){
            in_byte = UARTGetDataByte(uart);
        }
        if(on_data_received[port]!=NULL)
            on_data_received[port](port,in_byte,error);
        /* clear the error flag. */
        INTClearFlag(INT_SOURCE_UART_ERROR(uart));
    }
    
    /* If receive interrupt was triggered, feed user apps with data. */
    if (INTGetFlag(INT_SOURCE_UART_RX(uart))) {
        /* Clear interrupt to prevent reentry */
        INTClearFlag(INT_SOURCE_UART_RX(uart));
        /* Copy the received data into input buffer */
        while (UARTReceivedDataIsAvailable(uart)) {
            uint8_t c = UARTGetDataByte(uart);
            if(on_data_received[port]!=NULL)
                on_data_received[port](port, c,HAL_UART_ERR_NONE);
        }
    }
}
Example #6
0
/*
 * MPC5x00 MSCAN interrupt handler
 */
static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle)
{
  rtems_status_code status;
  mscan_handle *mscan_hdl = (mscan_handle *) handle;
  struct mscan_channel_info *chan = &chan_info[mscan_hdl->mscan_channel];
  struct can_message rx_mess,
   *rx_mess_ptr,
   *tx_mess_ptr;
  mscan *m = chan->regs;
  register uint8_t idx;

  /*
     handle tx ring buffer
   */

  /* loop over all 3 tx buffers */
  for (idx = TFLG_TXE0; idx <= TFLG_TXE2; idx = idx << 1) {

    /* check for tx buffer vacation */
    if ((m->tflg) & idx) {

      /* try to get a message */
      tx_mess_ptr = get_tx_buffer(chan);

      /* check for new tx message */
      if (tx_mess_ptr != NULL) {

        /* select the tx buffer */
        m->bsel = idx;

        /* check for toucan interface */
        if ((mscan_hdl->toucan_callback) == NULL) {

          /* set tx id */
          m->txidr0 = SET_IDR0(tx_mess_ptr->mess_id);
          m->txidr1 = SET_IDR1(tx_mess_ptr->mess_id);
          m->txidr2 = 0;
          m->txidr3 = 0;

        }

        /* fill in tx data if TOUCAN is activ an TOUCAN index have a match with the tx buffer or TOUCAN is disabled */
        if (((mscan_hdl->toucan_callback) == NULL)
            || (((mscan_hdl->toucan_callback) != NULL)
                && ((tx_mess_ptr->toucan_tx_idx) == idx))) {

          /* insert dlc into m register */
          m->txdlr = (uint8_t) ((tx_mess_ptr->mess_len) & 0x000F);

          /* skip data copy in case of RTR */
          if (!(MSCAN_MESS_ID_HAS_RTR(tx_mess_ptr->mess_id))) {
            /* copy tx data to MSCAN registers */
            switch (m->txdlr) {
              case 8:
                m->txdsr7 = tx_mess_ptr->mess_data[7];
              case 7:
                m->txdsr6 = tx_mess_ptr->mess_data[6];
              case 6:
                m->txdsr5 = tx_mess_ptr->mess_data[5];
              case 5:
                m->txdsr4 = tx_mess_ptr->mess_data[4];
              case 4:
                m->txdsr3 = tx_mess_ptr->mess_data[3];
              case 3:
                m->txdsr2 = tx_mess_ptr->mess_data[2];
              case 2:
                m->txdsr1 = tx_mess_ptr->mess_data[1];
              case 1:
                m->txdsr0 = tx_mess_ptr->mess_data[0];
                break;
              default:
                break;
            }
          }

          /* enable message buffer specific interrupt */
          m->tier |= m->bsel;

          /* start transfer */
          m->tflg = m->bsel;

          /* release counting semaphore of tx ring buffer */
          rtems_semaphore_release((rtems_id) (chan->tx_rb_sid));

        } else {

          /* refill the tx ring buffer with the message */
          fill_tx_buffer(chan, tx_mess_ptr);

        }
      } else {
        /* reset interrupt enable bit */
        m->tier &= ~(idx);
      }
    }
  }

  /*
     handle rx interrupts
   */

  /* check for rx interrupt source */
  if (m->rier & RIER_RXFIE) {

    /* can messages received ? */
    while (m->rflg & RFLG_RXF) {

      if (mscan_hdl->toucan_callback == NULL) {

        /* select temporary rx buffer */
        rx_mess_ptr = &rx_mess;

      } else {

        /* check the rx fliter-match indicators (16-bit filter mode) */
        /* in case of more than one hit, lower hit has priority */
        idx = (m->idac) & 0x7;
        switch (idx) {

          case 0:
          case 1:
          case 2:
          case 3:
            rx_mess_ptr =
              (struct can_message *)
              &(mpc5200_mscan_rx_cntrl[mscan_hdl->mscan_channel].
                can_rx_message[idx]);
            break;

            /* this case should never happen */
          default:
            /* reset the rx indication flag */
            m->rflg |= RFLG_RXF;

            return;
            break;
        }

      }

      /* get rx ID */
      rx_mess_ptr->mess_id = GET_IDR0(m->rxidr0) | GET_IDR1(m->rxidr1);

      /* get rx len */
      rx_mess_ptr->mess_len = ((m->rxdlr) & 0x0F);

      /* get time stamp */
      rx_mess_ptr->mess_time_stamp = ((m->rxtimh << 8) | (m->rxtiml));

      /* skip data copy in case of RTR */
      if (!(MSCAN_MESS_ID_HAS_RTR(rx_mess_ptr->mess_id)))
      {

        /* get the data */
        switch (rx_mess_ptr->mess_len) {
          case 8:
            rx_mess_ptr->mess_data[7] = m->rxdsr7;
          case 7:
            rx_mess_ptr->mess_data[6] = m->rxdsr6;
          case 6:
            rx_mess_ptr->mess_data[5] = m->rxdsr5;
          case 5:
            rx_mess_ptr->mess_data[4] = m->rxdsr4;
          case 4:
            rx_mess_ptr->mess_data[3] = m->rxdsr3;
          case 3:
            rx_mess_ptr->mess_data[2] = m->rxdsr2;
          case 2:
            rx_mess_ptr->mess_data[1] = m->rxdsr1;
          case 1:
            rx_mess_ptr->mess_data[0] = m->rxdsr0;
          case 0:
          default:
            break;
        }
      }

      if (mscan_hdl->toucan_callback == NULL) {

        if ((status =
             rtems_message_queue_send(chan->rx_qid, (void *) rx_mess_ptr,
                                      sizeof (struct can_message))) !=
            RTEMS_SUCCESSFUL) {

          chan->int_rx_err++;

        }

      } else {

        mscan_hdl->toucan_callback((int16_t) (((m->idac) & 0x7) + 3));

      }

      /* reset the rx indication flag */
      m->rflg |= RFLG_RXF;

    }                           /* end of while(m->rflg & RFLG_RXF) */

  }

  /* status change detected */
  if (m->rflg & RFLG_CSCIF) {

    m->rflg |= RFLG_CSCIF;

    if (mscan_hdl->toucan_callback != NULL) {

      mscan_hdl->toucan_callback((int16_t) (-1));

    }

  }

}
Example #7
0
void  process_call()
{
    /* variables */
    enum tcp_conn_status  cur_status;	/* current connection state */



    /* get the current connection state */
    cur_status = tcp_connection_status();

    /* if the current connection state has changed, need to reset the */
    /*    the receive buffers, they may have old tone data in them */
    if (cur_status != last_status)
        reset_tx_buffer();

    /* always update the last status */
    last_status = cur_status;


    /* now check the status of the connection */
    switch  (cur_status)  {

        case CALL_RINGING:	/* connection is ringing on the other end */

				/* generate a buffer of ringing tone if */
				/*    there is room for it */
				if (rcv_available())  {
				    /* have a buffer, get and fill it */
				    ring_fill(get_rcv_buffer(), AUDIO_BUFLEN);
				}

				/* if there is a buffer to transmit, need */
                                /*    to discard it */
				if (xmit_available())  {
				    /* have a buffer, dump it */
				    get_xmit_buffer();
				}
				break;

        case CALL_BUSY:		/* connection is busy on the other end */

				/* generate a buffer of busy signal if */
				/*    there is room for it */
				if (rcv_available())  {
				    /* have a buffer, get and fill it */
				    busy_fill(get_rcv_buffer(), AUDIO_BUFLEN);
				}

				/* if there is a buffer to transmit, need */
                                /*    to discard it */
				if (xmit_available())  {
				    /* have a buffer, dump it */
				    get_xmit_buffer();
				}
				break;

        case CALL_CONNECTED:	/* are talking on the connection */

			        /* check if there is a buffer to transmit */
				if (xmit_available())  {
				    /* buffer is available - try sending it */
				    if (tcp_connection_tx(get_xmit_next_ptr(), AUDIO_BUFLEN))
				        /* actually sent it, let buffer functions know */
				        get_xmit_buffer();
				}

				/* check if have room for a received buffer */
				if (rcv_available())  {
				    /* have room - try to get a buffer */
				    if (tcp_connection_rx(get_rcv_next_ptr(), AUDIO_BUFLEN))
				        /* got the buffer, so allocate it */
					get_rcv_buffer();
				}
				break;

	default:		/* some other status, must have aborted call */

				/* if there is a buffer to transmit, need */
                                /*    to discard it */
				if (xmit_available())  {
				    /* have a buffer, dump it */
				    get_xmit_buffer();
				}
				break;
    }


    /* try to play and receive any buffers */

    /* check if a receive buffer is available for recording into */
    if (rx_available())  {

        /* have a receive buffer, see if update is ready */
	if (update_rx(get_rx_next_ptr()))
	    /* it wanted the buffer - actually allocate it */
	    get_rx_buffer();
    }

    /* check if a transmit buffer is available for playing */
    if (tx_available())  {

        /* have a transmit buffer, see if update is ready */
	if (update_tx(get_tx_next_ptr()))
	    /* it wanted the buffer - actually allocate it */
	    get_tx_buffer();
    }


    /* all done processing the call for now - return */
    return;

}