Skip to content
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

Adds chip select delay option #209

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Adds chip select delay option #209

wants to merge 1 commit into from

Conversation

johnnyman727
Copy link
Contributor

Fixes tessel/ambient-attx4#54 and maybe tessel/ir-attx4#32.

The ATTTINY based modules (Ambient and IR) are using a bit-banged version of SPI and need time to configure it prior to receiving data. Otherwise, they cannot reply in time.

This PR adds an optional chipSelectDelayUs property which alleviates that problem and makes the API more compatible with the T1 SPI API.

@kevinmehall
Copy link
Member

Ideally we'd do this kind of thing coprocessor-side with a CMD_WAIT, but that never got implemented.

@johnnyman727
Copy link
Contributor Author

@kevinmehall +1 but in the interest of time, I thought this would be easier (and it does fix a bunch of problems with the Ambient module).

@johnnyman727
Copy link
Contributor Author

I created an issue to track the WAIT command in the bridge API: #210

@johnnyman727
Copy link
Contributor Author

@kevinmehall other than that, does this code look good to you?

this.chipSelect.high();
this._port.uncork();

setTimeout(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally you would only uncork if you wanted a delay, otherwise you're going to get 100us-1ms of delay whether you like it or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your change isn't quite what I meant. In the case where you don't add a delay, you want to leave the entire transaction in one cork / uncork pair so it goes out in a single packet, but when you add a delay, you don't need cork/uncork, because you do want the commands separated.

this.chipSelect.low();
this._port._rx(data_len, callback);
this.chipSelect.high();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did the chipSelect.high() get removed here?

@kevinmehall
Copy link
Member

kevinmehall commented Sep 13, 2016

This approach isn't guaranteed to work. The setTimeout delays the time the command is sent, not when it is executed. If there are other commands already queued, spid is free to put the delayed commands together in the same packet, and they'll be executed just as before. To guarantee a delay without a firmware-side change, you would have to wait for a reply to each command, then wait, then send the next command.

if (this.chipSelectDelay > 0) {
this._port.uncork();
}
}, this.chipSelectDelay);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setTimeout still has a cost—any other code called after send but before the end of the execution turn will now execute before any of this code is executed. I think this needs to be reconsidered

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnnyman727
Copy link
Contributor Author

@kevinmehall and @rwaldron thanks for the review. Since there are so many concerns and gotchas with this approach, I'll try to go at it from the firmware angle instead.

I'm a little unsure as to the best way to complete it because I don't want to hold up the SPI bus. My plan is to implement the CMD_WAIT command which accepts a 16 bit unsigned int as the number of microseconds to delay. I'll setup a timer to trigger an interrupt after the delay completes and return EXEC_ASYNC in the interim from the port state machine. Once the delay completes, I'll just step into the next state machine command. @kevinmehall does this sound reasonable?

@rwaldron
Copy link
Contributor

I'll try to go at it from the firmware angle instead.

👍

ping when you need smoke testing :)

@johnnyman727
Copy link
Contributor Author

We'll probably replace this PR with #217 but I want to keep this PR around in case I'm not able to get the functionality built properly in firmware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants