2 * Copyright (C) 2011-2012 Tomasz Boleslaw CEDRO
3 * cederom@tlen.pl, http://www.tomek.cedro.info
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 /** @file: Generic OpenOCD interface. */
26 #include <interface/interface.h>
27 #include <helper/log.h>
29 extern struct jtag_interface
*jtag_interface
;
31 /******************************************************************************
32 * SIGNAL INFRASTRUCTURE AND OPERATIONS
33 ******************************************************************************/
35 /** Check if specified signal is already defined (case insensitive) and return
36 * its pointer if defined.
37 * \param *name signal name to check
38 * \return pointer to signal structure in memory if found, NULL otherwise.
40 oocd_interface_signal_t
*oocd_interface_signal_find(char *name
)
42 /* LOG_DEBUG("Searching for interface signal \"%s\"", name); */
43 /* Check if interface already exists */
44 if (!jtag_interface
) {
45 LOG_ERROR("Interface does not yet exist!");
48 /* Check if interface signal to already exists */
49 if (!jtag_interface
->signal
) {
50 LOG_DEBUG("No interface signals defined (yet?).");
53 /* Check if signal name is correct */
54 if (!name
|| strncmp(name
, " ", 1) == 0) {
55 LOG_ERROR("Interface signal name cannot be empty.");
58 /* Check if signal name already exist */
59 oocd_interface_signal_t
*sig
;
60 sig
= jtag_interface
->signal
;
62 if (!strncasecmp(sig
->name
, name
, 32)) {
63 LOG_DEBUG("Interface signal %s found.", sig
->name
);
68 /* If signal is not found return null pointer. */
69 LOG_WARNING("Interface signal %s not found.", name
);
72 /** Add new signal to the interface.
73 * Signal will be allocated in memory with provided name and mask.
74 * There is no sense for giving value field at this time because signal create
75 * can take place during initialization where interface is not yet ready, also
76 * they can be used for read and write, so this is higher level script task
77 * to initialize their default value with appropriate 'bitbang' call.
78 * The default value for new signal equals provided mask to maintain Hi-Z.
80 * \param *name is the signal name (max 32 char).
81 * \param mask is the signal mask (unsigned int).
82 * \param value is the initial value for signal to set.
83 * \return ERROR_OK on success or ERROR_FAIL on failure.
85 int oocd_interface_signal_add(char *name
, unsigned int mask
)
87 LOG_DEBUG("Adding signal \"%s\"", name
);
88 /* Check if interface already exists */
89 if (!jtag_interface
) {
90 LOG_ERROR("Interface does not yet exist!");
94 /* Check if name is correct string */
95 if (!name
|| strncmp(name
, " ", 1) == 0) {
96 LOG_ERROR("Signal name cannot be empty");
100 oocd_interface_signal_t
*newsignal
, *lastsignal
;
103 /* Check signal length (min=1, max=32 characters) */
104 snlen
= strnlen(name
, 32);
105 if (snlen
< 1 || snlen
> 32) {
106 LOG_ERROR("Signal name too short or too long!");
110 /* Check if signal name already exist and return error if so */
111 if (oocd_interface_signal_find(name
)) {
112 LOG_ERROR("Specified signal already exist!");
116 /* Allocate memory for new signal structure */
117 newsignal
= (oocd_interface_signal_t
*)calloc(1, sizeof(oocd_interface_signal_t
));
119 LOG_ERROR("cannot allocate memory for new signal: %s", name
);
122 newsignal
->name
= (char *)calloc(1, snlen
+1);
123 if (!newsignal
->name
) {
124 LOG_ERROR("cannot allocate memory for signal %s name", name
);
128 /* Initialize structure data and return or break on error */
130 if (!strncpy(newsignal
->name
, name
, snlen
)) {
131 LOG_ERROR("cannot copy signal %s name!", name
);
135 newsignal
->mask
= mask
;
136 newsignal
->value
= mask
;
138 if (!jtag_interface
->signal
) {
139 jtag_interface
->signal
= newsignal
;
141 lastsignal
= jtag_interface
->signal
;
142 while (lastsignal
->next
)
143 lastsignal
= lastsignal
->next
;
144 lastsignal
->next
= newsignal
;
146 LOG_DEBUG("Signal \"%s\" added.", name
);
150 /* If there was an error free up resources and return error */
151 free(newsignal
->name
);
156 /** Delete interface signal.
157 * Removes signal from singly linked list of interface signals and free memory.
158 * \param name is the name of the signal to remove.
159 * \return ERROR_OK on success, ERROR_FAIL on failure.
161 int oocd_interface_signal_del(char *name
)
163 LOG_DEBUG("Deleting signal \"%s\"", name
);
164 /* Check if interface already exists */
165 if (!jtag_interface
) {
166 LOG_ERROR("Interface does not yet exist!");
169 /* Check if interface any signal exist */
170 if (!jtag_interface
->signal
) {
171 LOG_ERROR("Signal list is empty!");
175 /* Check if signal name is correct */
176 if (!name
|| strncmp(name
, " ", 1) == 0) {
177 LOG_ERROR("Signal name cannot be empty.");
181 oocd_interface_signal_t
*delsig
= NULL
, *prevsig
= NULL
;
183 /* look for the signal name on the list */
184 delsig
= oocd_interface_signal_find(name
);
186 /* return error if signal is not on the list */
188 LOG_ERROR("Signal not found!");
192 /* detach signal to be removed from the list */
193 prevsig
= jtag_interface
->signal
;
194 if (prevsig
== delsig
) {
195 /* we need to detach first signal on the list */
196 jtag_interface
->signal
= jtag_interface
->signal
->next
;
198 for (; prevsig
->next
; prevsig
= prevsig
->next
) {
199 if (prevsig
->next
== delsig
) {
200 prevsig
->next
= prevsig
->next
->next
;
206 /* now free memory of detached element */
209 LOG_DEBUG("Signal \"%s\" removed.", name
);