How to work in Beaglebone black I2C2 using buidroot - buildroot

I have compiled an image with buildroot. I want to work with I2C2 which is located in P9.19 and P9.20 ( SCL and SDA). I have connected the BBB I2C2 to a kw40z - NXP controller. I have added pull up to SDA and SCL, shared ground and connected both SCL and SDA to each other. I do see /dev/i2c-2
I2C2 does not work. I tried i2cdetect -r 2 and also a C program but I am getting timeout.
My questions are:
Does I2C2 is enabled or should I add the I2C2 device tree overlay from here:
If so, I compile the above dts fragment into dtbo ( using the dtc compiler)
How do i tell buildroot in beagle bone to load that dtbo?
I read that buildroot and even Debian does not support cape manager.
So it should be static.
Does any one managed to work with I2C2 without overlay? or is it a must?
Thanks!

Problem solved for i2c1 and i2c2
I added the two fragments into the bone-common.dtsi
for both I2C1 and I2C2 ( this is I2C1 for example)
under the pin mux
&am33xx_pinmux {
i2c1_pins: pinmux_i2c1_pins {
pinctrl-single,pins = <
0x158 (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE2) /* i2c1_sda */
0x15c (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE2) /*i2c1_scl */>;
};
And the node itself in am335x-boneblack.dts
&i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
/* this is the configuration part */
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
};
Also , no need for external pull-up when its is internally of course.
The pins are 17 - scl and 18 sda

Related

TypeError: 'id' argument required in Attempting to add NEO M9N to raspbery pi pico

Here is my frankensteined code, the error arises when i'm defining gps_module on line 12. I'm attaching pico pin 4 to the SDA on the GPS, pin 5 to the SCL, ground, and power
from machine import Pin, UART, I2C
#Import utime library to implement delay
import utime, time
sda_pin = machine.Pin(4)
scl_pin = machine.Pin(5)
# Create an I2C object out of our SDA and SCL pin objects
gps_module = machine.I2C(sda=sda_pin, scl=scl_pin)
print(gps_module)
#Used to Store NMEA Sentences
buff = bytearray(255)
TIMEOUT = False
#store the status of satellite is fixed or not
FIX_STATUS = False
Try 1 or 0 in the declaration
gps_module = machine.I2C(1, sda=sda_pin, scl=scl_pin)
https://docs.micropython.org/en/latest/library/machine.I2C.html#constructors
class machine.I2C(id, *, scl, sda, freq=400000)
Construct and return a new I2C object using the following parameters:
id identifies a particular I2C peripheral. Allowed values for depend
on the particular port/board
scl should be a pin object specifying the pin to use for SCL.
sda should be a pin object specifying the pin to use for SDA.
freq should be an integer which sets the maximum frequency for SCL.

Chip Enable not setting at right moment using SPI

Am trying to set a Chip Enable (CE) of a pin to go high before a SPI transfer and go back low upon accomplishing of the transfer (either TX or RX). Am using the NRF24L01 and Nucleo-F303. It is said that when the CE is high, thats when i can do a real SPI transfer to the NRF24L01. However, the CE pin goes momentarily low and then high again even before the real transfer hasnt been accomplished
The rest of the pins seem to be synching accordingly. How do i get the CE pin to exactly go high prior to making a SPI transfer and then Low when am done or not doing any more transfers.
Here is how i've attempted to solve the problem
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
uint8_t data[6] = {0x5C, 0xBA, 0xBB, 0x4D, 0x5E, 0xFB,};
uint8_t data1[6] = {0};
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
if(HAL_SPI_TransmitReceive(&hspi1, data, data1, 6, HAL_MAX_DELAY) == HAL_OK)
{
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
}
}
}
and this is how i have configured GPIO_PIN_3 to function
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // digital Output
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Usually the Slave Select signal of SPI is active low but you can change this behaviour through bit SSIOP (it is the name of the bit on STM32H7 , might be different on other STM32).
About your other question, the Slave Select signal going inactive between two bytes, you can change that behaviour thanks to bit SSOM.
The different SPI configurations are usually pretty well described in the Reference Manual.
I ended up going bare-metal because the libraries were giving a lot of delay and had so many abstract layers

Raspberry Pi - SPI device tree changes

I trying to move the SPI bus on a Raspberry Pi 3. I would like to move it from GPIO 7-11 to GPIO pins 22-26. The file "bcm2708_common.dtsi" contains the node for the spi0 bus:
spi0: spi#7e204000 {
compatible = "brcm,bcm2835-spi";
reg = <0x7e204000 0x1000>;
interrupts = <2 22>;
clocks = <&clk_core>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
/* the dma channels */
dmas = <&dma 6>, <&dma 7>;
dma-names = "tx", "rx";
/* the chipselects used - <0> means native GPIO
* add more gpios if necessary as <&gpio 6 1>
* (but do not forget to make them output!)
*/
cs-gpios = <0>, <0>;
};
The spi is configured in the top-level dts file "bcm2710-rpi-3-b.dts":
&gpio {
spi0_pins: spi0_pins {
brcm,pins = <7 8 9 10 11>;
brcm,function = <4>; /* alt0 */
};
};
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
cs-gpios = <0 0>;
spidev#0{
compatible = "spidev";
reg = <0>; /* CE0 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <500000>;
};
spidev#1{
compatible = "spidev";
reg = <1>; /* CE1 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <500000>;
};
};
Is reconfiguring the spi pins as simple as changing the gpio entry to this or is there something more that I need to do?
&gpio {
spi0_pins: spi0_pins {
brcm,pins = <22 23 24 25 26>;
brcm,function = <4>; /* alt0 */
};
};
No. you can not just change the pin numbers in DTSI and get it to change.
Long answer:
The brcm,pins field is just information for driver to refer to, if hardware does not support the pins you write there, you can not get it to work. On the Rpi 3b, pins 7,8,9,10,11 are supported as SPI i.e they can be multiplexed as SPI (the field brcm,function tells which multiplex mode to set pins in).
Now, also if you search for BCM2835 ARM peripheral you will find on page 152 the following:
The BCM2835 devices has only one SPI interface of this type. It is
referred to in all the documentation as SPI0. It has two additional
mini SPI interfaces (SPI1 and SPI2). The specifiation of those can be
found under 2.3 Universal SPI Master (2x).
So, the SoC on Rpi itself does not support other spi on any other pin.
Now for the second sentence of the above quote
It has two additional mini SPI interfaces (SPI1 and SPI2). The specifiation of those > can be found under 2.3 Universal SPI Master (2x).
If you dig in to bcm283x.dtsi, you will find that both those mini spis are named SPI1 and SPI2. gpio pins assigned for them are given as spi1_gpio16 and spi2_gpio40
which use pins :
spi1_gpio16: spi1_gpio16 {
brcm,pins = <16 17 18 19 20 21>;
brcm,function = <BCM2835_FSEL_ALT4>;
};
spi2_gpio40: spi2_gpio40 {
brcm,pins = <40 41 42 43 44 45>;
brcm,function = <BCM2835_FSEL_ALT4>;
};
so again not the pins you want to use.
You may go for bit banging spi if you are really really in a fix and can not use anything else

The clock of stm32f103 SPI is different from theoretic calculation after initialization

I am a new to stm32f103c8t6. Now I am trying to learn the SPI function and finished the code from the RCC to SPI initialization. I used oscilloscope to measure the SPI1 SCK signal due to test equipment limitation. Indeed that is clock signal but much lower than my RCC configuration. I tried to search the reason, but still failed. So may I ask if someone knows the answer.
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
Errsts = RCC_WaitForHSEStartUp();
if (Errsts == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY == RESET))
{
}
FLASH_SetLatency(FLASH_Latency_1);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
The code above shows my configuration about RCC, I used HSE as clock and the final frequency is 8Mhz/2*9=36Mhz. Below is my SPI and GPIO initialization:
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA, GPIO_Pin_4,Bit_SET);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI2 */
SPI_Cmd(SPI1, ENABLE);
So SPI_BaudRatePrescaler=4 means my SPI clock is 36Mhz/4=9Mhz, but actually the oscilloscope shows the frequecy is around 200Khz, it is much lower the the expectation. Also I tried to config SPI_BaudRatePrescaler with different value, it seems that the outcome is not linear.
Therefore I would like to ask if someone knows the answer. Thanks a lot!
Double check your prescaler value in your configuration. According to the reference manual, a value of 4 in the baud rate field will result in a divider of 32. To get to a clock of around 200 kHz, you need a value in that register of 6 or 7, which results in a divider of 128 or 256 (281 kHz or 140 kHz). If you want a divider of 4, you'll need to put a value of 1 in there. Check and see if SPI_BaudRatePrescaler_4 results in a value of 4 in the register, or a value of 1.
The outcome is not linear because they are using it as an exponent of 2. A value of 0 is 2^(0+1), while 1 is 2^(1+1), etc, etc.

Hardware interrupt between Raspberry pi and Atmega 328

I have connected my RPI and atmega328 together in order to control the start of an event on my arduino. In order to do so, GPIO 25 (RPI) is connected directly to pin7 (Arduino PD7). I've got a python script on the RPI witch set the GPIO 25 to high then back to LOW:
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(25, GPIO.OUT)
GPIO.output(25, 1)
#Do some stuff
GPIO.output(25, 0)
The arduino is waiting in a loop for either a physical button to be pressed or the pin7 to be set to HIGH by the RPI:
const int interrupt = 7;
const int button = 13;
const int led = 9;
void setup() {
Serial.begin(9600);
pinMode(interrupt, INPUT);
pinMode(button,INPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
}
void loop() {
bool on = false;
bool buttonOn = false;
while (!on || !buttonOn) {
on = digitalRead(interrupt);
buttonOn = digitalRead(button);
digitalWrite(led, LOW);
}
digitalWrite(led, HIGH);
delay(1000);
}
Now unfortunately this doesn't work. I have checked the logic level of the atmega328 (https://learn.sparkfun.com/tutorials/logic-levels) and it seems that 3.3V is good enough for HIGH signal.
Am I missing something with the pull up /pull down resistance? I know the PD7 on the atmega is specified as follow:
Port D is an 8-bit bi-directional I/O port with internal pull-up
resistors (selected for each bit). The Port D output buffers have
symmetrical drive characteristics with both high sink and source
capability. As inputs, Port D pins that are externally pulled low will
source current if the pull-up resistors are activated. The Port D pins
are tristated when a reset condition becomes active, even if the clock
is not running.
EDIT:
I have done more testing and I am getting the HIGH or LOW value correctly. It seems that the issue comes from the:
while ((!on) || (!buttonOn)) {
Is there an issue with Arduino and the OR operator in a while loop? Even when one condition is true and the other one is false, it never goes out of the loop.
while ((!on) || (!buttonOn)) {
}
That loop will run as long as one of the variables is false.
Yesterday I was for some reason thinking that you were reading the interrupt pin twice when reading your code.
3.3 v output should be ok to turn the Arduino input high.
You can have a wiring problem or your raspberry pi can be so fast that the arduino misses the pulse.
Change your program on the raspberry pi to leave the output high for so long (e.g. 10) seconds that you can measure it with a multimeter to see that you are setting the right pin.
Does the Arduino now see the input?