Replies: 6 comments 1 reply
-
Yah I have no idea why he won't steal the DxC/mTC wire library. That you can't do both slave and master even on the same set of pins when the stock arduino core can is particularly egregious (you'll note that I implemented support in twipins for the megaAVR 0-series too, not just the parts I support >.>). Though i'll be the first to admit that making the simultaneous master+slave work was hard - in fact I had tried, failed, and eventually gave up. It was still crap (though the baud rate calculation wasn't as wrong as the stock core - though it was still quite wrong) when @MX682X came along and pretty much rewrote the whole thing. You may have noticed the binaries come out smaller too :-P fastPtr_y is just a way to bully the compiler into generating better code, because the two asm As we all know the compiler is nearly immune to hints and even forceful nudges towards making better code. To change it's dumb decisions often requires nothing short of a knee to the groin will do it, in the form of near-do-nothing asm statements that simply force it to allocate registers less badly; the main reason for this is when it's getting into a place where it's generating adiw-ld-sbiw-adiw-ld-sbiw typer sequences, because the higher level code assumes the three pointer registers are equal, and has generated virtual instructions to do displacement with X. X can't do displacement, so it converts these into an adiw (add immediate to word), then a load, then sbiw (subtract immediate from word). There is no later pass that removes two consecutive instructions where one directly undoes the effect of the first, so you get that 3:1 size and time multiplication instead of 2:1. Building pointers in a real hurry is also a common thing it's bad at, because you can often use assumptions that it can't legally make to simplify it (for example, you know that the PORTx structs start at 0x0400 and are 0x20 bytes long, so you can go from a port number to a pointer register pointing to that port in just 3 clocks. I forget how many the compiler takes, but it's too stupid many. And multibyte datatypes and bitshifts are often a disaster too. (I used semi-automated means to make all 60 xorshift random number generators with 16 bits of state which had a full 2^16-1 period with assembly, so I could test which ones generated the best random numbers (got 15 really good ones, though I ruled out some of them based on concerns about patterns my tests might not spot). It was doing some of the stupidest things I've ever seen avr-gcc do for certain shift amounts, like copying two registers with movw, xoring one of them with itself, copying the other byte of the word to that zero, and then zeroing that byte - when the thing itwas going to do at the end was an xor, and anything xor'ed with zero is left unchanged... AND IT STILL DID THE XOR OF THE SEED BIT WITH THE REGISTER IT HAD JUST ZERO'ED! Now granted, that project probably already is a rolling disaster - the board is on Rev. G, and there will be a Rev. H, and like a dozen of the earlier rev's were burned out before I found out what was happening to them, and I have killed at least 5 strings of 2811's, probably more...(I mean, I have a bin with a bunch that don't work and I don't know why. In one case I found the bad LED, cut away the potting material and was able to spot the crack in the IC where it had been split open by an overvoltage event that would have let smoke out but for the potting material) But if it's a rolling disaster now, imagine how bad it would be if I needed to have 5 times as many controllers because they were all spending the majority of their time generating random numbers. I know very well how bad the performance with 32-bit division is. One time on ATTinyCore, I'd let something end up not getting optimized away... in micros(). People were understandably not thrilled when micros was taking about 100 us to return. (They also weren't happy before, because it was giving the wrong answer (not a little bit wrong either - I think the worst one was like 33% slow or something godawful like that) for some clock speeds... I tell you, there's just no satisfying people.... You would not believe the amount of time that went into testing and tweaking millis() and micros() on mTC (and by extension DxC, since it got the same code) to eliminate the cases where micros would fall behind millis, and then catch up at the end of the millisecond, and generally eliminate every single instance of timetravel in either direction. I've quantified the micros error for all 1000 values that the first 3 decimal digits can take (it repeats after that) to make sure that there was no time travel, sometimes having to change it because when it rolled over from 999 to 1000 it would jump backward 3 microseconds. And it was then reimplemented in asm because even the bitshift division was slower than it had to be and micros is one of those functions where you really do care how long it takes to execute, yaknow? and even a single microsecond of backwards timetravel beyond the execution time of micros (which may be quite fast, especially if you're overclocking the hell out of it) is enough to have catastrophic effects (every time delay hits the backwards jump, an extra millisecond will go by as far as delay is concerned) |
Beta Was this translation helpful? Give feedback.
-
I think I may be stuck on the pinswap issue actually, as far as using this with MegaCoreX. Using swap(0) or swap(1) compiles, but swap(2) doesn't.
which seems to occur if PIN_WIRE_SDA or variant is not defined? |
Beta Was this translation helpful? Give feedback.
-
Oh god a bunch of stuff is busted in there.... |
Beta Was this translation helpful? Give feedback.
-
(latest version should fix issues when moved to the mega0's |
Beta Was this translation helpful? Give feedback.
-
I believe there are some typos that affect build and then other issues that could be typo or they could be due to compiler directive issues in twi_pins.c. I pulled the latest .zip from the GitHub main page.
So I take it that 'x' is just errant and can be deleted. Sorting out what's going on with the other structure is a little more challenging and I figure you already know what's going on there. |
Beta Was this translation helpful? Give feedback.
-
Thanks. x is errant character, and the compiler's suggestion of _gm instead of _gc is correct. I think the third one is a missing semicolon on previous line, and it looks like there probably aren't the same number of opening and closing parens somewhere |
Beta Was this translation helpful? Give feedback.
-
I wasn't sure the best place to discuss, as I know this was discussed at MegaCoreX MCUdude/MegaCoreX#134 and that person seemed to get it working successfully. I know it was suggested in more than one discussion to incorporate this library into MegaCoreX, for various features and in my case for the master+slave operation. The maintainer doesn't seem to be interested in doing that since it was quite some time ago it was suggested. I was really surprised to find that neither ArduinoCore-megaavr or MegaCoreX support the M+S capability, since the standard AVR core has supported it for as long as I've used it (many years).
This issue arduino/ArduinoCore-megaavr#66 had discussion explaining a method for adding that functionality back as well, and makes that sound like a fairly simple way.
So where I stand with it is that I replaced the MegaCoreX Wire with the one from DxCore and added:
at the top of Wire.h, specifically the TWI define has to be before twi.h include it seems (took a little time figuring that one out, however obvious it should be).
Also corrected the very recent _toggleStreamFn issue in twi.c, since not released with that yet, per: #396
That got me to the point of linking, but there was an issue with an asm directive for pointer/register manipulation used in HandleSlaveIRQ, in some versions (mTC I think) it's done as a macro _fastPtr_y to do something same/similar and that macro is defined in dirty_tricks.h. Using the files from DxCore, this asm is written directly in the function. At first this did not appear to work because I think just swapping files did not make them appear as "touched" so I still got the "undefined reference" to the macro when linking, but doing a touch and rebuilding seems to have worked. That sorta happened in the midst of writing out some of this, so the simple answer may be to just use the direct line, but thought it's still worth bringing some attention to this for the benefit of others and see if there's any reason to do something like the macro in this case or information to add for doing this. I have not yet tried to program and run a device.
Beta Was this translation helpful? Give feedback.
All reactions