// do not re-schedule while locked the timer ISR // this needs to be real quick static __inline__ bool __attribute__((always_inline)) _IsrTmrLock(OSAL_CRITSECT_DATA_TYPE* pCritStat) { *pCritStat = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_LOW); return DRV_TMR_AlarmDisable(sSysTmrObject.driverHandle); }
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Write ( USB_DEVICE_CDC_INDEX iCDC , USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle , const void * data , size_t size , USB_DEVICE_CDC_TRANSFER_FLAGS flags ) { unsigned int cnt; unsigned int remainder; USB_DEVICE_IRP * irp; USB_DEVICE_IRP_FLAG irpFlag = 0; USB_DEVICE_CDC_INSTANCE * thisCDCDevice; USB_DEVICE_CDC_ENDPOINT * endpoint; OSAL_RESULT osalError; USB_ERROR irpError; OSAL_CRITSECT_DATA_TYPE IntState; /* Check the validity of the function driver index */ if ( iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER ) { /* Invalid CDC index */ SYS_ASSERT(false, "Invalid CDC Device Index"); return USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID; } /* Initialize the transfer handle, get the instance object * and the transmit endpoint */ * transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; thisCDCDevice = &gUSBDeviceCDCInstance[iCDC]; endpoint = &thisCDCDevice->dataInterface.endpoint[USB_DEVICE_CDC_ENDPOINT_TX]; if(!(endpoint->isConfigured)) { /* This means that the endpoint is not configured yet */ SYS_ASSERT(false, "Endpoint not configured"); return (USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED); } if(size == 0) { /* Size cannot be zero */ return (USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID); } /* Check the flag */ if(flags & USB_DEVICE_CDC_TRANSFER_FLAGS_MORE_DATA_PENDING) { if(size < endpoint->maxPacketSize) { /* For a data pending flag, we must atleast get max packet * size worth data */ return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID); } remainder = size % endpoint->maxPacketSize; if(remainder != 0) { size -= remainder; } irpFlag = USB_DEVICE_IRP_FLAG_DATA_PENDING; } else if(flags & USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE) { irpFlag = USB_DEVICE_IRP_FLAG_DATA_COMPLETE; } if(thisCDCDevice->currentQSizeWrite >= thisCDCDevice->queueSizeWrite) { SYS_ASSERT(false, "Write Queue is full"); return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); } /*Obtain mutex to get access to a shared resource, check return value*/ osalError = OSAL_MUTEX_Lock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP, OSAL_WAIT_FOREVER); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed lock was not obtained, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* loop and find a free IRP in the Q */ for ( cnt = 0; cnt < USB_DEVICE_CDC_QUEUE_DEPTH_COMBINED; cnt ++ ) { if(gUSBDeviceCDCIRP[cnt].status < (USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING) { /* This means the IRP is free */ irp = &gUSBDeviceCDCIRP[cnt]; irp->data = (void *)data; irp->size = size; irp->userData = (uintptr_t) iCDC; irp->callback = _USB_DEVICE_CDC_WriteIRPCallback; irp->flags = irpFlag; /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update the Write queue size */ thisCDCDevice->currentQSizeWrite++; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = (USB_DEVICE_CDC_TRANSFER_HANDLE)irp; irpError = USB_DEVICE_IRPSubmit(thisCDCDevice->deviceHandle, endpoint->address, irp); /* If IRP Submit function returned any error, then invalidate the Transfer handle. */ if (irpError != USB_ERROR_NONE ) { /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update the Write queue size */ thisCDCDevice->currentQSizeWrite--; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } return(irpError); } } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* If here means we could not find a spare IRP */ return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); }
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_SerialStateNotificationSend ( USB_DEVICE_CDC_INDEX iCDC , USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle , USB_CDC_SERIAL_STATE * notificationData ) { unsigned int cnt; USB_DEVICE_IRP * irp; USB_DEVICE_CDC_ENDPOINT * endpoint; USB_DEVICE_CDC_INSTANCE * thisCDCDevice; OSAL_RESULT osalError; USB_ERROR irpError; OSAL_CRITSECT_DATA_TYPE IntState; *transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; /* Check the validity of the function driver index */ if ( iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER ) { /* Invalid CDC index */ SYS_ASSERT(false, "Invalid CDC Device Index"); return USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID; } thisCDCDevice = &gUSBDeviceCDCInstance[iCDC]; endpoint = &thisCDCDevice->notificationInterface.endpoint[USB_DEVICE_CDC_ENDPOINT_TX]; if(!(endpoint->isConfigured)) { /* This means that the endpoint is not configured yet */ SYS_ASSERT(false, "Endpoint not configured"); return (USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED); } if(thisCDCDevice->currentQSizeSerialStateNotification >= thisCDCDevice->queueSizeSerialStateNotification) { SYS_ASSERT(false, "Serial State Notification Send Queue is full"); return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); } /*Obtain mutex to get access to a shared resource, check return value*/ osalError = OSAL_MUTEX_Lock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP, OSAL_WAIT_FOREVER); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed lock was not obtained, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* Loop and find a free IRP in the Q */ for ( cnt = 0; cnt < USB_DEVICE_CDC_QUEUE_DEPTH_COMBINED; cnt ++ ) { if(gUSBDeviceCDCIRP[cnt].status < (USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING) { /* This means the IRP is free */ irp = &gUSBDeviceCDCIRP[cnt]; irp->data = notificationData; irp->size = sizeof(USB_CDC_SERIAL_STATE); irp->userData = (uintptr_t) iCDC; irp->callback = _USB_DEVICE_CDC_SerialStateSendIRPCallback; irp->flags = USB_DEVICE_IRP_FLAG_DATA_COMPLETE; /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update Serial State Notification Queue Size */ thisCDCDevice->currentQSizeSerialStateNotification ++; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = (USB_DEVICE_CDC_TRANSFER_HANDLE) irp; irpError = USB_DEVICE_IRPSubmit(thisCDCDevice->deviceHandle, endpoint->address, irp); /* If IRP Submit function returned any error, then invalidate the Transfer handle. */ if (irpError != USB_ERROR_NONE ) { /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update Serial State Notification Queue Size */ thisCDCDevice->currentQSizeSerialStateNotification --; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } return(irpError); } } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* If here means we could not find a spare IRP */ return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); }
USB_DEVICE_CDC_RESULT USB_DEVICE_CDC_Read ( USB_DEVICE_CDC_INDEX iCDC , USB_DEVICE_CDC_TRANSFER_HANDLE * transferHandle , void * data , size_t size ) { unsigned int cnt; unsigned int remainder; USB_DEVICE_IRP * irp; USB_DEVICE_CDC_ENDPOINT * endpoint; USB_DEVICE_CDC_INSTANCE * thisCDCDevice; OSAL_RESULT osalError; USB_ERROR irpError; OSAL_CRITSECT_DATA_TYPE IntState; /* Check the validity of the function driver index */ if ( iCDC >= USB_DEVICE_CDC_INSTANCES_NUMBER ) { /* Invalid CDC index */ SYS_ASSERT(false, "Invalid CDC Device Index"); return USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_INVALID; } thisCDCDevice = &gUSBDeviceCDCInstance[iCDC]; endpoint = &thisCDCDevice->dataInterface.endpoint[USB_DEVICE_CDC_ENDPOINT_RX]; *transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; /* Check if the endpoint is configured */ if(!(endpoint->isConfigured)) { /* This means that the endpoint is not configured yet */ SYS_ASSERT(false, "Endpoint not configured"); return (USB_DEVICE_CDC_RESULT_ERROR_INSTANCE_NOT_CONFIGURED); } /* For read the size should be a multiple of endpoint size*/ remainder = size % endpoint->maxPacketSize; if((size == 0) || (remainder != 0)) { /* Size is not valid */ SYS_ASSERT(false, "Invalid size in IRP read"); return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_SIZE_INVALID); } /* Make sure that we are with in the queue size for this instance */ if(thisCDCDevice->currentQSizeRead >= thisCDCDevice->queueSizeRead) { SYS_ASSERT(false, "Read Queue is full"); return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); } /*Obtain mutex to get access to a shared resource, check return value*/ osalError = OSAL_MUTEX_Lock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP, OSAL_WAIT_FOREVER); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed lock was not obtained, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* Loop and find a free IRP in the Q */ for ( cnt = 0; cnt < USB_DEVICE_CDC_QUEUE_DEPTH_COMBINED; cnt ++ ) { if(gUSBDeviceCDCIRP[cnt].status < (USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING) { /* This means the IRP is free. Configure the IRP * update the current queue size and then submit */ irp = &gUSBDeviceCDCIRP[cnt]; irp->data = data; irp->size = size; irp->userData = (uintptr_t) iCDC; irp->callback = _USB_DEVICE_CDC_ReadIRPCallback; /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update the read queue size */ thisCDCDevice->currentQSizeRead++; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = (USB_DEVICE_CDC_TRANSFER_HANDLE)irp; irpError = USB_DEVICE_IRPSubmit(thisCDCDevice->deviceHandle, endpoint->address, irp); /* If IRP Submit function returned any error, then invalidate the Transfer handle. */ if (irpError != USB_ERROR_NONE ) { /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update the read queue size */ thisCDCDevice->currentQSizeRead--; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } return(irpError); } } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&gUSBDeviceCdcCommonDataObj.mutexCDCIRP); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed unlock was not complete, or error occurred, let user know about error*/ return (USB_DEVICE_CDC_RESULT_ERROR); } /* If here means we could not find a spare IRP */ return(USB_DEVICE_CDC_RESULT_ERROR_TRANSFER_QUEUE_FULL); }
USB_DEVICE_RESULT USB_DEVICE_EndpointWrite ( USB_DEVICE_HANDLE usbDeviceHandle, USB_DEVICE_TRANSFER_HANDLE * transferHandle, USB_ENDPOINT_ADDRESS endpoint, const void * data, size_t size, USB_DEVICE_TRANSFER_FLAGS flags ) { int count = 0; USB_DEVICE_OBJ* devClientHandle; USB_ERROR irpSubmitError; SYS_MODULE_INDEX deviceInstanceNumber; USB_DEVICE_Q_SIZE_ENDPOINT* thisEndpointQueueSize; USB_DEVICE_IRP * irp ; OSAL_RESULT osalError; *transferHandle = USB_DEVICE_TRANSFER_HANDLE_INVALID; OSAL_CRITSECT_DATA_TYPE IntState; /* Validate the handle */ devClientHandle = _USB_DEVICE_ClientHandleValidate(usbDeviceHandle); if (devClientHandle == NULL) { SYS_DEBUG(0, "USB Device Layer: Invalid Client Handle"); return(USB_DEVICE_RESULT_ERROR_DEVICE_HANDLE_INVALID); } /* Get Device Instance Number */ deviceInstanceNumber = devClientHandle->usbDevLayerIndex; /* Get Handle to the Endpoint Queue Size structure */ thisEndpointQueueSize = &qSizeEndpoint[deviceInstanceNumber]; /* Make sure that we are with in the queue size for this instance */ if(thisEndpointQueueSize->qSizeCurrentEpWrite >= thisEndpointQueueSize->qSizeMaxEpWrite) { SYS_DEBUG(0, "Write Queue is full"); return(USB_DEVICE_RESULT_ERROR_TRANSFER_QUEUE_FULL); } /*Obtain mutex to get access to a shared resource, check return value*/ osalError = OSAL_MUTEX_Lock(&(devClientHandle->mutexEndpointIRP), OSAL_WAIT_FOREVER); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed lock was not obtained, or error occurred, let user know about error*/ return (USB_DEVICE_RESULT_ERROR); } /* Check if the if there is free slot available in queue */ for(count = 0; count < (USB_DEVICE_ENDPOINT_QUEUE_DEPTH_COMBINED) ; count ++ ) { if(gUSBDeviceEndpointIRP[count].status < (USB_DEVICE_IRP_STATUS)USB_DEVICE_IRP_FLAG_DATA_PENDING) { /* This means the IRP is free. Configure the IRP * update the current queue size and then submit */ irp = &gUSBDeviceEndpointIRP[count]; irp->data = (void *)data; irp->size = size; irp->flags = flags; irp->callback = &_USB_DEVICE_EndpointWriteCallBack; irp->userData = (uintptr_t)devClientHandle; (* transferHandle) = ( USB_DEVICE_TRANSFER_HANDLE )irp; /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); (thisEndpointQueueSize->qSizeCurrentEpWrite)++; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); irpSubmitError = USB_DEVICE_IRPSubmit( devClientHandle, endpoint, irp); /* If IRP Submit function returned any error, then invalidate the Transfer handle. */ if (irpSubmitError != USB_ERROR_NONE ) { /* Prevent other tasks pre-empting this sequence of code */ IntState = OSAL_CRIT_Enter(OSAL_CRIT_TYPE_HIGH); /* Update the read queue size */ (thisEndpointQueueSize->qSizeCurrentEpWrite)--; OSAL_CRIT_Leave(OSAL_CRIT_TYPE_HIGH, IntState); *transferHandle = USB_DEVICE_TRANSFER_HANDLE_INVALID; } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&(devClientHandle->mutexEndpointIRP)); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed lock was not obtained, or error occurred, let user know about error*/ return (USB_DEVICE_RESULT_ERROR); } return(irpSubmitError); } } /*Release mutex, done with shared resource*/ osalError = OSAL_MUTEX_Unlock(&(devClientHandle->mutexEndpointIRP)); if(osalError != OSAL_RESULT_TRUE) { /*Do not proceed, unlock was not completed, or error occurred, let user know about error*/ return (USB_DEVICE_RESULT_ERROR); } /* We could not find a spare IRP */ SYS_DEBUG(0, "USB Device Endpoint Write: Transfer queue is full"); return USB_DEVICE_RESULT_ERROR_TRANSFER_QUEUE_FULL; }