1 /*
2 * $Id$
3 *
4 * Copyright (C) 2002 ETC s.r.o.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * Written by Marcel Telka <marcel@telka.sk>, 2002.
22 *
23 */
24
25 #include <sysdep.h>
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <urjtag/part.h>
32 #include <urjtag/tap_register.h>
33 #include <urjtag/data_register.h>
34 #include <urjtag/error.h>
35
36 urj_data_register_t *
urj_part_data_register_alloc(const char * name,int len)37 urj_part_data_register_alloc (const char *name, int len)
38 {
39 urj_data_register_t *dr;
40
41 if (!name)
42 return NULL;
43
44 dr = malloc (sizeof *dr);
45 if (!dr)
46 {
47 urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
48 sizeof *dr);
49 return NULL;
50 }
51
52 if (strlen (name) > URJ_DATA_REGISTER_MAXLEN)
53 urj_warning (_("Data register name too long\n"));
54 strncpy (dr->name, name, URJ_DATA_REGISTER_MAXLEN);
55 dr->name[URJ_DATA_REGISTER_MAXLEN] = '\0';
56
57 if (len > 0)
58 {
59 dr->in = urj_tap_register_alloc (len);
60 dr->out = urj_tap_register_alloc (len);
61 }
62 else
63 {
64 dr->in = urj_tap_register_alloc (1);
65 dr->out = urj_tap_register_alloc (1);
66 }
67 if (!dr->in || !dr->out)
68 {
69 // retain error state
70 free (dr->in);
71 free (dr->out);
72 free (dr->name);
73 free (dr);
74 return NULL;
75 }
76
77 dr->next = NULL;
78
79 return dr;
80 }
81
82 void
urj_part_data_register_free(urj_data_register_t * dr)83 urj_part_data_register_free (urj_data_register_t *dr)
84 {
85 if (!dr)
86 return;
87
88 urj_tap_register_free (dr->in);
89 urj_tap_register_free (dr->out);
90 free (dr);
91 }
92
93 int
urj_part_data_register_define(urj_part_t * part,const char * name,int len)94 urj_part_data_register_define (urj_part_t *part, const char *name, int len)
95 {
96 urj_data_register_t *dr;
97
98 if (urj_part_find_data_register (part, name) != NULL)
99 {
100 urj_error_set (URJ_ERROR_ALREADY,
101 _("Data register '%s' already defined"), name);
102 return URJ_STATUS_FAIL;
103 }
104
105 dr = urj_part_data_register_alloc (name, len);
106 if (!dr)
107 // retain error state
108 return URJ_STATUS_FAIL;
109
110 dr->next = part->data_registers;
111 part->data_registers = dr;
112
113 /* Boundary Scan Register */
114 if (strcasecmp (dr->name, "BSR") == 0)
115 {
116 int i;
117
118 part->boundary_length = len;
119 part->bsbits = malloc (part->boundary_length * sizeof *part->bsbits);
120 if (!part->bsbits)
121 {
122 urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
123 part->boundary_length * sizeof *part->bsbits);
124 return URJ_STATUS_FAIL;
125 }
126 for (i = 0; i < part->boundary_length; i++)
127 part->bsbits[i] = NULL;
128 }
129
130 /* Device Identification Register */
131 else if (strcasecmp (dr->name, "DIR") == 0)
132 urj_tap_register_init (dr->out, urj_tap_register_get_string (part->id));
133
134 return URJ_STATUS_OK;
135 }
136
137 int
urj_part_data_register_realloc(urj_data_register_t * dr,int new_len)138 urj_part_data_register_realloc (urj_data_register_t *dr, int new_len)
139 {
140 if (urj_tap_register_realloc (dr->in, new_len) == NULL)
141 return URJ_STATUS_FAIL;
142 if (urj_tap_register_realloc (dr->out, new_len) == NULL)
143 return URJ_STATUS_FAIL;
144
145 return URJ_STATUS_OK;
146 }
147