summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c')
-rw-r--r--c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c1064
1 files changed, 0 insertions, 1064 deletions
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c b/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c
deleted file mode 100644
index c13957bcf8..0000000000
--- a/c/src/lib/libbsp/arm/altera-cyclone-v/hwlib/src/hwmgr/alt_dma_program.c
+++ /dev/null
@@ -1,1064 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2013 Altera Corporation. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- ******************************************************************************/
-
-#include <bsp/alt_dma_program.h>
-#include <bsp/alt_cache.h>
-#include <stdio.h>
-
-/////
-
-// NOTE: To enable debugging output, delete the next line and uncomment the
-// line after.
-#define dprintf(...)
-// #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
-
-/////
-
-//
-// The following section describes how the bits are used in the "flag" field:
-//
-
-// [17:16] Which loop registers (LOOP0, LOOP1) are currently being used by a
-// partially assembled program. LOOP0 is always used before LOOP1. LOOP1 is
-// always ended before LOOP0.
-#define ALT_DMA_PROGRAM_FLAG_LOOP0 (1UL << 16)
-#define ALT_DMA_PROGRAM_FLAG_LOOP1 (1UL << 17)
-#define ALT_DMA_PROGRAM_FLAG_LOOP_ALL (ALT_DMA_PROGRAM_FLAG_LOOP0 | ALT_DMA_PROGRAM_FLAG_LOOP1)
-
-// [18] Flag that marks LOOP0 as a forever loop. Said another way, LOOP0 is
-// being used to execute the DMALPFE directive.
-#define ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE (1UL << 18)
-// [19] Flag that marks LOOP1 as a forever loop. Said another way, LOOP1 is
-// being used to execute the DMALPFE directive.
-#define ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE (1UL << 19)
-
-// [24] Flag that the first SAR has been programmed. The SAR field is valid and
-// is the offset from the start of the buffer where SAR is located.
-#define ALT_DMA_PROGRAM_FLAG_SAR (1UL << 24)
-// [25] Flag that the first DAR has been programmed. The DAR field is valid and
-// is the offset from the start of the buffer where DAR is located.
-#define ALT_DMA_PROGRAM_FLAG_DAR (1UL << 25)
-
-// [31] Flag that marks the last assembled instruction as DMAEND.
-#define ALT_DMA_PROGRAM_FLAG_ENDED (1UL << 31)
-
-/////
-
-ALT_STATUS_CODE alt_dma_program_init(ALT_DMA_PROGRAM_t * pgm)
-{
- // Clear the variables that matter.
- pgm->flag = 0;
- pgm->code_size = 0;
-
- // Calculate the cache aligned start location of the buffer.
- size_t buffer = (size_t)pgm->program;
- size_t offset = ((buffer + ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1) & ~(ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1)) - buffer;
-
- // It is safe to cast to uint16_t because the extra offset can only be up to
- // (ALT_DMA_PROGRAM_CACHE_LINE_SIZE - 1) or 31, which is within range of the
- // uint16_t.
- pgm->buffer_start = (uint16_t)offset;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_uninit(ALT_DMA_PROGRAM_t * pgm)
-{
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_clear(ALT_DMA_PROGRAM_t * pgm)
-{
- // Clear the variables that matter
- pgm->flag = 0;
- pgm->code_size = 0;
-
- return ALT_E_SUCCESS;
-}
-
-__attribute__((weak)) ALT_STATUS_CODE alt_cache_system_clean(void * address, size_t length)
-{
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_validate(const ALT_DMA_PROGRAM_t * pgm)
-{
- // Verify that at least one instruction is in the buffer
- if (pgm->code_size == 0)
- {
- return ALT_E_ERROR;
- }
-
- // Verify all loops are completed.
- if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
- {
- return ALT_E_ERROR;
- }
-
- // Verify last item is DMAEND
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_ENDED))
- {
- return ALT_E_ERROR;
- }
-
- // Sync the DMA program to RAM.
- void * vaddr = (void *)((uintptr_t)(pgm->program + pgm->buffer_start) & ~(ALT_CACHE_LINE_SIZE - 1));
- size_t length = (pgm->code_size + ALT_CACHE_LINE_SIZE) & ~(ALT_CACHE_LINE_SIZE - 1);
-
- dprintf("DEBUG[DMAP]: Program (real) @ %p, length = 0x%x.\n", pgm->program + pgm->buffer_start, pgm->code_size);
- dprintf("DEBUG[DMAP]: Clean: addr = %p, length = 0x%x.\n", vaddr, length);
-
- return alt_cache_system_clean(vaddr, length);
-}
-
-ALT_STATUS_CODE alt_dma_program_progress_reg(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_REG_t reg,
- uint32_t current, uint32_t * progress)
-{
- // Pointer to where the register is initialized in the program buffer.
- uint8_t * buffer = NULL;
-
- switch (reg)
- {
- case ALT_DMA_PROGRAM_REG_SAR:
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
- {
- return ALT_E_BAD_ARG;
- }
- buffer = pgm->program + pgm->buffer_start + pgm->sar;
- break;
-
- case ALT_DMA_PROGRAM_REG_DAR:
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
- {
- return ALT_E_BAD_ARG;
- }
- buffer = pgm->program + pgm->buffer_start + pgm->dar;
- break;
-
- default:
- return ALT_E_BAD_ARG;
- }
-
- uint32_t initial =
- (buffer[3] << 24) |
- (buffer[2] << 16) |
- (buffer[1] << 8) |
- (buffer[0] << 0);
-
- *progress = current - initial;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_update_reg(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_REG_t reg, uint32_t val)
-{
- uint8_t * buffer = NULL;
-
- switch (reg)
- {
- case ALT_DMA_PROGRAM_REG_SAR:
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
- {
- return ALT_E_BAD_ARG;
- }
- buffer = pgm->program + pgm->buffer_start + pgm->sar;
- break;
-
- case ALT_DMA_PROGRAM_REG_DAR:
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
- {
- return ALT_E_BAD_ARG;
- }
- buffer = pgm->program + pgm->buffer_start + pgm->dar;
- break;
-
- default:
- return ALT_E_BAD_ARG;
- }
-
- buffer[0] = (uint8_t)((val >> 0) & 0xff);
- buffer[1] = (uint8_t)((val >> 8) & 0xff);
- buffer[2] = (uint8_t)((val >> 16) & 0xff);
- buffer[3] = (uint8_t)((val >> 24) & 0xff);
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAADDH(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val)
-{
- // For information on DMAADDH, see PL330, section 4.3.1.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 3) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify valid register; construct instruction modifier.
- uint8_t ra_mask = 0;
- switch (addr_reg)
- {
- case ALT_DMA_PROGRAM_REG_SAR:
- ra_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_REG_DAR:
- ra_mask = 0x2;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAADDH
- buffer[0] = 0x54 | ra_mask;
- buffer[1] = (uint8_t)(val & 0xff);
- buffer[2] = (uint8_t)(val >> 8);
-
- // Update the code size.
- pgm->code_size += 3;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAADNH(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_REG_t addr_reg, uint16_t val)
-{
- // For information on DMAADNH, see PL330, section 4.3.2.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 3) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify valid register; construct instruction modifier.
- uint8_t ra_mask = 0;
- switch (addr_reg)
- {
- case ALT_DMA_PROGRAM_REG_SAR:
- ra_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_REG_DAR:
- ra_mask = 0x2;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAADNH
- buffer[0] = 0x5c | ra_mask;
- buffer[1] = (uint8_t)(val & 0xff);
- buffer[2] = (uint8_t)(val >> 8);
-
- // Update the code size.
- pgm->code_size += 3;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAEND(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMAEND, see PL330, section 4.3.3.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAEND
- buffer[0] = 0x00;
-
- // Update the code size.
- pgm->code_size += 1;
-
- // Mark program as ended.
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_ENDED;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAFLUSHP(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PERIPH_t periph)
-{
- // For information on DMAFLUSHP, see PL330, section 4.3.4.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify valid peripheral identifier.
- if (periph > ((1 << 5) - 1))
- {
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAFLUSHP
- buffer[0] = 0x35;
- buffer[1] = (uint8_t)(periph) << 3;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAGO(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_CHANNEL_t channel, uint32_t val,
- ALT_DMA_SECURITY_t sec)
-{
- // For information on DMAGO, see PL330, section 4.3.5.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 6) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify channel
- switch (channel)
- {
- case ALT_DMA_CHANNEL_0:
- case ALT_DMA_CHANNEL_1:
- case ALT_DMA_CHANNEL_2:
- case ALT_DMA_CHANNEL_3:
- case ALT_DMA_CHANNEL_4:
- case ALT_DMA_CHANNEL_5:
- case ALT_DMA_CHANNEL_6:
- case ALT_DMA_CHANNEL_7:
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Verify security; construct ns mask value
- uint8_t ns_mask = 0;
- switch (sec)
- {
- case ALT_DMA_SECURITY_DEFAULT:
- case ALT_DMA_SECURITY_SECURE:
- ns_mask = 0x0;
- break;
- case ALT_DMA_SECURITY_NONSECURE:
- ns_mask = 0x2;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAGO
- buffer[0] = 0xa0 | ns_mask;
- buffer[1] = (uint8_t)channel;
- buffer[2] = (uint8_t)((val >> 0) & 0xff);
- buffer[3] = (uint8_t)((val >> 8) & 0xff);
- buffer[4] = (uint8_t)((val >> 16) & 0xff);
- buffer[5] = (uint8_t)((val >> 24) & 0xff);
-
- // Update the code size.
- pgm->code_size += 6;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAKILL(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMAKILL, see PL330, section 4.3.6.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAKILL
- buffer[0] = 0x01;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMALD(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_INST_MOD_t mod)
-{
- // For information on DMALD, see PL330, section 4.3.7.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify instruction modifier; construct bs, x mask value.
- uint8_t bsx_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_NONE:
- bsx_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bsx_mask = 0x1;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bsx_mask = 0x3;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMALD
- buffer[0] = 0x04 | bsx_mask;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMALDP(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph)
-{
- // For information on DMALDP, see PL330, section 4.3.8.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify instruction modifier; construct bs mask value.
- uint8_t bs_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bs_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bs_mask = 0x2;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Verify valid peripheral identifier.
- if (periph > ((1 << 5) - 1))
- {
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMALDP
- buffer[0] = 0x25 | bs_mask;
- buffer[1] = (uint8_t)(periph) << 3;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMALP(ALT_DMA_PROGRAM_t * pgm,
- uint32_t iterations)
-{
- // For information on DMALP, see PL330, section 4.3.9.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify iterations in range
- if ((iterations == 0) || (iterations > 256))
- {
- return ALT_E_BAD_ARG;
- }
-
- // Find suitable LOOPx register to use; construct lc mask value.
- uint8_t lc_mask = 0;
- switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
- {
- case 0: // No LOOPx in use. Use LOOP0.
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0;
- pgm->loop0 = pgm->code_size + 2; // This is the first instruction after the DMALP
- lc_mask = 0x0;
- break;
-
- case ALT_DMA_PROGRAM_FLAG_LOOP0: // LOOP0 in use. Use LOOP1.
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1;
- pgm->loop1 = pgm->code_size + 2; // This is the first instruction after the DMALP
- lc_mask = 0x2;
- break;
-
- case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. Report error.
- return ALT_E_BAD_OPERATION;
-
- default: // Catastrophic error !!!
- return ALT_E_ERROR;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMALP
- buffer[0] = 0x20 | lc_mask;
- buffer[1] = (uint8_t)(iterations - 1);
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMALPEND(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_INST_MOD_t mod)
-{
- // For information on DMALPEND, see PL330, section 4.3.10.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify instruction modifier; construct bs, x mask value.
- uint8_t bsx_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_NONE:
- bsx_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bsx_mask = 0x1;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bsx_mask = 0x3;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Determine the loop to end, if it is a forever loop; construct lc mask, nf mask, and backwards jump value.
- uint8_t lc_mask = 0;
- uint8_t nf_mask = 0;
- uint16_t backwards_jump = 0;
- switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
- {
- case ALT_DMA_PROGRAM_FLAG_LOOP0: // LOOP0 in use. End LOOP0.
-
- backwards_jump = pgm->code_size - pgm->loop0;
-
- pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP0;
- pgm->loop0 = 0;
-
- lc_mask = 0x0;
-
- if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE)
- {
- pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE;
- }
- else
- {
- nf_mask = 0x10;
- }
- break;
-
- case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. End LOOP1.
-
- backwards_jump = pgm->code_size - pgm->loop1;
-
- pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP1;
- pgm->loop1 = 0;
-
- lc_mask = 0x4;
-
- if (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE)
- {
- pgm->flag &= ~ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE;
- }
- else
- {
- nf_mask = 0x10;
- }
- break;
-
- case 0: // No LOOPx in use. Report error!
- return ALT_E_BAD_OPERATION;
-
- default: // Catastrophic error !!!
- return ALT_E_ERROR;
- }
-
- // Verify that the jump size is suitable
- if (backwards_jump > 255)
- {
- return ALT_E_ARG_RANGE;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMALPEND
- buffer[0] = 0x28 | nf_mask | lc_mask | bsx_mask;
- buffer[1] = (uint8_t)(backwards_jump);
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMALPFE(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMALPFE, see PL330, section 4.3.11.
-
- // Find suitable LOOPx register to use;
- switch (pgm->flag & ALT_DMA_PROGRAM_FLAG_LOOP_ALL)
- {
- case 0: // No LOOPx in use. Use LOOP0.
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0;
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP0_IS_FE;
- pgm->loop0 = pgm->code_size;
- break;
-
- case ALT_DMA_PROGRAM_FLAG_LOOP0: // LOOP0 in use. Use LOOP1.
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1;
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_LOOP1_IS_FE;
- pgm->loop1 = pgm->code_size;
- break;
-
- case ALT_DMA_PROGRAM_FLAG_LOOP_ALL: // All LOOPx in use. Report error.
- return ALT_E_BAD_OPERATION;
-
- default: // Catastrophic error !!!
- return ALT_E_ERROR;
- }
-
- // Nothing to assemble.
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAMOV(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_REG_t chan_reg, uint32_t val)
-{
- // For information on DMAMOV, see PL330, section 4.3.12.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 6) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify channel register; construct rd mask value
- uint8_t rd_mask = 0;
- switch (chan_reg)
- {
- case ALT_DMA_PROGRAM_REG_SAR:
- rd_mask = 0;
- // If SAR has not been set before, mark the location of where SAR is in the buffer.
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_SAR))
- {
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_SAR;
- pgm->sar = pgm->code_size + 2;
- }
- break;
-
- case ALT_DMA_PROGRAM_REG_CCR:
- rd_mask = 1;
- break;
-
- case ALT_DMA_PROGRAM_REG_DAR:
- rd_mask = 2;
- // If DAR has not been set before, mark the location of where DAR is in the buffer.
- if (!(pgm->flag & ALT_DMA_PROGRAM_FLAG_DAR))
- {
- pgm->flag |= ALT_DMA_PROGRAM_FLAG_DAR;
- pgm->dar = pgm->code_size + 2;
- }
- break;
-
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAMOV
- buffer[0] = 0xbc;;
- buffer[1] = rd_mask;
- buffer[2] = (uint8_t)((val >> 0) & 0xff);
- buffer[3] = (uint8_t)((val >> 8) & 0xff);
- buffer[4] = (uint8_t)((val >> 16) & 0xff);
- buffer[5] = (uint8_t)((val >> 24) & 0xff);
-
- // Update the code size.
- pgm->code_size += 6;
-
- return ALT_E_SUCCESS;
-
-}
-
-ALT_STATUS_CODE alt_dma_program_DMANOP(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMANOP, see PL330, section 4.3.13.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMANOP
- buffer[0] = 0x18;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMARMB(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMARMB, see PL330, section 4.3.14.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMARMB
- buffer[0] = 0x12;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMASEV(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_EVENT_t evt)
-{
- // For information on DMA, see PL330, section 4.3.15.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Validate evt selection
- switch (evt)
- {
- case ALT_DMA_EVENT_0:
- case ALT_DMA_EVENT_1:
- case ALT_DMA_EVENT_2:
- case ALT_DMA_EVENT_3:
- case ALT_DMA_EVENT_4:
- case ALT_DMA_EVENT_5:
- case ALT_DMA_EVENT_6:
- case ALT_DMA_EVENT_7:
- case ALT_DMA_EVENT_ABORT:
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMASEV
- buffer[0] = 0x34;
- buffer[1] = (uint8_t)(evt) << 3;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAST(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_INST_MOD_t mod)
-{
- // For information on DMAST, see PL330, section 4.3.16.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify instruction modifier; construct bs, x mask value.
- uint8_t bsx_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_NONE:
- bsx_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bsx_mask = 0x1;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bsx_mask = 0x3;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAST
- buffer[0] = 0x08 | bsx_mask;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMASTP(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PROGRAM_INST_MOD_t mod, ALT_DMA_PERIPH_t periph)
-{
- // For information on DMASTP, see PL330, section 4.3.17.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify instruction modifier; construct bs mask value.
- uint8_t bs_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bs_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bs_mask = 0x2;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Verify valid peripheral identifier.
- if (periph > ((1 << 5) - 1))
- {
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMASTP
- buffer[0] = 0x29 | bs_mask;
- buffer[1] = (uint8_t)(periph) << 3;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMASTZ(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMASTZ, see PL330, section 4.3.18.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMASTZ
- buffer[0] = 0x0c;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAWFE(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_EVENT_t evt, bool invalid)
-{
- // For information on DMAWFE, see PL330, section 4.3.19.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Validate evt selection
- switch (evt)
- {
- case ALT_DMA_EVENT_0:
- case ALT_DMA_EVENT_1:
- case ALT_DMA_EVENT_2:
- case ALT_DMA_EVENT_3:
- case ALT_DMA_EVENT_4:
- case ALT_DMA_EVENT_5:
- case ALT_DMA_EVENT_6:
- case ALT_DMA_EVENT_7:
- case ALT_DMA_EVENT_ABORT:
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Construct i mask value
- uint8_t i_mask = 0;
- if (invalid)
- {
- i_mask = 0x2;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAWFE
- buffer[0] = 0x36;
- buffer[1] = ((uint8_t)(evt) << 3) | i_mask;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAWFP(ALT_DMA_PROGRAM_t * pgm,
- ALT_DMA_PERIPH_t periph, ALT_DMA_PROGRAM_INST_MOD_t mod)
-{
- // For information on DMAWFP, see PL330, section 4.3.20.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 2) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Verify valid peripheral identifier.
- if (periph > ((1 << 5) - 1))
- {
- return ALT_E_BAD_ARG;
- }
-
- // Verify instruction modifier; construct bs, p mask value.
- uint8_t bsp_mask = 0;
- switch (mod)
- {
- case ALT_DMA_PROGRAM_INST_MOD_SINGLE:
- bsp_mask = 0x0;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_BURST:
- bsp_mask = 0x2;
- break;
- case ALT_DMA_PROGRAM_INST_MOD_PERIPH:
- bsp_mask = 0x1;
- break;
- default:
- return ALT_E_BAD_ARG;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAWFP
- buffer[0] = 0x30 | bsp_mask;
- buffer[1] = (uint8_t)(periph) << 3;
-
- // Update the code size.
- pgm->code_size += 2;
-
- return ALT_E_SUCCESS;
-}
-
-ALT_STATUS_CODE alt_dma_program_DMAWMB(ALT_DMA_PROGRAM_t * pgm)
-{
- // For information on DMAWMB, see PL330, section 4.3.21.
-
- // Check for sufficient space in buffer
- if ((pgm->code_size + 1) > ALT_DMA_PROGRAM_PROVISION_BUFFER_SIZE)
- {
- return ALT_E_BUF_OVF;
- }
-
- // Buffer of where to assemble the instruction.
- uint8_t * buffer = pgm->program + pgm->buffer_start + pgm->code_size;
-
- // Assemble DMAWMB
- buffer[0] = 0x13;
-
- // Update the code size.
- pgm->code_size += 1;
-
- return ALT_E_SUCCESS;
-}