Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Rainbow INstruction difficulty on the XTiny 402
Goto page Previous  1, 2, 3  Next
 
Post new topic   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Sun Feb 07, 2021 10:38 am    Post subject: Reply with quote

Mark
wouldn't it be better to use the R27 register if you already have the argument there and leave the decision to the main program according to the set processor?
Wouldn't it be possible to write it like this?
Original
Code:

#IF _XMEGA=1
   LDI ZH, &H06                  ; take care that this will not work for PORTQ and PORTR
#ELSEIF _XTINY=1
   LDI ZH, &H04                  ; different port address
#ELSE                  
   CLR ZH                        ; normal AVR  
#ENDIF
   LDS Zl ,{BOW__Cur_Port}       ; io port
   LDS R18 ,{BOW__Cur_Pin}       ; io pin
   MOV R19,R18
   COM R19
   RET
 


Modified
Code:

   MOV R31,R27
   LDS Zl ,{BOW__Cur_Port}       ; io port
   LDS R18 ,{BOW__Cur_Pin}       ; io pin
   MOV R19,R18
   COM R19
   RET
 


This would avoid problems in the future with the arrival of new processors
RS
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Feb 07, 2021 2:06 pm    Post subject: Reply with quote

SZTRAD wrote:
wouldn't it be better to use the R27 register if you already have the argument there

What does drive you to the idea that the argument for the high-byte port address is in R27(XH)?
If you'd have done a short simulation, then you'd have noticed, that at time BOW_LOAD_PORT_PIN: is called first time, R27's register content is &H20 and subsequents too.
To work for your suggestion, R27 must have been &H06.

Do you understand the purpose of the conditional compilation block?
Or let me ask the other way around:
From where else in the lib-code the compiler would know, how to set the pointer Z high-byte for the following indirect access to &h04 for ATINY?

Right, there would be another way, get it from parameter BOW__CUR_PORT.
Alas this information about the pointers high address it's not derivable from the PORT parameter, which seem to be from non-XMega days a byte address, thus it can contain only the lower byte of the port address.

The author, which is not Mark btw., had to help himself with the conditional compilation block.
Only XTINY was missing, as in 2015 Bascom did not provide support for XTinys then, for the reason maybe, that they were not in production these days.


Last edited by MWS on Sun Feb 07, 2021 2:24 pm; edited 1 time in total
Back to top
View user's profile
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Sun Feb 07, 2021 2:23 pm    Post subject: Reply with quote

Try it for all rows of processors and you will see that it will work. I understand why the driver is written as it is. I'm just saying how to do it automatically.
This is nothing against the original solver of the controller. I am based on the operation of config rainbow settings and its writing in flash memory.
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Feb 07, 2021 2:32 pm    Post subject: Reply with quote

SZTRAD wrote:
Try it for all rows of processors and you will see that it will work.

I've added to my earlier post while you replied. Find there the proof why your suggestion won't work.
If you've in contrary still the same belief, then quote in detail why you think R27 contains the PORT's high address byte.

You'd need to explain this:
Quote:
I am based on the operation of config rainbow settings and its writing in flash memory.

It is only to guess, but not to understand what you want to say.
Back to top
View user's profile
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Sun Feb 07, 2021 2:54 pm    Post subject: Reply with quote

When translating, Mark stores the upper part of the address in the R27 register (note the last line). According to the simulator, the config routine is called before each entry into the library, so formally there is nothing to stop you from using it. Or am I wrong? I'm an old man and I can knit.

Code:

ATmega
  LPM R0,Z+             Load program memory and postincrement
  STS 0x0105,R0         Store direct to data space
  MOV R26,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x0106,R0         Store direct to data space
  MOV R16,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x0107,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x0108,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x0109,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x010A,R0         Store direct to data space
  CLR R27               Clear Register

ATxmega
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2032,R0         Store direct to data space
  MOV R26,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2033,R0         Store direct to data space
  MOV R16,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2034,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2035,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2036,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x2037,R0         Store direct to data space
  LDI R27,0x06          Load immediate

Xtiny
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F15,R0         Store direct to data space
  MOV R26,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F16,R0         Store direct to data space
  MOV R16,R0            Copy register
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F17,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F18,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F19,R0         Store direct to data space
  LPM R0,Z+             Load program memory and postincrement
  STS 0x3F1A,R0         Store direct to data space
  LDI R27,0x04          Load immediate


RS


Last edited by SZTRAD on Sun Feb 07, 2021 3:07 pm; edited 1 time in total
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sun Feb 07, 2021 2:58 pm    Post subject: Reply with quote

I did not wrote the original lib, it was made my Galahat from the German bascom forum.
I did however made a variant based on his work which is integrated with bascom.
I also added a variant for the rgb leds with an additional white led.

I understand what you mean : when the code is called, the registers can be set. But it saves code to do it this way.
And like MWS mentioned : when this lib was there there was no support for xmega and xtiny did not even exist.
So xmega was added with a directive.
I understand your point. when checking mega X/DA/DB i will check if the ports have yet another offset. And see if it makes sense.
Also some normal AVR ports have high IO address and there the code will fail too. So it makes sense to move that part of the code from the lib to the caller code in the compiler.

_________________
Mark
Back to top
View user's profile Visit poster's website
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Sun Feb 07, 2021 3:03 pm    Post subject: Reply with quote

OK
The new series currently uses addresses identical to xtiny
RS
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Sun Feb 07, 2021 3:52 pm    Post subject: Reply with quote

In the caller code rb init procedure XH is set. But this register is later used and trashed so it can not be used.
And this init code is only done once.
of course there are many alternatives. like using an extra byte to store this info. but that would take more flash.
and sram could be used to store such info but that is a waste of memory imo.
i had a look but i think the effort required is not worth it. after all it takes new testing for all platforms with hardware. the only benefit would be to support ports of normal avr on an extended address.

when using 1 port it would be simpler but some use multiple ports with multiple pins. i have seen projects with many leds. btw the channels were increased to 16. i see the help did not reflect this.

_________________
Mark
Back to top
View user's profile Visit poster's website
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Feb 07, 2021 6:29 pm    Post subject: Reply with quote

A bit more universal port addressing.
Already some EQUs in the lib, let these follow:
Code:
#IF VarExist("PORTA")
* .equ BASE_PORT_ADDR_H = VARPTR("PORTA") / 256
#ELSEIF VarExist("PORTB")
* .equ BASE_PORT_ADDR_H = VARPTR("PORTB") / 256
#ELSEIF VarExist("PORTC")
* .equ BASE_PORT_ADDR_H = VARPTR("PORTC") / 256
#ELSE
  .equ BASE_PORT_ADDR_H = 0
#ENDIF
 

Exchange lib-function BOW_LOAD_PORT_PIN with:
Code:
BOW_LOAD_PORT_PIN:
   LDS Zl ,{BOW__Cur_Port}       ; io port
*  LDI ZH , BASE_PORT_ADDR_H     ; load high byte of port base address into ZH
   LDS R18 ,{BOW__Cur_Pin}       ; io pin
   MOV R19,R18
   COM R19
RET
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Feb 07, 2021 7:06 pm    Post subject: Reply with quote

SZTRAD wrote:
so formally there is nothing to stop you from using it.

Formally there's nothing, actually a lot.
As R27/XH is a pointer, it is one of the mainly used register, in this case already void after config returns.
This info needs to be at hand the very moment the lib requires it, to have it at config time and trash it after won't help.
Back to top
View user's profile
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Sun Feb 07, 2021 9:05 pm    Post subject: Reply with quote

MWS do you really think I don't know this?
Thank you for the MWS alert, but Mark's compiler works as it should. This means that it performs initialization again before each call to lib because it works with RAM.
If I hadn't tried it, I wouldn't have asked.
I asked I got an answer. I don't like when something has to change in libraries. It is terribly bad to look for mistakes when the interviewer has a different library than me.
For Mark.
you don't have to change anything, the information is already stored in flash memory.
That listing is made from the real contents of the memory using a paper compiler.
As I wrote above, I have already received an answer.
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Sun Feb 07, 2021 10:15 pm    Post subject: Reply with quote

SZTRAD wrote:
MWS do you really think I don't know this?

You do exactly sound this way. I have the impression, that you love to jump into threads providing all sorts of distraction.
At least you do better work of playing the armchair quarterback, after others solved the problem. Very Happy
Quote:
Thank you for the MWS alert, but Mark's compiler works as it should.

I did not tell it wouldn't.
Quote:
This means that it performs initialization again before each call to lib because it works with RAM.

Again utter nonsense. The config-/init-code is executed as soon config-settings are changed, for example by rb_selectchannel(), rb_changepin().

Do a simulation and find out yourself, use rainbow_ws2812_Demo.bas, out-comment rb_changepin, set a breakpoint to config rainbow and let run.
It will stop two times, the first at config itself and second time as rb_selectchannel is called. All other commands within Do/Loop do not trigger any config/init.

So you can learn that commands, which do not change the configuration, of course call also lib functions, which is the sense of a lib, but do not call config-/init-code.
This is the proper way, as otherwise cycles would be wasted within unnecessary configs/inits.
Quote:
before each call to lib because it works with RAM.

If SRam is only read but not written, its value can be read without change indefinitely until power loss.
Slowly, but surly I feel to waste my time by answering your unfounded posts, maybe try to increase your level of understanding at least a little bit, before trying again.
Quote:
If I hadn't tried it, I wouldn't have asked.

If you would have finished with trying, you would have found the reason.
Quote:
I don't like when something has to change in libraries. It is terribly bad to look for mistakes when the interviewer has a different library than me.

Btw., it is common use and good practice to alter software, including libraries, otherwise also this problem would stay unsolved.
It is further good practice to inform the maker or maintainer of the software about changes made.
Back to top
View user's profile
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Mon Feb 08, 2021 9:59 am    Post subject: Reply with quote

You use sharp words. Be very careful of the word nonsense.
I approached your game, although I don't like it either. Once decided, one does not intend to accept another person's opinion (based on trial). You're wrong, but I'm not going to convince you.
I'll take the original JC software. I'll use a modified library from Mark.
Load the resulting .hex code into AtmelStudio 7. Start the simulation.
According to you, the loading block should be executed 1. Hmm and it will be executed 11 times. What can it be? This is because the compiler assumes that the contents of IRAMs and constants can be overwritten. Therefore, it performs a data recovery before each lib call. This is how all compilers work by reloading the constants stored in the program. And it's the right function.
I tried again. That would end it, I don't mean to convince you of something you think works differently.

Code:
 $crystal = 10000000            '10.0 MHz, Internal RC Osc


   $regfile = "m328pdef.dat"                                'Micro being used


   $hwstack = 64                                            'Hardware Stack
   $swstack = 64                                            'Software Stack
   $framesize = 64                                          'Frame Space

   $lib "RAINBOWBSCN_n.lib"                                   'Force new Rainbow LED Library


   Config Portb.0 = Output                                  'PCB LED
   Config Portb.1 = Output                                  'Dig LED string


   Dim Color(3) as Byte                                     'Color array for digital leds
   dim i as byte
   dim m as byte

'===============================================================================

   Config Rainbow = 1 , RGB = 3 , RB0_LEN = 2 , RB0_Port = Portb , RB0_Pin = 1




    m=0
   Do
   for i=0 to 10 step 1
     Gosub DigLEDTest1
    m=m+1
   next i

   wait 100

   Loop                          'Forever

'+++++++++++++++++++++++++++++++++++++++++++++
DigLEDTest1:
   'Turn On All (Two) LEDs, Low Intensity Blue
   'Select the Active string of digital LEDs
   RB_SelectChannel 0                 'Channel #0
   Gosub LEDColor4                     'Low intensity Blue
   RB_FILL color(1)                    'Turn on ALL Leds in strip
   Return



LEDColor4:
   'This sets up the data for the digital LEDs
   'Color #4 = Low Intensity Blue
   Color(1) = 0                                             'Red
   Color(2) = 0                                             'Green
   Color(3) = 10                                            'Blue
   Return
 


Block loading from Flash memory .Stopping and manual start performed at address 78
Code:

00000064  LPM R0,Z+             Load program memory and postincrement
00000065  STS 0x0105,R0         Store direct to data space
00000067  MOV R26,R0            Copy register
00000068  LPM R0,Z+             Load program memory and postincrement
00000069  STS 0x0106,R0         Store direct to data space
0000006B  MOV R16,R0            Copy register
0000006C  LPM R0,Z+             Load program memory and postincrement
0000006D  STS 0x0107,R0         Store direct to data space
0000006F  LPM R0,Z+             Load program memory and postincrement
00000070  STS 0x0108,R0         Store direct to data space
00000072  LPM R0,Z+             Load program memory and postincrement
00000073  STS 0x0109,R0         Store direct to data space
00000075  LPM R0,Z+             Load program memory and postincrement
00000076  STS 0x010A,R0         Store direct to data space
00000078  CLR R27               Clear Register


If you want the whole decompiled program, say so .
The possibility that the manufacturer of the AS7 software does not know how the decompiler and simulator works will probably not be probable.
This would close this useless and offensive conversation for me.
RS
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5921
Location: Holland

blank.gif
PostPosted: Mon Feb 08, 2021 11:02 am    Post subject: Reply with quote

I am a bit confused about the whole discussion.
But here are the facts :
- BOW_LOAD_PORT_PIN is called from RB_SEND, RB_CLEARStripe,RB_FILLStripe
- BOW_LOAD_PORT_PIN need to set the Z pointer to the port address.
- the compiler does not store word address for the port but a single byte. that because the code originated from the normal AVR decade with ports on a normal IO address
- this makes it required to set the MSB of the port address to the right value. which was always 0. But for xmega it is 6 and xtiny it is 4.
- as part of the config rainbow there is a table created with the port and pin info. it also contains code to set the used ports to the right state. and it contains code RB_PININIT which is called from RB_Change_pin. this code also takes into account the platform thus loads R27 with the proper value.

now we could store this R27 into an additional byte from SRAM. and use that in BOW_LOAD_PIN.
But the conditional code that sets the port with LDI works equal well and does not take sram.

The X register is trashed by many code. so we can not rely on that.
IMO the only way to do it is to use sram. either i do not understand the original problem, discussion, or ?
But when someone see a possibility to make it simpler and to move the code out of the lib without using sram, let me know with a sample.
I must admit that it is long time ago i worked on this lib and i might overlook something.

the code should however work with code like this :
do
rbsend
waitms 100
r26=0 'simulate other user code that destroy X pointer
r27=0
loop

_________________
Mark
Back to top
View user's profile Visit poster's website
SZTRAD

Bascom Member



Joined: 30 Dec 2019
Posts: 165

blank.gif
PostPosted: Mon Feb 08, 2021 12:17 pm    Post subject: Reply with quote

Mark
I understand your attitude and your words. Can I post all the decompiled code here and show you what's going on? I don't like doing this, this doesn't belong in the discussion. The method of translation is your property and the layout of the resulting code is too.
I hate it when someone makes me an ox
You refresh the loading of constants before each entry into the library code. For atmega you negate the MSB port in R27, for xmega you save in R27 06h, for xtinny analogously 04h.
I asked if you could use anything more. I take the argument that you still have a problem for the above reasons. Nothing against it. But it is a simple fact that the part of the codes I gave in the previous post is always run. Coincidentally, R27 is not used in the library, but port constants are only called once in the library. It was an idea after examining the resulting code, and I see no reason for the invectives.
Back to top
View user's profile
Display posts from previous:   
Post new topic   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum