blob: f3951147d9021c845a924dc30155c3fd4125092f [file] [log] [blame]
Kévin Redonc94e0fc2019-03-07 19:15:29 +01001/**
2 * \file
3 *
4 * \brief Memory with DMA functionality implementation.
5 *
6 * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Subject to your compliance with these terms, you may use Microchip
13 * software and any derivatives exclusively with Microchip products.
14 * It is your responsibility to comply with third party license terms applicable
15 * to your use of third party software (including open source software) that
16 * may accompany Microchip software.
17 *
18 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
20 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
21 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
22 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
23 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
24 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
25 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
26 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
27 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
28 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
29 *
30 * \asf_license_stop
31 *
32 */
33
34#include "dma_memory.h"
35#include "dma_memory_config.h"
36#include <utils_assert.h>
37#include <utils.h>
38#include <hal_atomic.h>
39
40/**
41 * \brief Driver version
42 */
43#define DRIVER_VERSION 0x00000001u
44
45/**
46 * \brief memory with dma descriptor instance
47 */
48static struct dma_memory_descriptor descr;
49
50/**
51 * \internal Process transfer done interrupts
52 *
53 * \param[in] resource The pointer to memory resource
54 */
55static void dma_transfer_done(struct _dma_resource *resource)
56{
57 (void)resource;
58 if (descr.memory_cb.complete) {
59 descr.memory_cb.complete();
60 }
61}
62
63/**
64 * \internal Process transfer error interrupts
65 *
66 * \param[in] resource The pointer to memory resource
67 */
68static void dma_memory_error(struct _dma_resource *resource)
69{
70 (void)resource;
71 if (descr.memory_cb.error) {
72 descr.memory_cb.error();
73 }
74}
75
76/**
77 * \brief Initialize DMA
78 */
79int32_t dma_memory_init(void)
80{
81 _dma_get_channel_resource(&descr.resource, CONF_DMA_MEMORY_CHANNEL);
82 descr.resource->dma_cb.transfer_done = dma_transfer_done;
83 descr.resource->dma_cb.error = dma_memory_error;
84
85 return ERR_NONE;
86}
87
88/**
89 * \brief Register DMA callback
90 */
91int32_t dma_memory_register_callback(const enum dma_memory_callback_type type, dma_memory_cb_t cb)
92{
93 switch (type) {
94 case DMA_MEMORY_COMPLETE_CB:
95 descr.memory_cb.complete = cb;
96 break;
97
98 case DMA_MEMORY_ERROR_CB:
99 descr.memory_cb.error = cb;
100 break;
101
102 default:
103 return ERR_INVALID_ARG;
104 }
105
106 _dma_set_irq_state(CONF_DMA_MEMORY_CHANNEL, (enum _dma_callback_type)type, (cb != NULL));
107
108 return ERR_NONE;
109}
110
111/**
112 * \brief Memory copy with dma
113 */
114int32_t dma_memcpy(void *dst, void *src, uint32_t size)
115{
116 _dma_srcinc_enable(CONF_DMA_MEMORY_CHANNEL, true);
117 _dma_dstinc_enable(CONF_DMA_MEMORY_CHANNEL, true);
118 _dma_set_destination_address(CONF_DMA_MEMORY_CHANNEL, dst);
119 _dma_set_source_address(CONF_DMA_MEMORY_CHANNEL, src);
120 _dma_set_data_amount(CONF_DMA_MEMORY_CHANNEL, size);
121 _dma_enable_transaction(CONF_DMA_MEMORY_CHANNEL, true);
122
123 return ERR_NONE;
124}
125
126/**
127 * \brief Memory set with dma
128 */
129int32_t dma_memset(void *dst, int32_t ch, uint32_t size)
130{
131 static int32_t tmp_ch;
132
133 tmp_ch = ch;
134
135 _dma_set_source_address(CONF_DMA_MEMORY_CHANNEL, &tmp_ch);
136 _dma_srcinc_enable(CONF_DMA_MEMORY_CHANNEL, false);
137 _dma_dstinc_enable(CONF_DMA_MEMORY_CHANNEL, true);
138 _dma_set_destination_address(CONF_DMA_MEMORY_CHANNEL, dst);
139 _dma_set_data_amount(CONF_DMA_MEMORY_CHANNEL, size);
140 _dma_enable_transaction(CONF_DMA_MEMORY_CHANNEL, true);
141
142 return ERR_NONE;
143}