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.
7 years, 1 month ago.
SPI.transfer and EthernetInterface mutually exclusive. Bug?
Hi there fam,
I've got what seems like a really strange bug where SPI::transfer and EthernetInterface (which I would think would be decoupled) break each other in strange ways. Here's a code snippet. Look at "@ Note {1...3}" commented lines to see what I'm talking about.
It always compiles. The issue is that at runtime either the EthernetInterface::connect call fails (does not attain IP address). Or the SPI::transfer command does not put out any data.
I think this may have to do with MBED underlying RTOS. (this build needs the 'PIO_FRAMEWORK_MBED_RTOS_PRESENT' compile flag)
I wonder if this issue is related to: https://os.mbed.com/forum/bugs-suggestions/topic/28418/
Heisen Bug
#include "mbed.h" #include "EthernetInterface.h" // #include <UDPSocket.h> #define IP "10.200.1.123" #define MASK "255.255.255.0" #define GATEWAY "10.200.1.1" // #define LED_FREQ 400000 // spi #define OPC_PORT 7890 volatile int count = 1; uint8_t firmware_version = 42; //uint8_t mac_addr_address = 0xFA; typedef unsigned char _enet_address[6]; _enet_address mac_addr; SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK); typedef struct { const unsigned int start = 0; } start_frame_t; // a single LED frame typedef struct { unsigned char brightness; unsigned char blue; unsigned char green; unsigned char red; } APARGB_t; typedef struct { const unsigned int end = 0xffffffff; } end_frame_t; typedef struct { start_frame_t start_frame; APARGB_t LED_frames[LED_NUM]; end_frame_t end_frame; } APA_buffer_t; APA_buffer_t sum_buf; // @ NOTE 1: This block is mutually exclusive with runtime function of EthernetInterface void transfer() { for (int i = 0; i < LED_NUM; i++) { sum_buf.LED_frames[i].brightness = ((0x7 << 5) | LED_GLOBAL); sum_buf.LED_frames[i].red = (led_buf[i] & 0xff); sum_buf.LED_frames[i].green = ((led_buf[i] >> 8) & 0xff); // G sum_buf.LED_frames[i].blue = ((led_buf[i] >> 16) & 0xff); // B } spi.transfer((const void *)&sum_buf, sizeof(sum_buf), (void *)NULL, 0, bit_width, NULL, 0); // the following call also breaks // spi.write((const char*)&sum_buf, sizeof(sum_buf), (char*)NULL, 0); // @ NOTE 2: I can use the following block no matter what but it is too slow for my application // int i; // // start frame // for (i = 0; i < 4; i ++) { // spi.write(0); // } // // led frame // for (i = 0; i < LED_NUM; i ++) { // spi.write((0x7 << 5) | LED_GLOBAL); // spi.write(led_buf[i] & 0xff); // R // // spi.write(packet.values[i].blue); // spi.write((led_buf[i] >> 8) & 0xff); // G // // spi.write(packet.values[i].green); // spi.write((led_buf[i] >> 16) & 0xff); // B // // spi.write(packet.values[i].red); // R // } // // end frame // for (i = 0; i < 4; i ++) { // spi.write(1); // } } int main() { int tswitch = 0; APA102_strip strip; strip.testStrip(); EthernetInterface net; int network_status = net.set_network(IP, MASK, GATEWAY); if (network_status != 0) { printf("ERROR: Network Status: %d\n", network_status); } net.connect(); const char *ip = net.get_ip_address(); printf("IP address is: %s\n", ip ? ip : "No IP"); while (tswitch < 7) { wait(0.05); if ((tswitch++) & 1) { strip.allRed(); strip.transferStrip(); } else { strip.allGreen(); strip.transferStrip(); } } // Open a socket on the network interface, and create a TCP connection to mbed.org UDPSocket socket; socket.open(&net); socket.bind(OPC_PORT); //port to use SocketAddress address(&net, NULL, NULL); // // OPC Message object OPC_message message; // @ NOTE 3: commenting or uncommenting the following line will determine whether or not SPI::transfer works at runtime socket.recvfrom(&address, &message.packet, sizeof message.packet); };
Which dev board and which Mbed OS version does this occur? Any shared pins between Eth interface and SPI?
posted by Jan Jongboom 10 Jan 2018