Uart higher BaudRate problems in Raspberry Pi - c

Any idea why my native C application can't reach higher baudrates than 38400?
I have exactly the same application which i successfully initialize to listen and transmit on 9600, 19200, 38400 baudes. However as soon as i set up for 57600 i get garabage out of the transmitter(receiver i don't know). I'm listening to it with a terminal so i see the garbage directly from pin header.
I use Raspbian and uart on Pin 14 and 15 of the GPIO header.
Is there any adjustment of some precission fraction which causes the problem?
Right now i just do this (and it works):
cfsetispeed(&options,B38400);
cfsetospeed(&options,B38400);
tcsetattr(uart0_filestream, TCSANOW, &options);
fcntl(uart0_filestream, F_SETFL,O_NDELAY);
TX part:
int a = write(uart0_filestream, StartOfTheMessage, Length);
Thank you.

Your UART wires do not support the higher baud rate.

Related

Proper use of SPI functions in RP2040 C/C++ SDK with PGA2310 volume control IC

I've been working on a project where I use a PGA2310 volume control IC to set the volume of an audio signal. The chip's interface is supposedly SPI, but no matter how much I try, I just can't seem to get it right. The chip takes a 16 bit word over SPI that contains the left and right channel volume information.
I'm wondering if I am using the sdk all wrong and my code is whacked.
I guess my question is: Am I setting up and using the SPI functions correctly?
Here is my code
/**
* SPI interface for PGA2310 volume control ic
*/
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "pico/time.h"
const int CS = 0;
const int SDI = 1;
const int SCLK = 2;
const int LED_PIN16 = 16;
const int LED_PIN25 = 25;
uint16_t PGA2310();
uint16_t PGA2310() {
int baud = 1600000;
// SPI inistalization
spi_init(spi0, baud);
spi_set_format(spi0, 16, SPI_CPOL_0 , SPI_CPHA_0, SPI_MSB_FIRST);
// Sets SPI pins
gpio_set_function(CS, GPIO_FUNC_SPI);
gpio_set_function(SDI, GPIO_FUNC_SPI);
gpio_set_function(SCLK, GPIO_FUNC_SPI);
// Sets LED pins
gpio_init(LED_PIN16);
gpio_set_dir(LED_PIN16, GPIO_OUT);
gpio_init(LED_PIN25);
gpio_set_dir(LED_PIN25, GPIO_OUT);
// Data to send to chip. only sending first 8 bits for right channel.
// This is because I am currently just testing the output of the right channel
uint16_t high = 255;
uint16_t low = 100;
// Test by toggling between high and low volume states with LED indicators
while (true) {
gpio_put(LED_PIN25, 1);
spi_write16_blocking(spi0, &high, 1);
sleep_ms(2000);
gpio_put(LED_PIN25, 0);
spi_write16_blocking(spi0, &low, 1);
sleep_ms(2000);
}
}
I've tried a bunch of different methods that I found online for using SPI with the pico SDK. I've tried just sending 8 bits.
Let me know if more info is needed.
As explained in comments, SPI normally consists of 4 signals: /SS, SCLK, MOSI and MISO.
/SS = slave select, also known as chip select. Almost always active low.
SCLK = serial clock.
MOSI = Master Output Slave Input. The main data line. Your MCU seems to call this SDO (serial data out?).
MISO = Master Input Slave Output. Optional signal for duplex (two way) communication SPI. Your MCU seems to call this SDI (serial data input).
In this case the MCU is the master so you should be using MOSI/SDO. A MCU is almost always the master, except when communicating with other MCUs.
Additionally, always double check which CPOL and CPHA settings that the slave expects. Getting these wrong is a classic problem and can lead to subtle "clock skew" problems where everything works fine most of the time, then fail and give corrupt data intermittently.
The names you pick for variables/constants in C code do not have any effect on the hardware and they disappear as soon as the code is compiled. The most important thing is that you understand how the hardware works, read the documentation for the RP2040 SDK functions you are calling, and then pass the correct values to the RP2040 SDK functions.
The biggest problem is that you need to rethink every pin assignment. The RP2040 hardware SPI pin functions are defined in column F1 of the "GPIO Functions" section of the RP2040 datasheet. Here is an excerpt from that table:
This table tells us, for example, you cannot use pin 0 as the SPI0 CS function. If you assign that pin to be an SPI pin, it will be the SPI0 RX (data receiving) pin.
At a minimum, you need to pick one pin to be the SPI0 SCK pin and another to be the SPI0 TX pin, and you must connect those pins from the RP2040 to the equivalent pins on your device. Then you might also need to pick an RP2040 pin to control the CS pin on your device, if it has one. On the RP2040 side, this pin would be configured as a GPIO output pin and you would drive it low or high to enable your device. Refer to your device's datasheet for details about what signals it expects on its inputs and then use an oscilloscope to make sure you are generating compliant signals.
Another problem is that the spi_write16_blocking is probably modifying your high and low variables, so you will probably need to set those to the right values before each time that you use them. (So there is no point in having two different variables like that, just have one.)

Issue in interfacing E-Ink display with STM8S103F3P6 microcontroller

I am using Waveshare 1.54" ePaper Module. Using SPI peripheral:
CPU freq is 16Mhz
SPI Prescaler DIV by 8
MSB FIRST
CPOL=0, CPHA=1
The Display does not response but it respond with TI CC1310 properly.
The problem with SPI is after transmitting byte it does not go to ideal high state.
I have checked with logic analyser.
The SPI is initialised thus:
/****************** Initializing The SPI Peripheral ******************/
void SPI_setup(void)
{
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE); //Enable SPI Peripheral Clock
//Set the MOSI, MISO and SCk at high Level.
//GPIO_ExternalPullUpConfig(GPIOC, (GPIO_Pin_TypeDef)(GPIO_PIN_6),ENABLE);
SPI_DeInit();
SPI_Init(SPI_FIRSTBIT_MSB, //Send MSB First
SPI_BAUDRATEPRESCALER_8, //Fosc/16 = 1MHz
SPI_MODE_MASTER,
SPI_CLOCKPOLARITY_LOW, //IDEAL Clock Polarity is LOW
SPI_CLOCKPHASE_2EDGE, //The first clock transition is the first data capture edge
SPI_DATADIRECTION_2LINES_FULLDUPLEX, //Only TX is Enable
SPI_NSS_SOFT,
0x00);
SPI_Cmd(ENABLE);
}
This is pretty much the same problem you had at Issue in interfacing SPI e-ink display with PIC 18F46K22 only on a different processor. Worth noting that CPHA on STM8 has the opposite sense to CPE on PIC18 which may be the cause of your error. That is to say that CPHA=1 on the STM8 has the same effect as CKE=0 on the PIC18. You really have to look at the timing diagrams for each part carefully.
From https://www.waveshare.com/wiki/1.54inch_e-Paper_Module:
Compare with the STM8 reference manual:
Clearly you need one of:
CPHA=1 / CPOL=1 (SPI_CLOCKPOLARITY_HIGH / SPI_CLOCKPHASE_2EDGE) or
CPHA=0 / CPOL=0 (SPI_CLOCKPOLARITY_LOW / SPI_CLOCKPHASE_1EDGE)
If it is the SCLK that you want to be normally-high, then you need the first option - although I fail to see why that is "ideal", the Waveshare diagram clearly indicates that either is acceptable.

ESP32 Analog pin not reading when bluetooth is connected

I have been using ESP32 and writing code in Arduino. However, when I enable Bluetooth, GPIO4 and GPIO15 does not work to read analog inputs. I have connected IR LED's on both pins and reading analog signals. If Bluetooth code is not used, ESP32 is reading the analog signals and displaying it on serial monitor. If the below Bluetooth code is used, the reading is shown as 255 on both pins (reading 5v. Yes, they are 5v for now and will be level shifted to 3.3v).
Can someone please check and suggest a solution?
I have switched the sensors, removed them and whatever I do, the reading is the same when Bluetooth is read
Bluetooth code:
void init_bluetooth() {
ESP_BT.begin("EKA Robot"); //Name of your Bluetooth Signal
Serial.println("Bluetooth Device is Ready to Pair");
}
IR code:
// Read Infrared LED on GPIO4. Similar function exists to read GPIO15
int readIR() {
int sensorValue = analogRead(oaPinL);
delay(5);
sensorValue = map(sensorValue, 0, 4095, 0, 255);
return (sensorValue);
}
I expect to read the sensor values. However, all it shows is 255. Does it mean it is somehow pulled high?
There are two A/D converters in the ESP32 chip, ADC1 and ADC2. ADC2 pins can not be used when Wi-Fi or Bluetooth is used. Pins connected to ADC1 do work. These are GPIO32-36 and GPIO39.

Raspberry Pi can't send data to PC through serial communication

I am trying to send/receive data over the serial connection (GPIO UART pins) between a Raspberry Pi 2(raspian wheezy) and an STM32F4 board. I am using the sample code in the link: http://www.raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart.
It works when I connect the TX and RX pins on the board together. However, when I connect RPI to my laptop by module USB-TTL PL2303 and use hyper terminal to see the result, the received characters are garbage characters. I don't understand why. Is there anything I missed?
Could you give me some advice I could look for, please? Thank you!
Most likely you are using incorrect baud rate. It should be 115200 (115200-8-N-1) (you can use else but then you need to set both endpoints to the same baud). Check the baud rate of the serial connection using stty
stty -F /dev/ttyX
or setserial. In case of baud rate error you can try what authors say:
Try using a slower BAUD rate (or a single 0xFF byte which only has the
start bit low) and see if it works. We had a problem using 115k2 baud
rate where our microcontroller communicating with the RPi could hit
113636baud or 119047baud. 113636baud had the lowest error margin so
we used it and TX from the RPi being received by the microcontroller
worked fine. However when transmitting to the RPi nothing was ever
received. Changing the microcontroller to use 119047baud caused RX to
work.

example code, documents on MCP23017 (16 pin IO extender, I2C) as an 7-segment LCD driver

the MCP23017 from Microchip is an I2C based 16-pin IO extender. I have been able to set up the device once (set pin direction and values), but after that i cannot change the values as expected unless i reset / power cycle the device. this is the code i used to initalize it and set the pins up the first time:
I2C_Start();
I2C_Write(0x40); // slave address
I2C_Write(0x00); // address register
... (sequential mode so next 10 are set to I2C_Write(0x00);
I2C_Write(0x08); // IOCON: HAEN=1
I2C_Write(0x08); // IOCON: HAEN=1
... (sequential mode so next 6 are set to I2C_Write(0x00);
I2C_Write(0xFEu); // GPIOA
I2C_Write(0x01u); // GPIOB
I2C_Stop();
after this i would like to be able to toggle the output values (0xFE <-> 0x01).
I attempted this code:
I2C_Start();
I2C_Write(0x40); // slave address
I2C_Write(0x12); // address register
I2C_Write(0x01u); // GPIOA
I2C_Write(0xFEu); // GPIOB
I2C_Stop();
at this point it seems to go out to lunch, the pins seem to be random in value (input vs. output, output High vs Low). If anyone as used this I2C IO extender please help me out. even if your not fully sure your more than welcome to comment. NOTE: I2C API shown here is a bit bang algorithm all clock cycles have aprox. 1ms weights between them.
useful documents (kind of): http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf
Try looking at the SCL and SDA signals using an oscilloscope or logic analyzer to check your timing and the data to make sure you are sending the I/O expander the values you think you are.

Resources