Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 5 months ago.
With SPI, how do you read from slave?
Is there a way to read?
Thanks!
3 Answers
9 years, 4 months ago.
That seems reasonably straight forward.How do you configure the nucleo as slave?
The handbook has an example for SPI Slave code. See here. Make sure you use the correct SPIx NSS pin for the SPI port that you are using. Note that the SPI Master code can use any pin for CS, but the SPI slave needs to use a dedicated NSS pin.
posted by 05 Aug 20159 years, 5 months ago.
Reading from SPI slaves works as usual: you write a dummy byte to the slave and the slave returns a value at the same time. Obviously, you need to connect the MISO pins and in most cases you first need to write some commands to the slave to select the correct internal register. For example when using the lpc1768 :
#include "mbed.h" SPI spi(p5, p6, p7); // mosi, miso, sclk DigitalOut cs(p8); int main() { // Select the device by setting chip select low cs = 0; // Send 0x8f, the command to read the WHOAMI register spi.write(0x8F); // Send a dummy byte to receive the contents of the WHOAMI register int whoami = spi.write(0x00); printf("WHOAMI register = 0x%X\n", whoami); // Deselect the device cs = 1; }
9 years, 2 months ago.
I have a question about the SPI read from slave. My ADC has six channel, so I need 96 clock. I wonder that is my code as follows correct?
Serial pc(P0_2, P0_3); // tx, rx*** SPI spi(P2_27,P2_26, P2_22); // mosi, miso, sclk DigitalOut reset(P5_2); DigitalOut convst(P5_3); DigitalIn busy(P5_4); DigitalOut cs(P2_23); // ssel int main() { convst = 0; reset = 0; cs = 1; // Chip must be deselected spi.format(16,2); // Setup the spi for 8 bit data, high steady state clock, spi.frequency(1000000); // second edge capture, with a 1MHz clock rate reset = 1; wait_ns(50); reset = 0; while(1) { convst = 1; wait_ns(20); while(busy != 0 ); // Select the device by seting chip select low cs = 0; // Send 0x8f, the command to read the WHOAMI register wait_ns(6); signed short CH_A0 = spi.write(0x0000); signed short CH_A1 = spi.write(0x0000); signed short CH_B0 = spi.write(0x0000); signed short CH_B1 = spi.write(0x0000); signed short CH_C0 = spi.write(0x0000); signed short CH_C1 = spi.write(0x0000); // Deselect the device cs = 1; convst = 0; wait_ns(40); pc.printf("SDO=%d,", SDO); pc.printf("CH_A0 = %d, ", CH_A0); pc.printf("CH_A1 = %d, ", CH_A1); pc.printf("CH_B0 = %d, ", CH_B0); pc.printf("CH_B1 = %d, ", CH_B1); pc.printf("CH_C0 = %d, ", CH_C0); pc.printf("CH_C1 = %d\r\n", CH_C1); } }
In general, this should be the procedure. However, it all depends on the slave device. What ADC are you using? The ADC datasheet should provide all the necessary information regarding the sequence of commands and read/write operations. You may have to set some control registers first before the ADC does anything at all. You may also have to set a specific SPI format (# bits, clock phase, clockspeed..)
posted by 02 Oct 2015I am using ADS8556 in Hardware mode. The datasheet shows that in HW mode, SDI pin is connected to GND.
That's what I confuse how can I read the data from it.
ADS8556 Datasheet is over there: http://www.ti.com/lit/ds/symlink/ads8556.pdf
I want to use LPC4088DM to control it.
and my code is as follows:
----------------------
Serial pc(P0_2, P0_3); // tx, rx*** SPI spi(P2_27,P2_26, P2_22); // mosi, miso, sclk DigitalOut reset(P5_2); DigitalOut convst(P5_3); DigitalIn busy(P5_4); DigitalOut cs(P2_23); // ssel int main() { convst = 0; reset = 0; cs = 1; // Chip must be deselected spi.format(16,2); // Setup the spi for 8 bit data, high steady state clock, spi.frequency(1000000); // second edge capture, with a 1MHz clock rate wait_ns(20); while(1) { reset = 1; reset = 0; convst = 1; wait_ns(20); while(busy != 0 ); convst = 0; wait_ns(6); cs = 0; // Select the device by seting chip select low float CH_A0, CH_A1, CH_B0, CH_B1, CH_C0, CH_C1; CH_A0 = spi.write(0x0000); CH_A1 = spi.write(0x0000); CH_B0 = spi.write(0x0000); CH_B1 = spi.write(0x0000); CH_C0 = spi.write(0x0000); CH_C1 = spi.write(0x0000); cs = 1; // Deselect the device wait_ns(40); pc.printf("CH_A0 = %f, ", CH_A0); pc.printf("CH_A1 = %f, ", CH_A1); pc.printf("CH_B0 = %f, ", CH_B0); pc.printf("CH_B1 = %f, ", CH_B1); pc.printf("CH_C0 = %f, ", CH_C0); pc.printf("CH_C1 = %f\r\n", CH_C1); } }
------------------
Is anywhere need to modify, please let me know. Thank you very much
posted by 02 Oct 2015Please use <<code>> and <</code>>
tags on separate lines around you posted code to keep it readable.
The device has many options. I assume you selected the serial mode (PAR/SER is high). In HW mode the SDI is at GND since you dont send any config data to the control register. All settings are defined by external pins. The SPI input on the mbed (MISO) should be connected to the ADC SDO_X. I suppose you have it set to SEL_A = 1, SEL B = SEL_C = 0 so that all outputs are routed to SDO_A (see fig 37). Did you use CONVST_A to activate all 6 ADCs or are all CONVST_X wired in parallel. Why do you store the results in a float. The 16 bit data is output as signed short. You dont need to use a reset inside the while loop. One reset before the loop should do it.
posted by 05 Oct 2015Thank you for answer my question. I'm using HW / serial mode now, and setting SEL_A = 1, SEL B = SEL_C = 0 already. Also the mbed(MISO) is connected to the ADC serial Control pin (SDO). And the CONVST_X are wired in parallel. I've modified the code float into signed short, and reset do one time before the loop. (The code that I've modify is as follows) Since the SDI at GND, so I don't send any config data to the control register. That's mean I can read data from MISO pin directly ?
Serial pc(P0_2, P0_3); // tx, rx*** SPI spi(P2_27,P2_26, P2_22); // mosi, miso, sclk DigitalOut reset(P5_2); DigitalOut convst(P5_3); DigitalIn busy(P5_4); DigitalOut cs(P2_23); // ssel int main() { convst = 0; reset = 0; cs = 1; // Chip must be deselected spi.format(16,2); // Setup the spi for 8 bit data, high steady state clock, spi.frequency(1000000); // second edge capture, with a 1MHz clock rate reset = 1; wait_ns(50); reset = 0; while(1) { convst = 1; wait_ns(20); while(busy != 0 ); // Select the device by seting chip select low cs = 0; // Send 0x8f, the command to read the WHOAMI register wait_ns(6); signed short CH_A0 = spi.write(0x0000); signed short CH_A1 = spi.write(0x0000); signed short CH_B0 = spi.write(0x0000); signed short CH_B1 = spi.write(0x0000); signed short CH_C0 = spi.write(0x0000); signed short CH_C1 = spi.write(0x0000); // Deselect the device cs = 1; convst = 0; wait_ns(40); pc.printf("CH_A0 = %d, ", CH_A0); pc.printf("CH_A1 = %d, ", CH_A1); pc.printf("CH_B0 = %d, ", CH_B0); pc.printf("CH_B1 = %d, ", CH_B1); pc.printf("CH_C0 = %d, ", CH_C0); pc.printf("CH_C1 = %d\r\n", CH_C1); } }