SPI Slave Driver
Re: SPI Slave Driver
I'd like to bump this thread as I need to do the same thing.
I have implemented plyatov's method of adding a switch in the spiConfig to bypass the hard coded MSTR setting on the SPI_CR1.
I'm not sure which chibi spi methods I should call to handle a transaction of data from the salve to the master.
I use the following in one of my drivers that is in master mode:
spiAcquireBus(spip); // Acquire ownership of the bus.
spiSelect(spip); // Slave Select assertion.
spiSend(spip, headerLength, headerBuffer); // Slave Register Select
spiSend(spip, bodylength, bodyBuffer); // Write operation.
spiUnselect(spip); // Slave Select de-assertion.
spiReleaseBus(spip); // Ownership release.
Though that is not working here.
Should I be using spiStartExchange? Is spiAcquireBus and spiSelect not necessary?
I am just randomly trying methods, it isn't working well. Does anyone know the proper sequence of calls for slave mode transmit?
I basically need something that is going to take a buffer of data, and then wait until the master begins to clock it through and return when complete.
Cheers
Alex
I have implemented plyatov's method of adding a switch in the spiConfig to bypass the hard coded MSTR setting on the SPI_CR1.
I'm not sure which chibi spi methods I should call to handle a transaction of data from the salve to the master.
I use the following in one of my drivers that is in master mode:
spiAcquireBus(spip); // Acquire ownership of the bus.
spiSelect(spip); // Slave Select assertion.
spiSend(spip, headerLength, headerBuffer); // Slave Register Select
spiSend(spip, bodylength, bodyBuffer); // Write operation.
spiUnselect(spip); // Slave Select de-assertion.
spiReleaseBus(spip); // Ownership release.
Though that is not working here.
Should I be using spiStartExchange? Is spiAcquireBus and spiSelect not necessary?
I am just randomly trying methods, it isn't working well. Does anyone know the proper sequence of calls for slave mode transmit?
I basically need something that is going to take a buffer of data, and then wait until the master begins to clock it through and return when complete.
Cheers
Alex
Re: SPI Slave Driver
Xela wrote:I'm not sure which chibi spi methods I should call to handle a transaction of data from the salve to the master.
Here is example of how to use my SPI slave patch in ChibiOS applications.
Example communicates with SPI master by means of tl_start_receive() and tl_start_send().
Additionally, assert_dsp_rdy() and clear_dsp_rdy() used for indication of SPI slave readiness to communicate with SPI master. Falling edge of dsp_rdy line generates IRQ for master and it initiates SPI transfer.
Code: Select all
static const SPIConfig spi2_cfg = {
.slave_mode = true,
.end_cb = NULL,
.ssport = GPIOB,
.sspad = GPIOB_SPI2_NSS,
.cr1 = 0 // SPI_MODE_0.
};
#if (SPI_USE_WAIT != TRUE)
#error enable SPI_USE_WAIT in the halconf.h
#endif // SPI_USE_WAIT
/**
* @brief Sends data over the SPI bus.
* @details This synchronous function performs a transmit operation.
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
* without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer
*
* @api
*/
static void sspiSend(SPIDriver *spip, size_t n, const void *txbuf) {
osalDbgCheck((spip != NULL) && (n > 0U) && (txbuf != NULL));
osalSysLock();
osalDbgAssert(spip->state == SPI_READY, "not ready");
osalDbgAssert(spip->config->end_cb == NULL, "has callback");
spiStartSendI(spip, n, txbuf);
assert_dsp_rdy();
(void) osalThreadSuspendS(&spip->thread);
clear_dsp_rdy();
osalSysUnlock();
}
/**
* @brief Receives data from the SPI bus.
* @details This synchronous function performs a receive operation.
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
* without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer
*
* @api
*/
static void sspiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
osalDbgCheck((spip != NULL) && (n > 0U) && (rxbuf != NULL));
osalSysLock();
osalDbgAssert(spip->state == SPI_READY, "not ready");
osalDbgAssert(spip->config->end_cb == NULL, "has callback");
spiStartReceiveI(spip, n, rxbuf);
assert_dsp_rdy();
(void) osalThreadSuspendS(&spip->thread);
clear_dsp_rdy();
osalSysUnlock();
}
/**
* tl_start_receive - setup SPI for data reception.
*/
static void tl_start_receive(void)
{
tl_state = receive_packet;
spiStart(&SPID2, &spi2_cfg);
sspiReceive(&SPID2, TL_PACKET_SIZE, tl_buf);
}
/**
* tl_start_send - setup SPI for data transmission.
*/
static void tl_start_send(void)
{
tl_state = send_packet;
spiStart(&SPID2, &spi2_cfg);
sspiSend(&SPID2, TL_PACKET_SIZE, tl_buf);
}
Re: SPI Slave Driver
Now that I have my master side built up, I don't quite have this working yet.
It is likely a configuration issue though I am not 100% certain I understand the behavior of this function in terms of execution and program flow.
This spiStartSendI() will send a byte to the SPI buffer via DMA.
The loading of the SPI data register will be handled by the SPI peripheral on board the STM MCU.
I don't have to worry about the fine low level details of signalling.
I am not entirely confident if i should treat spiStartSendI() as a blocking or non-blocking function.
Will this thread remain suspended until the tx buffer has been read?
I am unfortunately working with hardware that does not have an auxiliary line to use as a DATA_RDY signal (will add one later).
At this point i just need to transmit one byte to confirm the connection works.
I run my slave board code and I assume it loads the SPI data register (LEDs/step through show the function just then waits)
On the master side i then manually execute a transfer (with code that works ok in loopback).
While I triple check every single config detail and brute force different baud rates, could someone confirm I do understand how this function is meant to be used?
Alex
It is likely a configuration issue though I am not 100% certain I understand the behavior of this function in terms of execution and program flow.
This spiStartSendI() will send a byte to the SPI buffer via DMA.
The loading of the SPI data register will be handled by the SPI peripheral on board the STM MCU.
I don't have to worry about the fine low level details of signalling.
I am not entirely confident if i should treat spiStartSendI() as a blocking or non-blocking function.
Will this thread remain suspended until the tx buffer has been read?
I am unfortunately working with hardware that does not have an auxiliary line to use as a DATA_RDY signal (will add one later).
At this point i just need to transmit one byte to confirm the connection works.
I run my slave board code and I assume it loads the SPI data register (LEDs/step through show the function just then waits)
On the master side i then manually execute a transfer (with code that works ok in loopback).
While I triple check every single config detail and brute force different baud rates, could someone confirm I do understand how this function is meant to be used?
Alex
Re: SPI Slave Driver
Xela wrote:It is likely a configuration issue
You should use only SPIx_NSS line as Chip Select. And it must be configured into Alternate mode to behave as NSS pin of corresponding SPI module.
Typically this is made in the board.h file.
Xela wrote:This spiStartSendI() will send a byte to the SPI buffer via DMA.
It will not send. It will only prepare SPI module for DMA tranfer. The transfer will be started by means of HW, only when SPI master assert NSS line of MCU.
Xela wrote:I am not entirely confident if i should treat spiStartSendI() as a blocking or non-blocking function.
It is non blocking and exits nearly immediately after call.
Xela wrote:Will this thread remain suspended until the tx buffer has been read?
Thread will be suspended by osalThreadSuspendS() until SPI transfer is finalized (NSS line is cleared).
It will be quite helpfull if you will use logical analyzer to see SPI diagrams. I recommend "Saleae Logic 16". The "Saleae Logic 8" can be used too, but it is quite limited. Look at saleae.com or better at aliexpress.com for cheaper clones
- alex31
- Posts: 379
- Joined: Fri May 25, 2012 10:23 am
- Location: toulouse, france
- Has thanked: 38 times
- Been thanked: 62 times
- Contact:
Re: SPI Slave Driver
Hello,
I need advice to implement a SPI slave protocol using chibios/stm32
I want to mimic invensense IMU SPI protocol, which themselves mimic I²C protocol to read/write a register table :
The first byte sent select slave register on 7 LSB, and operation (read or write) on 1 MSB. then next bytes are read of written beginning at the selected address, and auto incrementing.
Since SPI does not permit clock stretching, it means that i only have one SPI clock cycle to get the register address, calculate the dma buffer address (an offset), and setup dma slave operation, does that will work ?
I need at least 1Mhz SPI frequency
Thanks for any advice.
Alexandre
I need advice to implement a SPI slave protocol using chibios/stm32
I want to mimic invensense IMU SPI protocol, which themselves mimic I²C protocol to read/write a register table :
The first byte sent select slave register on 7 LSB, and operation (read or write) on 1 MSB. then next bytes are read of written beginning at the selected address, and auto incrementing.
Since SPI does not permit clock stretching, it means that i only have one SPI clock cycle to get the register address, calculate the dma buffer address (an offset), and setup dma slave operation, does that will work ?
I need at least 1Mhz SPI frequency
Thanks for any advice.
Alexandre
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: SPI Slave Driver
asdasd wrote:i am using chibios 19.1 how can i use slave spi
it seen some thing different
Hi,
There is no SPI-slave driver yet in ChibiOS, what is discussed in this thread is a customization.
Giovanni
Re: SPI Slave Driver
i know that there is no SPI slave driver, but
if i have correct understand , if i have done the spi slave v1 patch witch made by " plyatov "
it must work??
asd
if i have correct understand , if i have done the spi slave v1 patch witch made by " plyatov "
it must work??
asd
Return to “Small Change Requests”
Who is online
Users browsing this forum: No registered users and 6 guests