Register address in ADXL345 digital accelerometer - accelerometer

I am confused with the registers present in the ADXL345 digital accelerometer.
The first thing which confuses me is where I have to write the data to set resolution for +/-2g. I didn't find any mention of this register in the datasheet.
Secondly, there are two registers in which the measurement value for the X axis is stored. How do I read that data from both registers? Do I need to send the address of the register at the same time, or what?

The first thing which confuses me is where I have to write the data to set resolution for +/-2g. I didn't find any mention of this register in the datasheet.
You'll find this information on page 26 of the data sheet (at least, in Rev. E of the data sheet). The range is controlled by bits 0 and 1 in register 0x31 (DATA_FORMAT).
Register 0x31—DATA_FORMAT (Read/Write)
The DATA_FORMAT register controls the presentation of data
to Register 0x32 through Register 0x37. All data, except that for
the ±16 g range, must be clipped to avoid rollover.
SELF_TEST Bit
A setting of 1 in the SELF_TEST bit applies a self-test force to
the sensor, causing a shift in the output data. A value of 0 disables
the self-test force.
SPI Bit
A value of 1 in the SPI bit sets the device to 3-wire SPI mode,
and a value of 0 sets the device to 4-wire SPI mode.
INT_INVERT Bit
A value of 0 in the INT_INVERT bit sets the interrupts to active
high, and a value of 1 sets the interrupts to active low.
FULL_RES Bit
When this bit is set to a value of 1, the device is in full resolution
mode, where the output resolution increases with the g range
set by the range bits to maintain a 4 mg/LSB scale factor. When
the FULL_RES bit is set to 0, the device is in 10-bit mode, and
the range bits determine the maximum g range and scale factor.
Justify Bit
A setting of 1 in the justify bit selects left-justified (MSB) mode,
and a setting of 0 selects right-justified mode with sign extension.
Range Bits
These bits set the g range as described in Table 21.
Table 21. g Range Setting
╔═════════╦══════════╗
║ Setting ║ ║
╠════╦════╣ g Range ║
║ D1 ║ D0 ║ ║
╠════╬════╬══════════╣
║ 0 ║ 0 ║ +/- 2 g ║
╠════╬════╬══════════╣
║ 0 ║ 1 ║ +/- 4 g ║
╠════╬════╬══════════╣
║ 1 ║ 0 ║ +/- 8 g ║
╠════╬════╬══════════╣
║ 1 ║ 1 ║ +/- 16 g ║
╚════╩════╩══════════╝
So, what you'll want to do is read the current value of register 0x31, mask off bits 0 and 1, set the value you want (as per Table 21), and then write the new value to register 0x31.
Secondly, there are two registers in which the measurement value for the X axis is stored. How do I read that data from both registers? Do I need to send the address of the register at the same time, or what?
No, you read each register sequentially.
Register 0x32 holds the least-significant bits of the x-axis value, and register 0x33 holds the most-significant bits of the x-axis value. Together, they combine to an x-axis reading with 13 (maximum) bits of precision, in two's-complement format. If you only needed 8 bits of precision, you could read only the MSB from register 0x33, which would be slightly faster than reading both registers.
The data sheet does make one additional recommendation that you should pay attention to:
It is recommended that a multiple-byte read of all registers be performed to prevent a change in data between reads of sequential registers.
How exactly you do a multiple-byte read varies, depending on whether you're using the SPI or I2C bus, but either way, it is described in the data sheet. For SPI:
To read or write multiple bytes in a single transmission, the
multiple-byte bit, located after the R/W bit in the first byte transfer
(MB in Figure 37 to Figure 39), must be set. After the register
addressing and the first byte of data, each subsequent set of clock
pulses (eight clock pulses) causes the ADXL345 to point to the
next register for a read or write. This shifting continues until the
clock pulses cease and CS is deasserted. To perform reads or writes
on different, nonsequential registers, CS must be deasserted
between transmissions and the new register must be addressed
separately.

Related

Reverse CAN BTR value from register value of stm32

i'm trying to get the baud rate of a chip by reverse engineering it.
the register value for BTR is reading: 0x23000B
As per http://www.bittiming.can-wiki.info/ it seems that real values are "-1" in the register. So it seems that
SJW -> 0x0 -> becomes 1
TS2 -> 0x2 -> becomes 3
TS1 -> 0x3 -> becomes 4
preampl -> 0xB -> 11d -> becomes 12d
so if my decoding is correct (can't really find a reference of what the register should contain officially in any docs):
The chip in question has a 48MHz clock
So 48Mhz/(preampl) => 48MHz/12 => 4Mhz
4.000.000 / (SJW + TS1 + TS2) => 500kbps
does this make any sense? also if you can find reference to the register value in a pdf i would greatly appreciate that.
Besides the calculation i'm not sure about the 48Mhz clock.
A CAN bit is divided into time quanta (tq). The tq are clocked with your CAN prescaler clock which needs to be accurate enough (<1% inaccuracy). When setting up baudrate, you should strive to place the sample point close to 87.5% of the bit length, which comes from an industry standard (CANopen).
(In case you a reverse-engineering something, they did not necessarily follow industry standards though and the sample point could be anywhere...)
Ideally 87.5% sample point is achieved by having a total of 16 tq, 14 tq before the sample point and 2 tq behind it. The desired baudrate is then obtained by:
1 tq fixed sync segment (can't be configured)
x tq propagation segment
y tq phase segment 1 (before sample point)
2 tq phase segment 2 (after sample point)
Different CAN controllers might name propagation segment + phase segment 1 as a single "propagation segment". It doesn't matter, it's the number of tq between the sync segment and the sample point that matters. One ideal example would be:
1 tq sync + 13 tq prop seg/phase seg 1 + 2 tq phase seg 2.
For a CAN clock of 4MHz this would give a bit rate of 4*10^6 / 16 = 250kbps.
Note that some CAN controllers do indeed expect you to subtract 1 tq from each segment length when you write to the register.
SJW, (re)synchronization jump width doesn't play a part in the baudrate calculation. It is a setting which allows a receiving node some room to re-sync in case of inaccurate baudrates. A "hard sync" is performed at the sync segment (bit edge) and then a re-synch is performed at the sample point. SJW allows some inaccuracies to happen here. It is typically just set to 1 and that works fine for all common baudrates. If you go up to 1MHz, it is recommended to increase SJW some, to 2 or 3.

What is the typical DRAM row buffer size? How to find it?

How can I find DRAM row buffer size programmatically or by using already existing tools in say a *nix system ?
As an example, with a Kingston DDR4, I executed the following commands (you might need to install some packages) :
sudo modprobe eeprom
decode-dimms
These commands, among many information, give me the characteristics of my DDR stick:
---=== Memory Characteristics ===---
Maximum module speed 2132 MHz (PC4-17000)
Size 16384 MB
Banks x Rows x Columns x Bits 16 x 16 x 10 x 64
SDRAM Device Width 8 bits
Ranks 2
Rank Mix Symmetrical
AA-RCD-RP-RAS (cycles) 14-14-14-35
Supported CAS Latencies 16T, 15T, 14T, 13T, 12T, 11T, 9T
Rows and columns are actually number of address bits (you can check the decode-dimms source at https://fossies.org/linux/i2c-tools/eeprom/decode-dimms, and understand what the code is doing when you look at the DDR4 SPD information: https://en.wikipedia.org/wiki/Serial_presence_detect#DDR4_SDRAM)
Thus, if we have 10 column bits, we have 1024 columns (2^10), where each column is composed of the module width (64 as per the data above, represented as "bits"). Since we can also see that the SDRAM device width is 8x, we can deduce that the DIMM locksteps 8 SDRAM chips (those black boxes you see in your DRAM stick) to get that total width of 64 bits.
The row buffer size in my DDR4 is, therefore, 64 bits * 1024 columns = 65536 bits wide (8192 Bytes). Row buffer sizes in DDR3 and DDR4 are mostly this length, but new architectures such as HMC and HBM have different sizes.
So, in one short commandline, to return in bits (just divide by 8 to get bytes):
decode-dimms | grep "Columns x Bits" | awk -F 'x' '{print (2^$(NF-1))*$NF}
PS: mind you, this handles a single DIMM. if you have multiple DIMMS decode-dimms might return information for multiple modules.

How to calculate which virtual logical address corresponds to physical address?

Assume that the page table for the process currently running on the processor looks as shown in the figure below. All numbers are decimal, all numbers starting with 0 and all addresses are memory syllable addresses. The page size is 1024 bytes.
Which physical address (if any) does each of the following logical (virtual) addresses correspond to? Indicates if a page error occurs while translating the title.
Which physical address (if any) does each of the following logical (virtual) addresses correspond to? Indicates if a page error occurs while translating the title.
a) 1085
b) 2321
c) 5409
number of pages
valid/invalid bit
number of frames
0
1
4
1
1
7
2
0
-
3
1
2
4
0
-
5
1
0
I don't want the solution for this problem, I want someone to explain how this kind of problems are solved.
I think you can guess most configuration from the question. I'll take a) as an example. Maybe you can tell me if I get the answer right and then you can solve the rest by yourself?
The first step is to determine what is the part of the virtual address representing the offset in the page table, and the part representing the offset in the physical frame. For address 1085 and page size of 1024 bytes, you need 10 bits for the offset in the physical frame and the rest for the offset in the page table.
1085 decimal = 0x43D = 0b100 0011 1101
The ten least significant bits (to the right) are the offset in the physical frame. That is 0b00 0011 1101 = 0x3D = 61 decimal. So now you know that the offset in the physical frame will be 61 bytes.
To calculate in what page this offset will be, you take the leftover bits (to the left). That is 0b1 = 0x1 = 1 decimal. This references page table entry 1. Page table entry 1 has the valid bit set. It means that the page is present in memory and will not cause a page fault. The page table entry points to frame number 7. There are 7 frames before frame 7: frames 0, 1, 2, 3, 4, 5, and 6. Thus this virtual address should translate to 7 * 1024 + 61 = 7229.

How to calculate page frames in a 16 bit address pointer

I'm looking over some exam papers for Operating Systems and I have come across a question which I simply cannot figure out. The memory management scheme is paging
Here is the question:
An operating system that runs on a CPU with a 16 bit address pointer employs a paging memory management scheme with a page size of 1024 bytes.
a) At most how many frames can physical memory contain?
b) Indicate which bits in an address pointer are used for page and offset.
c) A process image of size 3.5K resides in memory. You are given the page table of this process in Figure 1 below. What physical address will the hexadecimal logical address 0x0FCE result in? Show your calculations.
d) How much internal fragmentation does this process produce?
Page Frame
0 4
1 8
2 9
3 6
Figure 1 Process Page Table
Can anybody help me with this ?
A 16bit address bus allows to access 2^16 = 64kB of physical memory. Since on this system you have pages of size 1024B = 2^10, your memory falls into 2^16 / 2^10 = 2^6 physical frames.
Given the previous result, with pages of 1024 = 2^10 bytes, you need 10 bits for accessing any bytes of the page. Thus, the 6 high-order bits ares used for getting the page index from the page table (basically the figure 1 in your homework), and the 10 low-order bits are used for offsetting in that page.
The logical address 0xfce resides in the fourth page because the six high-order bits are 000011b = 3 = 4th page = 0x0c00-0x0fff. Given the page table and assuming the physical memory is sequential, the fourth page maps to the sixth physical frame which start at 1024 * 6 = 0x1800 = 0001100000000000b. The six high-order bits of the page are 000110b, where we add the 10 bits of offset resulting from the previous answer: 000110b << 10 | 0x3ce = 0x1bce.
Since the frame allocation is not sequential (4, 6, 8, 9), the hole between pages 4 and 6 (i.e. 1024B), and the hole between page 6 and 8(i.e. again 1024B), result in physical memory fragmentation.
Hope this help.

Calculation of physical address in 8086

I learnt that the physical address is calculated by shifting the segment address (16-bit) left 4 times and adding it with the 16-bit offset address. The memory in the 8086 architecture is 1M.
My question is if the segment register and the offset value both are FFFFH and FFFFH then the result would be more than FFFFH i.e., more than 1M.
FFFF0
+ FFFF
----------
10FFEF
haw is it actually calculated...??
It does modular arithmetic, dropping any carries. So for a segment of FFFF and offset of FFFF, you compute FFFF0 + FFFF = 10FFEF but it "drops" the initial 1, leaving a real answer of 0FFEF.
The 8086 address bus is only 20 bits wide, which gives a max high address of 0xFFFFF = 1,048,575. It's calculated just the way you did it, but only the low-order 20 bits are used in the memory fetch.