/** * @brief Sets the number of transfers to be performed. * @note This function can be invoked in both ISR or thread context. * * @pre The channel must have been allocated using @p dmaChannelAllocate(). * @post After use the channel can be released using @p dmaChannelRelease(). * * @param[in] dmastp pointer to a sama_dma_channel_t structure * @param[in] size value to be written in the XDMAC_CUBC register * * @special * */ void dmaChannelSetTransactionSize(sama_dma_channel_t *dmachp, size_t n) { uint32_t i; uint32_t divisor; /* Single block single microblock */ if (n <= XDMAC_MAX_BT_SIZE) { (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(n); } /* Single block multiple microblocks */ else { /* If n exceeds XDMAC_MAX_BT_SIZE, split the transfer in microblocks */ for (i = 2; i < XDMAC_MAX_BT_SIZE; i++) { divisor = XDMAC_MAX_BT_SIZE / i; if (n % divisor) continue; if ((n / divisor) <= (XDMAC_MAX_BLOCK_LEN + 1)) { (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(i); (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CBC = XDMAC_CBC_BLEN((n / divisor) - 1); break; } } osalDbgAssert(i != XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); } }
/** * \brief Set block length for the relevant channel of given XDMA. * * \param pXdmac Pointer to the XDMAC peripheral. * \param channel Particular channel number. * \param blen Block length. */ void XDMAC_SetBlockControl(Xdmac *pXdmac, uint8_t channel, uint16_t blen) { assert(pXdmac); assert(channel < XDMAC_CHANNEL_NUM); pXdmac->XDMAC_CHID[channel].XDMAC_CBC = XDMAC_CBC_BLEN(blen); }