- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have an SOPC system with some custom avalon slaves. I would like to generate interrupts to nios with these blocks. I have searched here and on the altera site for documentation on how to implement the interrupt hardware in your avalon components but am coming up empty handed. Can anyone point me in the right direction?:confused::confused::confused:
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
just found the interrupt section in the avalon spec. Not much there, I guess you just assert a line and hold it until your custom slave logic gets told to clear the irq by the cpu. seems pretty simple.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
there is one catch...
you have to clear the irq-flag manually. But if you try to write via pointer on a peripheral module at the END of an interrupt subroutine (=last instruction) and have DATA CACHE enabled (standard, if using NIOS2/f), the data cache will be flushed and the write aborted.
// regular isr
static void test_isr(void* context, alt_u32 id)
{
...
// RESET INTERRUPT at the end of an interrupt
(*(long*)PERIPHERAL_BASE) = 0;
}
So better use IOWR(PERIPHERAL_BASE, 0, 0);
instead, to bypass the data cache. or use the alt_dcache_flush_all();
statement (# include <sys/alt_cache.h> ). it took me some time to figure out, why the interrupt flag wasn't cleared if the pointer insturction was the last one, but was cleared if there was an another one after it :D
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I OR all of the pointers to my Avalon HW blocks with the data cache bypass bit so I don't get this kind of behavior. Hopefully it will avoid me this problem.
# define DATA_CACHE_BYPASS_BIT 0x80000000 volatile alt_u32* avalon_component_p = (volatile alt_u32*)(AVALON_COMP_BASE|DATA_CACHE_BYPASS_BIT); This is how I define all of my hw pointers in my C code. if you have no idea what I'm talking about google up data cache bypass niosII and read their document. I'm still not clear why volatile isn't sufficient but nios provides you with the ability to make the 31st bit '1' in order to force data cache bypassing. :)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The ldio/stio family of instructions explicitly bypass the data cache.
Bit-31 provides an alternate method to bypass the data cache. Using the bit-31 cache bypass, the normal ld/st family of instructions may be used to bypass the data cache if the most-significant bit of the address (bit 31) is set to one. The value of bit 31 is only used internally to the CPU; bit 31 is forced to zero in the actual address accessed. This limits the maximum byte address space to 31 bits. Using bit 31 to bypass the data cache is a convenient mechanism for software because the cacheability of the associated address is contained within the address. This usage allows the address to be passed to code that uses the normal ld/st family of instructions, while still guaranteeing that all accesses to that address consistently bypass the data cache. Bit-31 cache bypass is only explicitly provided in the Nios II/f core, and should not be used for other Nios II cores. The other Nios II cores that do not support bit-31 cache bypass limit their maximum byte address space to 31 bits to ease migration of code from one implementation to another. They effectively ignore the value of bit 31, which allows code written for a Nios II/f core using bit 31 cache bypass to run correctly on other current Nios II implementations. In general, this feature is dependent on the Nios II core implementation.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
:confused:
Device drivers typically access control registers associated with their device. These registers are mapped into the Nios II address space. When accessing device registers, the data cache must be bypassed to ensure that accesses are not lost or deferred due to the data cache. For device drivers, the data cache should be bypassed by using the ldio/stio family of instructions. On Nios II cores without a data cache, these instructions behave just like their corresponding ld/st instructions, and therefore are benign. for c programmers, note that declaring a pointer as volatile does notcause accesses using that volatile pointer to bypass the data cache. the
volatile keyword only prevents the compiler from optimizing out
accesses using the pointer.
This volatile behavior is different from the methodology for the first-generation Nios processor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Declaring it volatile and making sure that bit 31 is set will ensure that the cache is bypassed. Also, Altera provides HAL functions to remap the address to an uncached address if you don't like doing the bit 31 thing.
Jake- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using the HAL functions is in fact better if you want to write code that can be recompiled for a NIOS CPU with MMU. The bit-31 trick won't work in that case IIRC.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Declaring it volatile and making sure that bit 31 is set will ensure that the cache is bypassed. Also, Altera provides HAL functions to remap the address to an uncached address if you don't like doing the bit 31 thing. Jake --- Quote End --- The 'volatile' only ensures that the compiler generate the instruction to write to memory. If the write is cached and the cache isn't write-through (I can't see a definition in the Nios ref book) then the write to memory won't happen until much later. Additionally you need to leave enough time between the memory write and exiting the ISR for the IRQ to actually have dropped. If you are executing code from tightly coupled memory, the io write requires an Avalon-MM transfer, and you do the write just before returning from the ISR it is possible the ISR will be re-entered.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page