Shared Data... Or Not? Help With Design
soshimo
Posts: 215
I'm creating a hardware/software bridge between an i2c device and another cpu. My first thought was pic or avr, then I started thinking about interrupts - ugh. Then, I thought, while it would be overkill for what I need - kind of like slapping a Ferrari engine on a Yugo (no offense to any Yugo owners) - it would be MUCH easier to do with the propeller because I need exact timings for both sides. Obviously there are tried and true i2c objects out there already, and I will be leveraging them for certain, but I have to also write the custom side which has granularity of some 700ns. The pulse train itself lasts 16.667ms with a 50% duty cycle with 12us per cycle. It's doable on other chips sure, but the ease with which I can do it on the propeller is astounding.
Okay, so those are the requirements, my problem is that I need to share hub memory between the two cogs running. I will have an i2c agent, which will leverage the existing i2c code out there, on one cog and another agent running the custom protocol on the other. I need to feed, and buffer, the information from the i2c agent to the custom agent but I'm worried that the round robin access of the cog memory will cause me problems, unless I can tell exactly how any cycles I have to wait for my turn. Otherwise I'll have to have a complex state mechanism with jump tables and such. I'm really trying for a simple approach on this. Unless there is something that I don't understand about hub access.
Finally, I had another thought. Can you start two programs on separate cogs from one spin program? I'm thinking I can have the one spin program start up, fire up the two agents on separate cogs, and pass in an argument for at least the custom agent. Then it can sit and spin, reading from the i2c object and sending the result to the agent. That way the main program can read from the i2c object and call a public method on the custom agent to pass in a value. The result would be "latched" and the agent can use it the next time it sends the data pulse train much like Beau's SPI SHIFTIN/SHIFTOUT examples. To be honest, that would be my preferred approach as it keeps coupling of the agents to a minimum, something I like to avoid at all costs, especially in an OO (pseudo or not) environment.
Okay, so those are the requirements, my problem is that I need to share hub memory between the two cogs running. I will have an i2c agent, which will leverage the existing i2c code out there, on one cog and another agent running the custom protocol on the other. I need to feed, and buffer, the information from the i2c agent to the custom agent but I'm worried that the round robin access of the cog memory will cause me problems, unless I can tell exactly how any cycles I have to wait for my turn. Otherwise I'll have to have a complex state mechanism with jump tables and such. I'm really trying for a simple approach on this. Unless there is something that I don't understand about hub access.
Finally, I had another thought. Can you start two programs on separate cogs from one spin program? I'm thinking I can have the one spin program start up, fire up the two agents on separate cogs, and pass in an argument for at least the custom agent. Then it can sit and spin, reading from the i2c object and sending the result to the agent. That way the main program can read from the i2c object and call a public method on the custom agent to pass in a value. The result would be "latched" and the agent can use it the next time it sends the data pulse train much like Beau's SPI SHIFTIN/SHIFTOUT examples. To be honest, that would be my preferred approach as it keeps coupling of the agents to a minimum, something I like to avoid at all costs, especially in an OO (pseudo or not) environment.
Comments
2) It's possible (easy in fact) to synchronize a cog to its shared memory access slot so that there's no waiting for access after the 1st access (where the synchronization occurs). This is done with all of the video drivers. In fact, cogs can be synchronized with each other as well as is done with several VGA drivers. This is done by each cog getting the value of the system clock, adding a value to it, then waiting for that time (in the future) to occur using a WAITCNT. At that point, each cog is running at a known point in the code at a known time in relationship to any other cog that does the same thing. Because the Propeller is deterministic, this relationship among cogs can be maintained. Have a look at the video drivers for examples.
3) A cog can synchronize itself to its hub slot by accessing a memory location. At that point (because the instructions are deterministic), it can read the system clock and synchronize itself to the hub and to other cogs doing the same thing.