This sub is for a ST7735 LCD and (I believe) the original code was created by HIPNIK.
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
↧
BASCOM-AVR : lcd dispaly box with HX8357 : NEWTOPIC
Hello,
in the hx8357_function.inc file I have :
[color=green:06695489f5]'*******************************************************************************
' Draw Box x start -- y start -- xend -- yend -- 1=fill 2=fill with Border 3=no fill -- color -- bordercolor
'*******************************************************************************
Sub Lcd_box(byval Xstart As Word , Byval Ystart As Word , Byval Xend As Word , Byval Yend As Word , Byval Fill As Byte , Byval Color As Word , Byval Bordercolor As Word)[/color:06695489f5]
I try :
lcd_box(135,50 ,165 ,70 ,2 ,white, black)
and I have a error
Error : 130 Line : 246 Incorrect number of parameters. The number of parameters must be [ 7]
where is my error ?
:cry:
thanks for your help
JP
[b:06695489f5][color=red:06695489f5](BASCOM-AVR version : 2.0.8.0 , Latest : 2.0.7.8 )[/b:06695489f5][/color:06695489f5]
↧
↧
BASCOM-AVR : lcd dispaly box with HX8357 : REPLY
From the Help:
[quote:10925c5ae4]The call statement enables you to implement your own statements.
When you don't supply the CALL statement, [b:10925c5ae4]you must leave out the parenthesis[/b:10925c5ae4].
[/quote:10925c5ae4]
Heheh :D Write "Call" before and code will compile withoutany error.
Have a nice day.
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
[quote:84d260cebe="enniom"]I think the FOR-NEXT loop for Carcount is all that is needed.[/quote:84d260cebe]
That's more than enough, as it's the very core of the sub and thus 99 percent of the work.
First I do not understand, why every argument of this sub is declared ByVal, thus requiring the compiler to create copies of the values and put them on the software stack.
It would make sense, if the original variables are altered within an interrupt and creating copies should assure data integrity somehow.
Otherwise there's no need of local ByVal copies, because the arguments are not altered within the sub.
Creating copies costs some cycles and SRam.
A rule of thumb: Avoid to mix Bascom commands and assembler within a certain block.
The block can be as small as a few opcodes, as the For/Next loop, and if I would do it, the block would consist out of the complete sub. The reason for that is: As more complex the assembler part is, the more it will be disturbed by thrown in Bascom functions.
Programming assembler efficiently requires to hold work-vars within the processor registers, the compiler however does not care which registers you use for your assembler code, and thus may destroy your register values by executing a Bascom function. This means you have to save either the whole bunch of used processor registers, or only those which a certain Bascom function uses, before calling a Bascom function.
Another issue is to forward values within registers to Bascom functions, in case some a is available from a lib, you can check what arguments it requires and call the appropriate label then. If the function is integrated and not available, you need to create an interface by exchanging the values via SRam variables, which is a rather bulky method.
Thus it is sometimes easier to do the required Bascom functions yourself, for example you need to output data via SPI.
In this case it is easy, as more as only one byte is sent out at a time.
Simply write the data to SPDR and wait for transmission complete, which is signaled by SPIF = 1.
As you want to program more efficiently, and assumed the Sub is the only code writing to SPI, I would do the check for SPIF beforehand, as this would allow for SPI-sending whilst other code can be executed, instead looping in a wait. You need to clear SPIF after writing to SPDR and you need to do a dummy SPI-write to set SPIF, otherwise the code gets stuck.
One more hint: arguments of the sub are indexed by the Y-pointer, which is register r28 and r29, displacements by steps of +2 will get you to the single arguments, the rightmost argument is Y+1/Y+0, to the left the mentioned displacement applies.
YL/YH represents a 16-bit address, which points to the memory start-address of an argument, which have their home either in the data area, if arguments are declared ByRef, or in SW-stack, if declared ByVal.
Think I posted some code sometime, where the method of getting the arguments is shown.
Beside all said, to translate this sub into assembler is a heavy weight for somebody unused to it. Some previously done assembler exercises would help.
Well, you can learn from it and you can always ask if you get stuck.
↧
BASCOM-AVR : RS232 between two AVRs using printbin/inputbin : NEWTOPIC
Hello,
I have a problem with sending 4 digit (0-9999) number.
[b:653f4e88e2]My transmitter:[/b:653f4e88e2]
[code:1:653f4e88e2]$regfile ="m16def.dat"
$crystal=7372800
$baud = 140
Dim S1 As long
Dim S2 As long
Do
S1=1
S2=9999
printbin S1
printbin S2
wait 1
loop[/code:1:653f4e88e2]
[b:653f4e88e2]My receiver:[/b:653f4e88e2]
[code:1:653f4e88e2]$regfile ="m16def.dat"
$crystal=7372800
$baud = 140
Dim S1 As Long
Dim S2 As long
Config lcd = 20*4
Config lcdpin =pin ,rs=portb.2,e= portb.3,db4= portb.4 , db5=portb.5, db6=portb.6, db7=portb.7
Cls
cursor off
Do
inputbin S1
inputbin S2
Locate 1 , 1
Lcd "Input Value: "
Locate 2 , 2
Lcd "= " ;S1 ;
Locate 3 , 2
Lcd "= " ;S2 ;
wait 1
Loop[/code:1:653f4e88e2]
I get number but for example if I send value 1 I get something like -25741699 on the other side.
Also if I send 2 different numbers they are switching which one is S1 and which is S2.
What am I missing here?
Thanks for any help.
[b:653f4e88e2][color=red:653f4e88e2](BASCOM-AVR version : 2.0.7.8 )[/b:653f4e88e2][/color:653f4e88e2]
↧
↧
BASCOM-AVR : lcd dispaly box with HX8357 : REPLY
I think I'm Mad !
I wrote Call for all sub , but i forgot this one ... and the error was not explicit. but I have some friends here !
Many thanks !
JP
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Thank you MWS for taking the time to help. Your thorough reply seems as if it could be Chapter 1 of a book about programming.
I have one follow up question: Is there a portion of the code which could be converted and would achieve the most speed improvement? Or, will this benefit be offset by violating the rule about mixing Bascom commands with assembler?
E
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
[quote:a1aca885c5="enniom"]Is there a portion of the code which could be converted and would achieve the most speed improvement?
May be the FOR-NEXT loop for Pixelcount?[/quote:a1aca885c5]
No, only the loop (as outer frame) is not time consuming, it's what's inside the loop.
Afair this is costly in terms of cycles:
[code:1:a1aca885c5]Pixel = Pixels.pixelcount[/code:1:a1aca885c5]
One would not do it this way, instead in assembler one would write [b:a1aca885c5]Pixels AND 1[/b:a1aca885c5] and set Pixel based on the result. After Pixels gets shifted one time right.
Every cycle counts in a often called code fragment.
Some more cycles may be gained by differently implementing SPI.
As said, after each byte shifted out, SPIF (or its XMega-equivalent) will wait for some time.
It has to wait for one byte:
[code:1:a1aca885c5]8 bits * Clockdiv = Clk2[/code:1:a1aca885c5]
which are 16 cycles.
Now assume that from execution (after the data was completely transmitted) of the first SPI-command till setup and start (writing SPDR or its counterpart) of the second SPI-command
[code:1:a1aca885c5]Spiout Spi_seq(1) , 1
Lcd_dc = 1
Spiout Spi_seq(4) , 1[/code:1:a1aca885c5]
there will be 30 cycles.
Alone these 30 cycles would be enough, allowing the data byte to get completely transmitted before the next byte is pushed into SPI's data register.
Of course also Lcd_dc must be set the way to have enough time to let SPI bang the byte out.
With [b:a1aca885c5]SPIOUT [/b:a1aca885c5] it will wait 16 cycles till data got out and then another 30 cycles till next start.
Have to confirm, I did not check the actual XMega-code, as it did not compile, but an average controller's datasheet gives as example:
[code:1:a1aca885c5]SPI_MasterTransmit:
; Start transmission of data (r16)
out SPDR,r16
Wait_Transmit:
; Wait for transmission complete
in r16, SPSR
sbrsr16, SPIF
rjmp Wait_Transmit
ret[/code:1:a1aca885c5]
[b:a1aca885c5]TBC[/b:a1aca885c5]
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Continued here, the forum's software did not like the extent of my post...
The effect: Cycles are wasted here, SPI runs not as fast as it can.
Well, there would be another issue, if the display can not follow this up-speeded data stream.
This means checking successful transmit immediately before pushing new data into SPI may save some cycles.
How many I can not tell, as your code throws out a bunch of errors, if I remove [b:1be78d7735]Config Submode = New[/b:1be78d7735]
Keeping it, the shown code and its Sub is simply not compiled, as it's never called and left out that way.
[quote:1be78d7735]Or, will this benefit be offset by violating the rule about mixing Bascom commands with assembler?[/quote:1be78d7735]
If you get it done to transform this inner loop into assembler, without having a register-reload-orgy at start of this block, you will achieve some gain.
To transform also the outer loop is a piece of cake then.
↧
↧
BASCOM-AVR : RS232 between two AVRs using printbin/inputbin : REPLY
If your receiver Wait 1 seconds then can lost incomming data.
Try use buffered receiving.
[code:1:56dece8a8a]$regfile ="m16def.dat"
$crystal=7372800
$hwstack = 32
$swstack = 16
$framesize = 64
$baud = 140
Config Serialin = Buffered , Size = 20
Dim S1 As Long
Dim S2 As long
Config lcd = 20*4
Config lcdpin =pin ,rs=portb.2,e= portb.3,db4= portb.4 , db5=portb.5, db6=portb.6, db7=portb.7
Cursor Off , Noblink
Cls
Enable Interrupts 'needed for buffered serial receiving
Do
If 0 < Ischarwaiting() Then 'only if some data waiting for read
Inputbin S1
Inputbin S2
Locate 1 , 1
Lcd "Input Value: "
Locate 2 , 2
Lcd "= " ;S1 ;
Locate 3 , 2
Lcd "= " ; S2 ;
End If
Loop[/code:1:56dece8a8a]
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Hi MWS. Yes, I had the same problem with the length of my original post. I had to split it in two. It seems only a certain length may be allowed.
[quote:b0295f3571]there would be another issue, if the display can not follow this up-speeded data stream.[/quote:b0295f3571]
I can confirm that the LCD responds OK with the XMEGA clock rate of 48Mz. I dont yet know how much faster we can go this routine. [BTW: my final goal is to run the XMEGA clock at the lowest possible to minimize power consumption while having the fastest LCD response possible. Based on UART Baud Rate Error, it seems the best clock rate will be 22MHz. At this clock rate, with the current sub, the LCD refresh now seems sluggish.]
I looked through the MMC-XMEGA.LIB file in the MCS folder. It seems the code might be like:
[code:1:b0295f3571]
Lcd_cs = 0
Lcd_dc = 0
!Ldi R16, xxx ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
_byte2spi2:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp _byte2spi2
!Lds R16 , SPIC_DATA
;do this for each of the 7 bytes to be shifted out of SPIC
[/code:1:b0295f3571]
Does this seem right?
E
[/quote]
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Yes, looks similar, with the difference it's not only banging bits out, but also reading them in.
SBRS skips the immediately following opcode (the relative jump), if the designated bit (7) within the processor register (and thus SPIC_STATUS) is set.
↧
BASCOM-AVR : atmega1284p : NEWTOPIC
Hi All,
unsure if i'm asking in the right place.
Can anyone help me figure out how i can check, how much time is spent in the service routine of my code. everything works but i don't know how long a service routine is too long. i know the service routine is run every 16ms but i don't know how long it takes the processor to get through it.
[b:9e0cdfc400][color=red:9e0cdfc400](BASCOM-AVR version : 2.0.7.8 )[/b:9e0cdfc400][/color:9e0cdfc400]
↧
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
THANK-YOU MWS.
While I have not yet measured this timing directly, I can confirm that this code is visually MUCH better.
[code:1:05df53f68e] For Pixelcount = 0 To 7 'Loop for 8 pixels to be set or not
Ypos = A + Pixelcount 'Each pixel on his own spot
' Pixel = Pixels.pixelcount 'Set the pixel (or not)
If Pixels.pixelcount = 1 Then Pixel = Forecolor Else Pixel = Backcolor
!push r16
Lcd_cs = 0
Lcd_dc = 0
!Lds R16, {spi_seq(1)} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi1:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi1
' Spiout Spi_seq(1) , 1
Lcd_dc = 1
!Lds R16, {spi_seq(4)} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi2:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi2
' Spiout Spi_seq(4) , 1
!Lds R16, {xpos} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi3:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi3
' Spiout Xpos , 1
Lcd_dc = 0
!Lds R16, {spi_seq(2)} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi4:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi4
' Spiout Spi_seq(2) , 1
Lcd_dc = 1
!Lds R16, {spi_seq(4)} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi5:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi5
' Spiout Spi_seq(4) , 1
!Lds R16, {ypos} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi6:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi6
' Spiout Ypos , 1
Lcd_dc = 0
!Lds R16, {spi_seq(3)} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi7:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi7
' Spiout Spi_seq(3) , 1
Lcd_dc = 1
!Lds R16, {colh} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi8:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi8
' Spiout Colh , 1
!Lds R16, {coll} ; here xxx is the necessary numeric value
!Sts SPIC_DATA, R16 ; SPIC data register
Jspi9:
!Lds R16,SPIC_STATUS ; get status
!Sbrs R16,7 ; skip if it is set
!rjmp jspi9
' Spiout Coll , 1
Lcd_cs = 1
!pop r16
Next Pixelcount
[/code:1:05df53f68e]
I decided to leave the code "unfolded" to save time for repeated Call/Return/Push/Pop calls.
E
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Since the above turned out to have a fairly simple solution, I was wondering if some speed gains can be made here.
[code:1:6227ab8d2a]$regfile = "xm192a3udef.dat"
$hwstack = 255
$swstack = 255
$framesize = 255
Osc_dfllctrl.0 = 1
Dfllrc32m_ctrl.0 = 1 'enable CALIBRATION
$crystal = 22000000
Config Osc = Enabled , 32mhzosc = Disabled
Osc_pllctrl = &B00_0_01011
Set Osc_ctrl.4 ' PLL enable
Bitwait Osc_status.4 , Set 'Check if PLL is ready
Config Sysclock = Pll , Prescalea = 1 , Prescalebc = 1_1 ' configure the systemclock ---> use PLL
Waitms 2
Config Serialout2 = Buffered , Size = 254
Config Com3 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "COM3:" For Binary As #1
Dim Payload(9) As Byte , I As Byte
Payload(1) = &HE0
Payload(2) = &HA1
Payload(3) = &HA2
Payload(4) = &HA3
Payload(5) = &HA4
Payload(6) = &HA5
Payload(7) = &HA6
Payload(8) = &HA7
Do
Payload(9) = 0
For I = 1 To 8
Print #1 , Chr(payload(i)) ; '<================
Payload(9) = Payload(9) Xor Payload(i) '<================
Next
Print #1 , Chr(payload(9)) ; '<================
Loop
End[/code:1:6227ab8d2a]
Is it possible to speed up the PRINT #2, ... and Payload(9) = Payload(9) XOR Payload(I) commands within the main loop? Because a buffered UART is used, I was hoping to write the Payload to the buffer then continue to do other things.
Is there a faster way to PRINT and XOR by using assembler?
Thanks again for your help.
E
↧
BASCOM-AVR : Help convert Basic to assembler : REPLY
Print is a more complex routine, if you want to write directly to the buffer, you have to imitate/rebuild it's functionality somehow.
Is this block really this time consuming, means is the output from the UART stuttering or a constant stream?
In case you bang more data into the print routine, than it can get rid of, the buffer runs full and you get the classic and blocking Print.
Which makes sense, as otherwise data would be lost.
If your complete main loop takes less than about 17200 cycles, you will run into this situation.
↧
BASCOM-AVR : RS232 between two AVRs using printbin/inputbin : REPLY
[quote:c2df0f37e5="EDC"]If your receiver Wait 1 second then can lost incomming data.
Try use buffered receiving.
[/quote:c2df0f37e5]
Thanks for your help,
I still get some weird long number and numbers are changing even if I am sending static "1" and static "9999" at the moment. Is there any problem with decoding when receiving values? Instead of getting value 1 I still get -215878456 for example. But the number is changing.
↧
↧
BASCOM-AVR : RS232 between two AVRs using printbin/inputbin : REPLY
This should work better :D
[code:1:8910ed1d87]$regfile ="m16def.dat"
$crystal=7372800
$hwstack = 32
$swstack = 16
$framesize = 64
$baud = 140
Dim Array(9) As Byte
Dim S1 As Long At Array(1) Overlay
Dim S2 As Long At Array(5) Overlay
Do
S1 = 1
S2 = 9999
Array(9) = Crc8(array(1) , 8)
Printbin Array(1) 'whole array will be sent
Wait 1
loop
[/code:1:8910ed1d87]
[code:1:8910ed1d87]$regfile ="m16def.dat"
$crystal=7372800
$hwstack = 32
$swstack = 16
$framesize = 64
$baud = 140
Config Serialin = Buffered , Size = 20
Dim S1 As Long
Dim S2 As long
Dim Array(9) As Byte
Dim Long1 As Long At Array(1) Overlay
Dim Long2 As Long At Array(5) Overlay
Dim Count As Byte , Timeout As Byte
Config lcd = 20*4
Config lcdpin =pin ,rs=portb.2,e= portb.3,db4= portb.4 , db5=portb.5, db6=portb.6, db7=portb.7
Cursor Off , Noblink
Cls
Enable Interrupts 'needed for buffered serial receiving
Lcd "Waiting.."
Count = 1
Do
If 0 < Ischarwaiting() Then 'only if some data waiting for read
Inputbin Array(count) , 1 'input only one byte cause transmission is slow
Timeout = 100 'set timeout for next byte
If Count < 9 Then
Incr Count
Else 'if we receive 9 bytes they will be tested
Cls
If Crc8(array(1) , 8) = Array(9) Then 'only if CRC match variables will be copied
S1 = Long1
S2 = Long2
Locate 1 , 1 : Lcd "Input Value: "
Locate 2 , 2 : Lcd "= " ; S1
Locate 3 , 2 : Lcd "= " ; S2
Else
Lcd "CRC problem"
End If
Count = 1
End If
End If
Waitms 1
'this will set array pointer to start if not whole array arrive on time
If Timeout > 0 Then
Decr Timeout
Else
Count = 1
End If
Loop[/code:1:8910ed1d87]
↧
BASCOM-AVR : RS232 between two AVRs using printbin/inputbin : REPLY
Yes EDC is right
-use an array is a good solution
I send one char-of-start and one char of end-of-start
to send
Print Chr(254); 'a high number chr to start
For Jbyte = 0 To 8
Print Chr(tabdate(jbyte));
Next
Print Chr(255);
to receive
Open "com3:" For Binary As #1
Do
If Ischarwaiting(#1) = 1 Then
Jbyte = Waitkey(#1)
If Jbyte = 254 Then
Serialflag = 1
End If
If Serialflag = 1 Then
If Jbyte = 255 Then
Clear Serialin3
Close #1
Exit Do
End If
Tabdate(kbyte) = Jbyte
Kbyte = Kbyte + 1
End If
End If
Loop
jp :wink:
↧
BASCOM-AVR : atmega1284p : REPLY
Easy way is to use simulator.
Watch video I record specially for this occasion :D
[url=https://youtu.be/8BSwydhArkQ]LINK TO VIDEO[/url]
Code used in video
[code:1:bcaf5a3cc7]
$regfile = "m1284pdef.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 32
$framesize = 128
$sim
Enable Int0 : On Int0 Int0_isr
Enable Interrupts
Dim Helpb As Byte , N As Byte
Do
'1. Lean cursor here and RightClick->Run to
!nop
'2. Now go to Interrupts Tab and set ISR flag
' You can watch that flag is set
'3 --- CLEAR CYCLES COUNTER AT THE BOTTOM ---
'4. Now lean cursor here nad RightClick->Run to
!nop ' '
Loop
Int0_isr:
'If ISR flag is set processor must jump here between this two NOP`s
For N = 1 To 255
Incr Helpb
Next
Return
[/code:1:bcaf5a3cc7]
↧