@@ -117,27 +117,26 @@ bool Ftduino::input_get(uint8_t ch) {
117117#define HB_ACT_2_CTRL 0b11000011
118118#endif
119119
120+ #if defined(OUTPUT_DRIVER_DRV8908) || defined(OUTPUT_DRIVER_AUTO)
121+ #define OP_CTRL_1 0x08
122+ #define OP_CTRL_2 0x09
123+ #define OLD_CTRL_1 0x1f
124+ #define OLD_CTRL_2 0x20
125+ #endif
126+
120127void Ftduino::output_init () {
121128 uint8_t i;
122-
129+
123130 // configure /SS, SCK and MOSI as output
124131 // drive /SS it high
125132 DDRB |= (1 <<0 ) | (1 <<1 ) | (1 <<2 );
126133 PORTB |= (1 <<0 );
127134
128- #if defined(OUTPUT_DRIVER_MC33879A) || defined(OUTPUT_DRIVER_AUTO)
129135 // enable SPI, no interrupts, MSB first, Master mode,
130136 // mode 1 (SCK low when idle, data valid on falling edge)
131137 // and clock = FCPU/16 = 1Mhz
132138 SPCR = (1 <<SPE) | (0 <<DORD) | (1 <<MSTR) |
133139 (0 <<CPOL) | (1 <<CPHA) | (0 <<SPR1) | (1 <<SPR0);
134- #elif defined(OUTPUT_DRIVER_TLE94108EL)
135- // enable SPI, no interrupts, LSB first, Master mode,
136- // mode 1 (SCK low when idle, data valid on falling edge)
137- // and clock = FCPU/16 = 1Mhz
138- SPCR = (1 <<SPE) | (1 <<DORD) | (1 <<MSTR) |
139- (0 <<CPOL) | (1 <<CPHA) | (0 <<SPR1) | (1 <<SPR0);
140- #endif
141140
142141 SPSR &= ~(1 <<SPI2X); // single speed
143142
@@ -152,6 +151,8 @@ void Ftduino::output_init() {
152151 PORTB &= ~(1 <<7 ); // no PWM on IN6
153152
154153#if defined(OUTPUT_DRIVER_AUTO)
154+ _delay_ms (1 );
155+
155156 // SPI has been initialized MSB first (for MC33879A). Try to
156157 // detect chip
157158
@@ -170,29 +171,41 @@ void Ftduino::output_init() {
170171
171172 if (!v0) {
172173 // mc33879a detected
173- odrv_mc33879a = true ;
174+ driver_chip = CHIP_MC33879;
175+ #endif
176+ #if defined(OUTPUT_DRIVER_AUTO) || defined(OUTPUT_DRIVER_MC33879)
174177 spi_tx = 0 ; // all outputs of
175178 output_spi_tx ();
176- } else {
179+ #endif
180+
181+ #if defined(OUTPUT_DRIVER_AUTO)
182+ } else if ((v0 & ~4 ) == 0x01 ) {
177183 // tle94108el detected
184+ driver_chip = CHIP_TLE94108;
185+ #endif
186+ #if defined(OUTPUT_DRIVER_AUTO) || defined(OUTPUT_DRIVER_TLE94108EL)
178187 SPCR |= (1 <<DORD); // switch to LSB first
179188
180- // TODO: we could reset the SYS_DIAG1 register (0b10011011)
181-
182- odrv_mc33879a = false ;
183189 state = 0 ;
184190 write_spi_reg (HB_ACT_1_CTRL, 0 );
185191 write_spi_reg (HB_ACT_2_CTRL, 0 );
186- }
192+ #endif
193+
194+ #if defined(OUTPUT_DRIVER_AUTO)
195+ } else if ((v0 & ~4 ) == 0xc0 ) {
196+ // drv8908 detected
197+ driver_chip = CHIP_DRV8908;
198+ #endif
199+ #if defined(OUTPUT_DRIVER_AUTO) || defined(OUTPUT_DRIVER_DRV8908)
200+ state = 0 ;
201+ write_spi_reg (OLD_CTRL_1, 0xff ); // disable open load detection
202+ write_spi_reg (OLD_CTRL_2, 0xc0 ); // ignore open load detection
203+ write_spi_reg (OP_CTRL_1, 0 );
204+ write_spi_reg (OP_CTRL_2, 0 );
187205#endif
188206
189- #if defined(OUTPUT_DRIVER_MC33879A)
190- spi_tx = 0 ; // all outputs off
191- output_spi_tx ();
192- #elif defined(OUTPUT_DRIVER_TLE94108EL)
193- state = 0 ;
194- write_spi_reg (HB_ACT_1_CTRL, 0 );
195- write_spi_reg (HB_ACT_2_CTRL, 0 );
207+ #if defined(OUTPUT_DRIVER_AUTO)
208+ }
196209#endif
197210}
198211
@@ -262,7 +275,7 @@ void Ftduino::output_set_mc33879a(uint8_t port, uint8_t mode)
262275}
263276#endif
264277
265- #if defined(OUTPUT_DRIVER_TLE94108EL) || defined(OUTPUT_DRIVER_AUTO)
278+ #if defined(OUTPUT_DRIVER_TLE94108EL) || defined(OUTPUT_DRIVER_DRV8908) || defined( OUTPUT_DRIVER_AUTO)
266279void Ftduino::write_spi_reg (uint8_t reg, uint8_t data) {
267280 PORTB &= ~(1 <<0 ); // set /SS low
268281 SPDR = reg; while (!(SPSR & (1 <<SPIF)));
@@ -273,7 +286,9 @@ void Ftduino::write_spi_reg(uint8_t reg, uint8_t data) {
273286 // before being allowed to drive it low again
274287 _delay_us (5 );
275288}
289+ #endif
276290
291+ #if defined(OUTPUT_DRIVER_TLE94108EL) || defined(OUTPUT_DRIVER_AUTO)
277292#if defined(OUTPUT_DRIVER_TLE94108EL)
278293void Ftduino::output_set (uint8_t port, uint8_t mode)
279294#endif
@@ -301,10 +316,39 @@ void Ftduino::output_set_tle94108el(uint8_t port, uint8_t mode)
301316}
302317#endif
303318
319+ #if defined(OUTPUT_DRIVER_DRV8908) || defined(OUTPUT_DRIVER_AUTO)
320+ #if defined(OUTPUT_DRIVER_DRV8908)
321+ void Ftduino::output_set (uint8_t port, uint8_t mode)
322+ #endif
323+ #if defined(OUTPUT_DRIVER_AUTO)
324+ void Ftduino::output_set_drv8908 (uint8_t port, uint8_t mode)
325+ #endif
326+ {
327+ // DEV8908 pins are mapped straight 0-7 to O1-O8
328+ // mode = 0 -> both drivers off,
329+ // mode = 1 -> highside on, mode = 2 -> lowside on
330+
331+ if (mode == 1 ) {
332+ state &= ~(1 << (2 *port)); // clear lowside driver
333+ state |= (2 << (2 *port)); // set highside driver
334+ } else if (mode == 2 ) {
335+ state |= (1 << (2 *port)); // set lowside driver
336+ state &= ~(2 << (2 *port)); // clear highside driver
337+ } else {
338+ state &= ~(3 << (2 *port)); // clear both drivers
339+ }
340+
341+ // and write state into registers
342+ write_spi_reg (OP_CTRL_1, state);
343+ write_spi_reg (OP_CTRL_2, state >> 8 );
344+ }
345+ #endif
346+
304347#if defined(OUTPUT_DRIVER_AUTO)
305348void Ftduino::output_set (uint8_t port, uint8_t mode) {
306- if (odrv_mc33879a) output_set_mc33879a (port, mode);
307- else output_set_tle94108el (port, mode);
349+ if (driver_chip == CHIP_MC33879) output_set_mc33879a (port, mode);
350+ else if (driver_chip == CHIP_TLE94108) output_set_tle94108el (port, mode);
351+ else if (driver_chip == CHIP_DRV8908) output_set_drv8908 (port, mode);
308352}
309353#endif
310354
@@ -384,4 +428,3 @@ Ftduino::Ftduino() {
384428 // the simple lib only uses the counters as digital inouts
385429 counter_init ();
386430}
387-
0 commit comments