static int mdc_adc_load(uint16 *buf, uint8 channle) { OSAL_ASSERT(buf != NULL); OSAL_ASSERT(channle <= SLOT_NUM); bsp_adc0_load(buf, channle, 0); return 0; }
void DRV_USART_Close ( DRV_HANDLE handle) { /* This function closes the client, The client object is de-allocated and returned to the pool. */ DRV_USART_CLIENT_OBJ * clientObj; DRV_USART_OBJ * dObj; /* Validate the handle */ clientObj = _DRV_USART_DriverHandleValidate(handle); if(clientObj == NULL) { /* Driver handle is not valid */ SYS_DEBUG(0, "Invalid Driver Handle"); return; } dObj = (DRV_USART_OBJ *)clientObj->hDriver; /* Remove all buffers that this client owns from the driver queue. This function will map to _DRV_USART_ClientBufferQueueObjectsRemove() if the driver was built for buffer queue support. Else this condition always maps to true. */ if(!_DRV_USART_CLIENT_BUFFER_QUEUE_OBJECTS_REMOVE(clientObj)) { /* The function could fail if the mutex time out occurred */ SYS_DEBUG(0, "Could not remove client buffer objects"); clientObj->status = DRV_USART_CLIENT_STATUS_ERROR; return; } /* Deallocate all semaphores */ OSAL_ASSERT((OSAL_SEM_Delete(&(clientObj->semWriteDone)) == OSAL_RESULT_TRUE), "Unable to delete client write done semaphore"); OSAL_ASSERT((OSAL_SEM_Delete(&(clientObj->semReadDone)) == OSAL_RESULT_TRUE), "Unable to delete client read done semaphore"); /* Reduce the number of clients */ dObj->nClients --; /* De-allocate the object */ clientObj->status = DRV_USART_CLIENT_STATUS_CLOSED; clientObj->inUse = false; return; }
void dis_print_scroll(uint8 line) { char buf[LCD_LINE_LEN + 1] = {0}; size_t size = 0; uint8 len = 0; uint8 j; OSAL_ASSERT(gSrollBuf != NULL); size = strlen(gSrollBuf); //SYS_TRACE("dis_print_scroll:[%d]->%s\r\n", size, gSrollBuf); len = size > LCD_LINE_LEN ? LCD_LINE_LEN: size; strncpy(buf, gSrollBuf, len); if(len > 1){ gSrollBuf++; }else{ gSrollBuf = gSystem_t->sroll_buf; } lcd_write_cmd(line); for(j = 0; j < LCD_LINE_LEN; j++){ if(buf[j] == 0){ lcd_write_data(' '); }else{ lcd_write_data(buf[j]); } } }
static menu_t *menu_list_add_next(menu_t **head, menu_id_t id) { menu_t *menu; menu_t *p = *head; menu = (menu_t *)MALLOC(sizeof(menu_t)); OSAL_ASSERT(menu != NULL); menu->id = id; menu->state = MENU_NORMAL; menu->child = NULL; menu->parent = NULL; menu->next = NULL; menu->prev = NULL; if(*head){ while(p->next){ p = p->next; } p->next = menu; menu->prev = p; }else{ *head = menu; } return menu; }
int eeprom_write(uint32 addr, uint8 *buf, size_t size) { uint8 write_size; size_t index = 0; OSAL_ASSERT(buf != NULL); do{ if(size > EPROM_PAGE_SIZE){ write_size = EPROM_PAGE_SIZE; }else{ write_size = size; } if(osal_iic_write_buf(EPROM, addr, buf, write_size) < 0){ return -1; } buf += write_size; index += write_size; addr += write_size; bsp_delay_ms(50); }while(index < size); return size; }
bool Is_ring_buffer_empty(ringbuf_device_t index) { ring_buffer_t *p; OSAL_ASSERT(index < DEVICE_NUM); p = ring_list[index]; return (p->read == p->write); }
size_t ring_buffer_len(ringbuf_device_t index) { ring_buffer_t *p; OSAL_ASSERT(index < DEVICE_NUM); p = ring_list[index]; if(p->write >= p->read) return (p->write - p->read); else return(RING_BUF_SIZE + p->write - p->read); }
int eeprom_read(uint32 addr, uint8 *buf, size_t size) { OSAL_ASSERT(buf != NULL); if(osal_iic_read_buf(EPROM, addr, buf, size) < 0){ return -1; } return size; }
static int mdc_slot_init(mdc_slot_state_t *slot, mdc_type_t type, uint8 index) { OSAL_ASSERT(index < SLOT_NUM); slot->index = index; switch(type){ case MDC_DIO: slot->type = MDC_DIO; slot->max_input = DIO_INPUT_N; slot->str_cmd = DEF_DIO_CMD[index]; slot->input = DIO_INPUT_COAX1; break; case MDC_USB: slot->type = MDC_USB; slot->max_input = USB_INPUT_N; slot->str_cmd = DEF_USB_CMD[index]; slot->input = USB_INPUT_PC; break; case MDC_HDMI: slot->type = MDC_HDMI; slot->max_input = HDMI_INPUT_N; slot->str_cmd = DEF_HDMI_CMD[index]; slot->input = HDMI_INPUT_1; break; case MDC_ANA: slot->type = MDC_ANA; slot->max_input = ANA_INPUT_N; slot->str_cmd = DEF_ANA_CMD[index]; slot->input = ANA_INPUT_PHONO; break; case MDC_BLUOS: slot->type = MDC_BLUOS; slot->max_input = BT_INPUT_N; slot->str_cmd = DEF_BLU_CMD[index]; slot->input = BT_INPUT; break; case MDC_HDMI_v2: slot->type = MDC_HDMI_v2; slot->max_input = HDMI_V2_INPUT_N; slot->str_cmd = DEF_HDMI_V2_CMD[index]; slot->input = HDMI_V2_INPUT_1; break; default: break; } return 0; }
static void dis_blu_status_menu_handler(sys_state_t *sys, uint8 para) { dis_print(LCD_LINE_1,ALIGN_CENTER, "%s", gCurSrc->src_name); OSAL_ASSERT(para < MDC_BLU_STATUS_NUM); if(para == 0){ dis_print(LCD_LINE_2,ALIGN_CENTER, "Volume %.1fdB", sys->master_vol); }else{ dis_print(LCD_LINE_2,ALIGN_CENTER, "%s", blu_status[para]); } }
size_t ring_buffer_peek_read(ringbuf_device_t index, uint8 *buf, size_t len) { ring_buffer_t *p; uint8 read; uint8 size; uint8 j; uint8 l; OSAL_ASSERT(buf != NULL); OSAL_ASSERT(index < DEVICE_NUM); p = ring_list[index]; read = p->read; size = ring_buffer_len(index); l = ((len >= size) ? size : len); for(j = 0; j < l; j++){ *buf++ = p->buffer[read]; read = (read + 1) % RING_BUF_SIZE; } return l; }
void ring_buffer_write(ringbuf_device_t index, uint8 ch) { ring_buffer_t *p; uint8 next = 0; OSAL_ASSERT(index < DEVICE_NUM); p = ring_list[index]; next = (p->write + 1) % RING_BUF_SIZE; /*ring buf is full*/ if(p->read == next) return; p->buffer[p->write] = ch; p->write = next; }
uint8 ring_buffer_read(ringbuf_device_t index) { uint8 byte = 0; ring_buffer_t *p; OSAL_ASSERT(index < DEVICE_NUM); p = ring_list[index]; /*the buffer is empty, just return 0*/ if(p->read == p->write) return 0; byte = p->buffer[p->read]; p->read = (p->read + 1) % RING_BUF_SIZE; return byte; }
static void mdc_prepare_test_environment(sys_state_t *sys, uint8 slot) { mdc_test_t *p = NULL; /*only do this once*/ if(sys->mdc_test == NULL){ p = (mdc_test_t *)MALLOC(sizeof(mdc_test_t)); OSAL_ASSERT(p != NULL); memset(p, 0, sizeof(mdc_test_t)); p->start_index = slot; p->cur_index = slot; p->item = TEST_ITEM_I2C; sys->mdc_test = (void *)p; // AC_STANDBY(1); // DC5V_EN(1); // DC3V_EN(1); mdc_power_set((mdc_slot_t)slot, ON); SYS_TRACE("mdc test environment prepared.\r\n"); } p->bitmap_insert |= (1 << slot); p->num++; }
size_t DRV_USART_Read(const DRV_HANDLE hClient, void * destination, size_t nBytes) { DRV_USART_CLIENT_OBJ * clientObj; DRV_USART_OBJ * hDriver; USART_MODULE_ID plibID; DRV_USART_BUFFER_OBJ * iterator, * bufferObj; size_t count = 0; uint8_t * data; bool status; /* Validate the driver handle */ clientObj = _DRV_USART_DriverHandleValidate(hClient); if(clientObj == NULL) { SYS_DEBUG(0, "Invalid driver handle"); return 0; } hDriver = (DRV_USART_OBJ *)clientObj->hDriver; plibID = hDriver->moduleId; if(!(clientObj->ioIntent & DRV_IO_INTENT_READ)) { /* This client did not open the driver for reading */ SYS_DEBUG(0, "Driver not opened for read"); return 0; } if((destination == NULL) || (nBytes == 0)) { /* We have a NULL pointer or dont have any data to write. */ SYS_DEBUG(0, "NULL data pointer or no data to write"); return 0; } data = (uint8_t *)destination; /* Grab he hardware instance mutex */ if(OSAL_MUTEX_Lock(hDriver->mutexDriverInstance, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { if(!(clientObj->ioIntent & DRV_IO_INTENT_NONBLOCKING)) { /* This is a blocking implementation. We populate the client buffer object and add it to the queue. We then wait till the buffer is completely processed. */ /* Because we are modifying the queue, we should disable the interrupt */ status = _DRV_USART_InterruptSourceDisable(hDriver->rxInterruptSource); /* Get the queue head */ iterator = hDriver->queueRead; /* If the queue is not empty, get to the end of the queue */ if(iterator != NULL) { while(iterator->next != NULL) { iterator = iterator->next; } } /* We should be at the end of the queue now. Populate the client buffer object */ bufferObj = &clientObj->bufferObject; bufferObj->buffer = destination; bufferObj->nCurrentBytes = 0; bufferObj->size = nBytes; bufferObj->inUse = true; bufferObj->hClient = clientObj; bufferObj->flags = (0 | DRV_USART_BUFFER_OBJ_FLAG_READ_WRITE); /* Add this object to the queue and enable the RX interrupt */ bufferObj->previous = iterator; bufferObj->next = NULL; /* If we are not at the start of the queue, then update the next pointer of the last object else set the queue head to point to this object */ if(hDriver->queueRead == NULL) { hDriver->queueRead = bufferObj; } else { iterator->next = bufferObj; bufferObj->previous = iterator; } /* Now enable the interrupt and release the mutex so that the system can proceed */ _DRV_USART_InterruptSourceEnable(hDriver->rxInterruptSource); OSAL_ASSERT((OSAL_MUTEX_Unlock(hDriver->mutexDriverInstance)), "Unable to unlock hardware instance mutex"); /* If we are in a bare metal configuration, then wait till the buffer is processed. If we are in RTOS configuration then pend on the client semaphore. */ if(OSAL_SEM_Pend(clientObj->semReadDone, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { /* This is the implementation of the blocking behavior. In a RTOS configuration, if the code reaches here, it means then that buffer has been processed. */ while(bufferObj->inUse); if(bufferObj->nCurrentBytes != nBytes) { /* This means this buffer was terminated because of an error. */ return(DRV_USART_READ_ERROR); } count = nBytes; } } else if(clientObj->ioIntent & DRV_IO_INTENT_NONBLOCKING) { /* This is a non blocking implementation*/ if(hDriver->queueRead != NULL) { /* This means queue is not empty. We cannot read data now. */ count = 0; } else { while((PLIB_USART_ReceiverDataIsAvailable(plibID)) && (count < nBytes)) { /* This is not a blocking implementation. We read the hardware till the FIFO is empty. */ data[count] = PLIB_USART_ReceiverByteReceive(plibID); count ++; /* We need to check for errors. Store the error in the client error field. */ clientObj->error = PLIB_USART_ErrorsGet(plibID); if(clientObj->error != DRV_USART_ERROR_NONE) { /* This means we have an error. Release the mutex and exit */ OSAL_ASSERT((OSAL_MUTEX_Unlock(hDriver->mutexDriverInstance)), "Unable to unlock hardware instance mutex"); return(DRV_USART_READ_ERROR); } } } } } else { /* Timed out while waiting for read mutex. * We simply return 0 */ count = 0; } return(count); }
bool _DRV_USART_ClientBufferQueueObjectsRemove(DRV_USART_CLIENT_OBJ * clientObj) { DRV_USART_OBJ * dObj = clientObj->hDriver; bool interruptWasEnabled = false; DRV_USART_BUFFER_OBJ * iterator = NULL; if(OSAL_MUTEX_Lock(dObj->mutexDriverInstance, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { /* Disable the transmit interrupt */ interruptWasEnabled = _DRV_USART_InterruptSourceDisable(dObj->txInterruptSource); iterator = dObj->queueWrite; while(iterator != NULL) { if(clientObj == (DRV_USART_CLIENT_OBJ *)iterator->hClient) { /* That means this buffer object is owned by this client. This buffer object should be removed. The following code removes the object from a doubly linked list queue. */ iterator->inUse = false; if(iterator->previous != NULL) { iterator->previous->next = iterator->next; } if(iterator->next != NULL) { iterator->next->previous = iterator->previous; } } iterator = iterator->next; } /* Re-enable the interrupt if it was enabled */ if(interruptWasEnabled) { _DRV_USART_InterruptSourceEnable(dObj->txInterruptSource); } /* Now check the receive buffer queue. Start by disabling the receive interrupt */ interruptWasEnabled = _DRV_USART_InterruptSourceDisable(dObj->rxInterruptSource); iterator = dObj->queueRead; while(iterator != NULL) { if(clientObj == (DRV_USART_CLIENT_OBJ *)iterator->hClient) { /* That means this buffer object is owned by this client. This buffer object should be removed. The following code removed the object from a doubly linked list queue. */ iterator->inUse = false; if(iterator->previous != NULL) { iterator->previous->next = iterator->next; } if(iterator->next != NULL) { iterator->next->previous = iterator->previous; } } iterator = iterator->next; } if(interruptWasEnabled) { _DRV_USART_InterruptSourceEnable(dObj->rxInterruptSource); } /* Unlock the mutex */ OSAL_ASSERT((OSAL_MUTEX_Unlock(dObj->mutexDriverInstance)), "Unable to unlock Driver instance mutex"); } else { /* The case where the mutex lock timed out and the client buffer objects could not be removed from the driver queue, the close function should fail. */ return false; } return true; }
void _DRV_USART_BufferQueueTxTasks(DRV_USART_OBJ * hDriver) { /* Start by getting the buffer at the head of queue. */ DRV_USART_BUFFER_OBJ * bufferObj; DRV_USART_CLIENT_OBJ * client; USART_MODULE_ID plibID; bool status; bufferObj = hDriver->queueWrite; plibID = hDriver->moduleId; /* If this driver is configured for polled mode in an RTOS, the tasks routine would be called from another thread. We need to get the driver instance mutex before updating the queue. If the driver is configured for interrupt mode, then _DRV_USART_TAKE_MUTEX will compile to true */ if(DRV_USART_INTERRUPT_MODE == false) { if(OSAL_MUTEX_Lock(hDriver->mutexDriverInstance, OSAL_WAIT_FOREVER)) { /* We were able to take the mutex */ } else { /* The mutex acquisition timed out. Return with an invalid handle. This code will not execute if there is no RTOS. */ return; } } if(bufferObj != NULL) { /* This means the queue is not empty. Check if this buffer is done */ if(bufferObj->nCurrentBytes >= bufferObj->size) { /* This means the buffer is completed. If there is a callback registered with client, then call it */ client = (DRV_USART_CLIENT_OBJ *)bufferObj->hClient; if((client->eventHandler != NULL) && (bufferObj->flags & DRV_USART_BUFFER_OBJ_FLAG_BUFFER_ADD)) { /* Before calling the event handler, the interrupt nesting counter is incremented. This will allow driver routine that are called from the event handler to know the interrupt nesting level. Events are only generated for buffers that were submitted using the buffer add routine */ hDriver->interruptNestingCount ++; client->eventHandler(DRV_USART_BUFFER_EVENT_COMPLETE, (DRV_USART_BUFFER_HANDLE)bufferObj, client->context); /* Decrement the nesting count */ hDriver->interruptNestingCount -- ; } /* Get the next buffer in the queue and deallocate * this buffer */ hDriver->queueWrite = bufferObj->next; bufferObj->inUse = false; hDriver->queueSizeCurrentWrite --; if(bufferObj->flags & DRV_USART_BUFFER_OBJ_FLAG_READ_WRITE) { /* This means we should post the semaphore */ OSAL_ASSERT(_DRV_USART_SEM_POST(client->semWriteDone) == OSAL_RESULT_TRUE, "Unable to post write buffer queue empty semaphore"); } } } /* Check if the queue is still not empty and process the buffer */ if(hDriver->queueWrite != NULL) { bufferObj = hDriver->queueWrite; /* Fill up the FIFO with data till the FIFO is full and we have data to send */ while((!PLIB_USART_TransmitterBufferIsFull(plibID)) && (bufferObj->nCurrentBytes < bufferObj->size )) { PLIB_USART_TransmitterByteSend(plibID, bufferObj->buffer[bufferObj->nCurrentBytes]); bufferObj->nCurrentBytes ++; } } else { /* If the queue is empty, then disable the TX interrupt */ status = _DRV_USART_InterruptSourceDisable(hDriver->txInterruptSource); } /* Release the mutex */ OSAL_ASSERT(_DRV_USART_RELEASE_MUTEX(hDriver->mutexDriverInstance), "Unable to release Hardware Instance Mutex"); }
static int mdc_setup_init (mdc_slot_state_t *slot, mdc_setup_t* setup, mdc_type_t type, uint8 index, uint8 offset, uint8 slot_num) { uint8 i; uint8 len; OSAL_ASSERT(index < SLOT_NUM); setup->index = index; switch(type){ case MDC_DIO: setup->type = type; for(i=0; i<DIO_INPUT_N; i++){ strcpy(setup->card.dio.name[i], DEF_DIO_NAME[1][i]); len = strlen(DEF_DIO_NAME[1][i]); OSAL_ASSERT(len + 1 < MAX_INPUT_NAME_LEN); //if(offset){ setup->card.dio.name[i][len] = 'A' + slot_num; // }else{ // setup->card.dio.name[i][len] = 'A'; // } setup->card.dio.name[i][len + 1] = 0; setup->card.dio.enable[i] = true; setup->card.dio.volume_control[i] = 0; //TBD setup->card.dio.volume_fixed[i] = 0; //TBD } slot->name = &(setup->card.dio.name); break; case MDC_USB: setup->type = type; for(i=0; i<USB_INPUT_N; i++){ strcpy(setup->card.usb.name[i], DEF_USB_NAME[offset][i]); if(offset && i != USB_INPUT_FRONT){ len = strlen(DEF_USB_NAME[offset][i]); OSAL_ASSERT(len + 1 < MAX_INPUT_NAME_LEN); setup->card.usb.name[i][len] = 'A' + slot_num; setup->card.usb.name[i][len + 1] = 0; } if (offset){ if ((index > 0)&&(i == USB_INPUT_FRONT)) { setup->card.usb.enable[i] = false; } else { setup->card.usb.enable[i] = true; } }else{ setup->card.usb.enable[i] = true; } setup->card.usb.volume_control[i] = 0;//TBD setup->card.usb.volume_fixed[i] = 0;//TBD } slot->name = &(setup->card.usb.name); break; case MDC_HDMI: setup->type = type; for(i=0; i<HDMI_INPUT_N; i++){ strcpy(setup->card.hdmi.name[i], DEF_HDMI_NAME[offset][i]); if(offset){ len = strlen(DEF_HDMI_NAME[offset][i]); OSAL_ASSERT(len + 1 < MAX_INPUT_NAME_LEN); setup->card.hdmi.name[i][len] = 'A'+ slot_num; setup->card.hdmi.name[i][len + 1] = 0; } setup->card.hdmi.enable[i] = true; setup->card.hdmi.volume_control[i] = 0; //TBD setup->card.hdmi.volume_fixed[i] = 0; //TBD } slot->name = &(setup->card.hdmi.name); break; case MDC_ANA: setup->type = type; for(i=0; i<ANA_INPUT_N; i++){ strcpy(setup->card.ana.name[i], DEF_ANA_NAME[offset][i]); if(offset){ len = strlen(DEF_ANA_NAME[offset][i]); OSAL_ASSERT(len + 1 < MAX_INPUT_NAME_LEN); setup->card.ana.name[i][len] = 'A' + slot_num; setup->card.ana.name[i][len + 1] = 0; } setup->card.ana.enable[i] = true; setup->card.ana.volume_control[i] = 0; //TBD setup->card.ana.volume_fixed[i] = 0; //TBD setup->card.ana.gain[i] = 0; //TBD setup->card.ana.adc_sr[i] = 0; //TBD } setup->card.ana.gain[ANA_INPUT_PHONO] = 0; setup->card.ana.phono_mode = PHONO_MM; slot->name = &(setup->card.ana.name); break; case MDC_BLUOS: setup->type = type; for(i=0; i<BT_INPUT_N; i++){ strcpy(setup->card.blu.name[i], DEF_BLU_NAME[offset][i]); if(offset){ len = strlen(DEF_BLU_NAME[offset][i]); OSAL_ASSERT(len + 1 < MAX_INPUT_NAME_LEN); setup->card.blu.name[i][len] = 'A' + slot_num; setup->card.blu.name[i][len + 1] = 0; } setup->card.blu.enable[i] = true; setup->card.blu.volume_control[i] = 0;//TBD setup->card.blu.volume_fixed[i] = 0; //TBD } slot->name = &(setup->card.blu.name); break; case MDC_HDMI_v2: setup->type = type; for(i=0; i<HDMI_V2_INPUT_N; i++){ strcpy(setup->card.hdmi2.name[i], DEF_HDMI_V2_NAME[offset][i]); if(offset){ len = strlen(DEF_HDMI_V2_NAME[offset][i]); OSAL_ASSERT(len + 1< MAX_INPUT_NAME_LEN); setup->card.hdmi2.name[i][len - 1] = 'A' + slot_num; setup->card.hdmi2.name[i][len + 1] = 0; } setup->card.hdmi2.enable[i] = true; setup->card.hdmi2.volume_control[i] = 0; setup->card.hdmi2.volume_fixed[i] = 0; } slot->name = &(setup->card.hdmi2.name); break; default: memset(setup, 0, sizeof(mdc_setup_t)); setup->type = MDC_CARD_NUM; break; } return 0; }
void DRV_USART_Deinitialize(SYS_MODULE_OBJ object) { DRV_USART_OBJ * dObj; DRV_USART_BUFFER_OBJ * iterator; bool status; /* Check that the object is valid */ if(object == SYS_MODULE_OBJ_INVALID) { SYS_DEBUG(0, "Invalid system object handle" ); return; } if(object >= DRV_USART_INSTANCES_NUMBER) { SYS_DEBUG(0, "Invalid system object handle" ); return; } dObj = (DRV_USART_OBJ*) &gDrvUSARTObj[object]; if(!dObj->inUse) { SYS_DEBUG(0, "Invalid system object handle"); return; } /* The driver will not have clients when it is being de-initialized. So the order in which we do the following steps is not that important */ /* Indicate that this object is not is use */ dObj->inUse = false; /* Deinitialize the USART status */ dObj->status = SYS_STATUS_UNINITIALIZED ; /* Disable the interrupt */ status = _DRV_USART_InterruptSourceDisable(dObj->txInterruptSource) ; status = _DRV_USART_InterruptSourceDisable(dObj->rxInterruptSource) ; status = _DRV_USART_InterruptSourceDisable(dObj->errorInterruptSource); /* Disable USART module */ PLIB_USART_Disable (dObj->moduleId); /* Deallocate all mutexes */ OSAL_ASSERT( (OSAL_MUTEX_Delete(&(dObj->mutexDriverInstance)) == OSAL_RESULT_TRUE), "Unable to delete client handle mutex" ); /* TODO: Disable all DMA interrupts */ /* Remove all objects from the read and write queue */ iterator = dObj->queueWrite; while(iterator != NULL) { /* Return the buffer object to the pool */ iterator->inUse = false; iterator = iterator->next; } iterator = dObj->queueRead; while(iterator != NULL) { /* Return the buffer object to the pool */ iterator->inUse = false; iterator = iterator->next; } }
DRV_HANDLE DRV_USART_Open ( const SYS_MODULE_INDEX drvIndex, const DRV_IO_INTENT ioIntent ) { DRV_USART_CLIENT_OBJ *clientObj; DRV_USART_OBJ *dObj; unsigned int iClient; if (drvIndex >= DRV_USART_INSTANCES_NUMBER) { /* Invalid driver index */ SYS_DEBUG(0, "Invalid Driver Instance"); return (DRV_HANDLE_INVALID); } dObj = &gDrvUSARTObj[drvIndex]; if((dObj->status != SYS_STATUS_READY) || (dObj->inUse == false)) { /* The USART module should be ready */ SYS_DEBUG(0, "Was the driver initialized?"); return DRV_HANDLE_INVALID; } if(dObj->isExclusive) { /* This means the another client has opened the driver in exclusive mode. The driver cannot be opened again */ SYS_DEBUG(0, "Driver already opened exclusively"); return ( DRV_HANDLE_INVALID ) ; } if((dObj->nClients > 0) && (ioIntent & DRV_IO_INTENT_EXCLUSIVE)) { /* This means the driver was already opened and another driver was trying to open it exclusively. We cannot give exclusive access in this case */ SYS_DEBUG(0, "Driver already opened. Cannot be opened exclusively"); return(DRV_HANDLE_INVALID); } /* Grab client object mutex here */ if(OSAL_MUTEX_Lock(gDrvUSARTCommonDataObj.mutexClientObjects, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { /* Enter here only if the lock was obtained (appplicable in RTOS only). If the mutex lock fails due to time out then this code does not get executed */ for(iClient = 0; iClient != DRV_USART_CLIENTS_NUMBER; iClient ++) { if(!gDrvUSARTClientObj[iClient].inUse) { /* This means we have a free client object to use */ clientObj = &gDrvUSARTClientObj[iClient]; clientObj->inUse = true; /* We have found a client object. Release the mutex */ OSAL_ASSERT((OSAL_MUTEX_Unlock(gDrvUSARTCommonDataObj.mutexClientObjects)), "Unable to unlock clients objects routine mutex"); clientObj->hDriver = dObj; /* In a case where the driver is configured for polled and bare metal operation, it will not suppot blocking operation */ clientObj->ioIntent = (ioIntent | _DRV_USART_ALWAYS_NON_BLOCKING); clientObj->eventHandler = NULL; clientObj->context = NULL; clientObj->error = DRV_USART_ERROR_NONE; if(ioIntent & DRV_IO_INTENT_EXCLUSIVE) { /* Set the driver exclusive flag */ dObj->isExclusive = true; } dObj->nClients ++; /* Create the semaphores */ OSAL_ASSERT(((OSAL_SEM_Create(&(clientObj->semReadDone), OSAL_SEM_TYPE_COUNTING, 1, 0)) == OSAL_RESULT_TRUE), "Unable to create client read done semaphore"); OSAL_ASSERT(((OSAL_SEM_Create(&(clientObj->semWriteDone), OSAL_SEM_TYPE_COUNTING, 1, 0)) == OSAL_RESULT_TRUE), "Unable to create client write done semaphore"); /* Update the client status */ clientObj->status = DRV_USART_CLIENT_STATUS_READY; return ((DRV_HANDLE) clientObj ); } } /* Could not find a client object. Release the mutex and return with an invalid handle. */ OSAL_ASSERT((OSAL_MUTEX_Unlock(gDrvUSARTCommonDataObj.mutexClientObjects)), "Unable to unlock clients objects routine mutex"); } /* If we have reached here, it means either we could not find a spare client object or the mutex timed out in a RTOS environment. */ return DRV_HANDLE_INVALID; }
static void dispaly_update_handler(sys_state_t *sys, menu_id_t id, uint8 para) { OSAL_ASSERT(sys != NULL); if(sys->status != STATUS_WORKING && sys->status != STAUS_INITING) return; gCurMenu = id; switch(id){ case SOURCE_MENU: dis_source_menu_handler(sys); break; case USB_FILE_LIST_MENU: dis_usb_file_list_menu_handler(sys, para); break; case USB_PLAY_MENU: dis_usb_play_menu_handler(sys, para); break; case USB_NOT_INSERT_MENU: dis_usb_not_insert_menu_handler(sys); break; case USB_READING_MENU: dis_usb_reading_menu_handler(sys); break; case BLU_STATUS_MENU: dis_blu_status_menu_handler(sys, para); break; case BT_STATUS_MENU: dis_bt_status_menu_handler(sys, para); break; case OUTPUT_SELECT_MENU: dis_output_select_menu(sys, para); break; case IR_CHANNEL_SELECT_MENU: dis_ir_channel_select_menu_handler(sys); break; case LINE_OUT_SELECT_MENU: dis_line_out_select_menu(sys, para); break; case AUTO_STANDBY_MENU: dis_auto_standby_menu_handler(sys); break; case DC_ERROR_MENU: dis_dc_error_menu_handler(sys); break; case OVER_TEMP_MENU: dis_over_temp_menu_handler(sys); break; case AC_ERROR_MENU: dis_ac_error_menu_handler(sys); break; case SPEAKE_MODE_SELECT_MENU: dis_speaker_mode_select_menu_handler(sys); break; case TREBEL_CONTROL_MENU: dis_treble_control_menu_handler(sys); break; case BASS_CONTROL_MENU: dis_bass_control_menu_handler(sys); break; case BALANCE_CONTROL_MENU: dis_balance_control_menu_handler(sys); break; case FIRMWARE_VERSION_MENU: dis_firmware_version_menu_handler(); break; case FIRMWARE_UPGRADE_MENU: dis_firmware_upgrade_menu_handler(sys); break; default: break; } }
SYS_MODULE_OBJ DRV_USART_Initialize ( const SYS_MODULE_INDEX drvIndex, const SYS_MODULE_INIT * const init ) { DRV_USART_OBJ *dObj = (DRV_USART_OBJ*)NULL; DRV_USART_INIT *usartInit = NULL ; /* Check if the specified driver index is in valid range */ if(drvIndex >= DRV_USART_INSTANCES_NUMBER) { SYS_DEBUG(0, "Invalid driver index"); return SYS_MODULE_OBJ_INVALID; } /* Check if this hardware instance was already initialized */ if(gDrvUSARTObj[drvIndex].inUse != false) { SYS_DEBUG(0, "Instance already in use"); return SYS_MODULE_OBJ_INVALID; } /* Assign to the local pointer the init data passed */ usartInit = ( DRV_USART_INIT * ) init ; /* Disable the USART module */ PLIB_USART_Disable (usartInit->usartID) ; /* Allocate the driver object and set the operation flag to be in use */ dObj = &gDrvUSARTObj[drvIndex]; dObj->inUse = true; /* Update the USART PLIB Id and other parameters. */ dObj->nClients = 0; dObj->moduleId = usartInit->usartID; dObj->brgClock = usartInit->brgClock; dObj->isExclusive = false; dObj->queueSizeRead = usartInit->queueSizeReceive; dObj->queueSizeWrite = usartInit->queueSizeTransmit; dObj->dmaChannelRead = usartInit->dmaReceive; dObj->dmaChannelWrite = usartInit->dmaTransmit; dObj->txInterruptSource = usartInit->interruptTransmit; dObj->rxInterruptSource = usartInit->interruptReceive; dObj->errorInterruptSource = usartInit->interruptError; dObj->dmaInterruptTransmit = usartInit->dmaInterruptTransmit; dObj->dmaInterruptReceive = usartInit->dmaInterruptReceive; dObj->interruptNestingCount = 0; dObj->queueSizeCurrentRead = 0; dObj->queueSizeCurrentWrite = 0; /* Setup the Hardware */ _DRV_USART_HardwareSetup(usartInit->usartID, usartInit ) ; /* Clear the interrupts */ SYS_INT_SourceStatusClear(dObj->txInterruptSource); SYS_INT_SourceStatusClear(dObj->rxInterruptSource); SYS_INT_SourceStatusClear(dObj->errorInterruptSource); /* Enable the interrupt source in case of interrupt mode */ _DRV_USART_InterruptSourceEnable(dObj->errorInterruptSource); /* TODO: Enable DMA interrupts if the DMA channel is selected */ /* Create the hardware instance mutex. */ OSAL_ASSERT((OSAL_MUTEX_Create(&(dObj->mutexDriverInstance)) == OSAL_RESULT_TRUE), "Unable to create hardware instance mutex"); /* Check if the global mutexes have been created. If not then create these. */ if(!gDrvUSARTCommonDataObj.membersAreInitialized) { /* This means that mutexes where not created. Create them. */ OSAL_ASSERT((OSAL_MUTEX_Create(&(gDrvUSARTCommonDataObj.mutexClientObjects)) == OSAL_RESULT_TRUE), "Unable to create client instance mutex"); OSAL_ASSERT((OSAL_MUTEX_Create(&(gDrvUSARTCommonDataObj.mutexBufferQueueObjects)) == OSAL_RESULT_TRUE), "Unable to create buffer queue objects mutex"); /* Set this flag so that global mutexes get allocated only once */ gDrvUSARTCommonDataObj.membersAreInitialized = true; } /* Enable the USART module */ PLIB_USART_Enable(usartInit->usartID) ; /* Update the status */ dObj->status = SYS_STATUS_READY; /* Return the object structure */ return ( (SYS_MODULE_OBJ)drvIndex ); }
void DRV_USART_BufferAddWrite ( DRV_HANDLE hClient, DRV_USART_BUFFER_HANDLE * bufferHandle, void * source, size_t nBytes ) { DRV_USART_CLIENT_OBJ * clientObj; DRV_USART_OBJ * hDriver; bool interruptWasEnabled = false; DRV_USART_BUFFER_OBJ * bufferObj, * iterator; unsigned int i; /* This function adds a buffer to the write queue */ /* We first check the arguments and initialize the buffer handle */ if(bufferHandle != NULL) { *bufferHandle = DRV_USART_BUFFER_HANDLE_INVALID; } /* Validate the driver handle */ clientObj = _DRV_USART_DriverHandleValidate(hClient); if(clientObj == NULL) { SYS_DEBUG(0, "Invalid Driver Handle"); return; } if((nBytes == 0) || (NULL == source) || (bufferHandle == NULL)) { /* We either got an invalid client handle, invalid source pointer or 0 bytes to transfer */ SYS_DEBUG(0, "Invalid parameters"); return; } hDriver = clientObj->hDriver; if(hDriver->queueSizeCurrentWrite >= hDriver->queueSizeWrite) { /* This means the queue is full. We cannot add this request */ SYS_DEBUG(0, "Transmit Queue is full"); return; } /* We will allow buffers to be added in the interrupt context of this USART driver. But we must make sure that if we are in interrupt, then we should not modify mutexes. */ if(hDriver->interruptNestingCount == 0) { /* Grab a mutex. This is okay because we are not in an interrupt context */ if(OSAL_MUTEX_Lock(hDriver->mutexDriverInstance, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { /* We will disable interrupts so that the queue status does not get updated asynchronously. This code will always execute. */ interruptWasEnabled = _DRV_USART_InterruptSourceDisable(hDriver->txInterruptSource); } else { /* The mutex acquisition timed out. Return with an invalid handle. This code will not execute if there is no RTOS. */ return; } } /* Search the buffer pool for a free buffer object */ for(i = 0 ; i < DRV_USART_QUEUE_DEPTH_COMBINED; i ++) { if(!gDrvUSARTBufferObj[i].inUse) { /* This means this object is free. * Configure the object and then * break */ bufferObj = &gDrvUSARTBufferObj[i]; bufferObj->size = nBytes; bufferObj->inUse = true; bufferObj->buffer = (uint8_t*)source; bufferObj->hClient = clientObj; bufferObj->nCurrentBytes = 0; bufferObj->next = NULL; bufferObj->previous = NULL; bufferObj->flags = (0 | DRV_USART_BUFFER_OBJ_FLAG_BUFFER_ADD); /* Assign a handle to this buffer */ *bufferHandle = (DRV_USART_BUFFER_HANDLE)bufferObj; break; } } if(i == DRV_USART_QUEUE_DEPTH_COMBINED) { /* This means we could not find a buffer. This will happen if the the DRV_USART_QUEUE_DEPTH_COMBINED parameter is configured to be less */ SYS_DEBUG(0, "Insufficient Combined Queue Depth"); /* Enable the interrupt if it was enabled */ if(interruptWasEnabled) { _DRV_USART_InterruptSourceEnable(hDriver->txInterruptSource); } /* Release mutex */ OSAL_ASSERT((OSAL_MUTEX_Unlock(hDriver->mutexDriverInstance)), "Unable to unlock buffer add write mutex"); return; } /* Increment the current queue size*/ hDriver->queueSizeCurrentWrite ++; /* Check if the queue is empty */ if(hDriver->queueWrite == NULL) { /* This is the first buffer in the queue */ hDriver->queueWrite = bufferObj; /* Enabling the interrupt here will cause the task routine to start processing this buffer. If this function is being called in an ISR, then this statement will not have any effect. */ _DRV_USART_InterruptSourceEnable(hDriver->txInterruptSource); } else { /* This means the write queue is not empty. We must add * the buffer object to the end of the queue */ iterator = hDriver->queueWrite; while(iterator->next != NULL) { /* Get the next buffer object */ iterator = iterator->next; } /* At this point, iterator will point to the last object in the queue. We add the buffer object to the linked list. Note that we need to set up the previous pointer as well because buffer should be deleted when the client closes the driver */ iterator->next = bufferObj; bufferObj->previous = iterator; /* We are done. Restore the interrupt enable status and return. */ if(interruptWasEnabled) { _DRV_USART_InterruptSourceEnable(hDriver->txInterruptSource); } } /* Release mutex */ OSAL_ASSERT((OSAL_MUTEX_Unlock(hDriver->mutexDriverInstance)), "Unable to unlock buffer add write mutex"); return; }
void update_detect_state(detect_event_t event) { OSAL_ASSERT(event < NUM_OF_DETECT); detectlist[event].state = DETECT_BEGIN; }
void _DRV_USART_BufferQueueRxTasks(DRV_USART_OBJ * hDriver) { DRV_USART_BUFFER_OBJ * bufferObj; DRV_USART_CLIENT_OBJ * client; USART_MODULE_ID plibID; bool status; bufferObj = hDriver->queueWrite; plibID = hDriver->moduleId; /* If this driver is configured for polled mode in an RTOS, the tasks routine would be called from another thread. We need to get the driver instance mutex before updating the queue. If the driver is configured for interrupt mode, then _DRV_USART_TAKE_MUTEX will compile to true */ if(DRV_USART_INTERRUPT_MODE == false) { if(OSAL_MUTEX_Lock(hDriver->mutexDriverInstance, OSAL_WAIT_FOREVER) == OSAL_RESULT_TRUE) { /* We were able to take the mutex */ } else { /* The mutex acquisition timed out. Return with an invalid handle. This code will not execute if there is no RTOS. */ return; } } /* In this function, the driver checks if there are any buffers in queue. If so the buffer is serviced. A buffer that is serviced completely is removed from the queue. Start by getting the buffer at the head of the queue */ bufferObj = hDriver->queueRead; if(bufferObj != NULL) { /* The USART driver is configured to generate an interrupt when the FIFO is not empty. Additionally the queue is not empty. Which means there is work to done in this routine. Read data from the FIFO till either the FIFO is empty or till we have read the requested number of bytes. */ while((PLIB_USART_ReceiverDataIsAvailable(plibID)) && (bufferObj->nCurrentBytes < bufferObj->size )) { bufferObj->buffer[bufferObj->nCurrentBytes] = PLIB_USART_ReceiverByteReceive(plibID); bufferObj->nCurrentBytes ++; } /* Check if this buffer is done */ if(bufferObj->nCurrentBytes >= bufferObj->size) { /* This means the buffer is completed. If there is a callback registered with client, then call it */ client = (DRV_USART_CLIENT_OBJ *)bufferObj->hClient; if((client->eventHandler != NULL) && (bufferObj->flags & DRV_USART_BUFFER_OBJ_FLAG_BUFFER_ADD)) { /* Call the event handler. We additionally increment the interrupt nesting count which lets the driver functions that are called from the event handler know that an interrupt context is active. */ hDriver->interruptNestingCount ++; client->eventHandler(DRV_USART_BUFFER_EVENT_COMPLETE, (DRV_USART_BUFFER_HANDLE)bufferObj, client->context); hDriver->interruptNestingCount --; } /* Get the next buffer in the queue and deallocate this buffer */ hDriver->queueRead = bufferObj->next; bufferObj->inUse = false; hDriver->queueSizeCurrentRead --; if(bufferObj->flags & DRV_USART_BUFFER_OBJ_FLAG_READ_WRITE) { /* This means we should post the semaphore */ OSAL_ASSERT(_DRV_USART_SEM_POST(client->semReadDone) == OSAL_RESULT_TRUE, "Unable to post write buffer queue empty semaphore"); } } } if(hDriver->queueRead == NULL) { /* The queue is empty. We can disable the interrupt */ status = _DRV_USART_InterruptSourceDisable(hDriver->rxInterruptSource); } /* Release the mutex */ OSAL_ASSERT(_DRV_USART_RELEASE_MUTEX(hDriver->mutexDriverInstance), "Unable to release Hardware Instance Mutex"); }