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