1 /*
2 * Copyright (c) 2023-2024, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <stdint.h>
34 #include <string.h>
35
36 #include <ti/devices/DeviceFamily.h>
37
38 #include <ti/drivers/rcl/RCL.h>
39 #include <ti/drivers/rcl/commands/adc_noise.h>
40
41 #include <ti/drivers/Power.h>
42
43 #include DeviceFamily_constructPath(inc/hw_lrfddbell.h)
44 #include DeviceFamily_constructPath(inc/pbe_common_ram_regs.h)
45
46 extern const LRF_Config LRF_configAdcNoise;
47
48 /* Place necessary RCL structs in BUFRAM to avoid using static SYSRAM. This saves 148 B */
49 /* Note that we need to skip the part of the BUFRAM used by common RAM variables, as they
50 may be written by the RCL */
51 #define PBE_COMMON_RAM_REGISTER_END_OFFSET 32UL
52 /* We know that the PBE_COMMON_RAM_FIFOCMDADD register is used by the LRF setup, so at least make sure that this is covered */
53 #if (PBE_COMMON_RAM_FIFOCMDADD_ADR >= (BUF_RAM_BASE_ADDR + PBE_COMMON_RAM_REGISTER_END_OFFSET))
54 #error "BUFRAM memory used by ADC noise wrapper overlaps initialized RAM variable"
55 #endif
56
57 #define RCL_CLIENT_ADDR (BUF_RAM_BASE_ADDR + PBE_COMMON_RAM_REGISTER_END_OFFSET)
58 #define RCL_ADC_NOISE_CMD_ADDR (RCL_CLIENT_ADDR + sizeof(RCL_Client))
59 #define CALLBACK_ADDR (RCL_ADC_NOISE_CMD_ADDR + sizeof(RCL_CmdAdcNoiseGet))
60
61 #define RCL_CLIENT_PTR ((RCL_Client*)RCL_CLIENT_ADDR)
62 #define RCL_ADC_NOISE_CMD_PTR ((RCL_CmdAdcNoiseGet*)RCL_ADC_NOISE_CMD_ADDR)
63 #define CALLBACK_PTR ((applicationCallback_t*)CALLBACK_ADDR)
64
65 #define STATUS_SUCCESS 0
66 #define STATUS_ERROR -1
67 #define RCL_STATUS_TO_WRAPPER_STATUS(x) ((x) == RCL_CommandStatus_Finished ? STATUS_SUCCESS : STATUS_ERROR)
68
69 /* Callback function type */
70 typedef void (*applicationCallback_t)(uint32_t* buffer, uint32_t numWords, int_fast16_t status);
71
72 /******************************************************************************
73 * Internal callback function
74 ******************************************************************************/
adcNoiseCallback(RCL_Command * cmd,LRF_Events lrfEvents,RCL_Events rclEvents)75 static void adcNoiseCallback(RCL_Command *cmd, LRF_Events lrfEvents, RCL_Events rclEvents)
76 {
77 RCL_CmdAdcNoiseGet *adcCmd = (RCL_CmdAdcNoiseGet *)cmd;
78
79 applicationCallback_t callback = *CALLBACK_PTR;
80
81 callback(adcCmd->output, adcCmd->numWords, RCL_STATUS_TO_WRAPPER_STATUS(cmd->status));
82
83 /* Close the RCL client */
84 RCL_close(cmd->runtime.client);
85
86 /* This must come after closing because command and client structs are in BUFRAM */
87 Power_releaseDependency(PowerLPF3_PERIPH_LRFD_BUFRAM);
88
89 /* Release power constraint to allow standby */
90 hal_power_release_constraint();
91 }
92
93 /******************************************************************************
94 * Public API
95 ******************************************************************************/
96
97
98 /*
99 * ======== RCL_AdcNoise_get_samples_blocking ========
100 */
RCL_AdcNoise_get_samples_blocking(uint32_t * buffer,uint32_t numWords)101 int_fast16_t RCL_AdcNoise_get_samples_blocking(uint32_t* buffer, uint32_t numWords)
102 {
103 RCL_CommandStatus status;
104 RCL_CmdAdcNoiseGet *adcNoiseCmd = RCL_ADC_NOISE_CMD_PTR;
105
106 /* Turn on BUFRAM before calling RCL_open, since the RCL_client resides in BUFRAM */
107 Power_setDependency(PowerLPF3_PERIPH_LRFD_BUFRAM);
108
109 /* Prevent the system from going to standby because BUFRAM doesn't have retention */
110 hal_power_set_constraint();
111
112 RCL_init();
113
114 /* Open client and provide settings */
115 RCL_Handle h = RCL_open(RCL_CLIENT_PTR, &LRF_configAdcNoise);
116
117 *adcNoiseCmd = RCL_CmdAdcNoiseGet_Default();
118
119 /* Set number of sample words */
120 adcNoiseCmd->numWords = numWords;
121 adcNoiseCmd->output = buffer;
122
123 /* Submit the command */
124 status = RCL_Command_submit(h, adcNoiseCmd);
125
126 if (status <= RCL_CommandStatus_Finished)
127 {
128 /* Wait for the command to finish. The thread will yield and other threads can run. */
129 status = RCL_Command_pend(adcNoiseCmd);
130 }
131
132 /* Close the RCL client */
133 RCL_close(h);
134
135 /* This must come after closing because command and client structs are in BUFRAM */
136 Power_releaseDependency(PowerLPF3_PERIPH_LRFD_BUFRAM);
137
138 /* Release power constraint to allow standby */
139 hal_power_release_constraint();
140
141 return RCL_STATUS_TO_WRAPPER_STATUS(status);
142 }
143
144 /*
145 * ======== RCL_AdcNoise_get_samples_callback ========
146 *
147 * NOTE: This function must be called from a task context, with interrupts enabled
148 */
RCL_AdcNoise_get_samples_callback(uint32_t * buffer,uint32_t numWords,applicationCallback_t callback)149 int_fast16_t RCL_AdcNoise_get_samples_callback(uint32_t* buffer, uint32_t numWords, applicationCallback_t callback)
150 {
151 RCL_CommandStatus status;
152 RCL_CmdAdcNoiseGet *adcNoiseCmd = RCL_ADC_NOISE_CMD_PTR;
153
154 /* Turn on BUFRAM before calling RCL_open, since the RCL_client resides in BUFRAM */
155 Power_setDependency(PowerLPF3_PERIPH_LRFD_BUFRAM);
156
157 /* Prevent the system from going to standby because BUFRAM doesn't have retention */
158 hal_power_set_constraint();
159
160 RCL_init();
161
162 /* Open client and provide settings */
163 RCL_Handle h = RCL_open(RCL_CLIENT_PTR, &LRF_configAdcNoise);
164
165 *adcNoiseCmd = RCL_CmdAdcNoiseGet_Default();
166
167 /* Set number of sample words */
168 adcNoiseCmd->numWords = numWords;
169 adcNoiseCmd->output = buffer;
170
171 /* Set callback function to be run at the end of the command */
172 adcNoiseCmd->common.runtime.callback = adcNoiseCallback;
173
174 *CALLBACK_PTR = callback;
175
176 /* Run callback at the end of the command only */
177 adcNoiseCmd->common.runtime.rclCallbackMask.value = RCL_EventLastCmdDone.value;
178
179 /* Submit the command */
180 status = RCL_Command_submit(h, adcNoiseCmd);
181
182 return RCL_STATUS_TO_WRAPPER_STATUS(status);
183 }
184