Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

More swordfish basic help please

Status
Not open for further replies.
I'm confused as to the difference in "Event" and then just "Interrupt." Event's are only for interrupts right?

Also, I'm not sure I fully understand the format as shown in the language reference guide:

Code:
// event handler type...
type TEvent = event()
// the event handler to call...
event EventHandler()
high(PORTD.0)
end event
// declare event variable...
dim OnEvent as TEvent
OnEvent = EventHandler // assign handler
OnEvent() // call handler
Why is "type TEvent = event() necessary?


What's with all the leading "T"s and "P"s and "F"s in so many things? (general question on the language, not specifically about the code above)

Thanks!
 
Events, unlike subroutines or functions, cannot be called directly from a user program or module. Instead, you call an event via a variable which holds the address of the event handler routine. For example,


Event handler type... type TEvent = event()

Events are also different from subroutines and functions with respect to their frame allocation, which isn't recycled. This is because event pointers cannot be tracked at compile time, preventing the frame usage for an event from being calculated. Events are therefore allocated their own, unique frame space.



Whilst the non-recycle nature of event frame allocation may appear to be a disadvantage, it's actually extremely useful when used with interrupts. An interrupt cannot risk calling a subroutine or function without proper context saving, because it may damage the frame stack. Events on the other hand have a unique frame space, which makes it safe to execute an event from within a subroutine. There are some caveats though. These are:



A high and low priority interrupt should never call the same event handler.

Although an event frame space is protected, making calls to other subroutines or functions could cause the program to become unstable, in much the same way as an interrupt would.



In short, events allow you to 'plug in' code into an ISR, without having to alter the interrupt logic. However, it should be noted that you should treat an interrupt triggered event handler with the same respect in terms of context saving and usage as you would the main interrupt routine itself.



The following is an example of an interrupt driven module, which fires an event handler when the hardware USART received some data:
Code:
module MyRX

 

// import USART library...

include "USART.bas"

 

// event handler type...

type TEvent = event()

 

// local and public variables...

dim FOnDataEvent as TEvent

public dim DataChar as USART.RCRegister.AsChar

 

// ISR routine...

interrupt OnRX()

   FOnDataEvent()

end interrupt

 

// initialize...

public sub Initialize(pOnDataEvent as TEvent)

   FOnDataEvent = pOnDataEvent

   USART.ClearOverrun

   USART.RCIEnable = true

   enable(OnRX)

end sub
The main program code can now use the generic functionality of the interrupt module to take some specific action, through the use of an event…

program MyRXProgram

Code:
// import module...

include "USART.bas"

include "MyRX.bas"

 

// event handler

event OnRX()

   if MyRX.DataChar = " " then

      high(PORTD.0)

   elseif MyRX.DataChar = "*" then

      high(PORTD.1)

   endif     

end event

 

// main program

SetBaudrate(br19200)

MyRX.Initialize(OnRX)

while true

wend

 

// In the above example, PORTD.0 goes high if a space character is received and PORTD.1 goes high if an asterisk is received.
 
Read subroutines and functions in the help file


Private – An optional keyword which ensures that a constant is only available from within the module it is declared. Constant declarations are private by default.

Public – An optional keyword which ensures that a constant is available to other programs or modules.

Identifier – A mandatory constant name, which follows the standard identifier naming conventions

Type – An optional data type. Supported types include boolean, bit, byte, word, longword, shortint, integer, longint, float and char.

Expression – A mandatory literal, constant declaration or a mixture of both.

Here probably the best way to learn is to put your mouse pointer over any text in the IDE and hit F1
Look at the pic and you'll see what i mean it will pop up and show you how to use or how it is being used.
 

Attachments

  • MOUSE_over.jpg
    MOUSE_over.jpg
    130.8 KB · Views: 196
Last edited:
Thanks for the reply.

Here's one thing I'm not understanding:

Code:
public sub Initialize(pOnDataEvent as TEvent)

   FOnDataEvent = pOnDataEvent

   USART.ClearOverrun

   USART.RCIEnable = true

   enable(OnRX)

end sub

First it seems that "TEvent" gets aliased to "event()", then to "FOnDataEvent", then to "POnDataEvent". What's with all this dang aliasing? I'm sure it is just some intricacy of the language that I don't understand, but it seems like 15% of the time gets spent saying "Call 'a' 'b'. Okay, now call it 'c'. Okay, now I want you to call it 'd'."

Why the parameter in the initialize sub? I'm half lost on parameters in general. Why does "pOnDataEvent" need to passed into this sub?

What's the difference in "FOnDataEvent" and "POnDataEvent"?
 
Last edited:
This is from the help file you picked the best place to start digging most people don't even know this module is in swordfish.


Events, unlike subroutines or functions, cannot be called directly from a user program or module. Instead, you call an event via a variable which holds the address of the event handler routine. For example,

Code:
// event handler type...

type TEvent = event()

 

// the event handler to call...

event EventHandler()

   high(PORTD.0)

end event

// declare event variable...

dim OnEvent as TEvent

OnEvent = EventHandler  // assign handler

OnEvent()               // call handler

Events are also different from subroutines and functions with respect to their frame allocation, which isn't recycled. This is because event pointers cannot be tracked at compile time, preventing the frame usage for an event from being calculated. Events are therefore allocated their own, unique frame space.



Whilst the non-recycle nature of event frame allocation may appear to be a disadvantage, it's actually extremely useful when used with interrupts. An interrupt cannot risk calling a subroutine or function without proper context saving, because it may damage the frame stack. Events on the other hand have a unique frame space, which makes it safe to execute an event from within a subroutine. There are some caveats though. These are:



A high and low priority interrupt should never call the same event handler.

Although an event frame space is protected, making calls to other subroutines or functions could cause the program to become unstable, in much the same way as an interrupt would.



In short, events allow you to 'plug in' code into an ISR, without having to alter the interrupt logic. However, it should be noted that you should treat an interrupt triggered event handler with the same respect in terms of context saving and usage as you would the main interrupt routine itself.



The following is an example of an interrupt driven module, which fires an event handler when the hardware USART received some data:
 
Last edited:
wannaB,

The initialize function takes a parameter that is a pointer to (i.e. the address of) an event. The variable starting p (i.e. pOnDataEvent) is a Pointer and so holds an address, in this case to a function. This address is then stored for later use in a variable (FOnDataEvent) that starts with F for function. I think you should ignore events and use conventional code until you fully understand pointer etc.

Mike.
 
This code he is looking at is used only with the swordfish USART module and your right I would leave it alone. Like i said most people don't even know it there. I didn't till about ago 3 months. And i need to use USART Ondata I ask on the forum and at swordfish and after a week i found the Interrupt based USART receive library Thats what your looking at. I was needing a buffer. And trying to call it directly
 
wannaB,

The initialize function takes a parameter that is a pointer to (i.e. the address of) an event. The variable starting p (i.e. pOnDataEvent) is a Pointer and so holds an address, in this case to a function. This address is then stored for later use in a variable (FOnDataEvent) that starts with F for function. I think you should ignore events and use conventional code until you fully understand pointer etc.

Mike.

Thanks for the reply. I don't see why pOnDataEvent needs to be copied to fOnDataEvent because by default pOnDataEvent is passed by value, not by reference, an should not actually get modified.
Do the "P", "F", and "T" actually change identifier itself, or is it just a convention in basic to help the programmer keep up with what type of variable it is?

Pommie, when you say not to use events, what happens if I substitute lines of code for the event itself.

Code:
// ISR routine...

interrupt OnRX()

   FOnDataEvent()

end interrupt

Can I just cut out the FOnDataEvent() and put in the lines of whatever that event call does and still maintain the same functionality?

I know for Interrupts in SF Basic it allows you to designate it either as a Hi or Lo priority. Does this mean I can only have two interrupt sources?

If I have a Timer0, Timer1, and UART Rec Buffer Full as interrupts, how does SF handle this if I put these handlers in the "Interrupt ....End Interrupt" format? Can I have all three of them? If so, what the heck is the advantage to the event routines versus just interrupts?

Thanks guys!
 
wannaBinventor your looking at the ISRRX.bas it's only for using a buffer to store strings Ondata it loads the buffer.

It's not used for anything but USART.

P, F ,T are just types there used mainly in modules
Can I just cut out the FOnDataEvent() and put in the lines of whatever that event call does and still maintain the same functionality?
You can do it any way you like roll your own even use asm

Have a look at this page https://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.Interrupts
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top