Small reorganization of interface includes. interface/interface.h now includes jtag...
[openocd/libswd.git] / src / interface / interface_signal.c
blobe878b0b6453183cf62d23347d1d9c1d032dca641
1 /*
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. */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
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!");
46 return NULL;
48 /* Check if interface signal to already exists */
49 if (!jtag_interface->signal) {
50 LOG_DEBUG("No interface signals defined (yet?).");
51 return NULL;
53 /* Check if signal name is correct */
54 if (!name || strncmp(name, " ", 1) == 0) {
55 LOG_ERROR("Interface signal name cannot be empty.");
56 return NULL;
58 /* Check if signal name already exist */
59 oocd_interface_signal_t *sig;
60 sig = jtag_interface->signal;
61 while (sig) {
62 if (!strncasecmp(sig->name, name, 32)) {
63 LOG_DEBUG("Interface signal %s found.", sig->name);
64 return sig;
66 sig = sig->next;
68 /* If signal is not found return null pointer. */
69 LOG_WARNING("Interface signal %s not found.", name);
70 return NULL;
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!");
91 return ERROR_FAIL;
94 /* Check if name is correct string */
95 if (!name || strncmp(name, " ", 1) == 0) {
96 LOG_ERROR("Signal name cannot be empty");
97 return ERROR_FAIL;
100 oocd_interface_signal_t *newsignal, *lastsignal;
101 int snlen;
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!");
107 return ERROR_FAIL;
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!");
113 return ERROR_FAIL;
116 /* Allocate memory for new signal structure */
117 newsignal = (oocd_interface_signal_t *)calloc(1, sizeof(oocd_interface_signal_t));
118 if (!newsignal) {
119 LOG_ERROR("cannot allocate memory for new signal: %s", name);
120 return ERROR_FAIL;
122 newsignal->name = (char *)calloc(1, snlen+1);
123 if (!newsignal->name) {
124 LOG_ERROR("cannot allocate memory for signal %s name", name);
125 return ERROR_FAIL;
128 /* Initialize structure data and return or break on error */
129 for (;;) {
130 if (!strncpy(newsignal->name, name, snlen)) {
131 LOG_ERROR("cannot copy signal %s name!", name);
132 break;
135 newsignal->mask = mask;
136 newsignal->value = mask;
138 if (!jtag_interface->signal) {
139 jtag_interface->signal = newsignal;
140 } else {
141 lastsignal = jtag_interface->signal;
142 while (lastsignal->next)
143 lastsignal = lastsignal->next;
144 lastsignal->next = newsignal;
146 LOG_DEBUG("Signal \"%s\" added.", name);
147 return ERROR_OK;
150 /* If there was an error free up resources and return error */
151 free(newsignal->name);
152 free(newsignal);
153 return ERROR_FAIL;
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!");
167 return ERROR_FAIL;
169 /* Check if interface any signal exist */
170 if (!jtag_interface->signal) {
171 LOG_ERROR("Signal list is empty!");
172 return ERROR_FAIL;
175 /* Check if signal name is correct */
176 if (!name || strncmp(name, " ", 1) == 0) {
177 LOG_ERROR("Signal name cannot be empty.");
178 return ERROR_FAIL;
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 */
187 if (!delsig) {
188 LOG_ERROR("Signal not found!");
189 return ERROR_FAIL;
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;
197 } else {
198 for (; prevsig->next; prevsig = prevsig->next) {
199 if (prevsig->next == delsig) {
200 prevsig->next = prevsig->next->next;
201 break;
206 /* now free memory of detached element */
207 free(delsig->name);
208 free(delsig);
209 LOG_DEBUG("Signal \"%s\" removed.", name);
210 return ERROR_OK;