/** * @brief: c UART0 IRQ Handler */ void uart_iprocess(void) { uint8_t IIR_IntId; // Interrupt ID from IIR LPC_UART_TypeDef *pUart = (LPC_UART_TypeDef *)LPC_UART0; __disable_irq(); #ifdef DEBUG_0 //uart1_put_string("Entering c_UART0_IRQHandler\n\r"); #endif // DEBUG_0 /* Reading IIR automatically acknowledges the interrupt */ IIR_IntId = (pUart->IIR) >> 1 ; // skip pending bit in IIR if (IIR_IntId & IIR_RDA) { // Receive Data Avaialbe /* read UART. Read RBR will clear the interrupt */ // Perform a 'context switch' PCB *old_proc = gp_current_process; gp_current_process = k_get_process(PID_UART_IPROC); g_char_in = pUart->RBR; #ifdef DEBUG_0 uart1_put_string("Reading a char = "); uart1_put_char(g_char_in); uart1_put_string("\n\r"); #endif // DEBUG_0 // process the character. If it is a hotkey, call the corresponding function // If we are reading, fall through to default and add to the command buffer switch (g_char_in) { case '\r': case '\n': if (g_is_reading) { // We've finished reading a command, send it to the KCD process MSG_BUF *message; g_is_reading = 0; strcpy("\n\r", (char *)(g_in_buffer + g_in_index)); if (is_memory_available()) { message = k_request_memory_block(); message->mtype = DEFAULT; strcpy((char *)g_in_buffer, message->mtext); k_send_message(PID_KCD, message); } g_in_index = 0; } break; case '%': if (!g_is_reading) { // Start reading a command g_is_reading = 1; g_in_index = 1; g_in_buffer[0] = '%'; break; } #if defined(DEBUG_0) && defined(_DEBUG_HOTKEYS) case READY_Q_COMMAND: if (!g_is_reading) { print_ready(); break; } case MEMORY_Q_COMMAND: if (!g_is_reading) { print_mem_blocked(); break; } case RECEIVE_Q_COMMAND: if (!g_is_reading) { print_receive_blocked(); break; } case MESSAGE_COMMAND: if (!g_is_reading) { print_messages(); break; } #endif /* DEBUG HOTKEYS */ default: if (g_is_reading) { // TODO: check bounds g_in_buffer[g_in_index++] = g_char_in; } } gp_current_process = old_proc; } else if (IIR_IntId & IIR_THRE) { /* THRE Interrupt, transmit holding register becomes empty */ // Check for messages and load the buffer // Perform a 'context switch' to the i-process MSG_BUF *message; PCB *old_proc = gp_current_process; gp_current_process = k_get_process(PID_UART_IPROC); // Don't block waiting for a message while (is_message(PID_UART_IPROC)) { int sender = PID_CRT; char *c; // Receive message and copy it to the buffer message = k_receive_message(&sender); c = message->mtext; //dprintf("Copying message to buffer: %s\n\r", message->mtext); if (*c != '\0') { do { g_out_buffer[g_out_end] = *c; g_out_end = (g_out_end + 1) % OUTPUT_BUFF_SIZE; c++; } while (g_out_end != g_out_start && *c != '\0'); } k_release_memory_block(message); } // Check if there is something in the circular buffer if (g_out_start != g_out_end) { g_char_out = g_out_buffer[g_out_start]; pUart->THR = g_char_out; g_out_start = (g_out_start + 1) % OUTPUT_BUFF_SIZE; } else { // nothing to print, disable the THRE interrupt pUart->IER ^= IER_THRE; // toggle (disable) the IER_THRE bit } gp_current_process = old_proc; } else { /* not implemented yet */ #ifdef DEBUG_0 //uart1_put_string("Should not get here!\n\r"); #endif // DEBUG_0 __enable_irq(); return; } __enable_irq(); }
/* * This function is called by the assembly STUB function */ void uart_handler() { // Disable all interupts atomic_up(); #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Enter: uart_handler\r\n"); rtx_dbug_outs((CHAR *) "Reading data...\r\n"); #endif // irene said this should be enough - would be // very rare if it wasn't ready to read while (!(SERIAL1_UCSR & 1)) { } char_in = SERIAL1_RD; #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Determining what to do with char...\r\n"); #endif struct io_message * msg; switch(char_in) { #ifdef _HOTKEYS_DEBUG case '!': rtx_dbug_outs((CHAR *) "'!' hotkey detected...\r\n"); print_queues(); // print processes on ready queue and priorities break; case '@': rtx_dbug_outs((CHAR *) "'@' hotkey detected...\r\n"); print_mem_blocked(); // print processes on memory blocked queue and priorities break; case '#': rtx_dbug_outs((CHAR *) "'#' hotkey detected...\r\n"); print_msg_blocked(); // print processes on message blocked queue and priorities break; case '$': rtx_dbug_outs((CHAR *) "'$' hotkey detected...\r\n"); print_availible_mem_queue(); // print available memory queue break; case '^': rtx_dbug_outs((CHAR *) "'^' hotkey detected...\r\n"); print_used_mem_queue(); // print used memory queue break; case '&': rtx_dbug_outs((CHAR *) "'&' hotkey detected...\r\n"); output_kcd_buffer(); // print kcd buffer break; case '*': rtx_dbug_outs((CHAR *) "'*' hotkey detected...\r\n"); print_cmds(); // print valid commands break; #endif default: #ifdef _IO_DEBUG rtx_dbug_outs((CHAR *) "Sending message to KCD proc...\r\n"); #endif if (!are_blocks_available()) { atomic_down(); return; } msg = (io_message *)request_memory_block(); // reset tx/rx and send it to kcd msg->tx = UART_PID; msg->rx = KCD_PID; msg->msg[0] = char_in; send_message(KCD_PID, msg); break; } // Enable all interupts atomic_down(); }