2 * Copyright © 2009 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 #define DBG_CLOCK (1 << 3)
22 #define DBG_DATA (1 << 4)
23 #define DBG_RESET_N (1 << 5)
25 #define DBG_CLOCK_PIN (P0_3)
26 #define DBG_DATA_PIN (P0_4)
27 #define DBG_RESET_N_PIN (P0_5)
30 ao_dbg_send_bits(uint8_t msk, uint8_t val)
32 P0 = (P0 & ~msk) | (val & msk);
35 #define ao_dbg_pause() do { _asm nop; nop; nop _endasm; } while (0);
38 ao_dbg_send_byte(uint8_t byte)
44 for (b = 0; b < 8; b++) {
49 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA, DBG_CLOCK|d);
51 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA, 0 |d);
58 ao_dbg_recv_byte(void)
60 __xdata uint8_t byte, b;
63 for (b = 0; b < 8; b++) {
65 ao_dbg_send_bits(DBG_CLOCK, DBG_CLOCK);
69 ao_dbg_send_bits(DBG_CLOCK, 0);
78 #define MOV_direct_data 0x75
80 #define MOV_Rn_data(n) (0x78 | (n))
81 #define DJNZ_Rn_rel(n) (0xd8 | (n))
82 #define MOV_A_direct 0xe5
83 #define MOV_direct1_direct2 0x85
84 #define MOV_direct_A 0xf5
85 #define MOV_DPTR_data16 0x90
86 #define MOV_A_data 0x74
87 #define MOVX_atDPTR_A 0xf0
88 #define MOVX_A_atDPTR 0xe0
94 #define DEBUG_INSTR(l) (0x54 | (l))
100 #define SFR_DPH1 0x85
102 __xdata uint8_t save_acc;
103 __xdata uint8_t save_psw;
104 __xdata uint8_t save_dpl0;
105 __xdata uint8_t save_dph0;
106 __xdata uint8_t save_dpl1;
107 __xdata uint8_t save_dph1;
110 ao_dbg_inst1(uint8_t a)
112 ao_dbg_send_byte(DEBUG_INSTR(1));
114 return ao_dbg_recv_byte();
118 ao_dbg_inst2(uint8_t a, uint8_t b)
120 ao_dbg_send_byte(DEBUG_INSTR(2));
123 return ao_dbg_recv_byte();
127 ao_dbg_inst3(uint8_t a, uint8_t b, uint8_t c)
129 ao_dbg_send_byte(DEBUG_INSTR(3));
133 return ao_dbg_recv_byte();
137 ao_dbg_start_transfer(uint16_t addr)
139 save_acc = ao_dbg_inst1(NOP);
140 save_psw = ao_dbg_inst2(MOV_A_direct, SFR_PSW);
141 save_dpl0 = ao_dbg_inst2(MOV_A_direct, SFR_DPL0);
142 save_dph0 = ao_dbg_inst2(MOV_A_direct, SFR_DPH0);
143 save_dpl1 = ao_dbg_inst2(MOV_A_direct, SFR_DPL1);
144 save_dph1 = ao_dbg_inst2(MOV_A_direct, SFR_DPH1);
145 ao_dbg_inst3(MOV_DPTR_data16, addr >> 8, addr);
149 ao_dbg_end_transfer(void)
151 ao_dbg_inst3(MOV_direct_data, SFR_DPL0, save_dpl0);
152 ao_dbg_inst3(MOV_direct_data, SFR_DPH0, save_dph0);
153 ao_dbg_inst3(MOV_direct_data, SFR_DPL1, save_dpl1);
154 ao_dbg_inst3(MOV_direct_data, SFR_DPH1, save_dph1);
155 ao_dbg_inst3(MOV_direct_data, SFR_PSW, save_psw);
156 ao_dbg_inst2(MOV_A_data, save_acc);
160 ao_dbg_write_byte(uint8_t byte)
162 ao_dbg_inst2(MOV_A_data, byte);
163 ao_dbg_inst1(MOVX_atDPTR_A);
164 ao_dbg_inst1(INC_DPTR);
168 ao_dbg_read_byte(void)
170 ao_dbg_inst1(MOVX_A_atDPTR);
171 return ao_dbg_inst1(INC_DPTR);
175 ao_dbg_set_pins(void)
177 /* Disable peripheral use of P0 */
182 /* make P0_4 tri-state */
184 P2INP &= ~(P2INP_PDUP0_PULL_DOWN);
186 /* Raise RESET_N and CLOCK */
187 P0 = DBG_RESET_N | DBG_CLOCK;
189 /* RESET_N and CLOCK are outputs now */
190 P0DIR = DBG_RESET_N | DBG_CLOCK;
194 ao_dbg_debug_mode(void)
197 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
198 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA| 0 );
199 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
200 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA| 0 );
201 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
202 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, 0 |DBG_DATA|DBG_RESET_N);
209 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
210 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
211 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
212 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
213 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA| 0 );
214 ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);