void DAC_DSR(DAC_DRIVER_INFO* drv_info, HANDLE hnd) { DAC_DRIVER_DATA* drv_data = drv_info->drv_data; DAC_TypeDef* dac = drv_info->hw_base; DAC_DRIVER_MODE *dac_mode = (DAC_DRIVER_MODE *)(hnd->mode.as_voidptr); uint32_t* dac_reg; hnd->next = NULL; if (hnd->cmd & FLAG_WRITE) { if(hnd->len >= dac_mode->dac_size) { hnd->res = RES_BUSY; drv_data->pending[dac_mode->dac_ch] = hnd; dac_reg = (uint32_t*)(void*)(dac_mode->dac_reg + (char*)dac); #if USE_DAC_DMA_DRIVER if(drv_data->dac_dma_hnd[dac_mode->dac_ch].res < RES_BUSY) { drv_data->dac_dma_hnd[dac_mode->dac_ch].drv_read_write(dac_reg, hnd->src.as_charptr, hnd->len); return; } #endif if(dac_mode->dac_size == 1) *dac_reg = *hnd->src.as_charptr++; else *dac_reg = *hnd->src.as_shortptr++; hnd->len -= dac_mode->dac_size; } svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
/** * Driver helper function * @param base * @return */ bool CHandle::svc_list_cancel(HANDLE& base) { if(list_remove(base)) { svc_HND_SET_STATUS(this, RES_SIG_IDLE); return (true); } return (false); }
//*---------------------------------------------------------------------------- //* DCR function //*---------------------------------------------------------------------------- void GUI_DCR(GUI_DRIVER_INFO* drv_info, unsigned int reason, HANDLE param) { GUI_DRIVER_DATA* drv_data; WINDOW win = (WINDOW)param; drv_data = drv_info->drv_data; switch(reason) { case DCR_RESET: display_init(drv_info); break; case DCR_OPEN: if(win->mode.as_int) { // WINDOW objects win->rect.x0 = 0; win->rect.y0 = 0; // win->rect.x1 = drv_info->lcd->size_x; // win->rect.y1 = drv_info->lcd->size_y; } win->res = RES_OK; break; case DCR_HANDLE: if(win->mode.as_int) { locked_set_byte(&win->mode0, FLG_OK); svc_send_signal(&gui_task, SIG_GUI_TASK); } break; case DCR_CANCEL: if(win->mode.as_int) { // this is WINDOW handle... locked_set_byte(&win->mode0, FLG_SIGNALED); win->svc_list_cancel(drv_data->waiting); } else { // not a WINDOW if(win == drv_data->helper) { //the helper task is waiting for object... drv_data->helper = NULL; win->dst.as_voidptr = NULL; svc_HND_SET_STATUS(win, RES_SIG_OK); } } break; } }
//*---------------------------------------------------------------------------- //* DSR function //*---------------------------------------------------------------------------- void GUI_DSR(GUI_DRIVER_INFO* drv_info, HANDLE hnd) { GUI_DRIVER_DATA* drv_data = drv_info->drv_data; HANDLE tmp; if(hnd->mode.as_int) { // this is GUI_OBJECT handle... hnd->res = RES_BUSY; hnd->mode0 = 0; hnd->mode1 = 0; if( (tmp=drv_data->helper) ) { //the helper task is waiting for object... hnd->next = NULL; drv_data->helper = NULL; tmp->dst.as_voidptr = hnd; svc_HND_SET_STATUS(tmp, RES_SIG_OK); } else { //queue the WINDOW object while helper task is busy hnd->next = drv_data->waiting; drv_data->waiting = hnd; } } else { // not a WINDOW object // this should be the helper task reading the waiting WINDOW objects if( (tmp=drv_data->waiting) ) { drv_data->waiting = NULL; hnd->dst.as_voidptr = tmp; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { hnd->res = RES_BUSY; drv_data->helper = hnd; } } }
void EXTI_DSR(EXTI_DRIVER_INFO* drv_info, HANDLE hnd) { PIN_DESC* pin; pin = (PIN_DESC*)hnd->mode.as_voidptr; if(hnd->cmd & FLAG_WRITE) { pin = (PIN_DESC*)hnd->mode.as_voidptr; while( *pin && hnd->len > 1) { // write on virtual ports is not supported through handles if (PD_PORT_Get(*pin) <= PD_LAST_PORT) PIO_Write(*pin, *hnd->src.as_shortptr); pin ++; hnd->src.as_shortptr++; hnd->len -=2; } svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } if(hnd->cmd & FLAG_READ) { if(hnd->cmd & FLAG_LOCK) { if(!(hnd->mode0 == PIOHND_INTPENDING)) { hnd->mode0 = PIOHND_WAITING; hnd->res = RES_BUSY; return; } } hnd->mode0 = PIOHND_IDLE; read_handle(hnd); svc_HND_SET_STATUS(hnd, RES_SIG_OK); } }
//*---------------------------------------------------------------------------- //* DSR function //*---------------------------------------------------------------------------- void CAN_DSR(CAN_INFO drv_info, HANDLE hnd) { CAN_DRIVER_DATA* drv_data = drv_info->drv_data; HANDLE tmp; if(hnd->mode.as_int) { // this is a CAN handle... hnd->next = NULL; if( (tmp=drv_data->helper) ) { //the helper task is waiting for object... hnd->res = RES_BUSY; drv_data->helper = NULL; tmp->dst.as_voidptr = hnd; svc_HND_SET_STATUS(tmp, RES_SIG_OK); } else { //queue the client handle while the helper task is busy hnd->list_add(drv_data->waiting); } } else { // this must be the helper if( (tmp=drv_data->waiting) ) { drv_data->waiting = tmp->next; hnd->dst.as_voidptr = tmp; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { hnd->res = RES_BUSY; drv_data->helper = hnd; } } }
/** DACC Driver DCR routine * * @param drv_info * @param reason * @param param */ void DACC_DCR(DACC_INFO drv_info, unsigned int reason, HANDLE param) { DACC_DRIVER_DATA drv_data = drv_info->drv_data; Dacc* pDacc = drv_info->hw_base; switch(reason) { case DCR_RESET: DACC_off(drv_info); break; case DCR_OPEN: { DRV_DACC_MODE pMode = (DRV_DACC_MODE)(param->mode.as_voidptr); if(drv_data->cnt) { if(pMode->DACC_MR != pDacc->DACC_MR) return; } else { DACC_on(drv_info, pMode); } pDacc->DACC_CHER = pMode->DACC_CHER; drv_data->cnt++; param->res = RES_OK; break; } case DCR_CLOSE: if(!--drv_data->cnt) DACC_off(drv_info); break; case DCR_CANCEL: if (drv_data->pending == param) { pDacc->DACC_PTCR = DACC_PTCR_TXTDIS; drv_data->pending = param->next; if(drv_data->pending) START_TX_HND(pDacc, drv_data->pending); svc_HND_SET_STATUS(param, RES_SIG_IDLE); } else param->svc_list_cancel(drv_data->pending); break; } }
//*---------------------------------------------------------------------------- //* DCR function //*---------------------------------------------------------------------------- void KEY2_DCR(KEY2_DRIVER_INFO* drv_info, unsigned int reason, HANDLE param) { KEY2_DRIVER_DATA* drv_data; drv_data = drv_info->drv_data; switch(reason) { case DCR_RESET: drv_data->key_in = 0; drv_data->key_out = 0; usr_task_init_static(&keyboard_task_desc, true); keyboard_task.sp->r0.as_cvoidptr = drv_info; break; case DCR_OPEN: param->res = RES_OK; break; case DCR_CANCEL: param->svc_list_cancel(drv_data->waiting); break; case DCR_PARAMS: //keycode sent from thread { HANDLE hnd = drv_data->waiting; if( hnd ) { // send the code to the waiting *hnd->dst.as_byteptr++ = (unsigned int)param; drv_data->waiting = hnd->next; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { // store the code in the key_buf drv_data->key_buf[drv_data->key_in] = (unsigned int)param; drv_data->key_in = (drv_data->key_in+1) & DRV_KEYBUF_SIZE; } } break; } }
//*---------------------------------------------------------------------------- //* DSR function //*---------------------------------------------------------------------------- void KEY2_DSR(KEY2_DRIVER_INFO* drv_info, HANDLE hnd) { KEY2_DRIVER_DATA* drv_data = drv_info->drv_data; if (drv_data->key_in == drv_data->key_out) { hnd->next = drv_data->waiting; hnd->res = RES_BUSY; drv_data->waiting = hnd; } else { *hnd->dst.as_byteptr++ = drv_data->key_buf[drv_data->key_out]; drv_data->key_out = (drv_data->key_out + 1) & DRV_KEYBUF_SIZE; hnd->len--; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } }
/** DACC Driver DSR routine * * @param drv_info * @param hnd */ void DACC_DSR(DACC_INFO drv_info, HANDLE hnd) { DACC_DRIVER_DATA drv_data = drv_info->drv_data; if(hnd->len) { if(drv_data->pending) { hnd->list_add(drv_data->pending); } else { hnd->next = NULL; drv_data->pending = hnd; START_TX_HND(drv_info->hw_base, hnd); } }else svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
/** * 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); } }
/** * DSR * @param drv_info * @param hnd */ void WDT_DSR(WDT_INFO drv_info, HANDLE hnd) { svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
/** 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 EXTI_DCR(EXTI_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd) { EXTI_DRIVER_DATA * drv_data = drv_info->drv_data ; const PIN_DESC* pin; unsigned int lines; switch( reason ) { case DCR_ISR: { lines = (unsigned int)hnd; //lines with edge // loop waiting handles for(hnd = drv_data->waiting; hnd; hnd = hnd->next) { // loop pin description list in the handle for(pin = (PIN_DESC*)hnd->mode.as_voidptr; *pin; pin++) { if(lines & *pin) { if(hnd->mode0 == PIOHND_WAITING) { hnd->mode0 = PIOHND_IDLE; read_handle(hnd); svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else hnd->mode0 = PIOHND_INTPENDING; break; //done with this handle } } } } break; case DCR_OPEN: { //Enable AFIO/SYSCFG... RCCPeripheralEnable(drv_info->info.peripheral_indx); pin = (PIN_DESC *)hnd->mode.as_voidptr; hnd->list_add(drv_data->waiting); hnd->mode0 = PIOHND_IDLE; while(*pin) { unsigned int pin_pattern, pos; PIO_Cfg(*pin); if(PD_MODE_Get(*pin) == PD_MODE_INPUT) { if(PD_INT_Get(*pin)) { pin_pattern = PD_PINS_Get(*pin); while(pin_pattern) { pos = 31 - __CLZ(pin_pattern); lines = 1 << pos; pin_pattern ^= lines; pos = stm_get_drv_indx(pos); // Handles can be open with any EXTI driver, so check // here if the actual driver is installed int adr = (int)DRV_TABLE[pos]; adr &= ~3; const EXTI_DRIVER_INFO* info; info = (const EXTI_DRIVER_INFO*)adr; if(info->info.isr == (DRV_ISR)EXTI_ISR) { drv_enable_isr(&info->info); /* Clear Rising Falling edge configuration */ info->hw_base->EXTI_RTSR &= ~lines; info->hw_base->EXTI_FTSR &= ~lines; exti_set_line_source(31 - __CLZ(lines), PD_PORT_Get(*pin)); /* Select the trigger for the selected external interrupts */ if(*pin & PD_INT_FE) // falling edge info->hw_base->EXTI_FTSR |= lines; if(*pin & PD_INT_RE) // rising edge info->hw_base->EXTI_RTSR |= lines; /* Enable line interrupt */ info->hw_base->EXTI_IMR |= lines; } } } } pin++; } hnd->res = RES_OK; } break; case DCR_CLOSE: { PIO_Cfg_List((PIN_DESC*)hnd->mode.as_voidptr); hnd->list_remove(drv_data->waiting); } break; case DCR_CANCEL: if (hnd->res & FLG_BUSY) { read_handle(hnd); svc_HND_SET_STATUS(hnd, RES_SIG_CANCEL); } break; case DCR_RESET: NVIC_DisableIRQ(drv_info->info.drv_index); RCCPeripheralReset(drv_info->info.peripheral_indx); RCCPeripheralDisable(drv_info->info.peripheral_indx); // turn off break; default: break; } }
void USB_DSR(USB_DRV_INFO drv_info, HANDLE hnd) { HANDLE tmp; USB_DRIVER_DATA* drv_data = drv_info->drv_data; hnd->next = NULL; hnd->res = RES_BUSY; if (hnd->cmd & FLAG_COMMAND) { if(hnd->mode.as_voidptr) { // this is a client handle... if( (tmp=drv_data->helper) ) { //the helper task is waiting for object... drv_data->helper = NULL; tmp->dst.as_voidptr = hnd; svc_HND_SET_STATUS(tmp, RES_SIG_OK); } else { //queue while helper task is busy hnd->next = drv_data->waiting; drv_data->waiting = hnd; } } else { // this should be the helper task if( (tmp=drv_data->waiting) ) { drv_data->waiting = tmp->next; hnd->dst.as_voidptr = tmp; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { drv_data->helper = hnd; } } return; } #if USB_ENABLE_OTG if(hnd->mode.as_ushort[1] != drv_data->drv_state_cnt) { //driver state has changed, handle must update... svc_HND_SET_STATUS(hnd, FLG_SIGNALED | RES_FATAL); return; } #endif if (hnd->cmd & FLAG_WRITE) { usb_drv_start_tx(drv_info, hnd); return; } if (hnd->cmd & FLAG_READ) { usb_drv_start_rx(drv_info, hnd); return; } svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
void DAC_DCR(DAC_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd) { DAC_DRIVER_DATA *drv_data = drv_info->drv_data; DAC_DRIVER_MODE *dac_mode = (DAC_DRIVER_MODE *)(hnd->mode.as_voidptr); switch(reason) { case DCR_RESET: RCCPeripheralReset(drv_info->info.peripheral_indx); RCCPeripheralDisable(drv_info->info.peripheral_indx); // ??? turn off #if USE_DAC_DMA_DRIVER drv_data->dac_dma_hnd[0].client.drv_index = drv_info->info.drv_index; drv_data->dac_dma_hnd[1].client.drv_index = drv_info->info.drv_index; #endif break; case DCR_OPEN: { if(dac_mode && dac_mode->dac_ch <2 && drv_data->dac_mode[dac_mode->dac_ch] == NULL) { if(!drv_data->dac_mode[0] && !drv_data->dac_mode[1]) { if(!ConfigureDac(drv_info)) break; } ConfigureDacChannel(drv_info->hw_base, dac_mode); drv_data->dac_mode[dac_mode->dac_ch] = dac_mode; hnd->res = RES_OK; } break; } case DCR_CLOSE: #if USE_DAC_DMA_DRIVER drv_data->dac_dma_hnd[dac_mode->dac_ch].close(); #endif drv_data->dac_mode[dac_mode->dac_ch] = NULL; if(!drv_data->dac_mode[0] && !drv_data->dac_mode[1]) { //Disable ? NVIC_DisableIRQ(drv_info->info.drv_index); RCCPeripheralDisable(drv_info->info.peripheral_indx); PIO_Free_List(drv_info->dac_pins); } break; case DCR_CANCEL: // can only cancel dma transfers #if USE_DAC_DMA_DRIVER if(drv_data->dac_dma_hnd[dac_mode->dac_ch].res & FLG_BUSY) drv_data->dac_dma_hnd[dac_mode->dac_ch].hcontrol(DCR_CANCEL); #endif break; case DCR_SIGNAL: #if USE_DAC_DMA_DRIVER TRACELN1("DAC sig"); if(hnd == &drv_data->dac_dma_hnd[0]) { hnd = drv_data->pending[0]; if(hnd) { if(hnd->len > drv_data->dac_dma_hnd[0].len) { hnd->src.as_byteptr += hnd->len - drv_data->dac_dma_hnd[0].len; hnd->len = drv_data->dac_dma_hnd[0].len; } drv_data->pending[0] = NULL; if (__get_CONTROL() & 2) usr_HND_SET_STATUS(hnd, RES_SIG_OK); else svc_HND_SET_STATUS(hnd, RES_SIG_OK); } } else { if(hnd == &drv_data->dac_dma_hnd[1]) { hnd = drv_data->pending[1]; if(hnd) { if(hnd->len > drv_data->dac_dma_hnd[1].len) { hnd->src.as_byteptr += hnd->len - drv_data->dac_dma_hnd[1].len; hnd->len = drv_data->dac_dma_hnd[1].len; } drv_data->pending[1] = NULL; usr_HND_SET_STATUS(hnd, RES_SIG_OK); } } } #endif break; } }
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; } }
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); }