|
Very Crazy Stoned Idea: Is there a way to measure the SPI capabilities (e.g. at startup)? I mean, you write something onto the display and read it back (if possible) and compare that to what it should be. If it fails you lower the speed until it works...
|
|
|
|
|
It's not a matter of finding the right speed unfortunately. It's a matter of finding *where* it's too fast. I have no idea what needs to be slowed down. I've tried slowing down the CS line change and DC line changes, but no dice. It's bizarre. I'm not really sure what else to try. I've also tried disabling these particular optimizations by themselves:
inline static void write_raw8(uint8_t value) FORCE_INLINE {
#ifdef OPTIMIZE_ESP32
*_spi_mosi_dlen = 7;
*_spi_w = value;
*_spi_cmd = SPI_USR;
while (*_spi_cmd & SPI_USR);
#elif defined(OPTIMIZE_AVR)
SPDR=(C);
while (!(SPSR&_BV(SPIF)));
#else // !OPTIMIZE_ESP32
spi.transfer(value);
#endif // !OPTIMIZE_ESP32
}
When I do that, but I keep the optimized line changes, I get the same problem.
When I unoptimize the line changes, but keep this optimized, same problem.
Only when I unoptimize both does the problem go away.
The thing to remember, is this optimized code works on boards that are well constructed.
Real programmers use butterflies
|
|
|
|
|
Sorry maybe a naiv question. I don't get this part, what about value here:
#elif defined(OPTIMIZE_AVR)
SPDR=(C);
while (!(SPSR&_BV(SPIF)));
|
|
|
|
|
I believe _BV is an internal macro that points to a volatile SPI "register" on the AVR machines
I copied this code from TFT_eSPI and haven't tested it yet though.
Real programmers use butterflies
|
|
|
|
|
I would take the case were it works with the old and not the optimized and put a scope or analyzer on it and see what the difference is.
In my SPI lib code I had to add nop's to give time for transition, could be as simple as that?
uint8_t CSpiBB::TransferData(uint8_t data)
{
volatile uint8_t result = 0;
volatile uint8_t start = 7;
volatile int8_t step = -1;
if (_dir == LSB)
{
start = 0;
step = 1;
}
for (volatile uint8_t i = start, cnt = 0; cnt < 8; cnt++, i = i + step)
{
if (data & (1 << i))
*_port |= (1 <<_mosi);
else
*_port &= ~(1 << _mosi);
*_port |= (1 << _clk);
asm volatile ("nop");
if (*_pin & (1 << _miso))
result |= (1 << i);
else
result &= ~(1 << i);
*_port &= ~(1 << _clk);
asm volatile ("nop");
}
return result;
}
The less you need, the more you have.
Even a blind squirrel gets a nut...occasionally.
JaxCoder.com
|
|
|
|
|
Might be but the TFT_eSPI code I'm using as a guide doesn't need it, and I am loathe to put assembly in my C++. I'll try it though and see if it helps. Thanks!
Real programmers use butterflies
|
|
|
|
|
I think, You should wait until you can fix the SPI problems and save other people's patience.
|
|
|
|
|
Not necessarily a common thing, but I've grabbed at least 4 different projects over the years that were partially working. Typically I've fixed only the components that were problematic for me but it saved me time to stand on the shoulders of others rather than having to build everything from scratch.
|
|
|
|
|
Well,
When users encounter a library that doesn't work they tend to toss it into the bin and never look back. I'd recommend holding off a bit until you understand the nature of the timing issue.
Best Wishes,
-David Delaune
|
|
|
|
|
The suits say: "ship it, we need the money"
>64
If you can keep your head while those about you are losing theirs, perhaps you don't understand the situation.
|
|
|
|
|
I assume developers are consumers of your library.
My extremely naïve take on what you've described:
Can you not let those developers supply some sort of sleep value, and, if provided, use it, and if not, let 'er rip as fast as it can?
Then document the living crap out of it. Share the results from your test matrix, and let those developers make their own choices. Maybe supply "known good defaults" for different chips.
I realize I'm talking in very broad terms. But I'm very much aware of what happens when you become so intimately familiar with details that you lose sight of the broader picture. If that's a viable solution, go for that...
|
|
|
|
|
I actually considered that but the optimized code only works on one board I tried, and I'd at least like to try it on another of the same model to see if it's a fluke. With something like this, you never know.
Real programmers use butterflies
|
|
|
|
|
Reading the other replies, I think you might be rushing it. IMHO, it needs more testing. Knowing you, you will likely keep at it and finally have an 'aha' moment.
"Go forth into the source" - Neal Morse
"Hope is contagious"
|
|
|
|
|
Yeah that's kind of where I'm at now too.
Real programmers use butterflies
|
|
|
|
|
What does your Marketing guy say?
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I'm the only marketer. The product is free, but in use by people.
Real programmers use butterflies
|
|
|
|
|
Marketing is always overly optimistic.
Your question should be, if I release, will it make me look bad; and is that worse than being late; which is easier to fix.
If the simple version worked, I would have gotten simple to work, then added the advanced functions, in parallel, and turned off the others when the new ones worked.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I've already done that though. It doesn't fix it. Only when all optimizations are turned off does it all work. If I turn on any of the optimizations I wrote, it fails on certain devices.
However, the reference code I used, which contains these optimizations works on those devices.
Hence my problem.
Real programmers use butterflies
|
|
|
|
|
No. You shouldn't release some design when you know it malfunctions under some circumstances, especially when you don't know exactly when and why it does.
FYI: electronic devices have lots of detailed specs, things like minimum pulse width, minimum set-up time (data valid before clocked/latched), minimum hold time (data valid after clocked/latched), etc. It is up to the system designer to make sure each and every one of those requirements is met. As most of these specs are minimum values, optimizing code can easily cause the timing requirements being violated. NOP instructions are not uncommon in low-level code, and then "smart" tools should be kept from eliminating them...
Luc Pattyn [My Articles]
The Windows 11 "taskbar" is disgusting. It should be at the left of the screen, with real icons, with text, progress, etc. They downgraded my developer PC to a bloody iPhone.
|
|
|
|
|
I was talking about taking the optimizations out. But anyway I don't think I'm going to release it without them. I'll get it working first.
As far as your FYI, yeah, I'll use my logic analyzer and datasheets if it comes to that, but that's a last resort. To say it's laborious is a huge understatement.
Real programmers use butterflies
|
|
|
|
|
You don't need a logic analyzer, you don't even need a scope, to get timing specs right. You should get them right by design, not by inspection.
You do need the data sheets of the components involved. Taking care of setup and hold times is the first thing you should do, they are a crucial part of the contract you have with the chip vendor. A data sheet is a unilateral contract, there is no way around it.
Luc Pattyn [My Articles]
The Windows 11 "taskbar" is disgusting. It should be at the left of the screen, with real icons, with text, progress, etc. They downgraded my developer PC to a bloody iPhone.
|
|
|
|
|
The problem with that is simply effort. Basically I'd need to know the timings for absolutely everything. It would take me months to write code that should take me days. I think I'll pass.
Real programmers use butterflies
|
|
|
|
|
That is overly pessimistic. Systems get designed without knowing "everything". What you do need is a basic approach to the setup-and-hold issue; so you need to make sure
A) data transfers don't overlap
B) each data transfer consists of three phases:
1. set the data ready
2. issue the clock/latch pulse
3. remove the data (i.e. guarantee the hold spec)
These steps must remain in sequence, with non-zero time between them. As electronic setup and hold requirements range in the (tens of) nanoseconds, having one or a few instructions in between normally suffices. How you get that depends on environment and available tooling.
If a general purpose driver is present, consider using three separate I/O operations. If a specialized driver is used, it should take care of the details itself.
Once you get a solution, use it everywhere. Separation of concerns applies at all levels.
PS: Beware of optimizing compilers; low-level code best is collected in a separate file that gets handled with other tools or tool settings.
Luc Pattyn [My Articles]
The Windows 11 "taskbar" is disgusting. It should be at the left of the screen, with real icons, with text, progress, etc. They downgraded my developer PC to a bloody iPhone.
|
|
|
|
|
This is all an excellent argument for using my logic analyzer.
Real programmers use butterflies
|
|
|
|
|
That does not make any sense to me; it sounds like using a debugger when code does not even compile.
BTW: a logic analyzer also has setup and hold requirements!
Luc Pattyn [My Articles]
The Windows 11 "taskbar" is disgusting. It should be at the left of the screen, with real icons, with text, progress, etc. They downgraded my developer PC to a bloody iPhone.
|
|
|
|