CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Working with multivector interrupts

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

Working with multivector interrupts
PostPosted: Sun Mar 09, 2025 7:05 am     Reply with quote

Hello, are there any built-in functions in the development environment for working with multivector interrupts? I did not find any in 5.115. There is a document from Microchip TB3162 where examples are given for XC8. Is there something similar here? I am interested in working with PIC18F46K42 and PIC18F47Q84 chips. I need functions for working with IVTBASE, MVECEN, IPR, and also how to use interrupt routine identifiers #INT_. If possible, I would like to see a code example.
Ttelmah



Joined: 11 Mar 2010
Posts: 19765

View user's profile Send private message

PostPosted: Mon Mar 10, 2025 1:56 am     Reply with quote

99% of PIC18's do not support multi-vector interrupts (except for the high/
This is why it is such a rare thing.
The keyword on the PIC's that do support it is simple:

#DEVICE VECTOR_INTS

This is one of those horrid 'hidden' extras. It was documented in the
CCS News posts.
[url]
https://www.ccsinfo.com/newsdesk_info.php?newsdeskPath=10&newsdesk_id=201
[/url]

With this set, the compiler, instead of generating a global interrupt handler
and then handling polling the interrupt flags to call the routines, generates
an interrupt vector table, enables the vector operation, and populates
the table with the addresses of the interrupt routines.

I think it is only the Q chips, and now some models of the Fx2 family that
have the support for this.

There was a bug with this a long time ago:
[url]
https://www.ccsinfo.com/forum/viewtopic.php?t=57463
[/url]

This was fixed in the next release.
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

PostPosted: Mon Mar 10, 2025 1:10 pm     Reply with quote

Thank you, Ttelmah. Figured it out. To be honest, I expected to see more opportunities for the user from the multivector interrupt system. For example, recording interrupt processing routines starting with a vector and ending with the command Retfie 1. But here, as in the usual interrupt system, there is saving of many temporary registers, three TBLPTR registers, the TABLAT register. And as a result, the performance does not increase much compared to the old system. It remains only to hope to fix everything using #INT_GLOBAL.
Tell me, what assembler command is written as DATA
Code:

0003E 0000           00029 DATA 00,00
  00040 0069           00030 DATA 69,00
00042 0000           00031 DATA 00,00

00040 is 0x08 + 2*0x1C vector number for TMR
temtronic



Joined: 01 Jul 2010
Posts: 9445
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 10, 2025 4:51 pm     Reply with quote

Another option, is to code your own Interrupt System.

From what I understand, the CCS approach saves 'lots of stuff' because you might need it.

Providing you KNOW what YOU need to save and use, you might be able to trim some time and/or code space BUT that could be risky.
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

PostPosted: Tue Mar 11, 2025 12:18 am     Reply with quote

Temtronic, it is not that easy to do. To enable MVECEN you need to use #device VECTOR_INTS, you can't set it via #FUSES. Secondly, it is not possible to create a subroutine without the #INT identifier at address 0x08. When using #INT_GLOBAL, the first three vectors are already occupied by commands (GOTO 108 (which leads nowhere), MOVLB0, ... the last line is occupied by the Retfie 0 command, despite the fact that there should be a jump address along the vector!)
temtronic



Joined: 01 Jul 2010
Posts: 9445
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Mar 11, 2025 5:47 am     Reply with quote

'not easy' ? Microchip wrote code in XC8( yes, I have the PDF...) CCS wrote their Interrupt 'controller'.( 'all purpose' ).. so you can write your own.
I know in the past, others have 'trimmed down' the CCS version for their specific needs so it can be done.

Why not take the XC8 code , convert to CCS C ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19765

View user's profile Send private message

PostPosted: Tue Mar 11, 2025 10:13 am     Reply with quote

Use the vector interrupt setting.
Then on the interrupt you want to service quickly, declare it as FAST.
Then add your own saving routines for the registers you use.
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

PostPosted: Thu Mar 13, 2025 12:29 am     Reply with quote

An example of the code that I would like to receive. I looked at the ASM listing, everything is in place. Is there a way to automate the substitution of the transition address in the assembler code "data"
Code:

#include <18F47Q84.h>
#device ADC=12, VECTOR_INTS,  HIGH_INTS=TRUE   // set #Fuse Mvecen  and High/Low
#use delay(internal=24MHz)

#byte IRP3   = 0x365        // manual priority set
 #bit TMR1IP  = IRP3.4  //T1 prior
//#bit  TMR1IP = getenv("SFR:IRP3").4   

#ORG 0x08, 0x050
void intglob (void)
{
      #asm asis
      data 0x0000     // 0x00 Software Interrupt
      data 0x0000     // 0x01 HLVD (High/Low-Voltage Detect)
      data 0x0000     // 0x02 OSF (Oscillator Fail)
      data 0x0000     // 0x03 CSW (Clock Switching)
      data 0x0000     // 0x04 TU16A (Universal Timer 16A)
      data 0x0000     // 0x05 CLC1 (ConfigurableLogic Cell)
      data 0x0000     // 0x06 CAN (CAN general)
      data 0x0000     // 0x07 IOC (Interrupt-On-Change)
      data 0x0000     // 0x08 INT0
      data 0x0000     // 0x09 ZCD (Zero-Cross Detection)
      data 0x0000     // 0x0A AD (ADC Conversion Complete)
      data 0x0000     // 0x0B ACT (Active Clock Tuning)
      data 0x0000     // 0x0C CM1 (Comparator)
      data 0x0000     // 0x0D SMT1 (Signal Measurement Timer)
      data 0x0000     // 0x0E SMT1PRA
      data 0x0000     // 0x0F SMT1PWA
      data 0x0000     // 0x10 ADT/ADCH1 (ADC Context 1)
      data 0x0000     // 0x11 ADCH2 (ADC Context 2)
      data 0x0000     // 0x12 ADCH3 (ADC Context 3)
      data 0x0000     // 0x13 ADCH4 (ADC Context 4)
      data 0x0000     // 0x14 DMA1SCNT (Direct Memory Access)
      data 0x0000     // 0x15 DMA1DCNT
      data 0x0000     // 0x16 DMA1OR
      data 0x0000     // 0x17 DMA1A
      data 0x0000     // 0x18 SPI1RX (Serial Peripheral Interface)
      data 0x0000     // 0x19 SPI1TX
      data 0x0000     // 0x1A SPI1
      data 0x0000     // 0x1B TMR2
      data 0x0052     // 0x1C TMR1
      data 0x0000     // 0x1D TMR1G
      data 0x0000     // 0x1E CCP1 (Capture/Compare/PWM)
      data 0x0102     // 0x1F TMR0
    #endasm
}

#ORG 0x052, 0x100
void INT_T1 (void)   // LOW prior
{
  static int16 j=0;
  ++j;
  set_timer1(0x1119);
  clear_interrupt (INT_TIMER1);
  #Asm asis
  retfie 1
  #endasm
}

#ORG 0x102, 0x150
void INT_T0 (void)   // HIGH prior
{
  static int16 i=0;
  ++i;
  set_timer0(0x0169);
  clear_interrupt (INT_TIMER0);
  #Asm asis
  retfie 1
  #endasm
}

void main()
{
setup_timer_1 ( T1_LFINTRC | T1_DIV_BY_8   );
setup_timer_0 ( T0_LFINTOSC | T0_DIV_64 | T0_16_BIT );

TMR1IP = 0;         // T1 LOW

enable_interrupts (INT_TIMER0);
enable_interrupts (INT_TIMER1);
enable_interrupts (global);

   while(TRUE)
   {
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19765

View user's profile Send private message

PostPosted: Thu Mar 13, 2025 3:21 am     Reply with quote

There is a huge problem with what you post. You have retfie 1 shown being
used in two interrupts, that since one is high priority, could occur inside
one another. This would result in disaster, with the inner one corrupting
the storage of the outer one.
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

PostPosted: Thu Mar 13, 2025 6:51 am     Reply with quote

According to the microchip manuals, there are two sets of saved ALU registers (low and high). In older versions of PIC 18, the low-priority one needs to be saved and restored manually.
Ttelmah



Joined: 11 Mar 2010
Posts: 19765

View user's profile Send private message

PostPosted: Thu Mar 13, 2025 7:46 am     Reply with quote

OK, good. I had not seen that improvement to these PIC18's.
On your autofill, label_address, can give you the physical address of any
routine, and can be used in the data statement.


Last edited by Ttelmah on Thu Mar 13, 2025 8:29 am; edited 1 time in total
dmitrboristuk



Joined: 26 Sep 2020
Posts: 69

View user's profile Send private message

PostPosted: Thu Mar 13, 2025 7:54 am     Reply with quote

label_address haven't tried. Thought about using #ORG + Const
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group