How to debug non functioning PHY driver and network interface for ethernet MAC on freertos? - tcp

Hi I'm desperately looking for some advice on things to try to figure out what's wrong with my code. I'm using the ATSAM4S Xplained Pro dev board with the Ethernet1 Xplained Pro Ext (the ethernet chip on this is ksz8851snl). I've ported freeRTOS onto the board using atmel studio. I have a blinky light task working. :) My problem is porting the tcp/ip stack native to freeRTOS. I found a pre written PHY and network interface in the freeRTOS zip. I thought that was sweet but it does not appear to work.
Here is a link to the whole driver I'm using. Just for reference, not asking anyone to do my work for me:
https://github.com/particle-iot/freertos/tree/master/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl
Basically I'm able to receive what appears to be erroneous ethernet packets. It's horrible!
I've been working all day without breaks on this, so I'm totally out of ideas as to how to approach this problem.
If you had a broken PHY driver, how would you go about getting it working? What clever debugging tricks would you try? I've never ported the tcp ip stack in freeRTOS before and I'm at a complete loss as to why it's still broken after so many things I've tried.
Also, one more important file is my conf_eth.h
I'm just gonna paste this one in since its short.
#ifndef CONF_ETH_H_INCLUDED
#define CONF_ETH_H_INCLUDED
#include "ioport.h"
#include "ioport_pio.h"
#include "FreeRTOSConfig.h"
/** Disable lwIP checksum (performed by hardware). */
#define CHECKSUM_GEN_IP 0
#define CHECKSUM_GEN_UDP 0
#define CHECKSUM_GEN_TCP 0
#define CHECKSUM_GEN_ICMP 0
#define CHECKSUM_CHECK_IP 0
#define CHECKSUM_CHECK_UDP 0
#define CHECKSUM_CHECK_TCP 0
/** Number of buffer for RX */
#define NETIF_RX_BUFFERS 3
/** Number of buffer for TX */
#define NETIF_TX_BUFFERS 3
/** MAC address definition. The MAC address must be unique on the network. */
#define ETHERNET_CONF_ETHADDR0 configMAC_ADDR0
#define ETHERNET_CONF_ETHADDR1 configMAC_ADDR1
#define ETHERNET_CONF_ETHADDR2 configMAC_ADDR2
#define ETHERNET_CONF_ETHADDR3 configMAC_ADDR3
#define ETHERNET_CONF_ETHADDR4 configMAC_ADDR4
#define ETHERNET_CONF_ETHADDR5 configMAC_ADDR5
/** SPI settings. */
#define KSZ8851SNL_SPI SPI
#define KSZ8851SNL_CLOCK_SPEED 30000000
#define KSZ8851SNL_CS_PIN 0 //This is the cs channel to use on atsam, there are 4 channels so 0-3
/** Pins configuration. GPIO values need to be set properly. */
#define KSZ8851SNL_RSTN_GPIO PIO_PA25_IDX
#define KSZ8851SNL_RSTN_FLAGS (PIO_PERIPH_A | PIO_PULLUP | PIO_TYPE_PIO_OUTPUT_1)
#define KSZ8851SNL_CSN_GPIO SPI_NPCS0_GPIO
#define KSZ8851SNL_CSN_FLAGS PIO_PERIPH_A | PIO_PULLUP | PIO_TYPE_PIO_OUTPUT_1//SPI_NPCS0_FLAGS
/** Push button pin definition. */
#define INTN_PIO PIOA
#define INTN_ID ID_PIOA
#define INTN_PIN_MSK PIO_PA1
#define INTN_ATTR (PIO_DEBOUNCE | PIO_IT_FALL_EDGE)
/* Interrupt priorities. (lowest value = highest priority) */
/* ISRs using FreeRTOS *FromISR APIs must have priorities below or equal to */
/* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. */
#define INT_PRIORITY_SPI 12
#define INT_PRIORITY_PIO 12
#define INTN_IRQn PIOA_IRQn
#endif /* CONF_ETH_H_INCLUDED */

Related

RCSwitch library seemingly not working for 433 Hz receiver on ESP32 NodeMCU

I'm pretty new to Arduino and especially ESP32. But - before I receive the tip "use an Arduino" - I decided to go for the ESP32 because of the size and the capability to connect it to the WLAN.
However, I am trying to build some control box for my terrarium which should - in the first design - steer various lamps and the rain pump via remote controlled outlets. For this I got an ESP32 NodeMCU, a RTC time module (which seems to work quite fine) and a 433 Hz receiver/sender set.
I followed several tutorials regarding the wiring and uploaded the example files to the ESP32. No matter which pin I connect the Receiver to (I need to connect the receiver first in order to read out the signals of the 433 Hz control which came with the outlets) I won't receive any signals on the receiver.
I embedded the library RCSwitch and I tried to configure my switch as follows (here with PIN 13 as example - I tried several other pins as well):
mySwitch.enableReceive(13)
As I read in some other blog, there might be the need to convert the pin number to its interrupt address, so I tried the following:
mySwitch.enableReceive(digitalPinToInterrupt(13))
The result is always the same: dead silence on the serial monitor (except the boot messages, etc.).
Am I using the wrong library or what am I doing wrong here?
I read that there should be a library called RFSwitch, but the only version I found only features the 433 Hz sender, not the receiver.
I would be really grateful for any hint concerning this issue - I'm pretty stuck here for many hours now...
I know this is pretty old and maybe you've resolved the issue by now but maybe it will help others. I had the same issue and what helped me was to set the pinMode:
pinMode(GPIO_NUM_35, INPUT);
mySwitch.enableReceive(digitalPinToInterrupt(GPIO_NUM_35));
Have been successful with RCSwitch today on ESP32 Dev Board and a 433MHZ receiver and sender. Here is what I have been stumbling on my journey.
Connecting the receiver (requires 5V)
You can use the ESP32-VIN for 5V if the Micro-USB is used to supply power
You may connect the Receiver-DATA to any ESP-32-Input-PIN BUT you might damage your ESP32 since it only allows ~3.3V
I tried first with some "makeshift" level shifting through resistors but I guess it lowers speed too much => A proper level-shifter (5V => 3.3V) might work out well
When referencing the PIN "xx" I have been just using the PIN-Number "Dxx" written on the ESP32-Dev-Board
You may connect an antenna of ~17.3cm to improve range
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
#define RXD2 27
void setup() {
Serial.begin(115200);
Serial.print("Ready to receive.");
mySwitch.enableReceive(RXD2);
}
void loop() {
if (mySwitch.available()) {
Serial.print("Received ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.print( mySwitch.getReceivedProtocol() );
Serial.print(" / ");
Serial.println( mySwitch.getReceivedDelay() );
mySwitch.resetAvailable();
}
}
In your RC and Outlet can be configured by DIP-Switches you might not need to connect the receiver overall - you can directly insert the DIP-Switches levels in the RCSwitch-Library
Connecting the sender (is fine with just 3.3V)
You can use the ESP32-3.3 to supply power
You may want to double check the PIN-Labels - I got confused because the DATA-Label was off and first interpreted as GND | DATA | VCC instead of GND | VCC | DATA
You may connect an antenna of ~17.3cm to improve range
#include <Arduino.h>
#include <WiFi.h>
#include <RCSwitch.h>
#define TXD2 25
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(115200);
// Transmitter is connected to Arduino Pin #10
mySwitch.enableTransmit(TXD2);
// Optional set protocol (default is 1, will work for most outlets)
// mySwitch.setProtocol(2);
// Optional set pulse length.
mySwitch.setPulseLength(311);
// Optional set number of transmission repetitions.
// mySwitch.setRepeatTransmit(15);
}
void loop() {
/* See Example: TypeA_WithDIPSwitches */
mySwitch.switchOn("01010", "10000");
Serial.println("Switch On");
delay(10000);
mySwitch.switchOff("01010", "10000");
Serial.println("Switch Off");
delay(10000);
}
I have not yet used sender or receiver while WiFi being active. Though I have been reading about issues while WiFi is active and receiving / sending via 433Mhz.
The sender must have 5 V supply to go far, and it has not output pin which can damage the ESP32, and the receiver. Instead, must be connected to 3.3 V because it has an output which goes to ESP2 (3.3 V supply) and the output of the receiver must not be more than 3.3 V, so as not to damage the GPIO input of ESP32.
ESP32
The data sender(input) goes to: GPIO 5: pinMode(5, OUTPUT)
The data receiver (output), goes to GPIO 4: pinMode(4, INPUT)
Sender supply: 5 V
Receiver supply: 3.3 V (not to damage ESP32 GPIO 4)

ESP8266 shutdown after compile

I have a big problem with esp8266-1.
Im updating code (any code, even "hello wordl") to esp8266. It was working for some time (sending temp reads from dallas temp through MQTT to RPI3) and now every upload to esp8266 has effect in interruption in any wireless comunication port: mwireless mouse has big problems, wifi is jammed.
What i did wrong?
Here some simple code:
#define pirPin 2 // Input for HC-SR501
int pirValue;
void setup() {
pinMode(pirPin, INPUT);
}
void loop() {
Serial.print(" Checking...");
pirValue = digitalRead(pirPin);
Serial.println(pirValue);
delay(1000);
}
Conection is good, becuse i madenter image description heree some sort of programming station for it with adapter, so i only pull it in to program.
Arduino setup
try this: add a capacitor in between VCC and GND. Pullup all the GPIO pins. Check the rest pin have floating values? if so pull up the reset pin too!

Protocol for writing data to 16x2 LCD via I2C

I am new to electronics and has completed a tutorial on how to operate a 16x2 Character LCD via I2C in Arduino using liquidCrystal_I2C. Everything works fine but I have a question about the low level interaction between the I2C and the LCD. Looking at the library's source code, I notice that when writing a 4 bits nibble (LiquidCrystal_I2C::write4bits), the code writes the nibble to the I2C expander first
(LiquidCrystal_I2C::expanderWrite), and then writes again when pulsing the Enable bit. Why is the first expanderWrite necessary? Why can't write4bits just call pulseEnable (with the blacklight bit set)?
I am sure there is a reason as I checked other library like RPLCD and see a similar pattern. Can anyone enlighten me? Thank you.
From the datasheet I found the LCD requires specific timing in the communication protocol.
On the rising edge of the enable line the Register Select and Read/Write lines must have already settled for tsu1 (100ns). On the falling edge of the enable line the data must have already settled for tsu2 (60ns). By writing _data they are also writing the RS and R/W lines as they are the lower nibble of _data.
This article covers the topic very thoroughly.
//**** From LiquidCrystal_I2C.h
// flags for backlight control
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100 // Enable bit
#define Rw B00000010 // Read/Write bit
#define Rs B00000001 // Register select bit
// ^--------Backlight bit defined above
// ^^^^---------Data bits
//**** From LiquidCrystal_I2C.cpp
void LiquidCrystal_I2C::write4bits(uint8_t value) {
expanderWrite(value);
pulseEnable(value);
}
void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
Wire.beginTransmission(_addr);
Wire.write((int)(_data) | _backlightval);
Wire.endTransmission();
}
void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
expanderWrite(_data | En); // En high
delayMicroseconds(1); // enable pulse must be >450ns
expanderWrite(_data & ~En); // En low
delayMicroseconds(50); // commands need > 37us to settle
}

I2C MCP3221 12 bit ADC reading 0 at any voltage

I've hooked up an MCP3221 to a Teensy 3.1 on the I2C bus and connect it to Vref(3.3V), just to check if it's working. However it's reading 0, even when I hook it up to a different voltage. Is my code faulty or should I just get a new device?
#include <MCP3221.h>
#include <Wire.h>
#include "SoftwareSerial.h"
#define ADDRESS 0x4D // 7 bits address is 0x4D, 8 bits is 0x9B
MCP3221 adc(155,0x3);
void setup() {
Serial.begin(9600);
Serial.println("First");
Wire.begin(); //connects I2C
}
void loop() {
Serial.println(adc.readI2CADC());
delay(10);
}
There is a list of device addresses in the Microchip data sheet DS21732C on the page 20.
Depends on the marking code on your chip.
You are not using the right address. You declare the constant but never use it. The adc declaration should be like this
MCP3221 adc(ADDRESS, 0x3);
Why? Doing a little search, I found out that instead of 8 bits address (155 in decimal or 0x9B in hexadecimal), you have to use 7 bits address, 0x4D in this case. You can see that in this example, too. I think you should have this example in the Arduino IDE, in File > Examples > MCP3221.
Looking at the example, seems like the second argument you passed to the adc can be wrong, too, but I'm not sure about this. Try a greater value if you see you always measure the same.

Using Arduino GSM library to switch on IComSat GSM board

I program my IComSat board attached to an Arduino Uno. It works, but the Icomsat module needs to be switched on by hand and I want to do that in software.
I using GSM_GPRS_IDE100_v309.zip
I using:
digitalWrite(GSM_ON, HIGH);
delay(300); /* spec says 200 should suffice */
digitalWrite(GSM_ON, LOW);
which is supposed to work.
You want to look in the GSM.h file. By default GSM_ON is defined as pin 8 and GSM_RESET is at pin 9, but for the IComSat that is different:
#define GSM_ON 9
#define GSM_RESET 8
You can see that on the schematics ( http://www.komputer.de/wordpress/wp-content/uploads/2012/02/sch-icomsat-v1.1.pdf ) page 2: PERKEY and D9 are connected, RESET and D8

Resources