I am working on CORTEX-A9 FreeRTOS port using ZEDBoard. I want to take PS-GPIO interrupt. But I am facing following issues here..
When an interrupt occur, GPIO handler calls two times...
When I set interrupt on rising or falling edge, Corresponding bit on GPIO status Register is not...
Here is the code of GPIO configuration..
void fpga_gpio_fabric_interrupt_init()
{
XScuGic_Config *pxGICConfig;
BaseType_t xStatus;
pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );
configASSERT( pxGICConfig );
configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) );
configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS );
xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus;
XGpioPs_Config *pxConfigPtr;
BaseType_t xStatus1;
pxConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID);
xStatus1 = XGpioPs_CfgInitialize(&xGpio, pxConfigPtr,pxConfigPtr->BaseAddr);
configASSERT( xStatus1 == XST_SUCCESS );
( void ) xStatus1;
XGpioPs_SetDirectionPin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, 0);
XScuGic_Connect(&xInterruptController, GPIO_INTERRUPT_ID,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
&xGpio);
XGpioPs_SetIntrTypePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN, XGPIOPS_IRQ_TYPE_LEVEL_LOW);
XGpioPs_SetCallbackHandler(&xGpio, (void *)&xGpio, (void *)GPIOIntrHandler);
xil_printf("Declaration Function is called \r\n");
XGpioPs_IntrEnablePin(&xGpio, ZYNQ_GPIO_INTERRUPT_PIN);
XScuGic_Enable(&xInterruptController, GPIO_INTERRUPT_ID);
}
void GPIOIntrHandler(void *CallBackRef)
{
xil_printf("Interrupt has been occurred \r\n");
XGpioPs *Gpioint = (XGpioPs *)CallBackRef;
XGpioPs_IntrClearPin(Gpioint, ZYNQ_GPIO_INTERRUPT_PIN);
}
Related
I'm trying to UART transceiver on my ZYNQ-7000 board using interrupts. Basically, it just take data from the serial terminal and send back to it.
After initialization, a message Uart Initialization Successful! is sent to and shown on the terminal which confirms that the ZYNQ can send data to the PC. But whenever I input some random letters, it seems that interrupt handler function, called void Handler(), was never called. It seems there is no interrupt generated at all. I've looked up a lot but cannot slove the problem. Could any one please help me with this, please.
Here is my code,
#include "xparameters.h"
#include "xuartps.h"
#include "xil_printf.h"
#include "xscugic.h"
#include "stdio.h"
// serial device ID
#define UART_DEVICE_ID XPAR_PS7_UART_1_DEVICE_ID
// interrupt ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
// serial port interrupt id
#define UART_INT_IRQ_ID XPAR_XUARTPS_1_INTR
// interrupt controller driver instance
XScuGic Intc;
// serial port driver instance
XUartPs Uart_Ps;
// data buffer size
#define MAX_LEN 512
u8 ReceivedBuffer[MAX_LEN];
volatile u32 ReceivedByteNum;
XUartPsFormat UartFormat = {
115200,
XUARTPS_FORMAT_8_BITS,
XUARTPS_FORMAT_NO_PARITY,
XUARTPS_FORMAT_1_STOP_BIT
};
// function declaration
int UartInit(XUartPs *uart_ps);
// interrupt handler
void Handler(void *call_back_ref);
int UartIntrInit(XScuGic *intc, XUartPs *uart_ps);
// main function
int main(void){
int status;
// initialize the serial port
status = UartInit(&Uart_Ps);
if(status == XST_FAILURE){
xil_printf("Uart Initialization Failed\r\n");
return XST_FAILURE;
}
// interrupt initialization
status = UartIntrInit(&Intc, &Uart_Ps);
if(status == XST_FAILURE){
xil_printf("Uart Initialization Failed\r\n");
return XST_FAILURE;
}
xil_printf("Uart Initialization Successful!\r\n");
// main loop
while (1) {};
return status;
}
int UartInit(XUartPs *uart_ps){
int status;
XUartPs_Config *uart_cfg;
uart_cfg = XUartPs_LookupConfig(UART_DEVICE_ID);
if(NULL == uart_cfg) return XST_FAILURE;
status = XUartPs_CfgInitialize(uart_ps, uart_cfg, uart_cfg->BaseAddress);
if(status != XST_SUCCESS) return XST_FAILURE;
// UART self test
status = XUartPs_SelfTest(uart_ps);
if(status != XST_SUCCESS) return XST_FAILURE;
XUartPs_SetOperMode(uart_ps, XUARTPS_OPER_MODE_NORMAL);
XUartPs_SetDataFormat(uart_ps, &UartFormat);
XUartPs_SetFifoThreshold(uart_ps, 32);
XUartPs_SetRecvTimeout(uart_ps, 8);
return XST_SUCCESS;
};
// UART Interrupt handler service
void Handler(void *call_back_ref){
xil_printf("Enter INTR\r\n");
XUartPs *uart_instance_ptr = (XUartPs *) call_back_ref;
u32 ReceivedCount = 0;
u32 IsrValue;
IsrValue = XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_IMR_OFFSET);
IsrValue &= XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_ISR_OFFSET);
// if interrupt is asserted
if( IsrValue & ((u32) XUARTPS_IXR_RXOVR) ){
XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR);
ReceivedCount = XUartPs_Recv(&Uart_Ps, ReceivedBuffer, MAX_LEN);
ReceivedByteNum += ReceivedCount;
}
else if( IsrValue & ((u32) XUARTPS_IXR_TOUT) ){
// Rx FIFO timeout / idle
XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_TOUT);
ReceivedCount = XUartPs_Recv(&Uart_Ps, ReceivedBuffer, MAX_LEN);
ReceivedByteNum += ReceivedCount;
// send out
for(u32 sendByte=0;sendByte<ReceivedByteNum;sendByte++){
XUartPs_SendByte(XPAR_PS7_UART_1_BASEADDR, ReceivedBuffer[sendByte]);
}
ReceivedByteNum = 0;
}
}
// UART Interrupt init
int UartIntrInit(XScuGic *intc, XUartPs *uart_ps){
int status;
// initialize the interrupt controller
XScuGic_Config *intc_cfg;
intc_cfg = XScuGic_LookupConfig(INTC_DEVICE_ID);
if(NULL == intc_cfg) return XST_FAILURE;
status = XScuGic_CfgInitialize(intc, intc_cfg, intc_cfg->CpuBaseAddress);
if(status != XST_SUCCESS) return XST_FAILURE;
// set and enable interrupt exception handle function
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, (void *) intc);
// set interrupt handler for interrupt
XScuGic_Connect(intc, UART_INT_IRQ_ID, (Xil_ExceptionHandler) Handler, (void *) uart_ps);
// set interrupt trigger mode
XUartPs_SetInterruptMask(uart_ps, XUARTPS_IXR_RXOVR | XUARTPS_IXR_TOUT);
Xil_ExceptionEnable();
XScuGic_Enable(intc, UART_INT_IRQ_ID);
return XST_SUCCESS;
}
I'm using UART1 controller at MIO 48, 49 which is confirmed at both the Vivado and the schematic.
There are few problems of your program.
Receive function
It seems you have not called the UART receive function (XUartPs_Recv).
In interrupt mode, the UART controller will start receiving after you called XUartPs_Recv, this function is non-blocking. When all data received, the UART controller will generate an interrupt, and all data has been written to the receive buffer by the interrupt handler function.
XUartPs_Recv(uart_ps, RecvBuffer, SIZE_IN_BYTE);
Interrupt Handler
UARTPS library provided the interrupt handler function (XUartPs_InterruptHandler). So you need to bind it to the XScuGic
XScuGic_Connect(intc, UART_INT_IRQ_ID,
(XInterruptHandler) XUartPs_InterruptHandler, uart_ps);
This interrupt handler can help you receive the data from UART FIFO and write to the receive buffer.
Custom Callback
If you want to do something when the interrupt occoured, you don't need to write a new handler function by yourself, but a Callback function is needed.
XUartPs_SetHandler(uart_ps, (XUartPs_Handler)Handler, uart_ps);
Use this function, your custom handler will be called from the
interrupt context (XUartPs_InterruptHandler) when data has been sent or received.
Addition
You may set the receiver timeout. If it is not set, and the last few bytes of data do not trigger the over-water or full interrupt, the bytes will not be received. By default it is disabled.
XUartPs_SetRecvTimeout(uart_ps, 8);
Reference
Please refer the official example by Xilinx on GitHub.
I've been trying to write some code on STM32F411re usign IAR workbench in order to learn more about Cortex. I tried to implement TIMER3 PWM mode (center-aligned) with TIMER 2 being called every (half a second, second doesnt matter as much performing LED blink) and ADC performing continious regular conversion on one channel. I've tried to implement it all using interrupts. TIMER3 interrupt is inteded to be generated on Overflow and underflow and within ISR i would change PWM width with value from ADC (changed with potentiometer).
Problem that i faced while creating project seems to be that, when TIMER3 is activated, program doesnt hit breakpoint ( does not enter) ADC ISR routine nor within any line of program within while(1) loop. When i comment TIMER 3, program normally goes through ADC ISR.
#include "stdio.h"
void Uart6Configuration(void);
void send_data (uint8_t c);
void init_PWM(void);
void init_ADC(void) ;
void init_Interupts(void);
unsigned long vrednost_ADC=0;
float temp=0;
unsigned long counter=0;
int main()
{
RCC->APB1ENR|=(1<<0); //TIMER 2
RCC->AHB1ENR|=(1<<0); //GPIOA
RCC->AHB1ENR|=(1<<2); //GPIOC
GPIOA->MODER|=(1<<10);
RCC->APB2ENR|=(1<<5); // USART6[PC6,PC7]
/* Define TIMER-a 3 */
RCC->APB1ENR|=(1<<1); //TIMER 3
GPIOB->MODER|=(1<<9);
GPIOB->AFR[0]|=(1<<17);
TIM2->PSC=89;
TIM2->ARR=0xFFFF;
TIM2->DIER|= (1<<0);
TIM2->EGR|= (1<<0);
Uart6Configuration();
init_PWM();
init_ADC();
init_Interupts();
TIM2->CR1|=(1<<0);
TIM3->CR1|=(1<<0);
while(!(TIM2->SR & (1<<0)));
ADC1->CR2|=(1<<30); // START ADC
/*GLAVNA PROGRAMSKA PETLJA*/
while(1)
{
counter++;
if(counter>100000)
{
printf("AD konverzija=%f \n\r",temp); //Terminal I/O
counter=0;
}
}
/* ************************/
return 0;
}
void TIM2_IRQHandler(void )
{
if(TIM2->SR & TIM_SR_UIF)
{
TIM2->SR &= ~TIM_SR_UIF;
GPIOA->ODR^=(1<<5);
}
TIM2->SR =0;
}
void Uart6Configuration (void)
{
GPIOC->MODER |= (2<<12); // --> Alternate Function for Pin PA11
GPIOC->MODER |= (2<<14); // --> Alternate Function for Pin PA12
GPIOC->OSPEEDR|=(3<<12)|(3<<14);
GPIOC->AFR[0] |= (8<<24); //AF7 bitovi 8,9,10,11 PC6
GPIOC->AFR[0] |= (8<<28); //AF7 bitovi 15,14,13,12 PC7
USART6->CR1=0;
USART6->CR1|=(1<<13);
USART6->CR1 &= ~(1<<12);
USART6->BRR=(3<<0)|(104<<4);
USART6->CR1|=(1<<2);
USART6->CR1|=(1<<3);
}
void send_data (uint8_t c)
{
while(!(USART6->SR & (1<<6)));
USART6->DR=c;
}
uint8_t UART6_GetChar (void)
{
/*********** STEPS FOLLOWED *************
1. Wait for the RXNE bit to set. It indicates that the data has been received and can be read.
2. Read the data from USART_DR Register. This also clears the RXNE bit
****************************************/
uint8_t temp;
while (!(USART2->SR & (1<<5))); // wait for RXNE bit to set
temp = USART2->DR; // Read the data. This clears the RXNE also
return temp;
}
void init_PWM(void)
{
/*PB_4*/
TIM3->PSC=15;
TIM3->ARR=750;
TIM3->CR1|= (1<<5)|(1<<6) | (1<<2); // PWM CENTAR EDGE MODE
TIM3->CCER|=(1<<0); //Capture/Compare 1 output enable.
TIM3->CCR1=500; //DUTY CYCLE
TIM3->CCMR1|=(1<<5)|(1<<6); // PWM MODE bit 5 i6
TIM3->DIER|=(1<<0);
}
void init_ADC(void)
{
RCC->APB2ENR|=(1<<8); // Clock za adc
GPIOA->MODER|=(1<<2)|(1<<3); // Analog mode PA.1
ADC1->SQR3|=(1<<0); // Choose channel ADC1/1
ADC1->CR1|=(1<<5); //EOCIE interupt generates when ADC finish conversion
ADC1->CR2|=(1<<1)|(1<<0); // Continious mode, ADC ON
}
void ADC_IRQHandler(void)
{
vrednost_ADC=ADC1->DR;
temp=(float)((vrednost_ADC/4095.0)*3.3) ;
}
void TIM3_IRQHandler(void )
{
if((TIM3->CNT & 10)<=0) // DETECTOVATI UNDERFLOW
{
TIM3->CCR1=(vrednost_ADC/4095)*1000;
TIM3->EGR|=(1<<0);
}
}
void init_Interupts(void)
{
NVIC_SetPriority (ADC_IRQn, (13));
NVIC_SetPriority (TIM2_IRQn, 14);
NVIC_SetPriority (TIM3_IRQn, 15);
NVIC_EnableIRQ(TIM2_IRQn);
NVIC_EnableIRQ(TIM3_IRQn);
NVIC_EnableIRQ(ADC_IRQn );
}```
I am using LPCXpresso1549 to generate chirp signal with frequency between 35000 Hz and 45000 Hz. First off, I generate DAC chirp samples on matlab, and store them in const uint16_t chirpData[]. The samples frequency is 96000 Hz, therefore 96001 samples. Then, I set the timer to send samples out one by one every (1/96000) second. However, my signal I got having frequency between 3200 Hz to 44000 Hz. Is that because the timer is slow?
enter code here
const uint16_t chirpData[NUM_SAMPLES] = { 2048, ...., 1728, 2048} //96001 sampels
#include "mbed.h"
#include "chirp.h"
Serial pc(USBTX, USBRX);
Timer t;
AnalogOut aout(P0_12);
int main()
{
int i = 0;
while(true) {
// Write the sample to the analog
t.start(); //start timer
if(t.read() >= 0.00001){ // 1/samplef = 0.00001
aout.write_u16(chirpData[i]);
i++;
t.reset(); // reset timer to zero
if(i > 96000) {
i = 0;
}
}
}
}
In this case I recommend you using Threads executing Tasks by:
#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
xTaskHandle taskHandle;
xTaskCreate(..); //Check Task.h
Then you can set your task cycle by
void your_task() {
unsigned task_cycle_ms = 1/freq; //Careful, convert to ms.
portTickType xLastWakeTime = 0;
portTickType xFrequency = task_cycle_ms/portTICK_RATE_MS;
for(;;) {
vTaskDelayUntil( &xLastWakeTime, xFrequency );
//your code to execute every cycle here
}
}
I'm kinda lost here with attaching interrupts for a V3 NodeMCU while programming it with the Arduino IDE.
So I've written this setup code:
void setup() {
//declare output and input pins
pinMode(D4, OUTPUT);
pinMode(D2, INPUT);
attachInterrupt(digitalPinToInterrupt(D2), buttonPressed, CHANGE);
pinMode(D7, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(D7), motionDetected, CHANGE);
//start the serial monitor (test purposes only)
Serial.begin(115200);
//initiate the EEPROM access and check stored values
EEPROM.begin(512);
getSetupVariables();
//setup the wifi connection to previous set SSID and password
setup_wifi();
//set the MQTT server to previous declared values and set the callback function
client.setServer(mqtt_server, 1883);
client.setCallback(handleMQTTCommands);
}
The interrupt ISRs are these two functions:
void buttonPressed() {
if(!isBusy && digitalRead(D2) == HIGH) {
Serial.println("button pressed");
if(targetDoorState == DOOR_STATE_OPEN) {
initiateOperation(DOOR_STATE_CLOSED);
} else if(targetDoorState == DOOR_STATE_CLOSED) {
initiateOperation(DOOR_STATE_OPEN);
}
}
}
void motionDetected() {
char MQTT_channel[100];
char msg[100];
detachInterrupt(D7);
MQTT_CHANNEL_SET_VALUE.toCharArray(MQTT_channel, (MQTT_CHANNEL_SET_VALUE.length() + 1));
if(digitalRead(D7) == HIGH) {
Serial.println("reached");
String MQTT_PAYLOAD_OBSTRUCTION_DETECTED = "{\"name\":\"" + DEVICE_NAME + "\", \"service_name\":\"garagedoor\",\"characteristic\":\"ObstructionDetected\", \"value\":"+ DOOR_STATE_OPEN +"}";
} else if(digitalRead(D7) == LOW) {
String MQTT_PAYLOAD_OBSTRUCTION_DETECTED = "{\"name\":\"" + DEVICE_NAME + "\", \"service_name\":\"garagedoor\",\"characteristic\":\"ObstructionDetected\", \"value\":"+ DOOR_STATE_CLOSED +"}";
}
MQTT_PAYLOAD_OBSTRUCTION_DETECTED.toCharArray(msg, (MQTT_PAYLOAD_OBSTRUCTION_DETECTED.length() + 1));
client.publish(MQTT_channel, msg);
delay(500);
attachInterrupt(digitalPinToInterrupt(D7), motionDetected, CHANGE);
}
So on pin D2 a button is attached. D7 has to listen to changes from a motion sensor. But when the motion sensor is triggered (thus the D7 interrupt needs to happen) both the D2 and D7 interrupt IREs are called. Does anyone have the same problem? Or sees what I'm doing wrong here?
I've tried different NodeMCU boards and all of them have this issue. I also searched for code examples, but all of them implement one attachInterrupt. When I comment out one of them, they work fine...
Thanks in advance!
When I send a request across the UART port from the PC (serial monitor) to the STM32F4 discovery board the signal will not be received. The board should normally answer with the same request which was received before (UART mirroring). I used an interrupt (without DMA) to send or to receive a message. In the interrupt service routine, interrupt flag has been set. This flag will be read in the main loop. I am not using a callback function.
Without the interrupt service (with only HAL_UART_Transmit(...) and HAL_UART_Receive(...) in the main loop) everything works fine. But I want a communication with interrupt.
In the RUN- Mode I have enable breakpoints in the ISR and the two if statements.
I would like to know, whether there is an issue with the ISR routine. But the ISR Routine works as it should be. By a request from the PC the ISR and the receive if statement is called.
The Problem is, that the receive register stay empty. And if this remains empty the controller will not send the request message.
What is wrong? Where is the problem and can you please help me? Is the configuration of the UART Port right?
Thanks for your help & support!
volatile enum RxStates {
UART_RX, DUMMY_RX, WAIT_RX
} stateRx;
volatile enum TxStates {
UART_TX_READY, DUMMY_TX, WAIT_TX
} stateTx;
static UART_HandleTypeDef s_UARTHandle;
GPIO_InitTypeDef GPIOC2_InitStruct; //GPIO
uint8_t empfang[8]; //buffer
void UART_ini(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__USART2_CLK_ENABLE();
//PIN TX
GPIOC2_InitStruct.Pin = GPIO_PIN_2;
GPIOC2_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIOC2_InitStruct.Alternate = GPIO_AF7_USART2;
GPIOC2_InitStruct.Speed = GPIO_SPEED_FAST;
GPIOC2_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIOC2_InitStruct);
//PIN RX
GPIOC2_InitStruct.Pin = GPIO_PIN_3;
GPIOC2_InitStruct.Mode = GPIO_MODE_AF_OD;
HAL_GPIO_Init(GPIOA, &GPIOC2_InitStruct);
//USART2
s_UARTHandle.Instance = USART2;
s_UARTHandle.Init.BaudRate = 9600;
s_UARTHandle.Init.WordLength = UART_WORDLENGTH_8B;
s_UARTHandle.Init.StopBits = UART_STOPBITS_1;
s_UARTHandle.Init.Parity = UART_PARITY_NONE;
s_UARTHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
s_UARTHandle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&s_UARTHandle);
__HAL_UART_ENABLE_IT(&s_UARTHandle, UART_IT_RXNE | UART_IT_TC);
HAL_NVIC_SetPriority(USART2_IRQn, 15, 15);
HAL_NVIC_EnableIRQ(USART2_IRQn); // Enable Interrupt
}//UART
int main(int argc, char* argv[])
{
//initialization of the interrupt flags
stateRx = WAIT_RX;
stateTx = WAIT_TX;
UART_ini(); //initialization UART
while (1)
{
//receive interrupt flag
if (stateRx == UART_RX)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET); //set LED
HAL_UART_Receive(&s_UARTHandle, empfang, 2, 10000000); //receive message
stateRx = WAIT_RX; //RESET flag
}
//transmit interrupt flag
if (stateTx == UART_TX_READY)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET); //set LED
HAL_UART_Transmit(&s_UARTHandle, empfang, 2, 10000); //send message
stateTx = WAIT_TX; //RESET flag
}
//RESET LED
if (stateTx != UART_TX_READY && stateRx != UART_RX)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, RESET); //RESET LED
}
}//while
}//main
void USART2_IRQHandler()
{
if (__HAL_UART_GET_FLAG(&s_UARTHandle, UART_FLAG_RXNE) == SET)
{
__HAL_UART_CLEAR_FLAG(&s_UARTHandle, UART_FLAG_RXNE); //clear ISR flag
stateRx = UART_RX; //set RX flag
}
if (__HAL_UART_GET_FLAG(&s_UARTHandle, UART_FLAG_TC) == SET)
{
__HAL_UART_CLEAR_FLAG(&s_UARTHandle, UART_FLAG_TC); //clear ISR flag
stateTx = UART_TX_READY; //set TX flag
}
}//ISR
//EOF
Look into HAL_UART_Receive function, this function waits for UART_FLAG_RXNE flag but you clear this flag in USART2_IRQHandler
Usually, when you use RX interrupt, you have to save received data into user buffer and then parse it.