Nut/OS  4.10.3
API Reference
jtag_tap.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2009 by egnite GmbH
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00021  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * Initially the code had been taken from the GPL'ed JTAG-O-MAT project.
00031  * Its author explicitly confirmed to publish this under BSDL.
00032  *
00033  * For additional information see http://www.ethernut.de/
00034  */
00035 
00045 #include <sys/timer.h>
00046 #include <stdlib.h>
00047 
00048 #include <dev/jtag_tap.h>
00049 
00050 typedef struct {
00051     uint8_t len;
00052     uint8_t seq;
00053 } TEST_MODE_PATH;
00054 
00058 static TEST_MODE_PATH mode_path[256] = {
00059     {0,0x00},{1,0x00},{2,0x02},{3,0x02},{4,0x02},{4,0x0a},{5,0x0a},{6,0x2a},
00060     {5,0x1a},{3,0x06},{4,0x06},{5,0x06},{5,0x16},{6,0x16},{7,0x56},{6,0x36},
00061     {3,0x07},{0,0x00},{1,0x01},{2,0x01},{3,0x01},{3,0x05},{4,0x05},{5,0x15},
00062     {4,0x0d},{2,0x03},{3,0x03},{4,0x03},{4,0x0b},{5,0x0b},{6,0x2b},{5,0x1b},
00063     {2,0x03},{3,0x03},{0,0x00},{1,0x00},{2,0x00},{2,0x02},{3,0x02},{4,0x0a},
00064     {3,0x06},{1,0x01},{2,0x01},{3,0x01},{3,0x05},{4,0x05},{5,0x15},{4,0x0d},
00065     {5,0x1f},{3,0x03},{3,0x07},{0,0x00},{1,0x00},{1,0x01},{2,0x01},{3,0x05},
00066     {2,0x03},{4,0x0f},{5,0x0f},{6,0x0f},{6,0x2f},{7,0x2f},{8,0xaf},{7,0x6f},
00067     {5,0x1f},{3,0x03},{3,0x07},{4,0x07},{0,0x00},{1,0x01},{2,0x01},{3,0x05},
00068     {2,0x03},{4,0x0f},{5,0x0f},{6,0x0f},{6,0x2f},{7,0x2f},{8,0xaf},{7,0x6f},
00069     {4,0x0f},{2,0x01},{2,0x03},{3,0x03},{4,0x03},{0,0x00},{1,0x00},{2,0x02},
00070     {1,0x01},{3,0x07},{4,0x07},{5,0x07},{5,0x17},{6,0x17},{7,0x57},{6,0x37},
00071     {5,0x1f},{3,0x03},{3,0x07},{4,0x07},{2,0x01},{3,0x05},{0,0x00},{1,0x01},
00072     {2,0x03},{4,0x0f},{5,0x0f},{6,0x0f},{6,0x2f},{7,0x2f},{8,0xaf},{7,0x6f},
00073     {4,0x0f},{2,0x01},{2,0x03},{3,0x03},{1,0x00},{2,0x02},{3,0x02},{0,0x00},
00074     {1,0x01},{3,0x07},{4,0x07},{5,0x07},{5,0x17},{6,0x17},{7,0x57},{6,0x37},
00075     {3,0x07},{1,0x00},{1,0x01},{2,0x01},{3,0x01},{3,0x05},{4,0x05},{5,0x15},
00076     {0,0x00},{2,0x03},{3,0x03},{4,0x03},{4,0x0b},{5,0x0b},{6,0x2b},{5,0x1b},
00077     {1,0x01},{2,0x01},{3,0x05},{4,0x05},{5,0x05},{5,0x15},{6,0x15},{7,0x55},
00078     {6,0x35},{0,0x00},{1,0x00},{2,0x00},{2,0x02},{3,0x02},{4,0x0a},{3,0x06},
00079     {5,0x1f},{3,0x03},{3,0x07},{4,0x07},{5,0x07},{5,0x17},{6,0x17},{7,0x57},
00080     {6,0x37},{4,0x0f},{0,0x00},{1,0x00},{1,0x01},{2,0x01},{3,0x05},{2,0x03},
00081     {5,0x1f},{3,0x03},{3,0x07},{4,0x07},{5,0x07},{5,0x17},{6,0x17},{7,0x57},
00082     {6,0x37},{4,0x0f},{5,0x0f},{0,0x00},{1,0x01},{2,0x01},{3,0x05},{2,0x03},
00083     {4,0x0f},{2,0x01},{2,0x03},{3,0x03},{4,0x03},{4,0x0b},{5,0x0b},{6,0x2b},
00084     {5,0x1b},{3,0x07},{4,0x07},{5,0x07},{0,0x00},{1,0x00},{2,0x02},{1,0x01},
00085     {5,0x1f},{3,0x03},{3,0x07},{4,0x07},{5,0x07},{5,0x17},{6,0x17},{7,0x57},
00086     {6,0x37},{4,0x0f},{5,0x0f},{2,0x01},{3,0x05},{0,0x00},{1,0x01},{2,0x03},
00087     {4,0x0f},{2,0x01},{2,0x03},{3,0x03},{4,0x03},{4,0x0b},{5,0x0b},{6,0x2b},
00088     {5,0x1b},{3,0x07},{4,0x07},{1,0x00},{2,0x02},{3,0x02},{0,0x00},{1,0x01},
00089     {3,0x07},{1,0x00},{1,0x01},{2,0x01},{3,0x01},{3,0x05},{4,0x05},{5,0x15},
00090     {4,0x0d},{2,0x03},{3,0x03},{4,0x03},{4,0x0b},{5,0x0b},{6,0x2b},{0,0x00}
00091 };
00092 
00101 JTAG_TAP *TapOpen(JTAG_CABLE *cable)
00102 {
00103     JTAG_TAP *tap = NULL;
00104     void *cib = cable->cable_open();
00105 
00106     if (cib) {
00107         tap = calloc(1, sizeof(JTAG_TAP));
00108         tap->tap_state = JTAG_UNKNOWN_STATE;
00109         tap->tap_irsize = 0;
00110         tap->tap_cable = cable;
00111         tap->tap_cib = cib;
00112     }
00113     return tap;
00114 }
00115 
00122 void TapClose(JTAG_TAP *tap)
00123 {
00124     tap->tap_cable->cable_close(tap->tap_cib);
00125     free(tap);
00126 }
00127 
00135 void TapTargetReset(JTAG_TAP *tap, uint32_t us)
00136 {
00137     tap->tap_cable->cable_reset_target(tap->tap_cib, 1);
00138     if (us) {
00139         NutMicroDelay(us);
00140     }
00141     tap->tap_cable->cable_reset_target(tap->tap_cib, 0);
00142     tap->tap_state = JTAG_UNKNOWN_STATE;
00143 }
00144 
00152 void TapStateWalk(JTAG_TAP *tap, int state)
00153 {
00154     int idx;
00155 
00156     if (tap->tap_state == JTAG_UNKNOWN_STATE || state == JTAG_TEST_LOGIC_RESET) {
00157         tap->tap_cable->cable_tms_put(tap->tap_cib, 0x1F, 5);
00158         tap->tap_state = JTAG_TEST_LOGIC_RESET;
00159     }
00160     idx = state;
00161     idx += tap->tap_state << 4;
00162     tap->tap_cable->cable_tms_put(tap->tap_cib, mode_path[idx].seq, mode_path[idx].len);
00163     tap->tap_state = state;
00164 }
00165 
00176 void TapSetIrSize(JTAG_TAP *tap, uint_fast8_t len)
00177 {
00178     tap->tap_irsize = len;
00179 }
00180 
00195 void TapData(JTAG_TAP *tap, uint8_t *rbuf, CONST uint8_t *wbuf, uint32_t len, uint_fast8_t last)
00196 {
00197     TapStateWalk(tap, JTAG_SHIFT_DR);
00198     tap->tap_cable->cable_transfer_data(tap->tap_cib, rbuf, wbuf, len, last);
00199     if (last) {
00200         tap->tap_state++;
00201     }
00202 }
00203 
00213 void TapInstruction(JTAG_TAP *tap, uint32_t code, uint_fast8_t last)
00214 {
00215     TapStateWalk(tap, JTAG_SHIFT_IR);
00216     tap->tap_cable->cable_transfer_data(tap->tap_cib, NULL, (uint8_t *) &code, tap->tap_irsize, last);
00217     if (last) {
00218         tap->tap_state++;
00219     }
00220 }