uHMCU Alpha 0.1 – Interrupts and improved assembly

Term is over! I’m free for another Easter so hopefully I can get a couple of blog posts done though I’m taking a trip to visit Chernobyl so my levels of irradiation might end up screwing up everything electronic… (lol.)

Assembler
The assembler I’ve been using previously had been written quite a while ago and while it worked mostly, adding extras in would make it even more convoluted so I’ve rewritten it. The majority of the assembler is formatting the code itself. The current features are:

  1. Allowing files to be included into one main program file using the “#include” command (yup, pretty much C like) e.g. #include inc_usart1.txt
  2. Allowing defines, like the #define derivative though instead, uses the -def directive e.g. -def Hello 123
  3. Obviously having comments using the ‘/’ character
  4. Labels defining jumps using the ‘@’ character. This saves counting every byte location!

As you can see, different characters define the type of line for ease of parsing. Each line essentially represents an instruction and allows for pretty easy parsing of a line (through tokenizing the line).

The assembler is written in C++ and is pretty fast, giving some information about the compilation and what the condensed form of code looks like.

assemblylisting.png
Compilation information screen

The assembler also directly outputs the .MIF files required for Quartus or Modelsim. In total, the assembler comes up 788 lines.

Interrupts
I’ve had the provisions for interrupts with my microcontroller for a while, I just hadn’t really implemented them. I’ve now written an interrupt controller and have tested it with a timer overflow interrupt.

Currently, all interrupts aren’t prioritised and there may be collisions if two interrupts occur at the same time so I’ll need to put provisions in for that (maybe some time dependent interrupt queue?) but for now, the super alpha interrupt controller works – at least in simulation.

interrupts_msec
Millisecond interrupts!

In the example above, I’ve set the timer to overflow at 50000 with a prescaler of 1 (divide by 2), which with a 100MHz clock (simulation speed), gives a “tick” rate of 1ms. The simulation clarifies that though there is an extra clock cycle of 10ns between register changes – hardly vital right now.

Currently the flow of finding which interrupt fired is a touch convoluted and consists of the processor jumping to the ISR, within the ISR, reading the interrupt controller register for which interrupt line fired then jumping to that interrupts ISR. I’ve only coded up the timer ISR as that’s the only interrupt that is active anyway. To ensure the microcontroller will definitely service the interrupt, regardless of which state it was in, the IRQ output from the interrupt controller stays high for 4 turns. The processor will then jump to the location stored in its ISRLOC register (ISR location) and execute the code from there. Upon completion of this, the processor will pull the pre-interrupt location off the PC stack and return to it. As of yet, the ISR consists of incrementing the value stored in register B – RB. I also don’t currently save and restore the context (RAM locations 0-3 would be used for this) as I’m not doing anything else anyway.

#include inc_tima.txt
#include inc_intctrl.txt

stk 0
/Initialize the INTLOC register
stk I @int
/Reset Millisec counter
str rb 0
/Initialize timer A for a 1msec period
str ra 1
rtm ra TIMA_CTRL
str ra 50000
rtm ra TIMA_OVF
str ra 1
rtm ra TIMA_PSC
str ra 4
/Enable the timer interrupt (line 2, 2^2=4)
rtm ra INTCTRL_IEN
str ra 1
/Enable global interrupts!
rtm ra INTCTRL_CTRL
str ra 66
/Start timer A and enable interrupt
rtm ra TIMA_CTRL
str ra 0
jmp @loop

@loop
/Useless main loop
alg inc ra
jmp @loop
@int
/Store context
/rtm ra 0
/rtm rb 1
/rtm rc 2
/rtm rd 3

/Read IRQ source
mtr rc INTCTRL_IRQ
str ra 4
alg and rc rc ra
/Invert bit from INTCTRL for JPZ
alg xor rc rc ra
/Jump to timer ISR
jpz rc @timirq

/Restore context
/mtr ra 0
/mtr rb 1
/mtr rc 2
/mtr rd 3
/Disable stack pushing
stk 0
/Return to previous code
ret

@timirq
/Clear the timer A interrupt request
str ra 0
rtm ra TIMA_INT
/Increment timer
alg inc rb
/Return to main ISR handler
ret

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s