Skip to content

Commit dfc7fbe

Browse files
SPI: Implemented MISO, MOSI, SCK and SS pins handling using avr_bitbang functions.
1 parent 5669a06 commit dfc7fbe

20 files changed

+427
-38
lines changed

simavr/cores/sim_mega128.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ const struct mcu_t {
391391
.vector = TIMER3_CAPT_vect,
392392
},
393393
},
394-
AVR_SPI_DECLARE(0, 0),
394+
AVR_SPI_DECLARE(0, 0, 'B', 1, 3, 2, 0),
395395
.twi = {
396396

397397
.r_twcr = TWCR,

simavr/cores/sim_mega1280.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ const struct mcu_t {
616616
},
617617

618618
},
619-
AVR_SPI_DECLARE(PRR0, PRSPI),
619+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 1, 3, 2, 0),
620620
.twi = {
621621

622622
.r_twcr = TWCR,

simavr/cores/sim_mega1281.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ const struct mcu_t {
431431
.vector = TIMER3_CAPT_vect,
432432
},
433433
},
434-
AVR_SPI_DECLARE(PRR0, PRSPI),
434+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 1, 3, 2, 0),
435435
.twi = {
436436

437437
.r_twcr = TWCR,

simavr/cores/sim_mega128rfr2.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ const struct mcu_t {
469469
.vector = TIMER3_CAPT_vect,
470470
},
471471
},
472-
AVR_SPI_DECLARE(PRR0, PRSPI),
472+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 1, 3, 2, 0),
473473
.twi = {
474474

475475
.r_twcr = TWCR,

simavr/cores/sim_mega169.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ const struct mcu_t {
319319
},
320320
},
321321
},
322-
AVR_SPI_DECLARE(PRR, PRSPI),
322+
AVR_SPI_DECLARE(PRR, PRSPI, 'B', 1, 3, 2, 0),
323323
};
324324

325325
static avr_t * make()

simavr/cores/sim_mega2560.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ const struct mcu_t {
618618
},
619619

620620
},
621-
AVR_SPI_DECLARE(PRR0, PRSPI),
621+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 1, 3, 2, 0),
622622
.twi = {
623623

624624
.r_twcr = TWCR,

simavr/cores/sim_megax.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ const struct mcu_t SIM_CORENAME = {
301301
},
302302
},
303303
},
304-
AVR_SPI_DECLARE(0, 0),
304+
AVR_SPI_DECLARE(0, 0, 'B', 7, 6, 5, 4),
305305
.twi = {
306306

307307
.r_twcr = TWCR,

simavr/cores/sim_megax4.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,9 @@ const struct mcu_t SIM_CORENAME = {
432432
},
433433
#endif
434434
#ifdef MSTR0 /* xx4a and xx4pa series */
435-
AVR_SPIX_DECLARE(0, PRR0, PRSPI),
435+
AVR_SPIX_DECLARE(0, PRR0, PRSPI, 'B', 7, 6, 5, 4),
436436
#else
437-
AVR_SPI_DECLARE(PRR0, PRSPI),
437+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 7, 6, 5, 4),
438438
#endif
439439
.twi = {
440440
.disabled = AVR_IO_REGBIT(PRR0,PRTWI),

simavr/cores/sim_megax8.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ const struct mcu_t SIM_CORENAME = {
345345
}
346346
}
347347
},
348-
AVR_SPI_DECLARE(PRR, PRSPI),
348+
AVR_SPI_DECLARE(PRR, PRSPI, 'B', 5, 4, 3, 2),
349349
.twi = {
350350
.disabled = AVR_IO_REGBIT(PRR,PRTWI),
351351

simavr/cores/sim_megaxm1.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ const struct mcu_t SIM_CORENAME = {
311311
},
312312
},
313313
},
314-
AVR_SPI_DECLARE(PRR, PRSPI),
314+
AVR_SPI_DECLARE(PRR, PRSPI, 'C', 7, 0, 1, 1),
315315
};
316316
#endif /* SIM_CORENAME */
317317

simavr/cores/sim_usb162.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ const struct mcu_t {
202202
},
203203
},
204204
},
205-
AVR_SPI_DECLARE(0, 0),
205+
AVR_SPI_DECLARE(PRR0, PRSPI, 'B', 7, 6, 5, 4),
206206
.usb = {
207207
.name='1',
208208
.disabled=AVR_IO_REGBIT(PRR1, PRUSB),// bit in the PRR

simavr/sim/avr/avr_mcu_section.h

+38
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum {
6363
AVR_MMCU_TAG_VCD_PORTPIN,
6464
AVR_MMCU_TAG_VCD_IRQ,
6565
AVR_MMCU_TAG_PORT_EXTERNAL_PULL,
66+
AVR_MMCU_TAG_BITBANG,
6667
};
6768

6869
enum {
@@ -72,6 +73,18 @@ enum {
7273
SIMAVR_CMD_UART_LOOPBACK,
7374
};
7475

76+
#define BITBANG_ON_SPI(_name) \
77+
((uint64_t)(_name >= '0' ? ((1 << (_name - '0'))&0xFF) : (1 << 8)) << 0)
78+
79+
#define BITBANG_ON_UART(_name) \
80+
((uint64_t)((1 << (_name - '0'))&0xFF) << 16)
81+
82+
#define BITBANG_ON_TWI(_name) \
83+
((uint64_t)(1) << 24)
84+
85+
#define BITBANG_ON_LIN(_name) \
86+
((uint64_t)(1) << 32)
87+
7588
#if __AVR__
7689
/*
7790
* WARNING. Due to newer GCC being stupid, they introduced a bug that
@@ -87,6 +100,12 @@ struct avr_mmcu_long_t {
87100
uint32_t val;
88101
} __attribute__((__packed__));
89102

103+
struct avr_mmcu_longlong_t {
104+
uint8_t tag;
105+
uint8_t len;
106+
uint64_t val;
107+
} __attribute__((__packed__));
108+
90109
struct avr_mmcu_string_t {
91110
uint8_t tag;
92111
uint8_t len;
@@ -121,6 +140,13 @@ struct avr_mmcu_vcd_trace_t {
121140
#define DO_CONCAT2(_a, _b) _a##_b
122141
#define DO_CONCAT(_a, _b) DO_CONCAT2(_a,_b)
123142

143+
#define AVR_MCU_LONGLONG(_tag, _val) \
144+
const struct avr_mmcu_longlong_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\
145+
.tag = _tag,\
146+
.len = sizeof(struct avr_mmcu_longlong_t) - 2,\
147+
.val = _val,\
148+
}
149+
124150
#define AVR_MCU_LONG(_tag, _val) \
125151
const struct avr_mmcu_long_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\
126152
.tag = _tag,\
@@ -131,6 +157,18 @@ struct avr_mmcu_vcd_trace_t {
131157
#define AVR_MCU_BYTE(_tag, _val) \
132158
const uint8_t _##_tag _MMCU_ = { _tag, 1, _val }
133159

160+
/*!
161+
* This Macro allows you turn on or off a bitbang feature for
162+
* peripherals, which support it (plese look code of the corresponding
163+
* module to ensure it's implemented).
164+
* By default bitbang is off for every peripheral.
165+
* You can turn it on using bitmask for specific peripheral instance,
166+
* e.g. the following turns it on for SPI0 and for USART1 in SPI mode:
167+
* AVR_MCU_BITBANG(BITBANG_ON_SPI(0) | BITBANG_ON_SPI('1'));
168+
*/
169+
#define AVR_MCU_BITBANG(_peripheral_on_mask) \
170+
AVR_MCU_LONGLONG(AVR_MMCU_TAG_BITBANG, _peripheral_on_mask)
171+
134172
/*!
135173
* This Macro allows you to specify traces for the VCD file output
136174
* engine. This specifies a default header, and let you fill in the

simavr/sim/avr_bitbang.c

+45-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929

3030
#include <stdio.h>
3131
#include <stdlib.h>
32+
#include <string.h>
3233

3334
#include "avr_bitbang.h"
3435

@@ -99,7 +100,12 @@ static void avr_bitbang_write_bit(avr_bitbang_t *p)
99100

100101
// output to HW pin
101102
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);
103109
}
104110

105111
// module callback
@@ -130,7 +136,12 @@ static void avr_bitbang_clk_edge(avr_bitbang_t *p)
130136

131137
// generate clock output on HW pin
132138
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);
134145
}
135146

136147
if ( phase ) {
@@ -175,6 +186,36 @@ static void avr_bitbang_clk_hook(struct avr_irq_t * irq, uint32_t value, void *
175186
avr_bitbang_clk_edge(p);
176187
}
177188

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+
178219
/**
179220
* reset bitbang sub-module
180221
*
@@ -220,7 +261,7 @@ void avr_bitbang_start(avr_bitbang_t * p)
220261
} else {
221262
// slave mode -> attach clock function to clock pin
222263
///@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);
224265
}
225266

226267
}
@@ -238,7 +279,7 @@ void avr_bitbang_stop(avr_bitbang_t * p)
238279

239280
p->enabled = 0;
240281
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);
242283
}
243284

244285
#ifdef __cplusplus

simavr/sim/avr_bitbang.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@
4848
#include "avr_ioport.h"
4949

5050

51+
/**
52+
* pin structure
53+
*/
54+
typedef struct avr_bitbang_iopin_t {
55+
uint16_t port : 8; ///< port e.g. 'B'
56+
uint16_t pin : 8; ///< pin number
57+
avr_ioport_t * ioport;
58+
avr_irq_t * irq;
59+
} avr_bitbang_iopin_t;
5160

5261

5362
/// SPI Module initialization and state structure
@@ -73,9 +82,9 @@ typedef struct avr_bitbang_t {
7382
uint32_t (*callback_transfer_finished)(uint32_t data, void *param); ///< callback function to notify about a complete transfer
7483
/// (read received data and write new output data)
7584

76-
avr_iopin_t p_clk; ///< clock pin (optional)
77-
avr_iopin_t p_in; ///< data in pin
78-
avr_iopin_t p_out; ///< data out pin
85+
avr_bitbang_iopin_t p_clk; ///< clock pin (optional)
86+
avr_bitbang_iopin_t p_in; ///< data in pin
87+
avr_bitbang_iopin_t p_out; ///< data out pin
7988

8089
// private data
8190
uint32_t data; ///< data buffer
@@ -92,6 +101,16 @@ typedef struct avr_bitbang_t {
92101
*/
93102
void avr_bitbang_reset(avr_t *avr, avr_bitbang_t * p);
94103

104+
/**
105+
* define bitbang pins
106+
*
107+
* @param p bitbang structure
108+
* @param clk clock pin
109+
* @param in incoming data pin
110+
* @param out outgoing data pin
111+
*/
112+
void avr_bitbang_defpins(avr_bitbang_t * p, avr_iopin_t *clk, avr_iopin_t *in, avr_iopin_t *out);
113+
95114
/**
96115
* start bitbang transfer
97116
*

0 commit comments

Comments
 (0)