/* * ======== UARTMSP432_writeCancel ======== */ void UARTMSP432_writeCancel(UART_Handle handle) { uintptr_t key; UARTMSP432_Object *object = handle->object; UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; unsigned int written; key = HwiP_disable(); /* Return if there is no write. */ if (!object->writeCount) { HwiP_restore(key); return; } /* Set size = 0 to prevent writing and restore interrupts. */ MAP_UART_disableInterrupt(hwAttrs->baseAddr, EUSCI_A_UART_TRANSMIT_INTERRUPT); written = object->writeCount; object->writeCount = 0; HwiP_restore(key); /* Remove constraints set during write */ Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); /* Reset the write buffer so we can pass it back */ object->writeCallback(handle, (void *)object->writeBuf, object->writeSize - written); DebugP_log2("UART:(%p) Write canceled, %d bytes written", hwAttrs->baseAddr, object->writeSize - written); }
/* * ======== UARTMSP432_write ======== */ int UARTMSP432_write(UART_Handle handle, const void *buffer, size_t size) { uintptr_t key; UARTMSP432_Object *object = handle->object; UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; if (!size) { return 0; } key = HwiP_disable(); if (object->writeCount) { HwiP_restore(key); DebugP_log1("UART:(%p) Could not write data, uart in use.", hwAttrs->baseAddr); return (UART_ERROR); } /* Save the data to be written and restore interrupts. */ object->writeBuf = buffer; object->writeSize = size; object->writeCount = size; HwiP_restore(key); /* * Set power constraint to keep peripheral active during transfer and * to prevent a performance level change */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); /* Enabling TX interrupt will trigger the Hwi which will handle the write */ MAP_UART_enableInterrupt(hwAttrs->baseAddr, EUSCI_A_UART_TRANSMIT_INTERRUPT); /* If writeMode is blocking, block and get the state. */ if (object->state.writeMode == UART_MODE_BLOCKING) { /* Pend on semaphore and wait for Hwi to finish. */ if (SemaphoreP_pend(object->writeSem, object->writeTimeout) != SemaphoreP_OK) { /* Semaphore timed out, make the write empty and log the write. */ MAP_UART_disableInterrupt(hwAttrs->baseAddr, EUSCI_A_UART_TRANSMIT_INTERRUPT); object->writeCount = 0; DebugP_log2("UART:(%p) Write timed out, %d bytes written", hwAttrs->baseAddr, object->writeCount); } return (object->writeSize - object->writeCount); } return (0); }
int CameraCC3200DMA_capture(Camera_Handle handle, void *buffer, unsigned int bufferlen) { CameraCC3200DMA_Object *object = handle->object; CameraCC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; uintptr_t key; key = HwiP_disable(); if (object->inUse) { HwiP_restore(key); DebugP_log1("Camera:(%p) Could not capture data, camera in use.", ((CameraCC3200DMA_HWAttrs const *) (handle->hwAttrs))->baseAddr); return (CAMERA_STATUS_UNDEFINEDCMD); } object->captureBuf = buffer; object->bufferlength = bufferlen; object->frameLength = 0; object->cameraDMAxIntrRcvd = 0; object->inUse = 1; object->cameraDMA_PingPongMode = 0; HwiP_restore(key); /* Set constraints to guarantee transaction */ Power_setConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); /* Start the DMA transfer */ CameraCC3200DMA_configDMA(handle); MAP_CameraCaptureStart(hwAttrs->baseAddr); /* If operationMode is blocking, block and get the status. */ if (object->operationMode == Camera_MODE_BLOCKING) { /* Pend on semaphore and wait for Hwi to finish. */ if (SemaphoreP_pend(object->captureSem, object->captureTimeout) != SemaphoreP_OK) { DebugP_log2("Camera:(%p) Capture timed out, %d bytes captured", ((CameraCC3200DMA_HWAttrs const *) (handle->hwAttrs))->baseAddr, object->frameLength); } else { MAP_CameraCaptureStop(hwAttrs->baseAddr, true); return (object->frameLength); } } return (0); }
/* * ======== SPICC3200DMA_close ======== * @pre Function assumes that the handle is not NULL */ void SPICC3200DMA_close(SPI_Handle handle) { uintptr_t key; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; MAP_SPIDisable(hwAttrs->baseAddr); MAP_SPICSDisable(hwAttrs->baseAddr); MAP_SPIDmaDisable(hwAttrs->baseAddr, SPI_RX_DMA | SPI_TX_DMA); MAP_SPIFIFODisable(hwAttrs->baseAddr, SPI_RX_FIFO | SPI_TX_FIFO); /* Release power dependency on SPI. */ Power_releaseDependency(getPowerMgrId(hwAttrs->baseAddr)); Power_releaseDependency(PowerCC3200_PERIPH_UDMA); Power_unregisterNotify(&(object->notifyObj)); if (object->hwiHandle) { HwiP_delete(object->hwiHandle); } if (object->transferComplete) { SemaphoreP_delete(object->transferComplete); } DebugP_log1("SPI:(%p) closed", hwAttrs->baseAddr); key = HwiP_disable(); object->isOpen = false; HwiP_restore(key); }
/* * ======== PWMTimerMSP432_close ======== * @pre Function assumes that the handle is not NULL */ void PWMTimerMSP432_close(PWM_Handle handle) { uintptr_t key; PWMTimerMSP432_Object *object = handle->object; PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; MAP_Timer_A_setCompareValue(hwAttrs->baseAddr, hwAttrs->compareRegister, 0); key = HwiP_disable(); /* Mark the output as unused */ (object->pwmTimerStatus)->activeOutputsMask &= ~(object->pwmCompareOutputBit); /* Stop timer & clear all status if no other PWM instances are being used */ if ((object->pwmTimerStatus)->activeOutputsMask == 0) { MAP_Timer_A_stopTimer(hwAttrs->baseAddr); (object->pwmTimerStatus)->cyclesPerMicroSec = 0; (object->pwmTimerStatus)->period = 0; (object->pwmTimerStatus)->prescalar = 0; } object->isOpen = false; HwiP_restore(key); /* Remove power constraints */ Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0); Power_releaseConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1); DebugP_log1("PWM: (%p) closed", (uintptr_t) handle); }
/* * ======== SPICC3200DMA_transfer ======== * @pre Function assumes that handle and transaction is not NULL */ bool SPICC3200DMA_transfer(SPI_Handle handle, SPI_Transaction *transaction) { uintptr_t key; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; /* This is a limitation by the micro DMA controller */ if ((transaction->count == 0) || (transaction->count > 1024) || !(transaction->rxBuf || transaction->txBuf) || (!(transaction->rxBuf && transaction->txBuf) && !hwAttrs->scratchBufPtr)) { return (false); } /* Check if a transfer is in progress */ key = HwiP_disable(); if (object->transaction) { HwiP_restore(key); DebugP_log1("SPI:(%p) ERROR! Transaction still in progress", ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr); return (false); } else { object->transaction = transaction; HwiP_restore(key); } /* Set constraints to guarantee transaction */ Power_setConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); SPICC3200DMA_configDMA(handle, transaction); MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW); MAP_SPIIntEnable(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW); MAP_SPIEnable(hwAttrs->baseAddr); MAP_SPICSEnable(hwAttrs->baseAddr); if (object->transferMode == SPI_MODE_BLOCKING) { DebugP_log1("SPI:(%p) transfer pending on transferComplete semaphore", ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr); SemaphoreP_pend(object->transferComplete, SemaphoreP_WAIT_FOREVER); } return (true); }
/* * ======== PWMTimerMSP432_control ======== * @pre Function assumes that the handle is not NULL */ int PWMTimerMSP432_control(PWM_Handle handle, unsigned int cmd, void *arg) { uintptr_t key; uint32_t period; uint8_t prescalar; PWMTimerMSP432_Object *object = handle->object; PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; switch(cmd) { case PWMTimerMSP432_CHANGE_PERIOD: DebugP_assert((uint32_t *) arg != NULL); key = HwiP_disable(); /* Calculate period in PWM timer counts */ period = (*(uint32_t *) arg) * (object->pwmTimerStatus)->cyclesPerMicroSec; prescalar = PWMTimerMSP432_calculatePrescalar(period); /* Ensure new period can be generated with current prescalar */ if (prescalar != (object->pwmTimerStatus)->prescalar) { HwiP_restore(key); return (-1); } MAP_Timer_A_setCompareValue(hwAttrs->baseAddr, TIMER_A_CAPTURECOMPARE_REGISTER_0, period/prescalar); /* Update PWM status with new period */ (object->pwmTimerStatus)->period = *((uint32_t *) arg); HwiP_restore(key); return (PWMTimerMSP432_CHANGE_PERIOD); default: /* No implementation yet */ return (PWM_STATUS_UNDEFINEDCMD); } }
/* * ======== PWMTimerMSP432_getPeriodMicroSecs ======== * @pre Function assumes that handle is not NULL */ unsigned int PWMTimerMSP432_getPeriodMicroSecs(PWM_Handle handle) { uintptr_t key; unsigned int period; PWMTimerMSP432_Object *object = handle->object; key = HwiP_disable(); period = (object->pwmTimerStatus)->period; HwiP_restore(key); return period; }
/* * ======== readTaskCallback ======== * This function is called the first time by the UART_read task and tries to * get all the data it can get from the ringBuffer. If it finished, it will * perform the user supplied callback. If it didn't finish, the ISR must handle * the remaining data. By setting the drainByISR flag, the UART_read function * handed over the responsibility to get the remaining data to the ISR. */ static int readTaskCallback(UART_Handle handle) { bool makeCallback = false; unsigned char readIn; unsigned char *bufferEnd; uintptr_t key; UARTMSP432_Object *object = handle->object; object->state.drainByISR = false; bufferEnd = (unsigned char*) object->readBuf + object->readSize; while (object->readCount) { if (RingBuf_get(&object->ringBuffer, &readIn) < 0) { break; } DebugP_log2("UART:(%p) read '0x%02x'", ((UARTMSP432_HWAttrs const *)(handle->hwAttrs))->baseAddr, (unsigned char) readIn); *(unsigned char *) (bufferEnd - object->readCount * sizeof(unsigned char)) = readIn; key = HwiP_disable(); object->readCount--; HwiP_restore(key); if (object->state.readDataMode == UART_DATA_TEXT && object->state.readReturnMode == UART_RETURN_NEWLINE && readIn == '\n') { makeCallback = true; break; } } if (!object->readCount || makeCallback) { /* Nested UART_reads from within callbacks are NOT supported!!! */ object->readCallback(handle, object->readBuf, object->readSize - object->readCount); object->readSize = 0; } else { object->state.drainByISR = true; } return (0); }
/* * ======== UARTMSP432_read ======== */ int UARTMSP432_read(UART_Handle handle, void *buffer, size_t size) { uintptr_t key; UARTMSP432_Object *object = handle->object; key = HwiP_disable(); if ((object->state.readMode == UART_MODE_CALLBACK) && object->readSize) { HwiP_restore(key); DebugP_log1("UART:(%p) Could not read data, uart in use.", ((UARTMSP432_HWAttrs const *)(handle->hwAttrs))->baseAddr); return (UART_ERROR); } /* Save the data to be read and restore interrupts. */ object->readBuf = buffer; object->readSize = size; object->readCount = size; HwiP_restore(key); return (object->readFxns.readTaskFxn(handle)); }
/* * ======== List_putHead ======== */ void List_putHead(List_List *list, List_Elem *elem) { uintptr_t key; key = HwiP_disable(); elem->next = list->head; elem->prev = NULL; if (list->head != NULL) { list->head->prev = elem; } else { list->tail = elem; } list->head = elem; HwiP_restore(key); }
/* * ======== List_get ======== */ List_Elem *List_get(List_List *list) { List_Elem *elem; uintptr_t key; key = HwiP_disable(); elem = list->head; /* See if the List was empty */ if (elem != NULL) { list->head = elem->next; if (elem->next != NULL) { elem->next->prev = NULL; } else { list->tail = NULL; } } HwiP_restore(key); return (elem); }
/* * ======== UARTMSP432_readCancel ======== */ void UARTMSP432_readCancel(UART_Handle handle) { uintptr_t key; UARTMSP432_Object *object = handle->object; if ((object->state.readMode != UART_MODE_CALLBACK) || (object->readSize == 0)) { return; } key = HwiP_disable(); object->state.drainByISR = false; /* * Indicate that what we've currently received is what we asked for so that * the existing logic handles the completion. */ object->readSize -= object->readCount; object->readCount = 0; HwiP_restore(key); object->readFxns.readTaskFxn(handle); }
/* * ======== UARTMSP432_open ======== */ UART_Handle UARTMSP432_open(UART_Handle handle, UART_Params *params) { unsigned int i; uintptr_t key; uint32_t clockFreq; uint8_t numPerfLevels; int32_t baudrateIndex; union { ClockP_Params clockParams; HwiP_Params hwiParams; SemaphoreP_Params semParams; } portsParams; PowerMSP432_Freqs powerFreqs; UARTMSP432_Object *object = handle->object; UARTMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; if (params == NULL) { params = (UART_Params *) &UART_defaultParams; } /* Check that a callback is set */ DebugP_assert((params->readMode != UART_MODE_CALLBACK) || (params->readCallback != NULL)); DebugP_assert((params->writeMode != UART_MODE_CALLBACK) || (params->writeCallback != NULL)); key = HwiP_disable(); if (object->state.opened) { HwiP_restore(key); DebugP_log1("UART:(%p) already in use.", hwAttrs->baseAddr); return (NULL); } object->state.opened = true; HwiP_restore(key); /* Ensure a supported clock source is used */ if (hwAttrs->clockSource != EUSCI_A_UART_CLOCKSOURCE_ACLK && hwAttrs->clockSource != EUSCI_A_UART_CLOCKSOURCE_SMCLK) { DebugP_log1("UART:(%p) Error! Using unsupported clock source.", hwAttrs->baseAddr); object->state.opened = false; return (NULL); } /* * Add power management support - Disable performance transitions while * opening the driver is open. This constraint remains active until a * UART_control() disables receive interrupts. Afterwards performance * levels can be changed by the application. A UART_control() call can * enable RX interrupts again and set the pertinent constraints. */ Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); /* * Verify that the driver can be opened at current performance level and * set constraints for other performance levels. */ numPerfLevels = PowerMSP432_getNumPerfLevels(); PowerMSP432_getFreqs(Power_getPerformanceLevel(), &powerFreqs); if (hwAttrs->clockSource == EUSCI_A_UART_CLOCKSOURCE_ACLK) { /* * Verify if driver can be opened with ACLK; ACLK does not change * in any performance level. */ baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT, hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.ACLK); if (baudrateIndex == -1) { DebugP_log3("UART:(%p) unable to find a valid buadrate %d " "configuration at clock input clock freq %d", hwAttrs->baseAddr, params->baudRate, powerFreqs.ACLK); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); object->state.opened = false; return (NULL); } clockFreq = powerFreqs.ACLK; } else { /* hwAttrs->clockSource == EUSCI_A_UART_CLOCKSOURCE_SMCLK */ baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT, hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.SMCLK); if (baudrateIndex == -1) { DebugP_log3("UART:(%p) unable to find a valid buadrate %d " "configuration at clock input clock freq %d", hwAttrs->baseAddr, params->baudRate, powerFreqs.SMCLK); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); object->state.opened = false; return (NULL); } clockFreq = powerFreqs.SMCLK; /* * SMCLK changes with performance levels. Set constraints for * unsupported performance levels. */ for (i = 0; i < numPerfLevels; i++) { PowerMSP432_getFreqs(i, &powerFreqs); baudrateIndex = findBaudDividerIndex(hwAttrs->baudrateLUT, hwAttrs->numBaudrateEntries, params->baudRate, powerFreqs.SMCLK); if (baudrateIndex == -1) { /* Set constraint and keep track of it in perfConstraintMask */ object->perfConstraintMask |= (1 << i); Power_setConstraint(PowerMSP432_DISALLOW_PERFLEVEL_0 + i); } } } /* * Shutdown not supported while driver is open. The DEEPSLEEP_0 constraint * keeps stops the device from going into LPM3 or higher. This is done * to keep the UART peripheral receiving in the background and storing data * in the internal ring buff. */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1); /* Register function to reconfigure peripheral on perf level changes */ Power_registerNotify(&object->perfChangeNotify, PowerMSP432_START_CHANGE_PERF_LEVEL | PowerMSP432_DONE_CHANGE_PERF_LEVEL, perfChangeNotifyFxn, (uintptr_t) handle); /* Create the Hwi for this UART peripheral */ HwiP_Params_init(&(portsParams.hwiParams)); portsParams.hwiParams.arg = (uintptr_t) handle; portsParams.hwiParams.priority = hwAttrs->intPriority; object->hwiHandle = HwiP_create(hwAttrs->intNum, UARTMSP432_hwiIntFxn, &(portsParams.hwiParams)); if (object->hwiHandle == NULL) { DebugP_log1("UART:(%p) HwiP_create() failed", hwAttrs->baseAddr); UARTMSP432_close(handle); return (NULL); } SemaphoreP_Params_init(&(portsParams.semParams)); portsParams.semParams.mode = SemaphoreP_Mode_BINARY; if (params->writeMode == UART_MODE_BLOCKING) { /* If write mode is blocking create a semaphore and set callback. */ object->writeSem = SemaphoreP_create(0, &(portsParams.semParams)); if (object->writeSem == NULL) { DebugP_log1("UART:(%p) SemaphoreP_create() failed.", hwAttrs->baseAddr); UARTMSP432_close(handle); return (NULL); } object->writeCallback = &writeSemCallback; } else { /* UART_MODE_CALLBACK - Store application callback */ object->writeCallback = params->writeCallback; } if (params->readMode == UART_MODE_BLOCKING) { /* If read mode is blocking create a semaphore and set callback. */ object->readSem = SemaphoreP_create(0, &(portsParams.semParams)); if (object->readSem == NULL) { DebugP_log1("UART:(%p) SemaphoreP_create() failed.", hwAttrs->baseAddr); UARTMSP432_close(handle); return (NULL); } object->readCallback = &readSemCallback; ClockP_Params_init(&(portsParams.clockParams)); portsParams.clockParams.arg = (uintptr_t) handle; object->timeoutClk = ClockP_create((ClockP_Fxn) &readBlockingTimeout, &(portsParams.clockParams)); if (object->timeoutClk == NULL) { DebugP_log1("UART:(%p) ClockP_create() failed.", hwAttrs->baseAddr); UARTMSP432_close(handle); return (NULL); } } else { object->state.drainByISR = false; object->readCallback = params->readCallback; } /* * Initialize UART read buffer - will store received bytes until * UART_read is invoked. */ RingBuf_construct(&object->ringBuffer, hwAttrs->ringBufPtr, hwAttrs->ringBufSize); /* * Store UART parameters & initialize peripheral. These are used to * re/initialize the peripheral when opened or changing performance level. */ object->state.readMode = params->readMode; object->state.writeMode = params->writeMode; object->state.readReturnMode = params->readReturnMode; object->state.readDataMode = params->readDataMode; object->state.writeDataMode = params->writeDataMode; object->state.readEcho = params->readEcho; object->readTimeout = params->readTimeout; object->writeTimeout = params->writeTimeout; object->baudRate = params->baudRate; object->stopBits = params->stopBits; object->parityType = params->parityType; object->readFxns = staticFxnTable[object->state.readMode][object->state.readDataMode]; object->writeBuf = NULL; object->readBuf = NULL; object->writeCount = 0; object->readCount = 0; object->writeSize = 0; object->readSize = 0; object->state.writeCR = false; object->state.txEnabled = false; object->state.rxEnabled = true; initHw(object, hwAttrs, clockFreq); DebugP_log1("UART:(%p) opened", hwAttrs->baseAddr); /* Return the handle */ return (handle); }
/* * ======== WatchdogMSP432_open ======== */ Watchdog_Handle WatchdogMSP432_open(Watchdog_Handle handle, Watchdog_Params *params) { uintptr_t key; HwiP_Params hwiParams; WatchdogMSP432_Object *object = handle->object; WatchdogMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; /* If params are NULL use defaults. */ if (params == NULL) { params = (Watchdog_Params *) &Watchdog_defaultParams; } /* Ensure a callbackFxn is specified if using watchdog in interval mode */ DebugP_assert((params->resetMode == Watchdog_RESET_ON) || (params->callbackFxn != NULL)); /* Don't allow preemption */ key = HwiP_disable(); /* Check if the Watchdog is open already with the HWAttrs */ if (object->isOpen) { HwiP_restore(key); DebugP_log1("Watchdog: Handle %x already in use.", (uintptr_t) handle); return (NULL); } object->isOpen = true; HwiP_restore(key); /* * Add power management support - Disable performance transitions while * opening the driver. */ Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); if (params->resetMode == Watchdog_RESET_ON || hwAttrs->clockSource == WDT_A_CLOCKSOURCE_SMCLK || hwAttrs->clockSource == WDT_A_CLOCKSOURCE_ACLK) { /* * Do not support power modes lower than LPM0 if in watchdog mode or * in interval mode and using SMCLK or ACLK as clock sources. * Additionally, LPM3.5 cannot be reached. */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0); } else { /* * Interval mode and not using SMCLK and ACLK as clock sources. Can * be configured as a LPM3.5 wake up source, so we do not set the * SHUTDOWN_0 constraint. */ Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1); } /* SHUTDOWN_1 (LPM4.5) not supported while driver is open */ Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1); /* Construct Hwi object for watchdog */ if (params->callbackFxn) { HwiP_Params_init(&hwiParams); hwiParams.arg = (uintptr_t) handle; hwiParams.priority = hwAttrs->intPriority; object->hwiHandle = HwiP_create(hwAttrs->intNum, params->callbackFxn, &hwiParams); if (!object->hwiHandle) { DebugP_log0("Watchdog: HwiP_create() failed"); Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); WatchdogMSP432_close(handle); return (NULL); } } /* Configure and initialize WDT */ object->resetMode = params->resetMode; if (object->resetMode == Watchdog_RESET_ON) { MAP_WDT_A_initWatchdogTimer(hwAttrs->clockSource, hwAttrs->clockDivider); } else { MAP_WDT_A_initIntervalTimer(hwAttrs->clockSource, hwAttrs->clockDivider); } MAP_WDT_A_startTimer(); /* Allow performance level changes */ Power_releaseConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); DebugP_log1("Watchdog: (0x%x) opened and enabled.", (uintptr_t) handle); /* Return handle of the Watchdog object */ return (handle); }
/* * ======== PWMTimerMSP432_setDuty ======== * @pre Function assumes that handle is not NULL */ void PWMTimerMSP432_setDuty(PWM_Handle handle, uint32_t duty) { uintptr_t key; uint16_t period; uint32_t newDuty; PWMTimerMSP432_Object *object = handle->object; PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; key = HwiP_disable(); period = MAP_Timer_A_getCaptureCompareCount(hwAttrs->baseAddr, TIMER_A_CAPTURECOMPARE_REGISTER_0); switch(object->dutyMode) { case PWM_DUTY_COUNTS: /* Duty specified as PWM timer counts */ DebugP_assert(duty <= period); newDuty = duty; break; case PWM_DUTY_TIME: /* Duty is specified in microseconds */ DebugP_assert(duty <= (object->pwmTimerStatus)->period); newDuty = (duty * (object->pwmTimerStatus)->cyclesPerMicroSec) / (object->pwmTimerStatus)->prescalar; break; case PWM_DUTY_SCALAR: /* Duty specified as a number [0 - 65535] scaled to the period */ DebugP_assert(duty <= maxDutyValue); if (duty >= maxDutyValue) { newDuty = period; } else { newDuty = (period * 100) / maxDutyValue; newDuty = (newDuty * duty) / 100; } break; default: DebugP_log1("PWM: (%p) unsupported PWM duty mode; duty unchanged", (uintptr_t) handle); return; } /* * This condition ensures that the output will remain active if the newDuty * is greater or equal to the period. */ if (newDuty >= period) { newDuty = (period + 1); } MAP_Timer_A_setCompareValue(hwAttrs->baseAddr, hwAttrs->compareRegister, newDuty); HwiP_restore(key); DebugP_log2("PWM: (%p) duty set to: %d", (uintptr_t) handle, duty); }
/* * ======== PWMTimerMSP432_open ======== * @pre Function assumes that the handle is not NULL */ PWM_Handle PWMTimerMSP432_open(PWM_Handle handle, PWM_Params *params) { uintptr_t key; bool timerIsRunning; uint8_t cyclesPerMicroSec; uint32_t clockFreq; uint32_t tempPeriod; Timer_A_PWMConfig pwmConfig; PowerMSP432_Freqs powerFreqs; PWMTimerMSP432_Object *object = handle->object; PWMTimerMSP432_HWAttrs const *hwAttrs = handle->hwAttrs; if(params == NULL) { params = (PWM_Params *) &PWM_defaultParams; } key = HwiP_disable(); /* * Before opening the PWM instance, we must verify that the Timer is not * already open or being used by another source (possibly the Kernel). * Additionally, the Timer peripheral could have already been initialized * by another PWM instance, so we must verify if any other PWM driver * (on the same Timer) is initialized. */ timerIsRunning = (TIMER_A_CMSIS(hwAttrs->baseAddr)->rCTL.b.bMC != TIMER_A_STOP_MODE); if (object->isOpen || (timerIsRunning && (object->pwmTimerStatus)->activeOutputsMask == 0)) { /* Timer already opened or used by source other than PWM driver */ HwiP_restore(key); DebugP_log1("PWM:(%p) timer used by another source.", (uintptr_t) handle); return (NULL); } /* * Timer capture/compare register 0 is used as the period. It cannot be * used to generate PWM output. */ DebugP_assert(hwAttrs->compareRegister != TIMER_A_CAPTURECOMPARE_REGISTER_0); /* * Add power management support - PWM driver does not allow performance * level changes, low power modes or shutdown while open. */ Power_setConstraint(PowerMSP432_DISALLOW_PERF_CHANGES); Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_0); Power_setConstraint(PowerMSP432_DISALLOW_SHUTDOWN_1); PowerMSP432_getFreqs(Power_getPerformanceLevel(), &powerFreqs); clockFreq = powerFreqs.SMCLK; cyclesPerMicroSec = clockFreq / 1000000; /* Assert if period is too large for peripheral */ tempPeriod = params->period * cyclesPerMicroSec; DebugP_assert(tempPeriod <= maxPrescalarValue * maxDutyValue); /* * Verify if timer has been initialized by another PWM instance. If so, * make sure PWM periods are the same, do not open driver if otherwise. */ if ((object->pwmTimerStatus)->period && (object->pwmTimerStatus)->period != params->period) { HwiP_restore(key); DebugP_log1("PWM:(%p) differing PWM periods, cannot open driver.", (uintptr_t) handle); PWMTimerMSP432_close(handle); return (NULL); } else { /* PWM timer has not been initialized */ (object->pwmTimerStatus)->cyclesPerMicroSec = cyclesPerMicroSec; (object->pwmTimerStatus)->prescalar = PWMTimerMSP432_calculatePrescalar(tempPeriod); (object->pwmTimerStatus)->period = params->period; } /* Mark driver as being used */ object->isOpen = true; (object->pwmTimerStatus)->activeOutputsMask |= object->pwmCompareOutputBit; HwiP_restore(key); /* Store PWM instance parameters */ object->dutyMode = params->dutyMode; /* Configure PWM output & start timer */ pwmConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; pwmConfig.clockSourceDivider = (object->pwmTimerStatus)->prescalar; pwmConfig.timerPeriod = tempPeriod / (object->pwmTimerStatus)->prescalar; pwmConfig.compareRegister = hwAttrs->compareRegister; pwmConfig.compareOutputMode = outputPolarity[params->polarity]; pwmConfig.dutyCycle = 0; MAP_Timer_A_generatePWM(hwAttrs->baseAddr, &pwmConfig); MAP_Timer_A_startCounter(hwAttrs->baseAddr, TIMER_A_UP_MODE); DebugP_log2("PWM:(%p) opened; period set to: %d", (uintptr_t) handle, params->period); return (handle); }
/* * ======== SPICC3200DMA_configDMA ======== * This functions configures the transmit and receive DMA channels for a given * SPI_Handle and SPI_Transaction * * @pre Function assumes that the handle and transaction is not NULL */ static void SPICC3200DMA_configDMA(SPI_Handle handle, SPI_Transaction *transaction) { uintptr_t key; SPIDataType dummy; void *buf; uint32_t channelControlOptions; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; /* Clear out the FIFO */ while (MAP_SPIDataGetNonBlocking(hwAttrs->baseAddr, &dummy)) {} /* Configure DMA for RX */ MAP_uDMAChannelAssign(hwAttrs->rxChannelIndex); MAP_uDMAChannelAttributeDisable(hwAttrs->rxChannelIndex, UDMA_ATTR_ALTSELECT); if (transaction->rxBuf) { channelControlOptions = dmaRxConfig[object->frameSize]; buf = transaction->rxBuf; } else { channelControlOptions = dmaNullConfig[object->frameSize]; buf = hwAttrs->scratchBufPtr; } MAP_uDMAChannelControlSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT, channelControlOptions); MAP_uDMAChannelTransferSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(hwAttrs->baseAddr + MCSPI_O_RX0), buf, transaction->count); /* Configure DMA for TX */ MAP_uDMAChannelAssign(hwAttrs->txChannelIndex); MAP_uDMAChannelAttributeDisable(hwAttrs->txChannelIndex, UDMA_ATTR_ALTSELECT); if (transaction->txBuf) { channelControlOptions = dmaTxConfig[object->frameSize]; buf = transaction->txBuf; } else { channelControlOptions = dmaNullConfig[object->frameSize]; *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue; buf = hwAttrs->scratchBufPtr; } MAP_uDMAChannelControlSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT, channelControlOptions); MAP_uDMAChannelTransferSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT, UDMA_MODE_BASIC, buf, (void *)(hwAttrs->baseAddr + MCSPI_O_TX0), transaction->count); DebugP_log1("SPI:(%p) DMA transfer enabled", hwAttrs->baseAddr); DebugP_log4("SPI: DMA transaction: %p, rxBuf: %p; txBuf: %p; Count: %d", (uintptr_t)transaction, (uintptr_t)transaction->rxBuf, (uintptr_t)transaction->txBuf, (uintptr_t)transaction->count); key = HwiP_disable(); MAP_uDMAChannelEnable(hwAttrs->rxChannelIndex); MAP_uDMAChannelEnable(hwAttrs->txChannelIndex); HwiP_restore(key); MAP_SPIWordCountSet(hwAttrs->baseAddr, transaction->count); }
/* * ======== SPICC3200DMA_open ======== * @pre Function assumes that the handle is not NULL */ SPI_Handle SPICC3200DMA_open(SPI_Handle handle, SPI_Params *params) { uintptr_t key; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; SemaphoreP_Params semParams; HwiP_Params hwiParams; key = HwiP_disable(); if(object->isOpen == true) { HwiP_restore(key); return (NULL); } object->isOpen = true; HwiP_restore(key); if (params == NULL) { params = (SPI_Params *) &SPI_defaultParams; } DebugP_assert((params->dataSize >= 4) && (params->dataSize <= 32)); /* Determine if we need to use an 8, 16 or 32-bit frameSize for the DMA */ if (params->dataSize <= 8) { object->frameSize = SPICC3200DMA_8bit; } else if (params->dataSize <= 16) { object->frameSize = SPICC3200DMA_16bit; } else { object->frameSize = SPICC3200DMA_32bit; } /* Store SPI mode of operation */ object->spiMode = params->mode; object->transferMode = params->transferMode; object->transaction = NULL; object->rxFifoTrigger = (1 << object->frameSize); object->txFifoTrigger = (1 << object->frameSize); object->bitRate = params->bitRate; object->frameFormat = params->frameFormat; object->dataSize = params->dataSize; /* Register power dependency - i.e. power up and enable clock for SPI. */ Power_setDependency(getPowerMgrId(hwAttrs->baseAddr)); Power_setDependency(PowerCC3200_PERIPH_UDMA); Power_registerNotify(&(object->notifyObj), PowerCC3200_AWAKE_LPDS, SPICC3200DMA_postNotify, (uintptr_t)handle); HwiP_Params_init(&hwiParams); hwiParams.arg = (uintptr_t)handle; hwiParams.priority = hwAttrs->intPriority; object->hwiHandle = HwiP_create(hwAttrs->intNum, SPICC3200DMA_hwiFxn, &hwiParams); if (object->hwiHandle == NULL) { SPICC3200DMA_close(handle); return (NULL); } if (object->transferMode == SPI_MODE_BLOCKING) { DebugP_log1("SPI:(%p) in SPI_MODE_BLOCKING mode", hwAttrs->baseAddr); SemaphoreP_Params_init(&semParams); semParams.mode = SemaphoreP_Mode_BINARY; object->transferComplete = SemaphoreP_create(0, &semParams); if (object->transferComplete == NULL) { SPICC3200DMA_close(handle); return (NULL); } object->transferCallbackFxn = SPICC3200DMA_transferCallback; } else { DebugP_log1("SPI:(%p) in SPI_MODE_CALLBACK mode", hwAttrs->baseAddr); DebugP_assert(params->transferCallbackFxn != NULL); object->transferCallbackFxn = params->transferCallbackFxn; } if (uDMAControlBase == NULL) { uDMAControlBase = MAP_uDMAControlBaseGet(); } SPICC3200DMA_initHw(handle); DebugP_log3("SPI:(%p) CPU freq: %d; SPI freq to %d", hwAttrs->baseAddr, PRCMPeripheralClockGet(hwAttrs->spiPRCM), params->bitRate); DebugP_log1("SPI:(%p) opened", hwAttrs->baseAddr); return (handle); }
/* * ======== CameraCC3200DMA_open ======== */ Camera_Handle CameraCC3200DMA_open(Camera_Handle handle, Camera_Params *params) { uintptr_t key; CameraCC3200DMA_Object *object = handle->object; CameraCC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; unsigned long hSyncPolarityConfig; unsigned long vSyncPolarityConfig; unsigned long byteOrderConfig; unsigned long interfaceSync; unsigned long pixelClkConfig; HwiP_Params hwiParams; SemaphoreP_Params semParams; /* If params are NULL use defaults. */ if (params == NULL) { params = (Camera_Params *) &Camera_defaultParams; } /* Timeouts cannot be 0 */ DebugP_assert((params->captureTimeout != 0)); /* Check that a callback is set */ DebugP_assert((params->captureMode != Camera_MODE_CALLBACK) || (params->captureCallback != NULL)); /* Disable preemption while checking if the Camera is open. */ key = HwiP_disable(); /* Check if the Camera is open already with the base addr. */ if (object->opened == true) { HwiP_restore(key); DebugP_log1("Camera:(%p) already in use.", hwAttrs->baseAddr); return (NULL); } object->opened = true; HwiP_restore(key); object->operationMode = params->captureMode; object->captureCallback = params->captureCallback; object->captureTimeout = params->captureTimeout; /* Set Camera variables to defaults. */ object->captureBuf = NULL; object->bufferlength = 0; object->frameLength = 0; object->inUse = 0; /* * Register power dependency. Keeps the clock running in SLP * and DSLP modes. */ Power_setDependency(PowerCC3200_PERIPH_CAMERA); Power_setDependency(PowerCC3200_PERIPH_UDMA); /* Disable the Camera interrupt. */ MAP_CameraIntDisable(hwAttrs->baseAddr, (CAM_INT_FE | CAM_INT_DMA)); HwiP_clearInterrupt(hwAttrs->intNum); /* Create Hwi object for the Camera peripheral. */ /* Register the interrupt for this Camera peripheral. */ HwiP_Params_init(&hwiParams); hwiParams.arg = (uintptr_t)handle; hwiParams.priority = hwAttrs->intPriority; object->hwiHandle = HwiP_create(hwAttrs->intNum, CameraCC3200DMA_hwiIntFxn, &hwiParams); if (object->hwiHandle == NULL) { CameraCC3200DMA_close(handle); return (NULL); } MAP_IntEnable(INT_CAMERA); SemaphoreP_Params_init(&semParams); semParams.mode = SemaphoreP_Mode_BINARY; /* If capture is blocking create a semaphore and set callback. */ if (object->operationMode == Camera_MODE_BLOCKING) { object->captureSem = SemaphoreP_create(0, &semParams); if (object->captureSem) { CameraCC3200DMA_close(handle); return (NULL); } object->captureCallback = &captureSemCallback; } MAP_CameraReset(hwAttrs->baseAddr); if (params->hsyncPolarity == Camera_HSYNC_POLARITY_HIGH) { hSyncPolarityConfig = CAM_HS_POL_HI; } else { hSyncPolarityConfig = CAM_HS_POL_LO; } if (params->vsyncPolarity == Camera_VSYNC_POLARITY_HIGH) { vSyncPolarityConfig = CAM_VS_POL_HI; } else { vSyncPolarityConfig = CAM_VS_POL_LO; } if (params->byteOrder == Camera_BYTE_ORDER_SWAP) { byteOrderConfig = CAM_ORDERCAM_SWAP; } else { byteOrderConfig = 0; } if (params->interfaceSync == Camera_INTERFACE_SYNC_OFF) { interfaceSync = CAM_NOBT_SYNCHRO; } else { interfaceSync = CAM_NOBT_SYNCHRO | CAM_IF_SYNCHRO | CAM_BT_CORRECT_EN; } if (params->pixelClkConfig == Camera_PCLK_CONFIG_RISING_EDGE) { pixelClkConfig = CAM_PCLK_RISE_EDGE; } else { pixelClkConfig = CAM_PCLK_FALL_EDGE; } MAP_CameraParamsConfig(hwAttrs->baseAddr, hSyncPolarityConfig, vSyncPolarityConfig, byteOrderConfig | interfaceSync | pixelClkConfig); /*Set the clock divider based on the output clock */ MAP_CameraXClkConfig(hwAttrs->baseAddr, PRCMPeripheralClockGet(PRCM_CAMERA), params->outputClock); /*Setting the FIFO threshold for a DMA request */ MAP_CameraThresholdSet(hwAttrs->baseAddr, 8); MAP_CameraIntEnable(hwAttrs->baseAddr, (CAM_INT_FE | CAM_INT_DMA)); MAP_CameraDMAEnable(hwAttrs->baseAddr); DebugP_log1("Camera:(%p) opened", hwAttrs->baseAddr); /* Return the handle */ return (handle); }