/** 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); }
//*---------------------------------------------------------------------------- //* 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; } } }
/** * 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); } }
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 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); }