JTAG: How do I know the width of the Instruction Register? - jtag

Assumed I have a JTAG-chain with several devices from different manufactures:
How does my software, which shall communicate with a specific system within that chain, known the length of the IR for all the others devices within the chain? I do have to know them to send a certain instruction to my device, right?

It is possible to detect the total length of all IR registers in your JTAG daisy-chain. It is also possible to detect the number of devices (or TAPs) in your chain. But you can't detect the individual IR length of a single TAP.
What you can do: You can read out the JTAG ID code register of all of you TAPs. The ID code register (in DR path) is always 32 bit and gets selected by test-logic-reset.
With the ID code you can identify the existing TAPs and look up in the datasheet the length of the individual IR registers.
And yes: In general you do have to know the individual IR length of all the TAPs in your chain to communicate with one of them.

try here: http://www.fpga4fun.com/JTAG3.html
When IR = '1...1', the BYPASS is selected.
The idea is to send a lot of '1' so regardless of IR length all devices will select BYPASS.

Related

A question about Interrupt cycle FGI and FGO flipflops conditions - Basic Computer Organization and design

Computer System Architecture - Morris Mano In chapter 5 section 7 figure 5-13
When IEN it checks whether "FGI" or "FGO" are set to 1 then an interrupt cycle happens, but as I know is when FGI = 1 it means that information in INPR cannot be changed, and FGO is the reverse to that which means that when FGO is set to 1 then information in AC will be transferred to OUTR 'OUTR can be changed' so the question here shouldn't the condition of applying interrupt cycle happen when "FGI" = 0 or "FGO" = 1 since INPR or OUTR can be changed under these conditions which now make since to execute an interrupt?
Either flag being 1 logically means a device is "ready", but what "ready" means differs for input and for output devices.  In either case, flag being 1 means that the processor can or should now take action.
FGI=1 means the input device is ready, but that really means a new input is available (e.g. the user typed a key on a keyboard) and the processor should accept it.  FGO=1 prevents the input device(s) from overwriting a prior input held in INPR that the processor hasn't accepted yet. When the processor accepts the input, FGI goes to 0 unlocking the INPR register, and that allows the input device to write again, which it will eventually do when the user presses another key (sending FGI back to 1 to signal the processor).
FGO=1 means ready for output, which really means the last output has been fully accepted by the device, so the OUTR register is unlocked for the processor to write a new data (character for the console).  FGO=0 prevents the processor from writing OUTR as the output device hasn't accepted the last one yet.
The interrupt service routine should check each flag, and if FGI=1 then accept an input (INPR->AC) and move it into a buffer for the user program to read when it is ready. Whereas if FGO=1, then move an output character from memory buffer into the AC, and then do AC->OUTR, also lowering FGO to 0, which will preclude the processor writing until that data has been accepted by the device.
So, FGI=0 means that the processor has accepted the prior INPR value provided by the input device, and there is no new character as yet but the register is unlocked so the device can write at will.
FGO=0 means that the processor has written a value to the OUTR register, but the output device hasn't accepted that yet, so the register should be considered locked.

Question about Message Signaled Interrupts (MSI) on x86 LAPIC system

Hi I'm writing a kernel and plan to use MSI interrupt for PCI devices.
However, I'm also quite confused by the documentations.
My understanding about MSI are as follow:
From PCI device point of view:
Documentations indicate that I
need to find Capabillty ID = 0x05 to locate 3 registers: Message control (MCR), Message Address (MAR) and Message Data (MDR) registers
MCR provide control functionality for MSI interrupt,
MAR provide the physical address the PCI device
will write once interrupt occurs
MDR forms out the actual data it will write into the physical address
From CPU point of view:
Documentation shows that Message Address register contains fixed top of 0xFEE, and following by destination ID (LAPIC ID) and other controlling bits as follow:
The Message Data register will contain the following information, including the interrupt vector:
After reading all of these, I am thinking if the APIC_ID is 0x0h would the Message Address conflict with the Local APIC memory mapping? Although the address of FEE00000~FEE00010 are reserved.
In addition, is it true that the vector number in MDR is corresponding to the IDT vector number. In other words, if I put MAR = 0xFEE0000C (Destination ID = 0, Using logical APIC ID) and MDR = 0x0032 (edge trigger, Vector = 50) and enable the MSI interrupt, then once the device issues an interrupt CPU would correspondingly run the function pointed by IDT[50]? After that I write 0h to EOI register to end it?
Finally, according to the documentation, the upper 32 bit of MAR is not used? Can anyone help on this?
Thanks a lot!
Your understanding of how to detect and program MSI in a PCI (or PCIe) device is correct.*
The message address controls the destination (which CPU the interrupt is sent to), while the message data contains the vector number. For normal interrupts, all bits of the message data should be 0 except for the low 8 bits, which contain the vector.
The vector is an index into the IDT, so if the message data is 0x0032, the interrupt is delivered through entry 50 of the IDT.**
If the Destination ID in an interrupt message is 0, the Message Address of the MSI does match the default address of the local APIC, but they do not conflict, because the APIC can only be written by the CPU and MSIs can only be written by devices.
On x86 platforms, the upper 32 bits of the message address must be 0. This can be done by setting the upper part of the message address to 0 or by programming the device to use a 32-bit message address (in which case the upper message address register is not used). The PCI spec was designed to work with systems where 64-bit MSI addresses are used, but x86 systems never use the upper 32 bits of the message address.
Reprogramming the APIC base address by writing to the APIC_BASE MSR does not affect the address range used for MSI; it is always 0xFEExxxxx.
* You should also look at the MSI-X capability, because some devices support MSI-X but not MSI. MSI-X is a bit more flexible, which inevitably makes it a bit more complicated.
** When using the MSI capability, the message data isn't exactly the value in the Message Data Register (MDR). The MSI capability allows the device to use several contiguous vectors. When the device sends an interrupt message, it replaces the low bits of the MDR with a different value depending on the interrupt cause within the device.

In Application Programming issue

I'm working on project on STM32L152RCT6, where i have to build a mechanism to self update the code from the newly gated file(HEX file).
For that i have implemented such mechanism like boot loader where it checks for the new firmware if there it it has to cross verify and if found valid it has to store on "Application location".
I'm taking following steps.
Boot loader address = 0x08000000
Application address = 0x08008000
Somewhere on specified location it has to check for new file through Boot loader program.
If found valid it has to be copy all the HEX on location(as per the guide).
Than running the application code through jump on that location.
Now problem comes from step 5, all the above steps I've done even storing of data has been done properly(verify in STM32 utility), but when i'm jump to the application code it won't work.
Is there i have to cross check or something i'm missing?
Unlike other ARM controllers that directly jump to address 0 at reset, the Cortex-M series takes the start address from a vector table. If the program is loaded directly (without a bootloader), the vector table is at the start of the binary (loaded or mapped to address 0). First entry at offset 0 is the initial value of the stack pointer, second entry at address 4 is called the reset vector, it contains the address of the first instruction to be executed.
Programs loaded with a bootloader usually preserve this arrangement, and put the vector table at the start of the binary, 0x08008000 in your case. Then the reset vector would be at 0x08008004. But it's your application, you should check where did you put your vector table. Hint: look at the .map file generated by the linker to be sure. If it's indeed at 0x08008000, then you can transfer control to the application reset vector so:
void (*app)(void); // declare a pointer to a function
app = *(void (**)(void))0x08008004; // see below
app(); // invoke the function through the pointer
The complicated cast in the second line converts the physical address to a pointer to a pointer to a function, takes the value pointed to it, which is now a pointer to a function, and assigns it to app.
Then you should manage the switchover to the application vector table. You can do it either in the bootloader or in the application, or divide the steps between them.
Disable all interrupts and stop SysTick. Note that SysTick is not an interrupt, don't call NVIC_DisableIRQ() on it. I'd do this step in the bootloader, so it gets responsible to disable whatever it has enabled.
Assign the new vector table address to SCB->VTOR. Beware that the boilerplate SystemInit() function in system_stm32l1xx.c unconditionally changes SCB->VTOR back to the start of the flash, i.e. to 0x08000000, you should edit it to use the proper offset.
You can load the stack pointer value from the vector table too, but it's tricky to do it properly, and not really necessary, the application can just continue to use the stack that was set up in the bootloader. Just check it to make sure it's reasonable.
Have you changed the application according to the new falsh position?
For example the Vector Table has to be set correctl via
SCB->VTOR = ...
When your bootloader starts the app it has to configure everything back to the reset state as the application may relay on the default reset values. Espessially you need to:
Return values of all hardware registers to its reset values
Switch off all peripheral clocks (do not forget about the SysTick)
Disable all enabled interrupts
Return all clock domains to its reset values.
Set the vector table address
Load the stack pointer from the beginning of the APP vector table.
Call the APP entry point.(vertor table start + 4)
Your app has to be compiled and linked using the custom linker script where the FLASH start point is 0x8008000
for example:
FLASH (rx) : ORIGIN = 0x8000000 + 32K, LENGTH = 512K - 32K
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
where FLASH_BASE's value must be equal to the address of your IROM's value in KEIL
example:
#define FLASH_BASE 0x08004000
Keil configuration

NFC type B PUPI doubts

I have the Panasonic MN63Y1210 tag. I have read it with different phones and always I see that the ID is 0x00000000
I've made a program with Arduino and Adafruit's PN532 shield and I have that response too, in ATQB, the PUPI appears like 0x00000000, but when I read the ISO 14443-3 I read this:
A Pseudo-Unique Identifier (PUPI) is used to differenciate PICCs
during anticollision. This 4-byte number may be either a number
dinamically generated by the PICC or a diversified fixed number. The
PUPI shall only be generated by a state transition form the POWER-OFF
to the IDLE state.
For the transition from POWER OFF to IDLE, we need a field, so, I expect that when I try to read the tag this is not in POWER OFF, because I'm applying a field, but I think it is strange to have that PUPI of 0x00000000. I've tested with another tag (same Panasonic model) and I get the same PUPI...
Is this normal? Or what do you think about it?
I would suggest that you start by looking into the datasheet of the MN63Y1210:
On page 26 (table 3-13) you will find that the default value this chip uses for the PUPI is 00000000. You can configure that value, for instance, over the serial interface.

Handle idle sleep from audio virtual driver - Mac OSX

We have an virtual audio device driver similar to Sound flower. This virtual device will be listed in sound system preferences. Whenever our device gets selected in system preferences, it prevents idle sleep. If we switch the selection to default output device, everything works as expected.
If we execute 'pmset -g assertions' command in Terminal, it gives below output
Assertion status system-wide:
ChargeInhibit 0
PreventUserIdleDisplaySleep 0
PreventUserIdleSystemSleep 1
NoRealPowerSources_debug 0
CPUBoundAssertion 0
EnableIdleSleep 1
PreventSystemSleep 0
DisableInflow 0
DisableLowPowerBatteryWarnings 0
ExternalMedia 0
Listed by owning process:
pid 115: [0x0000012c00000073] PreventUserIdleSystemSleep named: MY_DRIVER_IDENTIFER.noidlesleep"
Could any one suggest me some pointers to resolve this issue.
I think this governed by the flag kIOPMPreventIdleSleep, which resides in the capabilityFlags field of the IOPMPowerState struct.
To participate in power management decisions, you'll need to add your device driver to the power management plane, typically in your overridden IOService::start(provider) method:
PMinit();
provider->joinPMtree(this);
registerPowerDriver(this, powerStates, numPowerStates);
where powerStates and numPowerStates specifies an array of power states you want your device to be able to be in. You'll probably not want more than 2 for a virtual device, and maybe you even only need one. I suspect a superclass of your class is setting states that are inhibiting sleep. Once you've registered for power management, your driver will be expected to handle the power management methods such as IOService::setPowerState().
Depending on how you want your device to behave, you might want to create 2 power states, one "live" when playing back or capturing sound (and inhibiting sleep) and the other "idle" when the device isn't doing anything, and allowing sleep.
The power management topic is a bit too big to cover entirely in a StackOverflow answer, so I suggest you read the docs on the stuff I've mentioned above and try clearing the relevant flag in your power state(s).
Hope that helps.