I can see in Segger Embedded Studio v4.52 under the Build Tab, there are two methods to build the project.
1- Build > Build zephyr/zephyr.elf
2- Build > Build solution
What is the difference between the two methods?
Kind regards
I can see in Segger Embedded Studio v4.52 under the Build Tab, there are two methods to build the project.
1- Build > Build zephyr/zephyr.elf
2- Build > Build solution
What is the difference between the two methods?
Kind regards
Hi again!
So, first of all, to answer your questions about SPI:
You are right, I did not catch that part. I have sent a message to the Nordic developer that has written this, but since they are based in LA I won't have an answer on this until tomorrow.
I just received an answer about this.
"An index representing the peripheral’s chip select line number. (If there is no chip select line, 0 is used.)"
The spi1 node has a cs-gpios property, which means that the unit addresses for node a and b (0 and 1 respectively) are indexes into the cs-gpios array (an index representing the peripheral's chip select line number). The spi1 node has no cs-gpios, so node c has no chip select configured in the device tree, and therefore its unit address is left at 0 (if there is no chip select line, 0 is used).
In all your overlay examples you're still instantiating the ADC peripheral, which we don't want to do.
This is the template you want to follow:
/ { n: node { compatible = " "; io-channels = <&adc 4>; label = "AIN_0"; }; };
The forward slash indicates the root node and is very important to include.
To include multiple ADC io-channels, just refer to the adc-node each time like this (not &adc5 and &adc7):
io-channels = <&adc 26>, <&adc 28>;
and if you want to use a different compatible property for the two nodes, you need to create two separate nodes like this:
/ { n: node_a { compatible = " "; io-channels = <&adc 26>; label = "AIN_5"; }; n: node_b { compatible = " "; io-channels = <&adc 28>; label = "AIN_7"; }; };
For you question about voltage-divider
The lower leg is not a resistor, but the other one is a resistor? Or are you using a capacitive divider where both elements are capacitors?
For your binding question, yes this is the correct way to do it, using the label you defined in the node.
adc_dev_5 = device_get_binding("AIN_5");
adc_dev_7 = device_get_binding("AIN_7");
To do the binding for the two analog inputs, this is how to do it for AIN_5 and AIN_7 respectively.
device_get_binding(DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),0))
device_get_binding(DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),1))
Best regards,
Heidi
If I include in main.c
#include <hal/nrf_saadc.h>
and use this overlay file
&pwm0 {
ch0-pin = < 29 >;
};
/ {
n: node {
compatible = "voltage-divider";
io-channels = <&adc 4>;
label = "AIN_0";
};
};
then I get a different error,
devicetree error: 'output-ohms' is marked as required in 'properties:' in C:/Zypher/v1.3.0/zephyr/dts/bindings\adc\voltage-divider.yaml, but does not appear in <Node /node in 'nrf5340pdk_nrf5340_cpuapp.dts.pre.tmp'>
This suggests I need to add these two lines to the device tree fragment in the overlay file
output-ohms = <???>;
full-ohms = <(??? + ???)>;
But I am not sure if the "voltage-divider" works with an R-C circuit?
Finally, get_binding() does not bind AIN_0, it can only bind ADC_0.
Are you sure the label line can have something other than ADC_0?
Maybe I Should make changes to the source code (the light intensity controller example) in main.c when I am using the overlay file ?
Kind regards
Mohamed
Hi!
Learner said:However, it is still rather confusing because looking at the definition of sub-node (a) and sub-node (c) they are identical but in fact they are telling us different information about the sub-node.
I agree that it might be confusing, but you cannot look at the unit-addresses of nodes alone, you always have to look at the unit-address in context to the parent node. And when you look at the parent node of sub-node a versus sub-node c it becomes clear that sub-node a's "0" means an index into the cs-gpios array and sub-node c's "0" is just "NULL".
For the binding, I was wrong, you cannot just use the raw string as the argument. You need to use the following macros for the first and second IO-channel respectively:
DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),0) DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),1)
As for the issue with the voltage-divider, I am just as confused as you but I will ask around if anyone has any experience using it with the circuit you are using.
Learner said:Maybe I Should make changes to the source code (the light intensity controller example) in main.c when I am using the overlay file ?
What do you mean by this? I assume you will have to change the main.c file, firstly to bind the IO-channels.
Best regards,
Heidi
Hi!
Learner said:However, it is still rather confusing because looking at the definition of sub-node (a) and sub-node (c) they are identical but in fact they are telling us different information about the sub-node.
I agree that it might be confusing, but you cannot look at the unit-addresses of nodes alone, you always have to look at the unit-address in context to the parent node. And when you look at the parent node of sub-node a versus sub-node c it becomes clear that sub-node a's "0" means an index into the cs-gpios array and sub-node c's "0" is just "NULL".
For the binding, I was wrong, you cannot just use the raw string as the argument. You need to use the following macros for the first and second IO-channel respectively:
DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),0) DT_IO_CHANNELS_LABEL_BY_IDX(DT_NODELABEL(n),1)
As for the issue with the voltage-divider, I am just as confused as you but I will ask around if anyone has any experience using it with the circuit you are using.
Learner said:Maybe I Should make changes to the source code (the light intensity controller example) in main.c when I am using the overlay file ?
What do you mean by this? I assume you will have to change the main.c file, firstly to bind the IO-channels.
Best regards,
Heidi
Good morning Heidi,
What do you mean by this? I assume you will have to change the main.c file, firstly to bind the IO-channels.
Yes, of course, to get the binding to work using the new labels with the DT_ macros.
ADC raw (LSB) conversion results: ----------------------------------------------
I used ADC on various microcontrollers before and the ADC peripherals were straight forward to use and always provided raw (LSB) a2d results. Whys is it so complicated with this SoC/zephyr?
Why can't I use the "nordic,nrf-saadc" driver since it is the native nordic adc driver?
General questions: ------------------------
1- How can I add a comment in the overlay and dts files? I added few lines with a leading # but it caused problems. Does the # need to be in a particular location on a line?
2- I sometimes see fragment of DeviceTree code containing this @... Does this mean the user has to replace the ... with a number?
Thank you.
Kind regards
Mohamed
Hi!
Let me answer these questions first:
1. In the overlay and dts files, comments are added with "// Comment" or for multiple lines "/* Comment 1 \n Comment 2 */".
The comment sign "#" is used for configuration files like prj.conf and KConfig files.
2. Yes, node-name@... means there should be some unit-address in "..." but this depends on the SoC which is why it's not included.
I'm still working on getting some more info about the ADC peripheral.
Learner said:Why can't I use the "nordic,nrf-saadc" driver since it is the native nordic adc driver?
This is what I was told by one of the developers. We can't use it because it's only made to instantiate the ADC peripheral, and that's not what this node is. I can try to find a better explanation for this.
Do you just want a way to get the raw a2d results? You can take a look at this sample code which shows how to get raw ADC data.
The light controller example that you were working with also demonstrates how to get raw ADC data from an analog input.
The reason this is complicated is that we are trying to do it through an overlay file and there is very little sample code available, as it seems this isn't the common way to do it.
Learner said:ADC raw (LSB) conversion results: ----------------------------------------------
What is this? Is this from the log file?
Best regards,
Heidi
Hi Heidi,
I may not always get the answer I am looking for but I do appreciate your efforts. A big THANK YOU.
The reason this is complicated is that we are trying to do it through an overlay file and there is very little sample code available, as it seems this isn't the common way to do it.
Yes, I did see examples using the adc peripheral but they all use the #define and DT_ macros. I thought since almost every other hardware configuration can be done via the overlay file it would be a neat way to get the adc peripheral configured in the same way. If nordic/zephyr experts think that this is not the way to go about it then it is fine but they must let users like me know as early as possible so that no time is wasted. I may have to drop the idea of using the overlay file for the adc peripheral, which is a shame because I think it is a neater way.
Do you just want a way to get the raw a2d results?
Yes, I was expecting to get raw (LSB) values that I can then process/scale in my firmware. So, the "nordic,nrf-saadc" should provide that.
This is what I was told by one of the developers. We can't use it because it's only made to instantiate the ADC peripheral, and that's not what this node is. I can try to find a better explanation for this.
Please do. I cannot believe nordic do not provide a driver for their ad peripheral...
What is this? Is this from the log file?
No, this is just me trying to make my post more readable and break it into sections to make life easier for the support staff like your good self.
Kind regards
Mohamed
Hi!
To get the raw ADC information, you don't need a device tree `[compatible]`, because this is just what the ADC driver returns. You only need this when there is external hardware-related information (like the resistance and capacitance of an RC-divider) that needs to be exposed to the code to convert a raw ADC reading into something meaningful. This is shown in the battery sample I have linked to previously.
The `[voltage-divider]` is intended to match the Linux binding with the same `[compatible]` name. I can't find a Linux compatible for "RC-divider" but if there is one try to use that instead.
Otherwise, users can create their own bindings and then use this as the `[compatible]`property. See the Zephyr Bindings documentation before you start writing it, for the file syntax and conventions, etc. Make sure to use a `[compatible]` that's namespaced to avoid conflict with other devicetree node identifiers; use something like `[companyname,rc-divider]`.
I spoke to one of the developers and he is going to try to write a binding and small sample for the HW setup you are using (the op-amp and RC-divider).
Learner said:Please do. I cannot believe nordic do not provide a driver for their ad peripheral...
Nordic definitely has a driver for the ADC peripheral, it's in zephyr/drivers/adc/adc_nrfx_saadc.c, and included in the general zephyr ADC driver here when CONFIG_ADC_NRFX_SAADC is enabled.
This driver is used in the battery sample here. This is what you will use in the main.c file, because not everything can be done in the device tree.
But we can wait for the binding and sample, and see if that helps you along!
Best regards,
Heidi
Thank you Heidi.
For now I will get rid of the overlay file and use the raw adc readings. I think this will be good enough for our application.
I am not sure what CHANNEL_INPUT adc configuration parameter. in the code fragment below does. The code has been extracted from
https://github.com/nrfconnect/sdk-zephyr/blob/master/tests/drivers/adc/adc_api/src/test_adc.c
#define ADC_1ST_CHANNEL_ID 0 Is this selecting analog input pin AIN0 i.e. port P0.04?
#define ADC_1ST_CHANNEL_INPUT NRF_SAADC_INPUT_AIN1 It is used to set .input_positive in struct adc_channel_cfg This equates to 2 but not sure what it does. What is the difference between CHANNEL_ID and CHANNEL_INPUT?
#define ADC_2ND_CHANNEL_ID 2 Is this selecting analog input pin AIN2 i.e. port P0.06?
#define ADC_2ND_CHANNEL_INPUT NRF_SAADC_INPUT_AIN2 It is used to set .input_positive in struct adc_channel_cfg This equates to 3 but not sure what it does. What is the difference between CHANNEL_ID and CHANNEL_INPUT?
Thank you
Kind regards
Mohamed