@@ -29,6 +29,7 @@ extern "C" {
29
29
30
30
#include <stdio.h>
31
31
#include <stdlib.h>
32
+ #include <string.h>
32
33
33
34
#include "avr_bitbang.h"
34
35
@@ -99,7 +100,12 @@ static void avr_bitbang_write_bit(avr_bitbang_t *p)
99
100
100
101
// output to HW pin
101
102
if ( p -> p_out .port ) {
102
- avr_raise_irq (avr_io_getirq (p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_out .port ), p -> p_out .pin ), bit );
103
+ avr_raise_irq (p -> p_out .irq , bit );
104
+ uint16_t addr = p -> p_out .ioport -> r_port ;
105
+ uint8_t value = (p -> avr -> data [addr ] & ~(1 << p -> p_out .pin )) | (!!bit << p -> p_out .pin );
106
+ // at least avr->data[addr] update is required, otherwise port state is broken
107
+ // also triggering vcd signal would be nice here
108
+ avr_core_watch_write (p -> avr , addr , value );
103
109
}
104
110
105
111
// module callback
@@ -130,7 +136,12 @@ static void avr_bitbang_clk_edge(avr_bitbang_t *p)
130
136
131
137
// generate clock output on HW pin
132
138
if ( p -> clk_generate && p -> p_clk .port ) {
133
- avr_raise_irq (avr_io_getirq (p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_clk .port ), p -> p_clk .pin ), clk );
139
+ avr_raise_irq (p -> p_clk .irq , clk );
140
+ uint16_t addr = p -> p_clk .ioport -> r_port ;
141
+ uint8_t value = (p -> avr -> data [addr ] & ~(1 << p -> p_clk .pin )) | (!!clk << p -> p_clk .pin );
142
+ // at least avr->data[addr] update is required, otherwise port state is broken
143
+ // also triggering vcd signal would be nice here
144
+ avr_core_watch_write (p -> avr , addr , value );
134
145
}
135
146
136
147
if ( phase ) {
@@ -175,6 +186,36 @@ static void avr_bitbang_clk_hook(struct avr_irq_t * irq, uint32_t value, void *
175
186
avr_bitbang_clk_edge (p );
176
187
}
177
188
189
+ /**
190
+ * define bitbang pins
191
+ *
192
+ * @param p bitbang structure
193
+ * @param clk clock pin
194
+ * @param in incoming data pin
195
+ * @param out outgoing data pin
196
+ */
197
+ void avr_bitbang_defpins (avr_bitbang_t * p , avr_iopin_t * clk , avr_iopin_t * in , avr_iopin_t * out )
198
+ {
199
+ if (clk ) {
200
+ p -> p_clk .port = clk -> port ;
201
+ p -> p_clk .pin = clk -> pin ;
202
+ p -> p_clk .ioport = (avr_ioport_t * )avr_io_findinstance (p -> avr , "port" , clk -> port );
203
+ p -> p_clk .irq = avr_io_getirq (p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_clk .port ), p -> p_clk .pin );
204
+ }
205
+ if (in ) {
206
+ p -> p_in .port = in -> port ;
207
+ p -> p_in .pin = in -> pin ;
208
+ p -> p_in .ioport = (avr_ioport_t * )avr_io_findinstance (p -> avr , "port" , in -> port );
209
+ p -> p_in .irq = avr_io_getirq (p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_in .port ), p -> p_in .pin );
210
+ }
211
+ if (out ) {
212
+ p -> p_out .port = out -> port ;
213
+ p -> p_out .pin = out -> pin ;
214
+ p -> p_out .ioport = (avr_ioport_t * )avr_io_findinstance (p -> avr , "port" , out -> port );
215
+ p -> p_out .irq = avr_io_getirq (p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_out .port ), p -> p_out .pin );
216
+ }
217
+ }
218
+
178
219
/**
179
220
* reset bitbang sub-module
180
221
*
@@ -220,7 +261,7 @@ void avr_bitbang_start(avr_bitbang_t * p)
220
261
} else {
221
262
// slave mode -> attach clock function to clock pin
222
263
///@todo test
223
- avr_irq_register_notify ( avr_io_getirq ( p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_clk .port ), p -> p_clk . pin ) , avr_bitbang_clk_hook , p );
264
+ avr_irq_register_notify ( p -> p_clk .irq , avr_bitbang_clk_hook , p );
224
265
}
225
266
226
267
}
@@ -238,7 +279,7 @@ void avr_bitbang_stop(avr_bitbang_t * p)
238
279
239
280
p -> enabled = 0 ;
240
281
avr_cycle_timer_cancel (p -> avr , avr_bitbang_clk_timer , p );
241
- avr_irq_unregister_notify ( avr_io_getirq ( p -> avr , AVR_IOCTL_IOPORT_GETIRQ ( p -> p_clk .port ), p -> p_clk . pin ) , avr_bitbang_clk_hook , p );
282
+ avr_irq_unregister_notify ( p -> p_clk .irq , avr_bitbang_clk_hook , p );
242
283
}
243
284
244
285
#ifdef __cplusplus
0 commit comments