LoRa, SX1276 transmission power managment - lora

I want to verify if my information about the Tx output power is correct or no, because i'm kinda confused, so if you could bear with me to tell you want i know or at least what i think it's true about this subject:
+ in Tx they are 3 power modes:
1- RFO: from -4 dBm to 15 dBm (Pout=Pmax-(15-OutputPower) = 10.8 + 0.6 * 7 - (15 - 15) = 15) 7 is the max value for the MaxPower and 15 is the max value for the outputPower so that's way the RFO can reach 15 dBm, but i don't know why they said it's only +14dBm? and set the PaSelect to 0 to use this mode and make sure the PA_Dac set to 0x04 (default value)
2- PA_Boost: from 2 dBm to 17 dBm (Pout=17-(15-OutputPower)) this is clear. set PaSelect bit to 1 to activate this mode. and make sure to set the PA_Dac to 0x04 (default value) (PA_DAC register = 0x84)
3- +20dBm: 20 dBm, to use this option we need to be in the PA_Boost mode (set PA_Boost bit to 1) and set the PA_DAC to 0x07 (PA_DAC register = 0x87).
About the RFO where i need to set 2 variable "MaxPower" and "Output Power", i don't know what is the right way to do that, i mean which one should i adjust to get the Tx power the user want to use. or should i set the "MaxPower" to 7 so the Pmax = 15 and from there i set the "Output Power" to get the Pout (which is the Tx power) the user wants, because it's gonna be easy to go from 15 to 0 by step of 1 dBm. hope one of you have a better solution?!
Now the last thing, the OCP, which is require for the PA_Boost and +20 dBm option because both works in high power (PA_HP) and i don't know how to set that register, i mean how to calculate Imax. i need help about this, and do i need to set this register for the RFO mode too?? if yes then how? (by the way, i know about the table of OCP in the datasheet and how to calculate the OCP from Imax, the problem that i don't know how to get or figure about the Imax.
One last question, is the order to configure the PaSelect Variable and MaxPower and Output Power and PA_DAC register and OCP register matters, my real confusion is about PaSelect variable and Output Power variable and PA_DAC register configuration order.
I hope i was clear and i will appreciate your help to correct me and confirm my information. Thank YOU.

Ok, to answer some of my questions:
what i said about RFO was right, but i still don’t know why they said it’s between -4 to 14 dBm and in the same datasheet in other section they said it’s 15 dBm. anyway, about how to set this in the register because you have 2 variable you need to set (maxPower, and outoutPower), you can notice we have 2 regions, from -4 to 0 dbm and from 0 to 15 dBm. for [-4, 0[ set the maxPower to 0 and that will give you a Pmax = 10.8 and from this equation Pout = Pmax - 15 + outputPower = 10.8 -15 + outputPower = -4.2 + outputPower, we can find outputPower = Pout + 4.2, and for the region [0, 15] we set the maxPower to 7 (the max value) so we will have this now , Pout = 15 - 15 + outputPower = outputPower.
About the PA_BOOST it a forward calculation nothing fancy, outputPower = Pout - 2 and don’t forget Pout should be between 2 and 17.
To switch betwen RFO and PA_BOOST, set the bit 7 in PaConfig register. and disable the +20 dBm option in the Pa_Dac register.
About the +20 dBm option, it's the same as PA_BOOST but instead of Pmax = 17, Pmax = 20 so outputPower = Pout - 5 , and you need to enable the PA_BOOST and then set the PA_Dac to 0x87, 7 to enable the +20 dBm option, , note : just by setting the outputPower to 0xf (15) you will get the 20dBm, and to disable this feature just set PaDac varaible to 4 ( set the PaDac register to 0x84) to disable it.
for the OCP, they have a table that gives you how to calculate the ocp value from the Imax,
ocp-trim [0-15], Imax [45, 120 mA] , Imax = 45 + 5 * ocpTrim
ocp-trim [16-27], Imax [130, 240 mA] , Imax = -30 + 10 * ocpTrim
ocp-trim > 27, Imax = 240mA , Imax = 240 mA
and about the Imax which is the current need for the Tx we can find this in the datasheet:
RFOP = 13 dBm uses 28mA
RFOP = 7 dBm uses 20 mA
PA_BOOST = 17 dBm uses 90 mA
+20 dBm opton uses 120mA
the OCP need to be enabled if you want to use the PA_BOOS.
about the order of the settings. i will just try to set the register in order, just in case.

Related

Media and Data Integrity Errors

I was wondering if anyone can tell me what these mean. From most people posting about them, there is no more than double digits. However, I have 1051556645921812989870080 Media and Data Integrity Errors on my SK hynix PC711 on my new HP dev one. Thanks!
Here's my entire smartctl output
`smartctl 7.3 2022-02-28 r5338 [x86_64-linux-6.0.7-arch1-1] (local build)
Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org
=== START OF INFORMATION SECTION ===
Model Number: SK hynix PC711 HFS001TDE9X073N
Serial Number: KDB3N511010503A37
Firmware Version: HPS0
PCI Vendor/Subsystem ID: 0x1c5c
IEEE OUI Identifier: 0xace42e
Total NVM Capacity: 1,024,209,543,168 [1.02 TB]
Unallocated NVM Capacity: 0
Controller ID: 1
NVMe Version: 1.3
Number of Namespaces: 1
Namespace 1 Size/Capacity: 1,024,209,543,168 [1.02 TB]
Namespace 1 Formatted LBA Size: 512
Namespace 1 IEEE EUI-64: ace42e 00254f98f1
Local Time is: Wed Nov 9 13:58:37 2022 EST
Firmware Updates (0x16): 3 Slots, no Reset required
Optional Admin Commands (0x001f): Security Format Frmw_DL NS_Mngmt Self_Test
Optional NVM Commands (0x005f): Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Timestmp
Log Page Attributes (0x1e): Cmd_Eff_Lg Ext_Get_Lg Telmtry_Lg Pers_Ev_Lg
Maximum Data Transfer Size: 64 Pages
Warning Comp. Temp. Threshold: 84 Celsius
Critical Comp. Temp. Threshold: 85 Celsius
Namespace 1 Features (0x02): NA_Fields
Supported Power States
St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat
0 + 6.3000W - - 0 0 0 0 5 5
1 + 2.4000W - - 1 1 1 1 30 30
2 + 1.9000W - - 2 2 2 2 100 100
3 - 0.0500W - - 3 3 3 3 1000 1000
4 - 0.0040W - - 3 3 3 3 1000 9000
Supported LBA Sizes (NSID 0x1)
Id Fmt Data Metadt Rel_Perf
0 + 512 0 0
1 - 4096 0 0
=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
SMART/Health Information (NVMe Log 0x02)
Critical Warning: 0x00
Temperature: 34 Celsius
Available Spare: 100%
Available Spare Threshold: 5%
Percentage Used: 0%
Data Units Read: 13,162,025 [6.73 TB]
Data Units Written: 3,846,954 [1.96 TB]
Host Read Commands: 156,458,059
Host Write Commands: 128,658,566
Controller Busy Time: 116
Power Cycles: 273
Power On Hours: 126
Unsafe Shutdowns: 15
Media and Data Integrity Errors: 1051556645921812989870080
Error Information Log Entries: 0
Warning Comp. Temperature Time: 0
Critical Comp. Temperature Time: 0
Temperature Sensor 1: 34 Celsius
Temperature Sensor 2: 36 Celsius
Error Information (NVMe Log 0x01, 16 of 256 entries)
No Errors Logged`
Encountered a similar SMART reading from the same model.
I'm seeing a reported Media and Data Integrity Errors rate of a value that's over 2 ^ 84.
It could just be an error with its SMART implementation or the utility reading from it.
Converting your reported value of 1051556645921812989870080 to hex, we get 0xdead0000000000000000 big endian and 0x0000000000000000adde little endian.
Similarly, when I convert my value to hex, I get 0xffff0000000000000000 big endian and 0x0000000000000000ffff little endian, where f is just denotes a value other than 0.
I'm going to assume that the Media and Data Integrity Errors value has no actual meaning with regard to real errors. I doubt that both of us would have values that are padded with 16 0's when converted to hex. Something is sending/receiving/parsing bad data.
If you poke around the other reported SMART values in your post, and on my end, some of them don't seem to make much sense, either.

Why are the variables are not taking the desired values

I have to check how many hundreds are there in a number and translate that number to letters. For example the number 700. I have done the following code:
DATA(lv_dmbtr) = ZDS_FG-DMBTR. //Declared local variable of type DMBTR, thus DMBTR=700.
lv_dmbtr = ZDS_FG-DMBTR MOD 100. //Finding how many times 700 is in 100 via MOD and putting the value in lv_dmbtr.
IF lv_dmbtr LE 9. //The value is less or equal than 9(if larger means that the DMBTR is larger than hundreds,
e.g. 8000)
lv_hundred = lv_dmbtr / 100. // Divide the 700 with 100, taking the number 7.
lv_hundred_check = lv_hundred MOD 1. // Then taking the value of 7 into the new variable, done in case the
lv_hundred is a decimal value, e.g. 7.32.
IF lv_hundred_check > 0.
CALL FUNCTION 'SPELL_AMOUNT'
EXPORTING
amount = lv_hundred_check
* CURRENCY = ' '
* FILLER = ' '
LANGUAGE = SY-LANGU
IMPORTING
in_words = lv_hundred_string // the value is put in the new string
EXCEPTIONS
not_found = 1
too_large = 2
OTHERS = 3.
ENDIF.
Now when I debugg the code, all the variables have the value 0. Thus, lv_dmbtr, lv_hundred, lv_hundred_check all have the value 0.
May anyone of you know where the problem may be?
Thank you in advance!
Sorry for writing a lot in the code, just wanted to clarify as much as I could what I had done.
yes so I want to display the value of a specific number 700-> seven, 1400-> four.
So the basic formula to get the hundred in a number is the following: Find out how many times 100 fits completely into your number with integer division.
99 / 100 = 0
700 / 100 = 7
701 / 100 = 7
1400 / 100 = 14
1401 / 100 = 14
Now you can simply take this number MOD 10 to get the the individual hundreds.
0 MOD 10 = 0
7 MOD 10 = 7
14 MOD 10 = 4
Keep in mind that ABAP, in contrast to many other programming languages, rounds automatically. So in code this would be:
CONSTANTS lc_hundred TYPE f VALUE '100.0'.
DATA(lv_number) = 1403.
DATA(lv_hundred_count) = CONV i( floor( ( abs( lv_number ) / lc_hundred ) ) MOD 10 ).

STM32f4 HID receive data

How to receive OUT report data from HOST PC in STM32f407 discovery board running as HID(USB) in device mode?
Is it possible?
I am thinking to send data from host using hidapi.
There is an official USB library. It is not easy, but you may try to run the examples and adapt them to your needs.
http://www.st.com/en/embedded-software/stsw-stm32046.html
Be careful with clock settings. I experienced problems with that. Here are the values I setup in system_stm32f4.c:
HSE = 8000000
PLL_M = 8
PLL_Q = 7
PLL_N = 336
PLL_P = 4
HSE is the crystal on the board. It replaces the embedded clock on the MCU. The other settings are slightly different from the values in the original configuration file. Here are the calculations of the different clocks:
PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
= 8000000 / 8 * 336 = 336000000
USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ
= 336000000 / 7
= 48000000
SYSCLK = PLL_VCO / PLL_P
= 336000000 / 4
= 84000000
HCLK = SYSCLK / 1
= 84000000
PCLK2 = HCLK / 1
= 84000000
PCLK1 = HCLK / 2
= 84000000 / 2
= 42000000
The “USB OTG FS” clock HAS to be >= 48MHz if you use USB FS. Otherwise the device won't be recognized.

Difficulty connecting to an ntp time server

I am trying to use the following piece of code to connect to a time server and attain the time but have had no luck:
Dim ntpServer As String = "time.windows.com"
Dim ntpData(47) As Byte
Dim addresses = Dns.GetHostEntry(ntpServer).AddressList
Dim EndP As IPEndPoint = New IPEndPoint(addresses(0), 123)
Dim soc As Socket = New Socket(AddressFamily.InterNetwork, _
SocketType.Dgram, ProtocolType.Udp)
soc.Connect(EndP)
soc.Send(ntpData)
soc.Receive(ntpData)
soc.Close()
Tracing through the program I can't get past the following line of code soc.Receive(ntpData). What am I doing wrong?
Thanks
you need to provide some basic information to the server:
ntpData(0) = 27
ntpData(0) contains a section called firstByteBits.
This section needs to be set before sending the data to query for a reply.
First byte is
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|LI | VN |Mode |
LI = leap indicator (0 in sent data)
VN = version number (3, bits 3 and 4 set)
Mode = Mode (client mode = 3, bits 6 and 7 set)
00011011 = 27 = 0x1B
And possibly a better NTP server. The time.windows.com:123 server pool is known to
be slow, sometimes not responding for a while, and of low accuracy. Better: pool.ntp.org:123 (but please read what's written on poo.ntp.org about regular use).
e.g. RFC 5905 for more details.

I'm new to visual basic and trying to understand how to set individual bits in a byte [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Hi, I am new to Visual Basic, I have a project where I need to be able to manipulate individual bits in a value.
I need to be able to switch these bits between 1 and 0 and combine multiple occurrences of bits into one variable in my code.
Each bit will represent a single TRUE / FALSE value, so I'm not looking for how to do a single TRUE / FALSE value in one variable, but rather multiple TRUE / FALSE values in one variable.
Can someone please explain to me how I can achieve this please.
Many thanks in advance.
Does it have to be exactly one bit?
Why don't you just use the actual built in VB data type of Boolean for this.
http://msdn.microsoft.com/en-us/library/wts33hb3(v=vs.80).aspx
It's sole reason for existence is so you can define variables that have 2 states, true or false.
Dim myVar As Boolean
myVar = True
myVar = Flase
if myVar = False Then
myVar = True
End If
UPDATE (1)
After reading through the various answers and comments from the OP I now understand what it is the OP is trying to achieve.
As others have said the smallest unit one can use in any of these languages is an 8 bit byte. There is simply no order of data type with a smaller bit size than this.
However, with a bit of creative thinking and a smattering of binary operations, you can refer to the contents of that byte as individual bits.
First however you need to understand the binary number system:
ALL numbers in binary are to the power of two, from right to left.
Each column is the double of it's predecessor, so:
1 becomes 2, 2 becomes 4, 4 becomes 8 and so on
looking at this purely in a binary number your columns would be labelled thus:
128 64 32 16 8 4 2 1 (Remember it's right to left)
this gives us the following:
The bit at position 1 = 1;
The bit at position 2 = 2;
The bit at position 3 = 4;
The bit at position 4 = 8;
and so on.
Using this method on the smallest data type you have (The byte) you can pack 8 bit's into one value. That is you could use one variable to hold 8 separate values of 1 or 0
So while you cannot go any smaller than a byte, you can still reduce memory consumption by packing 8 values into 1 variable.
How do you read and write the values?
Remember the column positions? well you can use something called Bit Shifting and Bit masks.
Bit Shifting is the process of using the
<<
and
>>
operators
A shifting operation takes as a parameter the number of columns to shift.
EG:
Dim byte myByte
myByte = 1 << 4
In this case the variable 'myByte' would become equal to 16, but you would have actually set bit position 5 to a 1, if we illustrate this, it will make better sense:
mybyte = 0 = 00000000 = 0
mybyte = 1 = 00000001 = 1
mybyte = 2 = 00000010 = (1 << 1)
mybyte = 4 = 00000100 = (1 << 2)
mybyte = 8 = 00001000 = (1 << 3)
mybyte = 16 = 00010000 = (1 << 4)
the 0 through to 16 if you note is equal to the right to left column values I mentioned above.
given what Iv'e just explained then, if you wanted to set bits 5, 4 and 1 to be equal to 1 and the rest to be 0, you could simply use:
mybyte = 25(16 + 8 + 1) = 00011001 = (1 << 4) + (1 << 3) + 1
to get your bits back out, into a singleton you just bit shift the other way
retrieved bit = mybyte >> 4 = 00000001
Now there is unfortunately however one small flaw with the bit shifting method.
by shifting back and forth you are highly likely to LOOSE information from any bits you might already have set, in order to prevent this from happening, it's better to combine your bit shifting operations with bit masks and boolean operations such as 'AND' & 'OR'
To understand what these do you first need to understand simple logic principles as follows:
AND
Output is one if both the A and B inputs are 1
Illustrating this graphically
A B | Output
-------------
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
As you can see if a bit position in our input number is a 1 and the same position in our input number B is 1, then we will keep that position in our output number, otherwise we will discard the bit and set it to a 0, take the following example:
00011001 = Bits 5,4 and 1 are set
00010000 = Our mask ONLY has bit 5 set
if we perform
00011001 AND 0010000
we will get a result of
00010000
which we can then shift down by 5
00010000 >> 5 = 00000001 = 1
so by using AND we now have a way of checking an individual bit in our byte for a value of 1:
if ((mybyte AND 16) >> 1) = 1 then
'Bit one is set
else
'Bit one is NOT set
end if
by using different masks, with the different values of 2 in the right to left columns as shown previously, we can easily extract different singular values from our byte and treat them as a simple bit value.
Setting a byte is just as easy, except you perform the operation the opposite way using an 'OR'
OR
Output is one if either the A or B inputs are 1
Illustrating this graphically
A B | Output
-------------
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1
eg:
00011001 OR 00000100 = 00011101
as you can see the bit at position 4 has been set.
To answer the fundamental question that started all this off however, you cannot use a data type in VB that has any resolution less than 1 byte, I suspect if you need absolute bit wise accuracy I'm guessing you must be writing either a compression algorithm or some kind of encryption system. :-)
01010100 01110010 01110101 01100101, is the string value of the word "TRUE"
What you want is to store the information in a boolean
Dim v As Boolean
v = True
v = False
or
If number = 84 Then ' 84 = 01010100 = T
v = True
End If
Other info
Technicaly you can't store anything in a bit, the smallest value is a char which is 8 bit. You'll need to learn how to do bitwise operation. Or use the BitArray class.
VB.NET (nor any other .NET language that I know of) has a "bit" data type. The smallest that you can use is a Byte. (Not a Char, they are two-bytes in size). So while you can read and convert a byte of value 84 into a byte with value 1 for true, and convert a byte of value 101 into a byte of value 0 for false, you are not saving any memory.
Now, if you have a small and fixed number of these flags, you CAN store several of them in one of the integer data types (in .NET the largest integer data type is 64 bits). Or if you have a large number of these flags you can use the BitArray class (which uses the same technique but backs it with an array so storage capacity is greater).