22 avr_spi.c
33
44 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5+ Modified 2020 by VintagePC <https://github.com/vintagepc> to support clock divisors
56
67 This file is part of simavr.
78
2526static avr_cycle_count_t avr_spi_raise (struct avr_t * avr , avr_cycle_count_t when , void * param )
2627{
2728 avr_spi_t * p = (avr_spi_t * )param ;
28-
29+
2930 if (avr_regbit_get (avr , p -> spe )) {
3031 // in master mode, any byte is sent as it comes..
3132 if (avr_regbit_get (avr , p -> mstr )) {
@@ -55,7 +56,13 @@ static void avr_spi_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, voi
5556 avr_regbit_clear (avr , p -> spi .raised );
5657
5758 avr_core_watch_write (avr , addr , v );
58- avr_cycle_timer_register_usec (avr , 100 , avr_spi_raise , p ); // should be speed dependent
59+ uint16_t uiClkShift = _avr_spi_clkdiv [avr -> data [p -> r_spcr ]& 0b11 ];
60+ // If master && 2X, double rate (half divisor)
61+ if (avr_regbit_get (avr , p -> mstr ) && avr_regbit_get (avr , p -> spr [2 ]))
62+ uiClkShift >>=1 ;
63+
64+ // We can wait directly in clockshifts, it is a divisor, so /4 means 4 avr cycles to clock out one bit.
65+ avr_cycle_timer_register (avr , uiClkShift <<3 , avr_spi_raise , p ); // *8 since 8 clocks to a byte.
5966 }
6067}
6168
@@ -72,7 +79,7 @@ static void avr_spi_irq_input(struct avr_irq_t * irq, uint32_t value, void * par
7279 p -> input_data_register = value ;
7380 avr_raise_interrupt (avr , & p -> spi );
7481
75- // if in slave mode,
82+ // if in slave mode,
7683 // 'output' the byte only when we received one...
7784 if (!avr_regbit_get (avr , p -> mstr )) {
7885 avr_raise_irq (p -> io .irq + SPI_IRQ_OUTPUT , avr -> data [p -> r_spdr ]);
@@ -108,4 +115,3 @@ void avr_spi_init(avr_t * avr, avr_spi_t * p)
108115 avr_register_io_write (avr , p -> r_spdr , avr_spi_write , p );
109116 avr_register_io_read (avr , p -> r_spdr , avr_spi_read , p );
110117}
111-
0 commit comments