static inline void STOP_RX_HND(UART_Type *Uart, UART_DRIVER_INFO * drv_info, HANDLE hnd) { STOP_RX(Uart); drv_info->drv_data->hnd_rcv = hnd->next; hnd->len = drv_info->drv_data->rx_remaining; usr_HND_SET_STATUS(hnd, RES_SIG_OK); if( (hnd=drv_info->drv_data->hnd_rcv) ) START_RX_HND(Uart, drv_info, hnd); else START_RX_BUF(Uart, drv_info, drv_info->drv_data); }
/** Stop receiving hnd * * @param pUsart * @param drv_data * @param hnd */ static void STOP_RX_HND(Usart* pUsart, UART_DRIVER_DATA drv_data, HANDLE hnd) { STOP_RX(pUsart); drv_data->hnd_rcv = hnd->next; hnd->len =pUsart->US_RCR; hnd->dst.as_int = pUsart->US_RPR; usr_HND_SET_STATUS(hnd, RES_SIG_OK); if( (hnd=drv_data->hnd_rcv) ) START_RX_HND(pUsart, drv_data, hnd); else START_RX_BUF(pUsart, drv_data); }
/** * USART DSR * @param drv_info * @param hnd */ void USART_DSR(USART_INFO drv_info, HANDLE hnd) { UART_DRIVER_DATA drv_data = drv_info->drv_data; unsigned char *ptr; signed int size; if(hnd->len) { hnd->next = NULL; if (hnd->cmd & FLAG_READ) { if(drv_data->hnd_rcv) { hnd->list_add(drv_data->hnd_rcv); return; } STOP_RX(drv_info->hw_base); //try to read from buffer ptr = (unsigned char*) (drv_info->hw_base->US_RPR); if (ptr != drv_data->rx_ptr) { if (ptr < drv_data->rx_ptr) { size = min(hnd->len, drv_info->buf_size - (drv_data->rx_ptr - drv_data->rx_buf)); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; if(drv_data->rx_ptr == &drv_data->rx_buf[drv_info->buf_size]) drv_data->rx_ptr = drv_data->rx_buf; } if (hnd->len && (ptr > drv_data->rx_ptr)) { size =min(hnd->len, ptr - drv_data->rx_ptr); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; } } if (hnd->len ) { //receive directly drv_data->hnd_rcv = hnd; START_RX_HND(drv_info->hw_base, drv_data, hnd); } else { RESUME_RX(drv_info->hw_base); svc_HND_SET_STATUS(hnd, RES_SIG_OK); } } else { if (hnd->cmd & FLAG_WRITE) { if(drv_data->hnd_snd) { hnd->list_add(drv_data->hnd_snd); } else { drv_data->hnd_snd = hnd; START_TX_HND(drv_info->hw_base, hnd); } } else { svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); } } } else { svc_HND_SET_STATUS(hnd, RES_SIG_IDLE); } }
/** USART DCR * * @param drv_info * @param reason * @param param */ void USART_DCR(USART_INFO drv_info, unsigned int reason, HANDLE param) { UART_DRIVER_DATA drv_data = drv_info->drv_data; unsigned int temp; switch(reason) { case DCR_RESET: drv_data->buf_size = drv_info->buf_size; USART_OFF(drv_info); break; case DCR_OPEN: { DRV_UART_MODE pMode = (DRV_UART_MODE)(param->mode.as_voidptr); if(pMode) { if(drv_data->cnt) { if( (pMode->mode != drv_data->mode) || (pMode->baudrate != drv_data->baudrate)) return; } else { drv_data->mode = pMode->mode; drv_data->baudrate =pMode->baudrate; USART_CFG(drv_info, pMode); START_RX_BUF(drv_info->hw_base, drv_data); } drv_data->cnt++; param->res = RES_OK; } break; } case DCR_CLOSE: if(drv_data->cnt) if(!--drv_data->cnt) USART_OFF(drv_info); break; case DCR_CANCEL: { if (param->cmd & FLAG_READ) { if(param == drv_data->hnd_rcv) { STOP_RX(drv_info->hw_base); temp = drv_info->hw_base->US_RCR; if(param->len > temp) { param->len = temp; param->dst.as_int = drv_info->hw_base->US_RPR; temp = RES_OK; } else temp = RES_SIG_IDLE; drv_data->hnd_rcv = param->next; if( drv_data->hnd_rcv ) START_RX_HND(drv_info->hw_base, drv_data, drv_data->hnd_rcv); else START_RX_BUF(drv_info->hw_base, drv_data); svc_HND_SET_STATUS(param, temp); } else param->svc_list_cancel(drv_data->hnd_rcv); } else { if(param == drv_data->hnd_snd) { STOP_TX(drv_info->hw_base); temp = drv_info->hw_base->US_TCR; if(param->len > temp) { param->len = temp; param->src.as_int = drv_info->hw_base->US_TPR; temp = RES_OK; } else temp = RES_SIG_IDLE; drv_data->hnd_snd = param->next; if( drv_data->hnd_snd ) START_TX_HND(drv_info->hw_base, drv_data->hnd_snd); svc_HND_SET_STATUS(param, temp); } else param->svc_list_cancel(drv_data->hnd_snd); } break; } case DCR_CLOCK: if(drv_data->cnt) drv_info->hw_base->US_BRGR = AT91_GetDiv(drv_data->baudrate); break; } }
void dsr_SerialDriver(UART_DRIVER_INFO* drv_info, HANDLE hnd) { unsigned char *ptr; signed int size; UART_DRIVER_DATA *drv_data = drv_info->drv_data; UART_Type * Uart = drv_info->hw_base; hnd->next = NULL; if (hnd->cmd & FLAG_READ) { hnd->mode0 = 0; // няма нищо прието в хендъла if(drv_data->hnd_rcv) { hnd->list_add(drv_data->hnd_rcv); return; } STOP_RX(Uart); //try to read from buffer ptr = drv_data->rx_wrptr; if( hnd->len && (ptr!= drv_data->rx_ptr) ) { if(ptr < drv_data->rx_ptr) { size =min(hnd->len, (unsigned int)(&drv_data->rx_buf[RX_BUF_SIZE]) - (unsigned int)drv_data->rx_ptr); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->mode0 = 1; // в хендъла е писано hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; if(drv_data->rx_ptr == &drv_data->rx_buf[RX_BUF_SIZE]) drv_data->rx_ptr = drv_data->rx_buf; } if( hnd->len && (ptr!= drv_data->rx_ptr) ) { size =min(hnd->len, ptr - drv_data->rx_ptr); hnd->mode0 = 1; // в хендъла е писано memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; } } if (hnd->len == 0) { RESUME_RX(Uart); svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } //receive directly hnd->res = RES_BUSY; drv_data->hnd_rcv = hnd; START_RX_HND(Uart, drv_info, hnd); return; } if (hnd->cmd & FLAG_WRITE) { if(hnd->len) { if(drv_data->hnd_snd) { hnd->list_add(drv_data->hnd_snd); return; } hnd->res = RES_BUSY; drv_data->hnd_snd = hnd; START_TX_HND(Uart, hnd); } else svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
void dcr_SerialDriver(UART_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd) { UART_Type * Uart = drv_info->hw_base; UART_DRIVER_DATA *drv_data = drv_info->drv_data; switch(reason) { case DCR_ISR: TX_CTS(drv_data, Uart, (unsigned int)hnd); return; case DCR_RESET: SysCtlPeripheralReset(drv_info->info.peripheral_indx); SysCtlPeripheralDisable(drv_info->info.peripheral_indx); // ??? turn off return; case DCR_OPEN: { UART_DRIVER_MODE *uart_mode = (UART_DRIVER_MODE *)(hnd->mode.as_voidptr); if(uart_mode) { //unsigned long mode, baudrate; if(drv_data->cnt) { if( uart_mode->mode != drv_data->mode.mode || uart_mode->baudrate != drv_data->mode.baudrate || uart_mode->hw_flow != drv_data->mode.hw_flow ) { return; } } else { // Enable AND Reset the UART peripheral SysCtlPeripheralReset(drv_info->info.peripheral_indx); if(drv_data->mode.hw_flow) { PIO_Cfg_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_ALL_PINS]); ConfigureUart(drv_info, drv_data, uart_mode); #ifdef HW_VER_10 if(drv_info->info.drv_index != UART1_IRQn) TX_CTS(drv_data, Uart, PIO_Read(drv_info->uart_pins[CTS_PIN])); #endif } else { PIO_Cfg_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_RX_TX_PINS]); ConfigureUart(drv_info, drv_data, uart_mode); } START_RX_BUF(Uart, drv_info, drv_data); } drv_data->cnt++; hnd->res = RES_OK; } return; } case DCR_CLOSE: if(drv_data->cnt) drv_data->cnt--; case DCR_CANCEL: { if( !(hnd->res & FLG_BUSY)) return; if (hnd->cmd & FLAG_READ) { if(hnd == drv_data->hnd_rcv) { STOP_RX(Uart); if(hnd->len > drv_data->rx_remaining || hnd->mode0 ) { hnd->len = drv_data->rx_remaining; hnd->res = RES_SIG_OK; } else hnd->res = RES_SIG_IDLE; drv_data->hnd_rcv = hnd->next; svc_HND_SET_STATUS(hnd, hnd->res); if( (hnd=drv_data->hnd_rcv) ) START_RX_HND(Uart, drv_info, hnd); else START_RX_BUF(Uart, drv_info, drv_data); } else { // try cnacel hnd->svc_list_cancel(drv_data->hnd_rcv); } } else { if(hnd == drv_data->hnd_snd) { STOP_TX(Uart); drv_data->hnd_snd = hnd->next; svc_HND_SET_STATUS(hnd, RES_SIG_IDLE); if( (hnd=drv_data->hnd_snd) ) START_TX_HND(Uart, hnd); } else { hnd->svc_list_cancel(drv_data->hnd_snd); } } if(!drv_data->cnt) { NVIC->NVIC_DisableIRQ(drv_info->info.drv_index); Uart->UARTDisable(); STOP_RX(Uart); STOP_TX(Uart); SysCtlPeripheralDisable(drv_info->info.peripheral_indx); SYSCTL->SysCtlPeripheralDeepSleepDisable(drv_info->info.peripheral_indx); SYSCTL->SysCtlPeripheralSleepDisable(drv_info->info.peripheral_indx); if(drv_data->mode.hw_flow) PIO_Free_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_ALL_PINS]); else PIO_Free_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_RX_TX_PINS]); } return; } case DCR_CLOCK: return; } }