…will be available later today on www.basicmicro.com for download. Fixes a bug in HSERVO from 8.0.1.0. Fixes a number of little issues we found but no one else has. Modified the debuger handler code to be a bit more robust.
Hi Nathan,
I installed the new beta and the good news is it did compile my C++ hello world program fine. FYI - Vista still complains about it not be digitally signed…
But now the Brat program does not compile. It did on your 8.0.1.1
Error: FILE C:\USERS\KURT\DESKTOP\LYNXMOTION\BRATWITHREMOTE.BAS(LINE 650) : [TOKEN ONE] : Compiler error 102
This line number points to the “return one” line in your getlongest function.
one var float
two var float
three var float
four var float
five var float
six var float
getlongest[one,two,three,four,five,six]
if(one<0.0)then
one=-1.0*one
endif
if(two<0.0)then
two=-1.0*two
endif
if(three<0.0)then
three=-1.0*three
endif
if(four<0.0)then
four=-1.0*four
endif
if(five<0.0)then
five=-1.0*five
endif
if(six<0.0)then
six=-1.0*six
endif
if(one<two)then
one=two
endif
if(one<three)then
one=three
endif
if(one<four)then
one=four
endif
if(one<five)then
one=five
endif
if(one<six)then
one=six
endif
return one
Thanks
Kurt
Ya, I did make a small change to how the return value was returned. I tested it but not with that program. Thats why I’m calling this a beta release. I knew I might have broken something. Can you send me a copy of your brat code. I want to be sure to use the exact code you are using.
Also FYI: All assembly opcodes in Hitachi assembly are now reserved words so if you are using any labels with names like “nop” “mov” “neg” ect. you will need to change them. This only applies to labels because they or command names are first on any line of code and no command names conflict so that only leaves user label names.
The reason for this change is that I’ve added inline assembly support(very beta). There are some limitations. Assembly code can’t bra/jmp into Basic code and Basic code can’t goto/gosub into assembly code. Labels are either Assembly labels or Basic labels. To determine what type a label is the compiler looks at the next line of code. If it’s an assembly opcode the label is an assembly label. If the next line of code is basic then the label is a basic label. There is no ASM{} command so you can’t create assembly macros or defines or conditional assembly commands because the basic compiler will not understand them and complain(error out).
I just used the Brat code in the Brat sticky and reprduced the error. Turns out it’s because its a FLOAT type variable. I’m fixing it so the return can return any variable type. When I’ve uploaded the fixed version I’ll post here.
Its fixed now. Same link.
Ok, it now compiles fine. I am running my brat code through some testing and one of my areas of code that receives the code from the tv remote and displays the results on the lcd display is rebooting the processor. At first I thought it was low battery, but I have now recharged the battery and still seeing the problem. I will try to localize it down some
Kurt
Ok. I’m guessing its in the interrupt handler code? If you can narrow it down that would be great. Send me what you can.
I have localized this down aways, it is actually faulting in my LCDConvertNumToString function. If I pass it a two digit number like: 15
Sometimes in the last while loop, it appears like iCnt1 and iCnt2 values do not get updated before it checks it in the While condition, which then allow iCnt1 to go negative (except unsigned so it goes to 255) and this loop continues and wipes out memory. I could probably stop the fault by converting these variables to SBYTE instead of BYTE, but…
I also found with the debugger that I had to rearrange my variables to get the iCnt1 and 2 to display. It only wanted to display something like the first 5 variables. It also did not show values in the array…
There is probably still a lot of code in this test program that is not needed, but:
[code];; Test Program to try to narrow done rebooting processor
;
; Warning: this is work in progress, use at your own risk…
; define which LCD I am using…
SEETRON con 1
LCDPIN con p0
#ifdef SEETRON
;LCD_BAUD con n9600
;LCD_BAUD con 206
LCD_BAUD con n2400
#else
LCD_BAUD con i2400
#endif
;Interrupt init
USE_HSERVO con 1
#ifdef USE_HSERVO
HSERVO_GROUPS con 3
ENABLEHSERVO
#endif
ONINTERRUPT WKPINT_3,handle_irpd
#if 0
PMR5.bit3 = 1
TMA=4 ;increments on clock/256
ENABLE WKPINT_3
#endif
iCnT1 var byte
iCnt2 var byte
iOutLast var sword
tmaCycle var byte
datacount var sbyte
irpd_data var word
command var byte
bCmd var byte
; variables for LCD… Not sure how to pass an array to a gosub so.
LCD_String var byte(17)
gosub LCD_Init
LCD_String = “Hello Brat”, 0
gosub LCD_Print[1, 0]
sound 9,[50\3960]
bcmd = 15
gosub LCDConvertNumToString[bCmd]
;----------------------------------------------------------------
; simple function to display what keys are hit on the Sony remote on the LCD
;
CheckOutRemote
gosub LCD_ClearAndReturn
LCD_String = “Check Remote”, 0
gosub LCD_Print[1,0]
command=0xFF
CORMain
if Command <> 0xff then
; now simply output the command number on 2nd line of LCD
bCmd = Command
gosub LCDConvertNumToString[bCmd]
gosub LCD_Print[2,1]
Command=0xFF
endif
goto CORMain
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Handle IRPD - try to not use timer interrupt as the largest value we need appears to be 195…
handle_irpd
tmaCycle=TCA
TMA = 0xc ; reset tma
TMA = 4 ; divide by 256
if (irr1.bit6) then
irr1.bit6 = 0
datacount = -1
resume
endif
if(datacount<0)then ;If negtive data count reset things…
datacount=0
else ;else process pulses
datacount=datacount+1
irpd_data=irpd_data>>1
if(tmaCycle>175 AND tmaCycle<195)then ;If we get a start pulse reset datacount and irpd_data
irpd_data=0
datacount=0
elseif(tmaCycle>100 and tmaCycle<120) ;we got a “1” pulse
irpd_data.bit10=1
elseif(tmaCycle>65 and tmaCycle<85) ;we got a “0” pulse
irpd_data.bit10=0
else ;we got an invalid pulse so reset
datacount = -1
resume
endif
if(datacount=11)then
datacount =-1
command = irpd_data&0x7F
endif
endif
Resume
;
; Serial LCD functions added by Kurt
;
LCD_Init
; make sure SerLCD has a chance to finish initializing after power-up
; Reset to 9600 and powerup… - Uncomment if having problems with LCD.
; serout LCDPIN, I9600, [0x12]
DISABLE WKPINT_3
Pause(1000)
; Now lets try setting it to 2400 baud. - uncomment if having problems
; Serout LCDPIN, I9600, [0x7c] ; 124,
; pause 2
; Serout LCDPIN, I9600, [11] ; 124,
#ifndef SEETRON
; Set the backlight to low
Serout LCDPIN, LCD_BAUD, [0x7C, 0x80] ; 124, 128 - Off
#endif
; Output the clear screen command
gosub LCD_WriteCommand[1] ; // Clear the screen
Pause(5)
ENABLE WKPINT_3
return
;
; Main LCD output function
;
line var sbyte
fPad var byte
LCD_Print[line, fPad]
DISABLE WKPINT_3
if line = 1 then
gosub LCD_WriteCommand[0x80]
elseif line = 2
gosub LCD_WriteCommand[0xC0]
endif
Pause(10)
for line = 0 to 14 ; try now to write to last position as it appears to autoscroll...
if fPad <> 2 and LCD_String(line) > 0 then
serout LCDPIN, LCD_BAUD, [LCD_String(line)]
else
if fPad = 0 then
goto LCDP_Enable
endif
fPad = 2
serout LCDPIN, LCD_BAUD, " "]
endif
Pause(1)
next
LCDP_Enable
ENABLE WKPINT_3
return
;
;DISPLAY DATA RAM ADDRESSES
;CHARACTER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
; + – -- – -- – -- – -- – -- – -- – -- – --
;LINE 1 | 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
;LINE 2 | C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
;
ich var byte
iline var byte
LCD_SetPos[ich, iline]
if iline = 1 then
gosub LCD_WriteCommand[0x80+ich]
else
gosub LCD_WriteCommand[0xC0+ich]
endif
pause 10
return
; clears the display and resets the current location to the upper left */
LCD_ClearAndReturn
DISABLE WKPINT_3
gosub LCD_WriteCommand[1] ; // clear display
Pause(100)
ENABLE WKPINT_3
return
fRight var byte
ichShift var byte
LCD_ShiftDisplay[fRight, ichShift]
if fRight <> 0 then
fRight = 0x1c
else
fRight = 0x18
endif
while (ichShift > 0)
gosub LCD_WriteCommand[fRight]
ichShift = ichShift -1
wend
return
; Send a command to the LCD, first send a command prefix character and then then command
cmd var byte
LCD_WriteCommand[cmd]
serout LCDPIN, LCD_BAUD, [0xfe]
pause 10
serout LCDPIN, LCD_BAUD, [cmd]
return
iOut var sword
LCDConvertNumToString[iOut]
if iOut < 0 then
LCD_String(0) = “-”
iOut = -iOut
iCnt1 = 1
iCnt2 = 1
else
iCnt1 = 0
iCnt2 = 0
endif
do
iOutLast = iOut
LCD_String(iCnt1) = "0" + iOut // 10
iOut = iOut / 10
iCnt1 = iCnt1 + 1
while (iOutLast > 10)
LCD_String(iCnt1) = 0
iCnt1 = iCnt1 - 1
while (iCnt1 > iCnt2)
swap LCD_String(iCnt1), LCD_String(iCnt2)
iCnt1 = iCnt1 - 1
iCnt2 = iCnt2 + 1
wend
return
[/code]
Let me know if you would rather continue this through email…
Kurt
Ok I narrowed it down. to the loop with the swap. Here is a reduced version of the program:
[code]
; Test Program to try to narrow done rebooting processor
;
; Warning: this is work in progress, use at your own risk…
iCnT1 var sword
iCnt2 var sword
iOutLast var sword
bCmd var sword
; variables for LCD… Not sure how to pass an array to a gosub so.
LCD_String var byte(17)
sound 9,[50\3960]
bcmd = 15
gosub LCDConvertNumToString[bCmd]
;----------------------------------------------------------------
; simple function to display what keys are hit on the Sony remote on the LCD
;
Main
goto Main
iOut var sword
LCDConvertNumToString[iOut]
if iOut < 0 then
LCD_String(0) = “-”
iOut = -iOut
iCnt1 = 1
iCnt2 = 1
else
iCnt1 = 0
iCnt2 = 0
endif
do
iOutLast = iOut
LCD_String(iCnt1) = "0" + iOut // 10
iOut = iOut / 10
iCnt1 = iCnt1 + 1
while (iOutLast > 10)
LCD_String(iCnt1) = 0
iCnt1 = iCnt1 - 1
while (iCnt1 > iCnt2)
swap LCD_String(iCnt1), LCD_String(iCnt2)
iCnt1 = iCnt1 - 1
iCnt2 = iCnt2 + 1
wend
return[/code]
It normally walks through to the return statement where probably the return value on the stack is corrupt and it reboots at that point. Not sure yet if it is the swap, that is not working properly or something else. Obviously I can recode this differently…
It’s probably the swap. I had to modify that command in particular on this release because of a change in the underlying variable handler. I’ll take a look at it tomorrow. Also the debugger was modified extensively so not too surprise3d you are having problems. I’m still playing around with it. Does the smaller test code show the same debugger problems? And yes we can continue this in email at least until a new beta is up.
To everyone else, I’ll post an update to this post when the next beta is available.
Ok, have continued in email…
The inline assembly sounds interesting. Any more information? For example, what registers can be uses? Do I have access to basic variables? Can I set up an assembly level interrupt handler? …
Thanks
Kurt
P.S. - It is probably beyond the scope of what you would like to do, but it would be interesting if you could allow the language to be extended in much the same way as you have things like USEHSERVO. Maybe allowing something like USExxxx, where there is some type of xxxx description file that describes the commands and a precompiles asm or C file that has the code to process the commands. I know I am probably just dreaming…
I’ll talk about the inline assembly here since more than you will want that info.
inline assembly can use er0 to er5. ER6 can be used it you save/restore the value when you enter/exit the assembly code. ER7 shouldn’t be messed with since it holds the stack pointer. You can access all byte/sbyte/word/sword and long variables directly.
eg:
mybyte var byte
mov.b @MYBYTE:16,r0l ;get bytes value and put in r0l register
Not all variable names and label names must be in CAPS in inline assembly. This is because the basic compiler automatically converts all basic code to uppercase. It will not automatically set assembly code to uppercase because some things in assembly must be lowercase(eg command names,register names).
I don’t recommend trying to use bit and nibble variables in inline assembly because you’ll have to figure out what bit/nib in the byte address being pointed at is the correct one.
I added ONASMINTERRUPT to the compiler this week and will be making a new beta available with that feature in it. ONASMINTERRUPT interrupts are direct to assembly language interrupts. 20 clock cycles after the interrupt happens(14 cycles are used by the processor and 6 are used with a 16bit jmp to your assembly code) you will be in your assembly code. You must save/restore any registers you use while in the interrupt handler and you must return from the handler with an “rte” assembly command. Note only the main interrupt can be used(see list below). To determine which sub ints actually happened(eg in the WKP int which WKP pin caused the int you must look at the WKP flags) you will have to do the work youself unlike the basic interrupts were this is handled for you. Also you have to clear the int flag yourself unlike basic ints which clear these flags for you automatically. In otherwords you have to do everything your self in assembly ints but you get the advtage of getting the best speed possible out of them. Here is the list of assembly ints.
IRQ0INT
IRQ1INT
IRQ2INT
IRQ3INT
WKPINT
TIMERVINT
SCI3INT
IICINT
ADINT
TIMERAINT (36X4 only)
TIMERWINT
RTCINT (3687 only)
TIMERZ0INT (3687 only)
TIMERZ1INT (3687 only)
SCI3_2INT (3687 only)
P.S. you aren’t too far off on this. It’s something I’ve been thinking of doing for a while. The difficult part will be making precompiled commands conform to HBasics calling conventions which are, to say the least, rather convoluted. Don’t expect anything like this for a while though.
A new Beta is available with the following fixes.
Serout flow control should now work. I was not able to test with a real flow controlled serial port so I may have the levels on the flow control lines reversed. Someone who needs this please let me know and I switch them if that is the case.
ADin is fixed. Use the pin name for the pin argument(eg ADin p16,temp to read the A/D value of P16 on an AtomPro28 module).
Hservo had a problem when used along with serout. That is no longer the case. Serout will no longer interfere with hservo(though hservo may interfere with serout).
Here is the link:
www.basicmicro.com/downloads/software/B … p_8013.exe
The link on the website will be updated asap but until then use the above link.
Flow control finally works but I still have a problem. The sounds are distorted.
Is the serial data RS-232A type of data? if so this might be my problem, or is it possible that it is inverted some how? How can I program this to not be inverted?
PA0 CON 0 ' pauses
PA1 CON 1
PA2 CON 2
PA3 CON 3
PA4 CON 4
PA5 CON 5
PA6 CON 6
Fast CON 7
Slow CON 8
Stress CON 14
Relax CON 15
_Wait CON 16 ' note underscore
Soft CON 18
Volume CON 20
Speed CON 21
Pitch CON 22
Bend CON 23
PortCtr CON 24
Port CON 25
Repeat_ CON 26
CallPhr CON 28
GotoPhr CON 29
Delay CON 30
Reset CON 31
IY CON 128
IH CON 129
EY CON 130
EH_ CON 131
AY CON 132
AX CON 133
UX CON 134
OH CON 135
AW CON 136
OW CON 137
UH CON 138
UW CON 139
MM CON 140
NE CON 141
NO CON 142
NGE CON 143
NGO CON 144
LE CON 145
LO CON 146
WW CON 147
RR CON 148
IYRR CON 149
EYRR CON 150
AXRR CON 151
AWRR CON 152
OWRR CON 153
EYIY CON 154
OHIY CON 155
OWIY CON 156
OHIH CON 157
IYEH CON 158
EHLL CON 159
IYUW CON 160
AXUW CON 161
IHWW CON 162
AYWW CON 163
OWWW CON 164
JH CON 165
VV CON 166
ZZ CON 167
ZH CON 168
DH_ CON 169
BE CON 170
BO CON 171
EB CON 172
OB CON 173
DE CON 174
_DO CON 175 ' note underscore
ED CON 176
OD CON 177
GE CON 178
GO CON 179
EG CON 180
OG CON 181
CH_ CON 182
HE CON 183
HO CON 184
WH CON 185
FF CON 186
SE CON 187
SO CON 188
SH CON 189
TH CON 190
TT CON 191
TU CON 192
TS CON 193
KE CON 194
KO CON 195
EK CON 196
OK CON 197
PE CON 198
PO CON 199
RO CON 200
R1 CON 201
R2 CON 202
R3 CON 203
R4 CON 204
R5 CON 205
R6 CON 206
R7 CON 207
R8 CON 208
R9 CON 209
A0 CON 210
A1 CON 211
A2 CON 212
A3 CON 213
A4 CON 214
A5 CON 215
A6 CON 216
A7 CON 217
A8 CON 218
A9 CON 219
_B0 CON 220 ' note underscore
_B1 CON 221
_B2 CON 222
_B3 CON 223
_B4 CON 224
_B5 CON 225
_B6 CON 226
_B7 CON 227
_B8 CON 228
_B9 CON 229
C0 CON 230
C1 CON 231
C2 CON 232
C3 CON 233
C4 CON 234
C5 CON 235
C6 CON 236
C7 CON 237
C8 CON 238
C9 CON 239
D0 CON 240 ' DTMF tones
D1 CON 241
D2 CON 242
D3 CON 243
D4 CON 244
D5 CON 245
D6 CON 246
D7 CON 247
D8 CON 248
D9 CON 249
D10 CON 250
D11 CON 251
M0 CON 252 ' sonar pin
M1 CON 253 ' pistol shot
M2 CON 254 ' WOW
EOS CON 255
TX con P6
RDY con P4
'
'------------------------- Prases ]--------------------------------------------------
'SEROUT 9, $0054,[Reset, Volume, 127] ' Defaults
ph1:
'My name is Vecter
SEROUT TX\RDY, N9600,[MM,OHIH,PA1,NE,EYIY,MM,PA2,IH,IH,SE,SE,PA2,VV,VV,EH_,KO,TT,RR,RR,PA2]
ph2:
'VERSION 1.0
SEROUT TX\RDY, N9600,[VV,AXRR,SH,SH,EY,NE,PA5,WW,WW,UX,NE,PO,OWIY,NE,TT,TT,PA5,OWWW,PA2,PA2,PA2,PA2]
ph3:
'Object Detected
SEROUT TX\RDY, N9600,[OH,BE,JH,EY,KO,TT,PA2,DE,IY,TT,EH_,EK,TT,EH_,ED,PA2]
ph4:
'Completed
SEROUT TX\RDY, N9600,[KO,MM,PO,LE,IY,TT,EH_,ED,PA2]
ph5:
'Hello
SEROUT TX\RDY, N9600,[HE,EH_,LE,OWWW,PA2]
ph6:
'BATTERY LOW
SEROUT TX\RDY, N9600,[OB,AY,TT,AXRR,IY,PA2,LE,LE,LE,OW,OW,OWWW,PA2]
ph7:
'Initializing
SEROUT TX\RDY, N9600,[FAST,IH,NE,IH,SH,SH,UX,LE,OHIH,ZZ,ZZ,NGE,PA2]
ph8:
'LEFT SIDE
SEROUT TX\RDY, N9600,[PA1,LE,EY,FF,FF,TU,PA6,SE,OHIH,DE,PA2]
ph9:
'RIGHT SIDE
SEROUT TX\RDY, N9600, [PA1,RR,RR,OHIH,TU,PA6,SE,OHIH,DE,PA2]
ph10:
SEROUT TX\RDY, N9600, [HO,OH,SE,TT,OH,LE,UX,VV,IY,IY,SE,TT,OH,PA2,BE,EYIY,OB,IY,IY,PA2]
ph11:
'Status OK
SEROUT TX\RDY, N9600, [SE,SE,TT,AY,TT,UX,SO,SO,PA2,OW,KE,EYIY]
ph12:
'Sonar Ready
SEROUT TX\RDY, N9600, [SE,OW,NE,AWRR,PA2,RR,EY,DE,IY,PA2]
ph13:
'Roaming Mode
SEROUT TX\RDY, N9600, [RR,OWWW,MM,MM,NGE,PA2,MM,OWWW,ED,PA2]
ph14:
'RSCU
SEROUT TX\RDY, N9600, [AWRR,EH_,SE,SE,PA1,SE,IY,IY,PA1,IY,UW,PA1,OB,OWWW,RR,ED,PA2]
ph15:
'Processing Data
SEROUT TX\RDY, N9600, [FAST,PE,RR,OH,SO,SE,EH_,SO,NGE,NGE,PA2,_DO,EYIY,DE,UX,pa2]
END
I have noticed that if I toy around with the baud setting I get different results. The stamp uses $0054 but I have no idea what baud this is. The BAP Uses N9600 but that seems to be to fast. I really don’t know whats going on with the serial data.
Flow control seems fine because my speakjet board’s LEDs flash indicating it is working.
$0054 is 9600 baud, non-inverted, 8 data bits, no parity.
$5054 is 9600 baud, non-inverted, 8 data bits, no parity.
I have tried $0054 and that didn’t work I have also tried i9600, e9600, and many other numbers with no luck. To check that my SJ board is still working and that I didn’t screw something up; last night after several failed attempts with the BAP, I hooked everything back up to the BS2 and walla! it worked fine. The SJ is working so something is wrong with the serial data being sent from the BAP.
I don’t understand. I had it working at one time with the BAP without flow control, but I can’t remember what version I was using or what pins I used either.
If you think the baud rate is slightly off, you might play around with the numbers. I don’t have the formula in front of me right now, but I have played some n9600 on my BAP to talk to LCD. I believe this translated to the number 208. (some number/baud rate). You can then try numbers like 207 or 209 to fine tune… Just a thought
Kurt
I’m thinking the baud rate is off. Ill have to try your suggestion today after work. Only guestion is do I send the raw number? or do I need to convert this number to hex?
Would this work? >> Serout TX\RDY, 208, [serial dada]