-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement video input switching capability using Amiga hotkeys and master-slave communication between two FF_OSD enabled blue pills #44
Comments
I don't think it would be easy to drive two OSD outputs simultaneously, but switching between VGA and AGA modes on PA7 and PB15 respectively is more plausible. Do you need H/V syncs for both? Would need care picking the second HSYNC pin. Perhaps PA9 as this is a spare channel on Timer1 (existing PA8 pin uses T1Ch1, so using T1Ch2 would be not too hard to implement). Unfortunately this collides with the serial pins (useful for debug) but serial could perhaps be done on UART2 on pins PA2 and PA3. In summary:
A further complication on (2) is that full mode switch usually requires a reset of the Blue Pill. Just because that's easier to implement and mode switches would usually be rare. So might need to fix that, or remember some state across reset. |
I guess so, yes. Both, AGA and RTG cards usually need H- and V-Sync. One can switch jumper the AGA output to do sync-on-green, but my guess is that this would further complicate things instead of helping...
Thinking aloud: What if we keep the concept of using two separate blue pills, but implement some kind of communication between them. The idea would be to have a kind of master-slave setup, where the slave isn't even connected to the Gotek via I²C. Instead master and slave communicate via their UART interfaces with the master sending the slave the text to display on the OSD. This would just be one additional config option (which defaults to master). To not interfere with debugging/config, a kind of handshake upon cold reset could be initiated. I.e., after booting up, the master would send some "magical" sequence saying "I am master" in regular intervals while not in config mode. Once a slave sees that sequence on its RX, it responds with another sequence letting the master know that it is ready to receive text from now on. Everything the slave receives on UART is henceforth displayed on its OSD... |
Thinking further, for this setup, even a config option might be overkill. A device could be set into slave mode by putting a jumper across SCL-SDA (or somewhere else, if that wouldn't work). |
This is possible. It might be easier to use I2C2 on the master and communicate using I2C. This gives you some framing, for example. The slave wouldn't be easily configurable but I suppose you would set him up in master mode, and thenceforth he wouldn't need configuring. Configuration things like OSD box position wouldn't affect the slave unless I2C commands to do so were added... |
Yes, I2C has the additional benefit of being a open drain bus by default, so - in theory - you could drive more than one slave from a single master. Can't think of a scenario where this would make sense, but you never know. ;-) Anyway, for my current design, this would simply mean to routing I2C2 instead of I2C1 to the passthrough connector on the master PCB, which is easily accomplished. What do you think about part 2 of my initial question - having that switching sequence of "mirror an input" - "high (impedance)" - "low". I can't think of a nice way to generalize this "state machine" approach other than having some kind of callback function attached to the hotkeys. Also, it would be nice to have an input pin we can agree on for such mirroring purposes. Ideally, this pin would be from the group of the five volt tolerant ones. |
Oh, and I like the idea of being able to configure the slave through the master by I2C. :-) |
Regarding the hotkey switch sequence, I'd probably hardcode it and give it a new name/id. Not troubled for Flash space so all sorts of things can be shoved in, really. Now, with all this, I'm unlikely to just get on and implement it. I don't have time, and other projects take precedence. However it might be considered for inclusion in the upstream codebase, also external patchsets on this codebase aren't too scary as it basically never changes (I'm not really implementing new features). |
Thanks @keirf. I'll try and code it in my private fork first and send a PR when I deem it ready for inclusion. As mentioned, I've got a setup that's basically working right now. Want to get rid of the additional PIC µC first and foremost... |
One (hopefully) last thing before I start coding: I've had a look at the pinout and found that if I want to activate I2C2 for master-to-slave communication, I need B10 for that, which is currently assigned to U2. I'd move U2 to B12 then. |
Not much choice on use of B10 and B11. Either move U2 or disable it for this configuration. Why use A15 for CTS? This pin is the DisplayEnable output for when using an external tristate buffer for the video output: In this mode, instead of the output GPIO being tristate, the tristate function is implemented in external buffer which requires two signals: the output and the output-enable. Better pick another pin, there are spares even if you insist on 5v tolerance. By the way pulled-up signals don't seem to kill the STM 3v3 pins, but of course those signals do get "pulled down" to 3v3. Gotek design has a bunch of signals like this. It does basically work, even if not ideal. |
I misunderstood the purpose of A15. Thought it was an input to enable/disable the OSD, not the display... What other 5V tolerant spare pin do you see? I don't want to repurpose any of the 3 user outputs, since I want to have the ability to switch between 4 Kickstart ROMs and need the 3rd pin to do the actual switching between the AGA and RTG outputs. On the PIC, whose pins don't tolerate 5V at all, when the PIC itself has a VDD of 3.3V, I used a simple voltage divider in front of the input, feeding about 3V into the PIC. Thus, in case I've not overlooked an unused 5V tolerant pin, I think I'll go down this route to be on the safe side. |
Hmm, A12 seems a good candidate... |
@keirf Just a request for comments: https://gist.github.com/tkurbad/1bdedc8757e1fb1730230057b1ea061a holds a patch that implements the video switch functionality as described. There's also a start of master-slave communication, namely a op(eration)_mode, configurable as "Master" or "Slave". Before I'm going down the rabbithole of I2C master slave communication on the STM32, I just want your opinion on the code and whether I can keep it styled that way. C isn't my native language when it comes to programming (I'm more of a Python guy), so I'm often unsure whether there might be much simpler or more efficient ways to do things. I'd appreciate if you might have a quick look. Thank you very much! |
On a side note, I just realized two things: The I2C communication to the slave blue pill is just a very simplified version of what FF does towards FF_OSD. This should be easily adopted. |
Thanks I will try to find some time to take a look a your gist! |
Style looks okay. I will have to think about how to deal with relocating U2. Unfortunately the existing pinout is baked into some FlashFloppy+OSD board designs. Probably it needs to be configurable, at run- or compile-time. Indeed this will probably live on a branch, and we can do some test builds and solicit some feedback from the community. |
Thanks for the comment. I'm d'accord with this stuff living in a branch. Besides the relocation of U2, driving I2C2 makes the code a bit convoluted and adds unnecessary complexity to the standard case of having a one-on-one connection between the Gotek and a FF_OSD blue pill. That said, I'm now done with copying most of the I2C master stuff from the FlashFloppy code and reducing it to a more simple version that can only drive a slave FF_OSD (but no LCD, OLED or whatever). The code compiles but still needs a lot of love. While looking at the I2C master stuff, I came to think that the differentiation between master and slave via config is not necessary at all. A device will act as master if it successfully probes another FF_OSD on its I2C2 port. If there's nothing there, no transfers will occur and the overhead introduced by the I2C2 initialisation will be minimal. Independtly of I2C I've ran into an issue with the video input switching: If I do a complete switching sequence of Auto -> Amiga -> RTG -> Auto, then when the Amiga display returns, the OSD backlight box still displays and resizes correctly, but no text is shown in the box. Do I have to do some kind of reinitialization after each switch? Can you give me hint what's probably going on, @keirf? |
Mode switches have so far required a full Blue Pill reset, so doing the switches without reset is sure to require some reinitialisation which has not so far been considered. |
This is somewhat mysterious nonetheless. I did some testing, rearranging the videoswitch_ functions on the go. Observations:
Wild assumption: Possible solutions: (a) Is hard to achieve without hardwiring the things that are configurable at the moment, e.g. the pin that drives the video switch |
Or reset but keep some state in ram that you pick up after reset. Probably disabling interrupts at bottom of screen is easiest if you can work out how to do that |
I investigated further: Will look into the way I do the display notification during switching first before looking at reset/interrupt. |
Took me a while to find out, but the disappearing OSD is seemingly a pre-existing bug and it only affects non-15kHz Screens. To replay try the following: Set up an Amiga with FF_OSD 1.9. Hook it up to the output of a flicker fixer. Start up the Amiga, enter the early startup menu. Hit CTRL-ALT-Del to turn the OSD off and back on again. You will most likely see one of the following:
Pressing the reset button on the blue pill brings back the OSD, but it will crash again eventually if CTRL-ALT-Del is used. The OSD on/off output is done in a differently from the user hotkey OSD outputs, i.e. by snprintf instead of memset..strcpy. NB: This happens with automatic frequency sync setting as well as when setting it to VGA statically. |
Think I found the fix. Will be in the final PR. Merry Christmas! |
Coming along! |
Solution implemented in PR #47 |
Hi,
this will be a longer one, but bear with me!
I own one of those AA3000+ Amiga mainboards sold by user 'hese' on Amibay. I'm putting it into a Amiga 3000 case as it is supposed to.
While I want to equip the final setup with a FlashFloppy driven Gotek, I want to retain the original Amiga 3000 look. In particular, I don't want to alter the case in any way. So, FF_OSD controlled by the Amiga keyboard is the way to go.
The AA3000+ board has a built-in video switch that is able to switch the VGA output between two video sources. Usually one of those is the Amiga's AGA output and the other some kind of RTG card, in my case a 3DFX Voodoo3 PCI card.
I want to use the FF_OSD hotkeys to (a) switch between four Kickstarts as in the example in default_config.c by means of U0 and U1 and (b) to be able to manually advance the 3-position video switch to either "automatically" (1) switch between the two video sources or choose Amiga or RTG output manually. This should be accomplished by user pin U2 on the FF_OSD.
Also, I want the OSD to appear in both, the Amiga and the RTG output.
(1) Automatic switching is accomplished by a piece of software called switchcontrol. It monitors the state of the graphics driver and drives the serial port's CTS signal low as soon as RTG output is desired. For automatic switching to work, CTS has to be jumpered to the input signal of the video switch circuit. If the jumper is removed and the switch input is left floating (or driven high), the output is fixed to the Amiga signal, if switch input is driven low, the output is fixed to RTG. On the mainboard, there's a pin header that has
CTS - SWITCH_INPUT - SWITCH_INPUT - GND
Thus by connecting a on-off-on switch, you could switch between auto, Amiga, and RTG. One goal is to accomplish the same by a simple state machine driven by U2.
In an initial working setup, I use two Blue Pills, connected in parallel to the Gotek's I²C port. One, the "master" plugs into the Amiga input of the mainboard and connects to the keyboard. It also has U0 and U1 switching by hotkey enabled as in the ROM switching example and U2 as a momentary button driven high by F10 on the keyboard. This Blue Pill has A0-A1 jumpered.
The second, let's call it "slave", Blue Pill connects to the RTG input on the mainboard and does not have A0-A1 jumpered. This way, the "master" receives all the Amiga keyboard commands and is able to control the Gotek, while the "slave" only receives the Gotek's output.
In my final working breadboard draft, U2 of the "master" egde triggers an interrupt of a PIC12F629 (which I happened to have laying around from another project). The PIC has an output connected to
SWITCH_IN
and a second input connected to the CTS output of the Amiga. Each detected low-to-high-edge of U2 advances the following state machine:To illustrate, here's my test setup (without the PIC12F629)
Rev. 0.2 of the "master board" integrates the PIC circuitry (and also has the cutout for the Blue Pill's oscillator corrected :-)
And here's a rendering of the much simpler "slave board"
While this setup works well enough, it has some drawbacks:
(1) It uses two Blue Pills where only one might be necessary, given H- and V-Sync can be provided twice independent from one another, and SPI1 and SPI2 can be used as outputs simultaneously, one for RTG the other for Amiga GFX.
(2) The PIC is very much of an overhead, because one additional input on the Blue Pill for CTS would suffice to implement the state machine therein. I just didn't like the idea of choosing one arbitrarily and starting to maintain my own fork of FF_OSD with this additional state machine. ;-)
(3) The "slave" Blue Pill doesn't know anything about the Amiga keyboard. Thus, all the output associated with hotkeys is only visible while Amiga graphics input is chosen. In addition, only the "master" has the nice multi-line output that is triggered by jumpering A0 and A1.
So, the logical idea would be to consolidate all of this into a single Blue (or, if Blue is not powerful enough) Black Pill.
On a side note, this setup would be interesting for people using the so-called "Ratte-Switches" for switching between Amiga and RTG output and perhaps for other scenarios where you don't need the switching but have two different video outputs on the same machine.
Much of this behaviour could be made accessible through the configuration menu I guess (well, a man can dream... ;-)
@keirf What do you think about this proposal? Does it have the slightest chance of being possible to implement?
The text was updated successfully, but these errors were encountered: