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 <jtag/interface.h>
28 #include <helper/log.h>
30 extern struct jtag_interface
*jtag_interface
;
32 /******************************************************************************
33 * SIGNAL INFRASTRUCTURE AND OPERATIONS
34 ******************************************************************************/
36 /** Check if specified signal is already defined (case insensitive) and return
37 * its pointer if defined.
38 * \param *name signal name to check
39 * \return pointer to signal structure in memory if found, NULL otherwise.
41 oocd_interface_signal_t
*oocd_interface_signal_find(char *name
)
43 /* LOG_DEBUG("Searching for interface signal \"%s\"", name); */
44 /* Check if interface already exists */
45 if (!jtag_interface
) {
46 LOG_ERROR("Interface does not yet exist!");
49 /* Check if interface signal to already exists */
50 if (!jtag_interface
->signal
) {
51 LOG_DEBUG("No interface signals defined (yet?).");
54 /* Check if signal name is correct */
55 if (!name
|| strncmp(name
, " ", 1) == 0) {
56 LOG_ERROR("Interface signal name cannot be empty.");
59 /* Check if signal name already exist */
60 oocd_interface_signal_t
*sig
;
61 sig
= jtag_interface
->signal
;
63 if (!strncasecmp(sig
->name
, name
, 32)) {
64 LOG_DEBUG("Interface signal %s found.", sig
->name
);
69 /* If signal is not found return null pointer. */
70 LOG_WARNING("Interface signal %s not found.", name
);
73 /** Add new signal to the interface.
74 * Signal will be allocated in memory with provided name and mask.
75 * There is no sense for giving value field at this time because signal create
76 * can take place during initialization where interface is not yet ready, also
77 * they can be used for read and write, so this is higher level script task
78 * to initialize their default value with appropriate 'bitbang' call.
79 * The default value for new signal equals provided mask to maintain Hi-Z.
81 * \param *name is the signal name (max 32 char).
82 * \param mask is the signal mask (unsigned int).
83 * \param value is the initial value for signal to set.
84 * \return ERROR_OK on success or ERROR_FAIL on failure.
86 int oocd_interface_signal_add(char *name
, unsigned int mask
)
88 LOG_DEBUG("Adding signal \"%s\"", name
);
89 /* Check if interface already exists */
90 if (!jtag_interface
) {
91 LOG_ERROR("Interface does not yet exist!");
95 /* Check if name is correct string */
96 if (!name
|| strncmp(name
, " ", 1) == 0) {
97 LOG_ERROR("Signal name cannot be empty");
101 oocd_interface_signal_t
*newsignal
, *lastsignal
;
104 /* Check signal length (min=1, max=32 characters) */
105 snlen
= strnlen(name
, 32);
106 if (snlen
< 1 || snlen
> 32) {
107 LOG_ERROR("Signal name too short or too long!");
111 /* Check if signal name already exist and return error if so */
112 if (oocd_interface_signal_find(name
)) {
113 LOG_ERROR("Specified signal already exist!");
117 /* Allocate memory for new signal structure */
118 newsignal
= (oocd_interface_signal_t
*)calloc(1, sizeof(oocd_interface_signal_t
));
120 LOG_ERROR("cannot allocate memory for new signal: %s", name
);
123 newsignal
->name
= (char *)calloc(1, snlen
+1);
124 if (!newsignal
->name
) {
125 LOG_ERROR("cannot allocate memory for signal %s name", name
);
129 /* Initialize structure data and return or break on error */
131 if (!strncpy(newsignal
->name
, name
, snlen
)) {
132 LOG_ERROR("cannot copy signal %s name!", name
);
136 newsignal
->mask
= mask
;
137 newsignal
->value
= mask
;
139 if (!jtag_interface
->signal
) {
140 jtag_interface
->signal
= newsignal
;
142 lastsignal
= jtag_interface
->signal
;
143 while (lastsignal
->next
)
144 lastsignal
= lastsignal
->next
;
145 lastsignal
->next
= newsignal
;
147 LOG_DEBUG("Signal \"%s\" added.", name
);
151 /* If there was an error free up resources and return error */
152 free(newsignal
->name
);
157 /** Delete interface signal.
158 * Removes signal from singly linked list of interface signals and free memory.
159 * \param name is the name of the signal to remove.
160 * \return ERROR_OK on success, ERROR_FAIL on failure.
162 int oocd_interface_signal_del(char *name
)
164 LOG_DEBUG("Deleting signal \"%s\"", name
);
165 /* Check if interface already exists */
166 if (!jtag_interface
) {
167 LOG_ERROR("Interface does not yet exist!");
170 /* Check if interface any signal exist */
171 if (!jtag_interface
->signal
) {
172 LOG_ERROR("Signal list is empty!");
176 /* Check if signal name is correct */
177 if (!name
|| strncmp(name
, " ", 1) == 0) {
178 LOG_ERROR("Signal name cannot be empty.");
182 oocd_interface_signal_t
*delsig
= NULL
, *prevsig
= NULL
;
184 /* look for the signal name on the list */
185 delsig
= oocd_interface_signal_find(name
);
187 /* return error if signal is not on the list */
189 LOG_ERROR("Signal not found!");
193 /* detach signal to be removed from the list */
194 prevsig
= jtag_interface
->signal
;
195 if (prevsig
== delsig
) {
196 /* we need to detach first signal on the list */
197 jtag_interface
->signal
= jtag_interface
->signal
->next
;
199 for (; prevsig
->next
; prevsig
= prevsig
->next
) {
200 if (prevsig
->next
== delsig
) {
201 prevsig
->next
= prevsig
->next
->next
;
207 /* now free memory of detached element */
210 LOG_DEBUG("Signal \"%s\" removed.", name
);