I am not sure how many other people are making use of the information about interrupts on the Atom Pro. But just in case someone else may find this information of use… I wonder if this information is best here or in the Wiki?
As part of my Brat project where I was trying to improve my communications with the PC using the DB9 serial Port(S_IN, S_OUT) I found:
IRQ0
The IO pin on the H8 that is associated with IRQ0 is P14 and on the Atom Pro, this is connected to both S_IN and S_OUT through a half duplex diode circuit. You can use this to your advantage if you would like your software on the Atom Pro to be able to detect when your PC program is trying to communicate with it, without having to leave your Pro code sitting in a SERIN. There are maybe better ways to implement this, but I will describe what has worked for me.
On the Atom Pro, I enable the interrupt on the trailing edge and implement a simple interrupt handler that reverts the I/O pin back to a normal IO pin and sets a state variable. This code looks something like:
[code]ONINTERRUPT IRQ0INT, HANDLE_IRQ0
fHostcommandPending var byte
; Initialize communications with PC
; lets setup to get interrupted if we get a rising edge on IRQ0. We can probably have the PC send a 0xff character
; which will show up as one spike up and then all zeros after as a prelude to our message header…
;
fHostcommandPending = 0
PMR1.bit4 = 1 ; enable pin to IRQ0 interrupt instead of normal I/O
IEGR1.bit0 = 0 ; Interrupt IRQ0 on falling edge
enable irq0
ienr1.bit0 = 1
HANDLE_IRQ0:
toggle p5 ; not needed, but sets led on ABB to let me know…
; disable our own interrupt.
PMR1.bit4 = 0 ; restore pin n to normal IO
fHostCommandPending = 1 ; let the main loop know that we have a packet pending
resume ; and return
[/code]
My Main loop in the Atom Pro simply tests for fHostCommandPending and calls off to a function to process the command. Something like:
main
' Check to see if the host PC has signalled us to process a host command
if fHostCommandPending then
gosub ProcessHostCommand
endif
...
goto main
; My processing of the code loos something like:
ProcessHostCommand:
serin s_in, i2400, 1000, GCHTimeout, [str bPacketHeader\4]
bcmd = bPacketHeader(0)
wSeqnum.lowbyte = bPacketHeader(1)
wSeqnum.highbyte = bPacketHeader(2)
cbExtra = bPacketHeader(3)
' do some simple validation of the input
if ((bCmd & 0xf0) <> 0xf0) or (cbExtra >= 30) then GCHPPacketError
' Now try to read in the rest of the packet, two cases, one with extra data and one without...
if cbExtra <> 0 then
serin s_in, i2400, 1000, GCHTimeoutExtra, [str bBuffer\cbExtra, bChksum]
else
serin s_in, i2400, 1000, GCHTimeoutExtra, [bchksum]
endif
; do the processing of the command
; at end fall through...
EndProcessHostCommand:
; now we will reenable us as an interrupt and resume
fHostCommandPending = 0
PMR1.bit4 = 1 ; restore pin interrupt state
ienr1.bit0 = 1
return
On the PC side (VB), I first simply send a single character of hex 0xff. This turns out that at the S_IN pin as a simply pulse for the start bit. This works great to trigger the interrupt. I then have the VB code wait a bit of time for the Atom Pro to get to a point to be in a SERIN and then I output my packet of information and wait for the Atom Pro to send back an Acknowlegement packet. More handshaking could be added here, but my current code on the PC looks something like:
[code] Public Function FSendPacketandCheckforAck(ByRef com1 As IO.Ports.SerialPort, ByRef ab As Byte(), ByVal cbPacket As Short, ByVal iRetryCnt As Short) As Boolean
Dim iLoop As Short
Dim abT(1) As Byte
abT(0) = &HFF
For iLoop = 0 To iRetryCnt
Try
com1.DiscardInBuffer()
' first output an &hff to try to get the brats attention...
com1.Write(abT, 0, 1)
System.Threading.Thread.Sleep(100) ' give the brat some time to get to the handler
' I will output this in two parts. First the fixed part that the brat will try to read as one.
com1.Write(ab, 0, 4) ' write out cmd, seql, seqh, cbExtra
' System.Threading.Thread.Sleep(30)
com1.Write(ab, 4, cbPacket - 4)
com1.BaseStream.Flush()
If FCheckforAck(com1, ab(0), cbPacket, (ab(2) << 8) + ab(1)) Then
Return True ' we succeeded.
System.Threading.Thread.Sleep(250) ' If an error happens wait a bit before we retry
End If
Catch ex As Exception
End Try
' now lets wait for a hopefull ACK!!!
Next
Return False
End Function[/code]