Weird problem with nonsensical received SPI data - Page 1
Forum section: electronics / general

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 05, 2017, 05:15:55 pm
content: I've got a weird problem with an SPI triple half-bridge driver IC that I can't find the cause of. I'm talking to it with an Arduino (ATmega328P), but not using the Arduino SPI library (although the problem does occur when using that too).The problem is this: when I have it hooked up using an I/O pin for Chip Select that'snotthe AVR's SS pin (PB2), the first time (since reset) I try to talk to the chip I get seemingly nonsense status output that doesn't reflect what's actually happening (the chip actually performs as expected, regardless of what the status data says it's doing). All further communication with the chip works perfectly fine.Some details on the chip: On each SPI transfer, the driver chip takes an input 16-bit control word, and outputs a 16-bit status word. The control word has bits for which outputs to enable, whether to shut down on error conditions, as well as a bit that instructs it clear any previous status flags. The output status word has bits indicating error conditions, the state of outputs, and an over-temp warning. Accordingly, my method of communication is as follows:1. Transfer a control word with the 'status reset' flag on. Ignore the output status.2. Wait a few hundred microseconds.3. Transfer the same control word again, but with status reset flag unset.4. Read the output status.I have my code dumping some debug info showing what is being transmitted and received. Here's an example of what I see when the problem occurs:Code:===> Control input word: 1110000000001101 Overvoltage Lockout: ON Underload Shutdown: ON Overcurrent Shutdown: ON HS Switch 3: OFF LS Switch 3: OFF HS Switch 2: OFF LS Switch 2: ON HS Switch 1: ON LS Switch 1: OFF Status Register Reset: ON===> Control input word: 1110000000001100 Overvoltage Lockout: ON Underload Shutdown: ON Overcurrent Shutdown: ON HS Switch 3: OFF LS Switch 3: OFF HS Switch 2: OFF LS Switch 2: ON HS Switch 1: ON LS Switch 1: OFF Status Register Reset: OFF<=== Status output word: 1110000000001101 Supply Voltage Fault: ON Underload / Open Circuit: ON Overload / Short Circuit: ON HS Switch 3: OFF LS Switch 3: OFF HS Switch 2: OFF LS Switch 2: ON HS Switch 1: ON LS Switch 1: OFF Overtemperature Prewarning: ONAs you can see, I get back status showing that all fault/warning flags are on, but also that the commanded outputs are still on, which should be impossible if those faults are really occurring. What also confirms that this is nonsense data is that if I have no power supply voltage (separate from logic supply) turned on, it normally flags a "supply voltage fault" and keeps all outputs off, but in the problem scenario, it still tells me that outputs are on as commanded, when it patently willneverdo that!I've eliminated the following as causes:- My SPI code, as problem also occurs when using the Arduino SPI library.- Bugs in the function I'm using to print out the output status.- The specific chip - swapped for another one, same issue.- The period between asserting the chip's 'enable' line before SPI communication (in case, I dunno, it's not 'waking up' properly) - added a few ms delay, still problem.Another oddity I discovered is when I have two driver chips, A & B, hooked up in parallel on the SPI bus - with A's CS on SS/PB2 and B's CS on, say, PB0. If I communicate with B first followed by A, I get the problem with B's status output. But if I reverse that order - A then B - then B's status output is fine.So, the problem appears to be related to whether the chip's CS line is on the AVR's SS/PB2 pin or not, but also whether first SPI communication is with a device thatdoeshave CS controlled by SS/PB2.I'm flummoxed.And I wish I had a proper multi-channel scope with SPI serial decode, so that I could at least determine whether this problem is perhaps some kind of register/memory issue on the AVR only, by verifying what is actually going over the MISO wire is the same as what is presented on SPDR in the micro.

author: MK14
author_rank: Super Contributor
timestamp: April 05, 2017, 05:55:44 pm
content: Quote from: HwAoRrDk on April 05, 2017, 05:15:55 pmOne possible thing to look at...Have you compared the waveform on a scope between using the SS pin (PB2) and PB0, using a suitable synchronizing trigger ?It sounds like you need to capture the two above traces SEPARATELY (i.e. 2 different runs, one with SS and the other using PB0, keeping everything else the same as far as practicable) and compare them.E.g. are the timings different or something ?N.b. Make sure you do this for the first (problematic) SPI transfer.

author: rstofer
author_rank: Super Contributor
timestamp: April 05, 2017, 06:39:17 pm
content: There are lots of opportunities to screw this up (ETA: I have done all of them). MSB vs LSB first is one opportunity. CPOL and CPHA are important. Raising CS' too soon after stuffing the last byte/word in the data register is another. Reading the data sent back as the command was transmitted MIGHT be another. I usually shift out all 1's when I want to read a status register that I selected during a previous write operation.The thing is, we don't have the datasheet for your driver, we can't see your code, at best all we can do is write down some of the gotcha's and you have probably already worked through all of them.When I want to see what SPI is sending from the master, I write a short loop of code that repeats the transmission over and over. Same data every time. I can see this on a scope without decoding. I trigger the scope on CS'. You can extend this to a couple of transactions if they are close enough together to fit on one screen. In code, set the return value to all 1's just before reading the data register to make sure you are reading anything at all.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 05, 2017, 07:57:27 pm
content: Quote from: MK14 on April 05, 2017, 05:55:44 pmI wish I could. Don't have a multi-channel scope nor with external trigger.I did have a look at CS on both SS and PB0, but didn't see anything funny going on.Hmm... A logic analyser would help here, would it not? I seem to recall there are some ways of using an Arduino as a basic one. Perhaps I could rig up a second Arduino to do that, and I suppose that might at least get me a handle on timing.Quote from: rstofer on April 05, 2017, 06:39:17 pmNo, it's not anything to do with how I have SPI set up. I have the correct bit order, polarity and phase. I mentioned earlier that overall everything works just fine - it's just the erroneous output data from the first round of communication with the device that's problematic. I suppose I could try adding a delay between making the SPI transfer and raising CS.This driver doesn't have multiple registers that can be selected. Data clocked in goes into the control register, and the status register's data is clocked out at the same time.Quote from: rstofer on April 05, 2017, 06:39:17 pmOops, I totally forgot to mention which driver chip it is.It's anInfineon TLE6208-3G.I can post my code if it'll help.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 05, 2017, 08:12:38 pm
content: Oh, by the way, I forgot to also mention that SPI clock speed has no bearing on the matter. Problem happens whether it's 1MHz or 125 KHz.

author: MK14
author_rank: Super Contributor
timestamp: April 05, 2017, 08:21:32 pm
content: It makes it harder or a lot harder if you have no decent way of seeing the signals, that are generated. They could be electrically funny or have the wrong logic values, or even subtleties in the timing. Because debugging is often finding out or seeing the differences between what youTHINKis/should/must be happening and what is happening inPRACTICE.It can give vital (even if tiny) clues, which help you pinpoint what the problem is.A real long shot, but have you got an initial delay (if needed) ?From the datasheet.QuoteI've only had a relatively quick glance at the datasheet, so could easily be mistaken.The schematics and code, might make you more likely to get useful help, for this.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 05, 2017, 08:51:52 pm
content: Quote from: MK14 on April 05, 2017, 08:21:32 pmYeah, tried that already. I mentioned it in my first post. I put a few milliseconds delay between switching the enable/inhibit pin high and switching CS low to start the transfer. Didn't make any difference. I might give it another go to make doubly sure.Here's my code:Code:/****** tle6208-3g_test.ino ******/#include "spi_master.h"#define SPI_MOSI_PIN 11#define SPI_MISO_PIN 12#define SPI_SCK_PIN 13#define SPI_CS_PIN 8 // 10#define INHIBIT_PIN 9#define TLE62083G_CTRL_OVLO 15#define TLE62083G_CTRL_ULSD 14#define TLE62083G_CTRL_OCSD 13#define TLE62083G_CTRL_HS3 6#define TLE62083G_CTRL_LS3 5#define TLE62083G_CTRL_HS2 4#define TLE62083G_CTRL_LS2 3#define TLE62083G_CTRL_HS1 2#define TLE62083G_CTRL_LS1 1#define TLE62083G_CTRL_SRR 0#define TLE62083G_STAT_PSF 15#define TLE62083G_STAT_UL 14#define TLE62083G_STAT_OL 13#define TLE62083G_STAT_HS3 6#define TLE62083G_STAT_LS3 5#define TLE62083G_STAT_HS2 4#define TLE62083G_STAT_LS2 3#define TLE62083G_STAT_HS1 2#define TLE62083G_STAT_LS1 1#define TLE62083G_STAT_TW 0void setup() {pinMode(SPI_CS_PIN, OUTPUT);pinMode(INHIBIT_PIN, OUTPUT);Serial.begin(115200);Serial.println(F("TLE6208-3G SPI TEST"));Serial.println(F("-------------------"));spi_init(1000000, SPI_LSB_FIRST, SPI_MODE_1);}void loop() {digitalWrite(INHIBIT_PIN, HIGH);updateDriver(_BV(TLE62083G_CTRL_HS1) | _BV(TLE62083G_CTRL_LS2), SPI_CS_PIN);delay(2000);updateDriver(0, SPI_CS_PIN);delay(2000);updateDriver(_BV(TLE62083G_CTRL_LS1) | _BV(TLE62083G_CTRL_HS2), SPI_CS_PIN);delay(2000);updateDriver(0, SPI_CS_PIN);delay(2000);digitalWrite(INHIBIT_PIN, LOW);delay(5000);}uint16_t updateDriver(uint16_t input, const uint8_t csPin) {uint16_t buf;input |= (_BV(TLE62083G_CTRL_SRR) | _BV(TLE62083G_CTRL_OCSD) | _BV(TLE62083G_CTRL_ULSD) | _BV(TLE62083G_CTRL_OVLO));printControlWord(input);buf = input;digitalWrite(csPin, LOW);spi_transfer_buf(&buf, sizeof(buf));digitalWrite(csPin, HIGH);delayMicroseconds(500);input &= ~(_BV(TLE62083G_CTRL_SRR));printControlWord(input);buf = input;digitalWrite(csPin, LOW);spi_transfer_buf(&buf, sizeof(buf));digitalWrite(csPin, HIGH);printStatusWord(buf);if(!controlStatusMatch(input, buf)) {Serial.println(F(" ERROR! Control versus status switch states do not match!"));}return buf;}void printControlWord(const uint16_t ctrl) {Serial.print(F(" ===> Control input word: "));Serial.println(ctrl, BIN);Serial.print(F("  Overvoltage Lockout: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_OVLO)) ? F("ON") : F("OFF"));Serial.print(F("  Underload Shutdown: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_ULSD)) ? F("ON") : F("OFF"));Serial.print(F("  Overcurrent Shutdown: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_OCSD)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 3: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_HS3)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 3: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_LS3)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 2: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_HS2)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 2: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_LS2)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 1: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_HS1)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 1: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_LS1)) ? F("ON") : F("OFF"));Serial.print(F("  Status Register Reset: "));Serial.println((ctrl & _BV(TLE62083G_CTRL_SRR)) ? F("ON") : F("OFF"));}void printStatusWord(const uint16_t stat) {Serial.print(F(" <=== Status output word: "));Serial.println(stat, BIN);Serial.print(F("  Supply Voltage Fault: "));Serial.println((stat & _BV(TLE62083G_STAT_PSF)) ? F("ON") : F("OFF"));Serial.print(F("  Underload / Open Circuit: "));Serial.println((stat & _BV(TLE62083G_STAT_UL)) ? F("ON") : F("OFF"));Serial.print(F("  Overload / Short Circuit: "));Serial.println((stat & _BV(TLE62083G_STAT_OL)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 3: "));Serial.println((stat & _BV(TLE62083G_STAT_HS3)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 3: "));Serial.println((stat & _BV(TLE62083G_STAT_LS3)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 2: "));Serial.println((stat & _BV(TLE62083G_STAT_HS2)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 2: "));Serial.println((stat & _BV(TLE62083G_STAT_LS2)) ? F("ON") : F("OFF"));Serial.print(F("  HS Switch 1: "));Serial.println((stat & _BV(TLE62083G_STAT_HS1)) ? F("ON") : F("OFF"));Serial.print(F("  LS Switch 1: "));Serial.println((stat & _BV(TLE62083G_STAT_LS1)) ? F("ON") : F("OFF"));Serial.print(F("  Overtemperature Prewarning: "));Serial.println((stat & _BV(TLE62083G_STAT_TW)) ? F("ON") : F("OFF"));}bool controlStatusMatch(uint16_t ctrl, uint16_t stat) {ctrl &= (_BV(TLE62083G_CTRL_HS3) | _BV(TLE62083G_CTRL_LS3) | _BV(TLE62083G_CTRL_HS2) | _BV(TLE62083G_CTRL_LS2) | _BV(TLE62083G_CTRL_HS1) | _BV(TLE62083G_CTRL_LS1));stat &= (_BV(TLE62083G_STAT_HS3) | _BV(TLE62083G_STAT_LS3) | _BV(TLE62083G_STAT_HS2) | _BV(TLE62083G_STAT_LS2) | _BV(TLE62083G_STAT_HS1) | _BV(TLE62083G_STAT_LS1));return ((ctrl ^ stat) == 0);}/****** spi_master.h ******/#ifndef SPI_MASTER_H#define SPI_MASTER_H#include <avr/io.h>#include <stddef.h>#ifdef __cplusplusextern "C" {#endiftypedef enum {SPI_MSB_FIRST = 0,SPI_LSB_FIRST = _BV(DORD)} spiDataOrder_t;typedef enum {SPI_MODE_0 = 0,SPI_MODE_1 = _BV(CPHA),SPI_MODE_2 = _BV(CPOL),SPI_MODE_3 = _BV(CPHA) | _BV(CPOL)} spiMode_t;void spi_init(const uint32_t speed, const spiDataOrder_t order, const spiMode_t mode);uint8_t spi_transfer_byte(const uint8_t data);void spi_transfer_buf(void *buf, size_t count);#ifdef __cplusplus} // extern "C"#endif#endif // SPI_MASTER_H/****** spi_master.c ******/#include "spi_master.h"void spi_init(const uint32_t speed, const spiDataOrder_t order, const spiMode_t mode) {uint8_t clockDiv = 0;DDRB |= _BV(DDB2);for(uint8_t i = 2; i <= 128; i *= 2) {if(speed >= F_CPU / i) break;clockDiv++;}if(clockDiv == 6) clockDiv++;clockDiv ^= 0x01;SPCR = _BV(SPE) | order | _BV(MSTR) | mode | (clockDiv >> 1);SPSR = (clockDiv & 0x01);SPSR;SPDR;DDRB |= _BV(DDB3) | _BV(DDB5);}uint8_t spi_transfer_byte(const uint8_t data) {SPDR = data;loop_until_bit_is_set(SPSR, SPIF);return SPDR;}void spi_transfer_buf(void *buf, size_t count) {uint8_t *data;if(!buf || count == 0) return;if(bit_is_set(SPCR, DORD)) {data = (uint8_t *)buf;do {*data = spi_transfer_byte(*data);data++;} while(--count > 0);} else {data = ((uint8_t *)buf) + (count - 1);do {*data = spi_transfer_byte(*data);data--;} while(--count > 0);}}There were a bunch of comments in there that I've cut out for brevity so this post isn't too long, so I hope it's understandable.

author: MK14
author_rank: Super Contributor
timestamp: April 05, 2017, 09:19:45 pm
content: So this seems to set buf = 0, later in the code, which ...Quotethen seems to bomb out (as buf is 0)...QuoteIs that correct and what you want it to do ?tl;drI don't easily understand why it returns if it (buf) is zero.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 05, 2017, 09:44:43 pm
content: Yes, that is correct, because of two things:a) updateDriver() always adds extra flags, making the value non-zero regardless of what was passed in.b) That check is for a nullpointer.

author: MK14
author_rank: Super Contributor
timestamp: April 05, 2017, 09:47:24 pm
content: Quote from: HwAoRrDk on April 05, 2017, 09:44:43 pmI missed (a), making me a fool.But at least I did not miss the fact that buf was being accessed as an address rather than its value, making me a total fool.Then there is (b)

author: rstofer
author_rank: Super Contributor
timestamp: April 05, 2017, 09:49:45 pm
content: Quote from: HwAoRrDk on April 05, 2017, 07:57:27 pmI'm sure you have this covered but, strictly speaking, the status received from the first transmission is the result of the previous command and a previous command hasn't been sent. The status received during transmission of command 'n' is the result of command 'n-1'. Figure 3 in the datasheet.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: April 06, 2017, 05:55:07 am
content: It can be interesting to look at the state of the SPI pins of the sender when it resets.I had a similar issue and my SPI pins toggled a bit during initialization which made the receiver (Slave in my case) think that communication was in progress. Setting the SS high on a Slave will also clear the data - you could use that to sync up bytes or groups of bytes (if you have multi-byte messages).Playing with the order of setting SPI pins to input/output and initializing the control register fixed it. Can't remember what the order was exactly but that is easy enough to find out.A master SPI can use any pins for SS to one or more of its Slaves. Configure the SS pin as output on the master and it will not be looked at by the SPI hardware. If SS on the Master is an input, you have to make sure it is high, because when it is low, the master mode is cleared from the control reg turning the SPI into slave mode. On a Slave SPI you have to use the dedicated SS pin afaict, for it is integral part of the handshake of communicating data between master and slave.Hope it helps.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 06, 2017, 01:28:14 pm
content: Quote from: rstofer on April 05, 2017, 09:49:45 pmYep, sure have. That's why I'm doing the following, as I already mentioned in my first post:QuoteI suppose technically speaking, it's nonsense status output being returned from the second command, albeit the first communication 'cycle'.Quote from: obiwanjacobi on April 06, 2017, 05:55:07 amOh yes, I figured out the hard way that SS has to be an output before you can configure it as a master.I initially had my spi_init() function setting SS to an output at the same time as for MOSI and SCK at the end of the function, but found that nothing worked at all. I had to load my code into Atmel Studio and run it through the emulator to realise that the MSTR bit wasn't taking hold. Didn't figure out what was going on until I more carefully read the ATmega datasheet.Looks like I really need to get at least a logic analyser so I can see if there's odd things going on with the SPI lines during initialisation, and also verifying the data on the wire. I think my earlier idea of running an Arduino as one might not be too helpful, as it appears you really need something like a Mega (2560) to have enough memory to capture a lot of samples, which I don't have. Was just looking on eBay and Saleae clones are very cheap, so I might take a punt on one of those.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 07, 2017, 03:02:28 pm
content: As I want to be controlling two of these drivers, I thought I would give the daisy-chain topology a go and see if that exhibits a similar problem.So, as per the diagram from the datasheet above, I hooked a pair of drivers up (let's call them A & B) as follows: Arduino MOSI to A's DI pin; A's DO pin to B's DI pin; B's DO pin to Arduino MISO pin; shared SCK and a single shared CS. I updated my code accordingly to transfer 32 bits - data for B followed by A.But I think there must be something I'm misunderstanding or missing about how this SPI topology is supposed to work. There are virtually no details in the datasheet about daisy-chaining apart from statements that it is supported and the diagram above.Are my assumptions about how it works wrong? I figured that it would work as follows:1. CS pulled low.2. Master shifts out B's 16-bit control word to device A.3. Device A shifts out its 16-bits of status word to device B.4. Device B shifts out its 16-bits of status word to Master.5. Master shifts out A's 16-bit control word to device A.6. Device A shifts out (i.e. overflows) its currently-held 16-bit control word (i.e. B's control) to device B.7. Device B shifts out (i.e. overflows) its currently-held 16-bit control word (i.e. A's status) to Master.8. CS pulled high; A & B latch their respective control words.But all I ever get back as status output is zero for both.This is the updated code I was using. When calling updateDrivers(), I was just passing the same flags as before for both A and B.Code:void updateDrivers(uint16_t inputA, uint16_t inputB) {uint16_t buf;inputA |= (_BV(TLE62083G_CTRL_SRR) | _BV(TLE62083G_CTRL_OCSD) | _BV(TLE62083G_CTRL_ULSD) | _BV(TLE62083G_CTRL_OVLO));inputB |= (_BV(TLE62083G_CTRL_SRR) | _BV(TLE62083G_CTRL_OCSD) | _BV(TLE62083G_CTRL_ULSD) | _BV(TLE62083G_CTRL_OVLO));printControlWord(inputA);printControlWord(inputB);buf = inputB;buf = inputA;digitalWrite(SPI_CS_PIN, LOW);spi_transfer_buf(buf, sizeof(buf));digitalWrite(SPI_CS_PIN, HIGH);delayMicroseconds(500);inputA &= ~(_BV(TLE62083G_CTRL_SRR));inputB &= ~(_BV(TLE62083G_CTRL_SRR));printControlWord(inputA);printControlWord(inputB);buf = inputB;buf = inputA;digitalWrite(SPI_CS_PIN, LOW);spi_transfer_buf(buf, sizeof(buf));digitalWrite(SPI_CS_PIN, HIGH);printStatusWord(buf);printStatusWord(buf);}

author: MK14
author_rank: Super Contributor
timestamp: April 07, 2017, 03:55:25 pm
content: If you can't obtain a scope (or logic analyzer), then you could connect LEDs, to some of the pin(s). Such as the main serial line(s), and temporarily put in delays (e.g. 1 second, faster if you are up to it), between each bit transmission.Then you could make sure the serial data is at least going in to the chip(s) and see if any bits are trying to come out.Alternatively spend 10 hours staring and reading through the entire project, repeatedlyObviously something is wrong, but without clues, you are playing aHUGEguessing game.If the data goes in ok but comes out all zeros, you know it is probably wired up wrong.If no data goes in then you have messed up your software.If data goes in and comes out in non-zero patterns, then it is the software again.tl;drIt would be nice to know what is going on, externally.

author: MK14
author_rank: Super Contributor
timestamp: April 07, 2017, 04:18:02 pm
content: To explain it again in different words...You probably have either got a problem with the software or one or more wires is now wired up wrong, when you introduced the extra device(s).If we/you knew which (hardware/software), it would save a lot of time.Also a scope or LED, would tell us if the serial wire between the two half-H bridge devices, is showing 1's and 0's or not.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: April 07, 2017, 04:42:48 pm
content: Oh, don't get me wrong, I fully understand I need to find out exactly what's going on at the wire level in order to address my initial problem. I've ordered a cheap USB logic analyser, but that won't be here for a while, so in the meantime I thought I'd change tack and try something else.I triple-checked my wiring on the daisy-chaining setup, and it seemed to be correct; that, coupled with the fact I'm essentially just guessing about how the software side of the daisy-chaining setup should be, led me to question my assumptions on the fundamentals of it. A third party's opinion on whether my assumptions make sense or not would be highly appreciated.

author: rstofer
author_rank: Super Contributor
timestamp: April 07, 2017, 06:01:30 pm
content: Quote from: HwAoRrDk on April 07, 2017, 04:42:48 pmYour logic seems consistent with the datasheet. Lower the CS' on both devices, shift out as a single 32 bit transaction, the 2 16 bit commands while simultaneously reading the 2 16 bit status words. Then raise CS' on both devices.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: April 08, 2017, 05:38:08 am
content: Quote from: HwAoRrDk on April 07, 2017, 03:02:28 pmI wouldn't try other topologies before sorting out the original problem. Better to go simpler than more complex. And don't just try random things until it works - understandwhyit's failing.Quote from: MK14Good advice. Better yet, wait for a trigger (eg. push-button) before each clock so you can 'single step' the SPI and see exactly what is happening at a paceyoucontrol.

author: CJay
author_rank: Super Contributor
timestamp: April 08, 2017, 07:53:22 am
content: Quote from: HwAoRrDk on April 05, 2017, 08:12:38 pmI haven't analysed the problem you're experiencing but I've been playing with Sigrok and one of the really cheap Cypress based Chinese logic analysers over the past few days, they work really nicely with the DS1307 (100KHz I2C) and a TM1638 based display that's being run as fast as I can (PIC 18F4550 and it's immensely useful for a quick visual indication of comms speed)I reckon they're a really good investment (£7) if you don't need the advanced features of a 'real' LA.