DWORD WINAPI ProcWaitSignal( LPVOID lpParam){ while(1){ printf("checking queue\n"); Sleep(1000); if (NbElmt != 0){ if ((!IsUpper(buf)) && (!IsLower(buf))) { printf("Mengonsumsi ke - %d : %c\n", ind, buf.TI[ind]); ind++; NbElmt--; // konsumsi buffer } else if (IsUpper(buf)) { SendXOFF(); printf("Masuk Upper limit\n"); printf("Mengonsumsi ke - %d : %c\n", ind, buf.TI[ind]); ind++; NbElmt--; // konsumsi buffer } else if (IsLower(buf)) { SendXON(); printf("Masuk Lower limit\n"); // no consume0 } } } return 0; };
int USART_Driver::Read( int ComPortNum, char* Data, size_t size ) { NATIVE_PROFILE_PAL_COM(); if((ComPortNum < 0) || (ComPortNum >= TOTAL_USART_PORT)) {ASSERT(FALSE); return -1;} if(Data == NULL ) return -1; HAL_USART_STATE& State = Hal_Usart_State[ComPortNum]; if ( IS_POWERSAVE_ENABLED(State) || (!IS_USART_INITIALIZED(State))) return -1; int CharsRead = 0; while(CharsRead < size) { // keep interrupts off only during pointer movement so we are atomic GLOBAL_LOCK(irq); size_t toRead; UINT8 *Src; toRead = size - CharsRead; Src = State.RxQueue.Pop( toRead ); if( NULL == Src ) break; // Check if FIFO level has just passed or gotten down to the low water mark if(State.RxQueue.NumberOfElements() <= State.RxBufferLowWaterMark && (State.RxQueue.NumberOfElements() + toRead) > State.RxBufferLowWaterMark) { if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_SWFLOW_CTRL) ) { // Clear our XOFF state SendXON( ComPortNum, XOFF_FLAG_FULL ); } if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_HWFLOW_CTRL) ) { CPU_USART_RxBufferFullInterruptEnable(ComPortNum, TRUE); } } memcpy(&Data[CharsRead], Src, toRead); // Copy data from queue to Read buffer CharsRead += toRead; } { GLOBAL_LOCK(irq); State.fDataEventSet = FALSE; if(!State.RxQueue.IsEmpty()) { SetEvent( ComPortNum, USART_EVENT_DATA_CHARS ); } } return CharsRead; }
void USART_Driver::ClockStopFinished() { GLOBAL_LOCK(irq); // undo previous work // if we sent are in XOFF state, clear that, and if we weren't already in XOFF state at time of clock stop, set XON state for( int port = 0; port < TOTAL_USART_PORT; port++) { if ( USART_FLAG_STATE(Hal_Usart_State[port], HAL_USART_STATE::c_RX_SWFLOW_CTRL)) { // clear our XOFF state SendXON( port, XOFF_CLOCK_HALT ); } } }
void USART_Driver::DiscardBuffer( int ComPortNum, BOOL fRx ) { if((ComPortNum < 0) || (ComPortNum >= TOTAL_USART_PORT)) return; HAL_USART_STATE& State = Hal_Usart_State[ComPortNum]; { GLOBAL_LOCK(irq); // circular buffer may require 2 pops for(int i=0; i<2; i++) { if(fRx) { size_t nElements = State.RxQueue.NumberOfElements(); State.RxQueue.Pop(nElements); } else { size_t nElements = State.TxQueue.NumberOfElements(); State.TxQueue.Pop(nElements); } } // // Re-enble RX after discarding the buffer (SW/HW handshaking) // if(fRx) { if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_SWFLOW_CTRL) ) { // Clear our XOFF state SendXON( ComPortNum, XOFF_FLAG_FULL ); } if( USART_FLAG_STATE(State, HAL_USART_STATE::c_RX_HWFLOW_CTRL) ) { CPU_USART_RxBufferFullInterruptEnable(ComPortNum, TRUE); } } } }