/** * @brief Fill an area with a color. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] color The color of the fill * * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif uint32_t area; area = cx*cy; GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else uint32_t index; for(index = 0; index < area; index++) GDISP_LLD(writedata)(color); #endif //#ifdef GDISP_USE_DMA }
/** * @brief Fill an area with a color. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] color The color of the fill * * @notapi */ void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { uint32_t area; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif area = cx*cy; gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1); write_index(RA8875_WRITE_MEMORY_START); #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else uint32_t index; for(index = 0; index < area; index++) write_data(color); #endif //#ifdef GDISP_USE_DMA }
/** * @brief Wait end of data transaction and performs finalizations. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. */ static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ osalSysLock(); if (sdcp->sdmmc->MASK != 0) osalThreadSuspendS(&sdcp->thread); if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) { osalSysUnlock(); return HAL_FAILED; } /* Waits for transfer completion at DMA level, then the stream is disabled and cleared.*/ dmaWaitCompletion(sdcp->dma); sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS; sdcp->sdmmc->DCTRL = 0; osalSysUnlock(); /* Finalize transaction.*/ if (n > 1) return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); return HAL_SUCCESS; }
/** * @brief Fill an area with a bitmap. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] srcx, srcy The bitmap position to start the fill from * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } if (srcx+cx > srccx) cx = srccx - srcx; if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); buffer += srcx + srcy * srccx; #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint32_t area = cx*cy; uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else coord_t endx, endy; unsigned lg; endx = srcx + cx; endy = y + cy; lg = srccx - cx; for(; y < endy; y++, buffer += lg) for(x=srcx; x < endx; x++) GDISP_LLD(writedata)(*buffer++); #endif //#ifdef GDISP_USE_DMA }
/** * @brief Wait end of data transaction and performs finalizations. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @return The operation status. * @retval CH_SUCCESS operation succeeded. * @retval CH_FAILED operation failed. */ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ chSysLock(); if (SDIO->MASK != 0) { chDbgAssert(sdcp->thread == NULL, "sdc_lld_start_data_transaction(), #1", "not NULL"); sdcp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); chDbgAssert(sdcp->thread == NULL, "sdc_lld_start_data_transaction(), #2", "not NULL"); } if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { chSysUnlock(); return CH_FAILED; } #if (defined(STM32F4XX) || defined(STM32F2XX)) /* Wait until DMA channel enabled to be sure that all data transferred.*/ while (sdcp->dma->stream->CR & STM32_DMA_CR_EN) ; /* DMA event flags must be manually cleared.*/ dmaStreamClearInterrupt(sdcp->dma); SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->DCTRL = 0; chSysUnlock(); /* Wait until interrupt flags to be cleared.*/ /*while (((DMA2->LISR) >> (sdcp->dma->ishift)) & STM32_DMA_ISR_TCIF) dmaStreamClearInterrupt(sdcp->dma);*/ #else /* Waits for transfer completion at DMA level, the the stream is disabled and cleared.*/ dmaWaitCompletion(sdcp->dma); SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->DCTRL = 0; chSysUnlock(); #endif /* Finalize transaction.*/ if (n > 1) return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); return CH_SUCCESS; }
/** * @brief Wait end of data transaction and performs finalizations. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] n number of blocks in transaction * @param[in] resp pointer to the response buffer * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. * @retval HAL_FAILED operation failed. */ static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, uint32_t *resp) { /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ osalSysLock(); if (sdcp->sdio->MASK != 0) osalThreadSuspendS(&sdcp->thread); if ((sdcp->sdio->STA & SDIO_STA_DATAEND) == 0) { osalSysUnlock(); return HAL_FAILED; } #if (defined(STM32F4XX) || defined(STM32F2XX)) /* Wait until DMA channel enabled to be sure that all data transferred.*/ while (sdcp->dma->stream->CR & STM32_DMA_CR_EN) ; /* DMA event flags must be manually cleared.*/ dmaStreamClearInterrupt(sdcp->dma); sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS; sdcp->sdio->DCTRL = 0; osalSysUnlock(); /* Wait until interrupt flags to be cleared.*/ /*while (((DMA2->LISR) >> (sdcp->dma->ishift)) & STM32_DMA_ISR_TCIF) dmaStreamClearInterrupt(sdcp->dma);*/ #else /* Waits for transfer completion at DMA level, then the stream is disabled and cleared.*/ dmaWaitCompletion(sdcp->dma); sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS; sdcp->sdio->DCTRL = 0; osalSysUnlock(); #endif /* Finalize transaction.*/ if (n > 1) return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); return HAL_SUCCESS; }
/* * Application entry point. */ int main(void) { unsigned i; static uint8_t patterns1[4096], patterns2[4096], buf1[4096], buf2[4096]; /* System initializations. - HAL initialization, this also initializes the configured device drivers and performs the board-specific initializations. - Kernel initialization, the main() function becomes a thread and the RTOS is active.*/ halInit(); chSysInit(); /* Creates the blinker thread.*/ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 10, Thread1, NULL); /* Activates the ADC1 driver and the temperature sensor.*/ adcStart(&ADCD1, NULL); adcSTM32EnableTSVREFE(); /* Starts an ADC continuous conversion and its watchdog virtual timer.*/ chVTSet(&adcvt, MS2ST(10), tmo, (void *)"ADC timeout"); adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH); /* Activating SPI drivers.*/ spiStart(&SPID1, &hs_spicfg); spiStart(&SPID2, &hs_spicfg); spiStart(&SPID3, &hs_spicfg); /* Starting SPI threads instances.*/ chThdCreateStatic(waSPI1, sizeof(waSPI1), NORMALPRIO + 1, spi_thread, &SPID1); chThdCreateStatic(waSPI2, sizeof(waSPI2), NORMALPRIO + 1, spi_thread, &SPID2); chThdCreateStatic(waSPI3, sizeof(waSPI3), NORMALPRIO + 1, spi_thread, &SPID3); /* Allocating two DMA2 streams for memory copy operations.*/ if (dmaStreamAllocate(STM32_DMA2_STREAM6, 0, NULL, NULL)) chSysHalt("DMA already in use"); if (dmaStreamAllocate(STM32_DMA2_STREAM7, 0, NULL, NULL)) chSysHalt("DMA already in use"); for (i = 0; i < sizeof (patterns1); i++) patterns1[i] = (uint8_t)i; for (i = 0; i < sizeof (patterns2); i++) patterns2[i] = (uint8_t)(i ^ 0xAA); /* Normal main() thread activity, it does continues memory copy operations using 2 DMA streams at the lowest priority.*/ while (true) { virtual_timer_t vt; chVTObjectInit(&vt); /* Starts a VT working as watchdog to catch a malfunction in the DMA driver.*/ chVTSet(&vt, MS2ST(10), tmo, (void *)"copy timeout"); /* Copy pattern 1.*/ dmaStartMemCopy(STM32_DMA2_STREAM6, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE, patterns1, buf1, sizeof (patterns1)); dmaStartMemCopy(STM32_DMA2_STREAM7, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE, patterns1, buf2, sizeof (patterns1)); dmaWaitCompletion(STM32_DMA2_STREAM6); dmaWaitCompletion(STM32_DMA2_STREAM7); if (memcmp(patterns1, buf1, sizeof (patterns1))) chSysHalt("pattern error"); if (memcmp(patterns1, buf2, sizeof (patterns1))) chSysHalt("pattern error"); /* Copy pattern 2.*/ dmaStartMemCopy(STM32_DMA2_STREAM6, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE, patterns2, buf1, sizeof (patterns2)); dmaStartMemCopy(STM32_DMA2_STREAM7, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE, patterns2, buf2, sizeof (patterns2)); dmaWaitCompletion(STM32_DMA2_STREAM6); dmaWaitCompletion(STM32_DMA2_STREAM7); if (memcmp(patterns2, buf1, sizeof (patterns2))) chSysHalt("pattern error"); if (memcmp(patterns2, buf2, sizeof (patterns2))) chSysHalt("pattern error"); /* Stops the watchdog.*/ chVTReset(&vt); chThdSleepMilliseconds(2); } return 0; }