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

Implement SPI Streaming commands in SPI BBIO #68

Closed
wants to merge 6 commits into from

Conversation

david-sawatzke
Copy link

This enables just sending individual bytes from the host one-by-one.
It's started by sending 0b00001000
By sending 0x00, the mode is stopped.
To send a 0x00 over spi, start it again with 0b00001001.
After the mode is entered, 0x01 is returned to the host. If a "zero beginning" is used, the read byte is now returned. After sending a byte, the accompanying returned byte is sent back. After sending a 0x00, 0x01 is returned and the mode is exited.

Potential use-cases:
This is usefull for programming AT89 microcontrollers, as you have to wait a bit after each byte until the flash is programmed. Using existing commands a new transfer would have to be started every time. This would greatly simplify it.
(This is not tested yet)

@bvernoux
Copy link
Member

  1. Could you test it to confirm it works before to merge it in master ?
  2. Could you add !USER_BUTTON in while loop in order to abort it with USER_BUTTON to avoid an infinite loop ?

Copy link
Collaborator

@Baldanos Baldanos left a comment

Choose a reason for hiding this comment

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

First of all, thanks for your submission.

Maybe I'm missing the point here, but I don't see how this mode is more simple to use than the bulk SPI transfer, especially when dealing with the null bytes.

  • Bulk method
for byte in bytes:
  send('\x11'+byte)   # bulk send 1 byte, then the byte to send
  [...]
  • Stream method :
send(0b00001000)
for byte in bytes:
  if byte == '\x00':
    send('\x00')       # quit stream mode
    send(0b00001001)   # enter stream_zero mode
  else:
    send(byte)

It could eventually be simplier to enter this stream mode by specifying the number of bytes to be transferred, then sending each byte one by one.

  • Proposed stream :
send(0b00001000)       # enter stream mode
send(len(bytes))       # will send that number of bytes
for byte in bytes:
  send(byte)

Also, be very careful with the read/write sequence. As SPI is full duplex, reading a byte also writes a byte to the slave (0xFF with Hydrabus).
I looked at https://www.samba.org/~jelmer/at89prog/at89prog, the programming commands take 3 bytes, so the stream method is not suitable for sending AT89 programming commands.

cprint(con, "\x01", 1);
if(bbio_subcommand == BBIO_SPI_STREAM_ZERO) {
bsp_spi_write_u8(proto->dev_num, "\x00", 1);
bsp_spi_read_u8(proto->dev_num, tx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

rx_data should be used here to be consistent with other functions in this mode.

cprint(con, tx_data, 1);
}
while (!USER_BUTTON) {
chnRead(con->sdu, rx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

tx_data should be used here to be consistent with other functions in this mode.

chnRead(con->sdu, rx_data, 1);
if(rx_data[0] == 0)
break;
bsp_spi_write_u8(proto->dev_num, rx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

tx_data should be used here to be consistent with other functions in this mode.

if(rx_data[0] == 0)
break;
bsp_spi_write_u8(proto->dev_num, rx_data, 1);
bsp_spi_read_u8(proto->dev_num, tx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

rx_data should be used here to be consistent with other functions in this mode.

if(bbio_subcommand == BBIO_SPI_STREAM_ZERO) {
bsp_spi_write_u8(proto->dev_num, "\x00", 1);
bsp_spi_read_u8(proto->dev_num, tx_data, 1);
cprint(con, tx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

rx_data should be used here to be consistent with other functions in this mode.
Also, a type casting is required to avoid a compiler warning :
cprint(con, (char *)rx_data, 1);

case BBIO_SPI_STREAM_ZERO:
cprint(con, "\x01", 1);
if(bbio_subcommand == BBIO_SPI_STREAM_ZERO) {
bsp_spi_write_u8(proto->dev_num, "\x00", 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

A type casting is required to avoid a compiler warning here :
bsp_spi_write_u8(proto->dev_num, (uint8_t *)"\x00", 1);

break;
bsp_spi_write_u8(proto->dev_num, rx_data, 1);
bsp_spi_read_u8(proto->dev_num, tx_data, 1);
cprint(con, tx_data, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

rx_data should be used here to be consistent with other functions in this mode.

@david-sawatzke
Copy link
Author

david-sawatzke commented Jan 2, 2017

Sorry for the confusion with the seperate read and write function calls. I forgot about the full-duplex nature of spi.

Using the stream transfer isn't simpler than the bulk transfer. I don't know what I thought about when I wrote that.

I now tested the speed difference between using the bulk method and the stream method and it's only twice as fast, so I don't think including it is worth the extra complexity (this also applies to the proposed method of sending the bytes beforehand, since that won't be very different).

The proposed method with sending the number of bytes beforehand also isn't that much simpler than the bulk transfer.

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.

None yet

3 participants