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, 10 months 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