How mode of operation will be decided in SPI protocol? - linux-device-driver

How mode of operation will be decided in SPI protocol?
- I read that there are four mode of operations available in SPI Communication(Mode - 0, 1, 2, 3), so when we do any device interfacing using SPI Protocol how to decide which mode we should configure, is it the data available in sheet given by vendor companies that you should use ___ mode while do interfacing with this device?
And also(same question as above for) baud rate at which Master and Slave will communicate?

Both of supported mode and frequency is provided by vendor. If you'r selected mode don't match to that provided by vendor then there is strong chances of missing some bits(either MSB or LSB depending on the mismatch).

Related

Can I write in an Input Register? Modbus

I've been working for 2 months in a MODBUS project and now I found a problem.
My client is asking me to write in an input register (Address 30001 to 40000).
I thought that was not a thing for me because every modbus documentation says that 30001 to 40000 registers are read-only.
Is it even possible to write in those registers? Thanks in advance
Both holding and input register related functions contain a 2-byte address value. This means that you can have 65536 input registers and 65536 holding registers in a device at the same time.
If your client is developing the firmware of the slave, they can place holding registers into the 3xxxx - 4xxxx area. They don't need to follow the memory layout of the original Modicon devices.
If one can afford diverging from the Modbus standard, it's even possible to increase the number of registers. In one of my projects, I was considering to use Preset Single Register (06) function as a bank select command. Of course, you can't call it Modbus anymore. But, the master can still access the slave using a standard library or diagnostics tools.
You can't write to Input Contacts or Input Registers, there is no Modbus function to write to them, they are read only by definition
Modbus is a protocol and in no case specifies where the values are stored, only how they are transmitted
Currently there are devices that support 6-digit addresses and therefore can address up to 65536 registers per group

Register Value and Memory Address for Read and Write for MAX144 ADC

I am using MAX144 ADC and in the Datasheet there is no information given about the control register to read the ADC values. I am using STM32L452RE micro-controller and using SPI to get data from ADC. Datasheet of the ADC is:
https://datasheets.maximintegrated.com/en/ds/MAX144-MAX145.pdf
anyone who encountered the same problem please guide.
my idea is to create a buffer of 2 bytes for SPI RX and store values in it. but i don't know what control register address should be assigned to it.
The conversion data is not stored internally in a register set. When you pull CS low the state of SCLK will determine wither it holds the conversion product(after a high to low transition to start it) or start streaming it on the falling edge of the second clock pulse.
This is all noted on page 9 of the data sheet. Pages 10 & 11 detail how to interface them to standard SPI.

How does an OS find a peripheral's assigned address(es)?

OK, here's what I mean:
Let's say you want to write your own bootable code.
Further, your code is going to be really simple.
So simple, in fact, that it only consists of a single instruction.
Your bootable code is going to write a byte or word or double word or whatever to a register or RAM location on a peripheral device, not main RAM or a CPU register.
How do you find out what address(es) have been assigned to that peripheral memory location by the BIOS / UEFI?
Here's a more concrete example:
My bootable code's first and only instruction will write the number 11H to a register located on the sound card.
If the BIOS / UEFI initialization code did its job properly, that sound card register should be mapped into the CPU's memory space and/or IO space.
I need to find that address to accomplish that write.
How do I find it?
This is what real operating systems must do at some point.
When you open control panel / device manager in Windows, you see all the memory ranges for peripherals listed there.
At some point, Windows must have queried the BIOS /UEFI to find this data.
Again, how is this done?
EDIT:
Here is my attempt at writing this bootable assembly program:
BITS 16
ORG 100h
start:
;I want to write a byte into a register on the sound card or NIC or
;whatever. So, I'm using a move instruction to accomplish that where X
;is the register's memory mapped or IO mapped address.
mov X,11h
times 510 - ($ - $$) db 0
dw 0xaa55
What number do I put in for X? How do I find the address of this peripheral's register?
If you want to do this with one instruction, you can just get the address for the device from the Windows device manager. But if you want to do it the "proper" way, you need to scan the PCI bus to find the device you want to program, and then read the Base Address Registers (BARs) of the device to find its MMIO ranges. This is what Windows does; it doesn't query the BIOS.
To find the device that you want to access, scan the PCI bus looking for the device. Devices are addressed on the PCI bus by their "BDF" (short for Bus/ Device/ Function). Devices are identified by a Vendor ID and a Device ID assigned by the vendor.
Read offset 0 and 2 of each BDF to get the Vendor ID and Device ID. When you have found the device you want to program, read the correct 32-bit BAR value at an offset between 10h and 24h. You need to know which BAR contains the register you want to program, which is specific to the device you are using.
This article describes how to access PCI config space and has sample code in C showing how to scan the PCI bus. http://wiki.osdev.org/PCI

What can cause spikes in the DACs output? Can it be implementation related?

i have 8 external DACs MCP4728 which i'm communicating with using i2c.
The data is coming directly from a USB cable (16-17ms) and i need to update/write those values as soon as i can.
Right now i'm writing to the i2c inside the USB callback function.
Normally i see code (not DAC related) where a flag is set and then in the main loop, since the flag to update is true, something is perfomed (in this case the DACs should be set).
Can the implementation be the source of those spikes (which tipically are present only with high frequency values) ?
Can bit-skew be the problem with 17ms of updating time ?

AHCI Driver for own OS

I have been programming a little AHCI driver for two weeks. I have read this article and Intel's Serial ATA Advanced Host Controller Interface (AHCI) 1.3. There is an example, which shows how to read sectors via DMA mode (osdev.org). I have done this operation (ATA_CMD_READ_DMA 0xC8) successfully, but when i tried to write sectors (ATA_CMD_WRITE_DMA 0xCA) to the device, the HBA set the error
Offset 30h: PxSERR – Port x Serial ATA Error - Handshake Error
(this is decoding from Intel AHCI specification). I don't understand why it happened. Please, help me.
In addition, I have tried to issue the command IDENTIFY 0xEC, but not successfully...
You asked this question nearly two months ago so I'm not sure if you've already figured this out. Please note that I'm writing from memory in terms of what must be done first, etc. I may not have remembered all, or accurately, what must be done. You should reference the AHCI spec for everything. The methods for doing this are as varied as there are programmers that have done this. For this reason, I'm not including code examples.
For starters, ensure that you've set the HBA state machine accordingly. You'll be able to find references for the state machines supported by the HBA in that same SATA spec 1.3. In lieu of this, you should check a few registers.
Please note that all page numbers are given with respect to viewing in Adobe Acrobat and are 8 pages more than numbered in the actual document
From page 24 and 25 of the spec., check GHC.IE and GHC.AE. These two will turn on interrupts and ensure that the HBA is working in AHCI mode. Another, very important register to check, is CAP.SSS (Page 23). If this bit is high, then the HBA Supports Staggered Spin-up. This means that the HBA will not perform any protocol negotiation for any port. Before you do the following, store the value of PxSIG (Page 35 and 36).
To actually spin up the port, you'll need to visit pages 33, 34 and 35 of the spec. These pages cover the PxCMD register. For each port supported by the HBA (check CAP.NP to know how many are there), you'll have to switch high bit PxCMD.SUD. After switching that bit high, you'll want to poll on PxSSTS (Page 36) to check the state of the PHY. You can check CAP.ISS in order to know what speed you can expect to see "come alive" on PxSSTS.
After spinning up the port, check PxSIG (Page 35 & 36). The value should be different than when you started. I don't recall now what you can expect them to become, but they will be different. When communication is actually established, the device sends to the host an initial FIS. Without this first FIS, the HBA will be unable to communicate with the device. (It's with this first FIS that the HBA sets the correct bits in PxSIG.)
Finally, after all of this, you'll need to set PxCMD.FRE (page 34). This bit in the port command register enables FIS delivery to the device. If this bit is low, the HBA will ignore anything you send to it.
As I said in the beginning, I'm not sure if this will answer all of your question but I hope that it does get you on the right track. I'm going from memory on the events that must be done in order to effectively communicate to a SATA device. I may not have remembered in full detail.
I hope this helps you.