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, 8 months ago.
Problems with spi-communication
Hi,
I have a Raspberry Pi and mbed Nucleo ST32F411RE connected via SPI.
This is the python's programme on the Raspberry Pi:
try: import tkinter as tk except: import Tkinter as tk import spidev spi = spidev.SpiDev() spi.open (0, 0) import time # spi.max_speed_hz = 1000000 button_width = 40 def bit_8_to_16(value=[]): return ( (value[0]<<8)+value[1] ) def bit_16_to_8(value=0): return_value = [] return_value.append(value>>8) return_value.append(value&0x00FF) return return_value def main(): root = tk.Tk() def do_exit(): print ("PROGRAMM BEENDET") root.quit() def do_adc_task_isrunning(): print ("ADC TASK RUNNING") spi.writebytes([0x00, 0xA0]) def do_adc_task_start(): print ("ADC TASK START") spi.writebytes([0x00, 0xA1]) def do_adc_task_stopp(): print ("ADC TASK STOPP") spi.writebytes([0x00, 0xA2]) def do_adc_task_setfrequency(): print ("ADC TASK SETFREQUENCY") spi.writebytes([0x00, 0xA3]) time.sleep(0.1) spi.writebytes([0x00, 100]) def do_fifo_anzahl_elements(): print ("FIFO ANZAHL ELEMENTS") spi.writebytes([0x00, 0xB0]) def do_fifo_get_one_element(): print ("FIFO GET ONE ELEMENT") spi.writebytes([0x00, 0xB1]) print (spi.readbytes(2)) def do_fifo_get_elements(): print ("FIFO GET ELEMENTS") spi.writebytes([0x00, 0xB2]) #ADC_TASK_ISRUNNING = 0x00A0, #ADC_TASK_START = 0x00A1, #ADC_TASK_STOPP = 0x00A2, #ADC_TASK_SETFREQUENCY = 0x00A3, #FIFO_ANZAHL_ELEMENTS = 0x00B0, #FIFO_GET_ONE_ELEMENT = 0x00B1, #FIFO_GET_ELEMENTS = 0x00B2 button_1 = tk.Button(text="ADC_TASK_START", width=button_width, command=do_adc_task_start ) button_1.pack() button_2 = tk.Button(text="ADC_TASK_STOPP", width=button_width, command=do_adc_task_stopp ) button_2.pack() button_3 = tk.Button(text="ADC_TASK_SETFREQUENCY", width=button_width, command=do_adc_task_setfrequency ) button_3.pack() button_4 = tk.Button(text="ADC_TASK_ISRUNNING", width=button_width, command=do_adc_task_isrunning ) button_4.pack() button_5 = tk.Button(text="FIFO_ANZAHL_ELEMENTS", width=button_width, command=do_fifo_anzahl_elements ) button_5.pack() button_6 = tk.Button(text="FIFO_GET_ONE_ELEMENT", width=button_width, command=do_fifo_get_one_element ) button_6.pack() button_7 = tk.Button(text="FIFO_GET_ELEMENTS", width=button_width, command=do_fifo_get_elements ) button_7.pack() exit_button = tk.Button (text="Exit", command=do_exit, width=button_width) exit_button.pack() root.mainloop() if __name__ == "__main__": main() spi.close()
This is c-code on mbed:
#include "mbed.h" #include "read_adc.h" #include "ringbuffer.h" #include "spi_commands.h" #ifdef TARGET_NUCLEO_F411RE SPISlave spidevice(PA_7, PA_6, PA_5, PA_15); // mosi, miso, sclk, ssel #endif #ifdef TARGET_LPC1768 SPISlave spidevice(p11, p12, p13, p14); // mosi, miso, sclk, ssel #endif // Ringbuffer initialisieren: RingBuffer ADC_Fifo; RingBuffer Error_Fifo; // ADC_Interrupt initialisieren ReadADCValues read_ADC_values; Serial pc(USBTX, USBRX); uint32_t help, get_element=0; void spi_evaluation(uint16_t command) { bool abort = false; switch (command) { case ADC_TASK_ISRUNNING: pc.printf ("\n\r ADC_TASK_ISRUNNING (%d)", read_ADC_values.is_active); break; case ADC_TASK_START: pc.printf ("\n\r ADC_TASK_START"); read_ADC_values.start(); break; case ADC_TASK_STOPP: pc.printf ("\n\r ADC_TASK_STOPP"); read_ADC_values.stopp(); break; case ADC_TASK_SETFREQUENCY: pc.printf ("\n\r ADC_TASK_FREQUENCY"); abort=true; while (abort) { if (spidevice.receive()) { abort = false; help=spidevice.read(); // read_ADC_values.set_sampling_rate( spidevice.read() ); } } // Ende while pc.printf ("\n\r NEW_FREQUENCY (%d)", help); break; case FIFO_ANZAHL_ELEMENTS: pc.printf ("\n\r FIFO ANZAHL ELEMENTS"); break; case FIFO_GET_ONE_ELEMENT: // pc.printf ("\n\r FIFO GET ONE ELEMENT"); spidevice.reply(get_element); get_element++; break; case FIFO_GET_ELEMENTS: pc.printf ("\n\r FIFO GET ELEMENTS"); break; } // Switch Ende } int main () { // uart konfigurieren pc.baud (921600); pc.printf ("\n\r Programm wurde gestartet"); // spi konfigurieren spidevice.format (16, 0); // spidevice.frequency(1000000); // ADC-Interrupt konfigurieren read_ADC_values.init(); while (1) { if (spidevice.receive()) { spi_evaluation (spidevice.read()); } // Ende if } // Hauptschleife Programm }
This is SPI_COMMANDS.h
/* In dieser Datei werden die Hexwerte für die SPI-Befehle, die vom SPI-Master kommen, mit lesbaren Worten codiert. */ #ifndef SPI_COMMANDS_H #define SPI_COMMANDS_H enum SPICommands { ADC_TASK_ISRUNNING = 0x00A0, ADC_TASK_START = 0x00A1, ADC_TASK_STOPP = 0x00A2, ADC_TASK_SETFREQUENCY = 0x00A3, FIFO_ANZAHL_ELEMENTS = 0x00B0, FIFO_GET_ONE_ELEMENT = 0x00B1, FIFO_GET_ELEMENTS = 0x00B2 }; #endif
I´ve a big problem:
When pressing the "FIFO GET ONE ELEMENT"-Button on Raspberry Pi I don´t receive correct values sometimes. There´s a counter in c-code and whenever data should be sended, sometimes I receive the same value several times. I don´t know what doing wrong.
case ADC_TASK_SETFREQUENCY: ... while (abort) { if (spidevice.receive()) { ...
def do_adc_task_setfrequency(): print ("ADC TASK SETFREQUENCY") spi.writebytes([0x00, 0xA3]) time.sleep(0.1) spi.writebytes([0x00, 100])
The communication between Raspberry Pi and Nucleo contains lots of errors. Can you tell me your experiences using spi-port for communication? What´s the cause of the defect?
1 Answer
9 years, 8 months ago.
Make sure you set the GPIO speed to the highest value for the SPI pins on the Nucleo. The SPI won't work properly at speeds higher than about 2mhz without doing so. This needs to be done either through the hal or directly to the register.
Depending on which SPI you are using the bit rate may be half of what you ask for on the Nucleo since MBED doesn't calculate the speed right if the peripheral is connected to the slower bus.
Sorry to be vague but you'll need to look up the specifics in the ST datasheet.
Good luck and I hope this helps.... Doug