Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Experiment with i2c Multibus and SSD1306 OLED

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
Insanity

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Sun Apr 25, 2021 9:14 am    Post subject: Experiment with i2c Multibus and SSD1306 OLED Reply with quote

Hello,
I'm not getting any further at the moment.
I am trying to operate several OLEDs on an Atmega 328p.
It works individually with the normal i2c declaration.
Individually with i2c Multibus, no reaction from the display.

The normal declaration with Config SDA = always works, but only one bus.
But I need 3 buses.
and the declaration with
Config I2cbus = 0, Scl = PortD.6, Sda = PortD.5
i2cbus = 0
it does not work.
The program always remains
Config Graphlcd = Custom, Cols = 128, Rows = 64, Lcdname = "SSD1306"
hang.

' Insanity
' Versuch mit i2c Multibus und OLED

$Regfile="M328pdef.dat"
$Crystal=8000000
$hwstack=64
$swstack=64
$framesize=64

'Display Config
$lib "glcdSSD1306-I2C.lib"
Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
Config I2CDelay = 5

Config I2cbus = 5 , Scl = PortD.6 , Sda = Portd.5
i2cbus=5

'Config Scl=PORTD.6
'Config Sda=PORTD.5

I2cInit
waitms 60

cls
Setfont My6_8
Lcdat 1 , 1 , "Test 1"
Lcdat 2 , 1 , "Test 2"
Lcdat 3 , 1 , "Test 3"
Lcdat 4 , 1 , "Test 4"
Lcdat 5 , 1 , "Test 5"
Lcdat 6 , 1 , "Test 6"
Lcdat 7 , 1 , "Test 7"
Lcdat 8 , 1 , "Test 8"

Do
Loop
End
$include "My6_8.font"


Is there a solution for the problem?

(BASCOM-AVR version : 2.0.8.3 )
Back to top
View user's profile
enniom

Bascom Member



Joined: 20 Oct 2009
Posts: 490

PostPosted: Sun Apr 25, 2021 5:05 pm    Post subject: Reply with quote

I2C address or CS (chip select)?

E
Back to top
View user's profile
Insanity

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Mon Apr 26, 2021 7:03 am    Post subject: Reply with quote

I do not understand your question
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 8:36 am    Post subject: Reply with quote

with i2c a device often can have multiple addresses. in that case you can use one bus and use different addresses to address the device.
but in case of an lcd it often has a fixed address. so one solution is to use the multibus option.

but there is also to point of the driver. in this case there is no provision to use it multiple times.
but it is simple :

use the multibus to set up 3 buses.
for each connected device, use INITLCD when the bus is selected.
this will initialize the lcd.

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

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Mon Apr 26, 2021 10:10 am    Post subject: Reply with quote

Code:

' Insanity
' Versuch mit i2c Multibus und OLED
$Regfile="M328pdef.dat"
$Crystal=8000000
$hwstack=64
$swstack=64
$framesize=64
$baud = 9600
Config Com1 = Dummy, Synchrone = 0, Parity = None, Stopbits = 1, Databits = 8, Clockpol = 0

Print "1"

Config I2CDelay = 5
Config I2cbus = 0 , Scl = PortD.6 , Sda = Portd.5
i2cbus=0
I2cInit

Print "2"

$lib "glcdSSD1306-I2C.lib"

Print "3"

Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
'InitLCD

Print "4"

'Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
InitLCD

Print "5"

Setfont font6x8
Lcdat 1,1,"Bin durch"

Do
Loop
     
End

$include "font6x8.font"
 


This program only runs up to print "3".
As soon as Config Graphlcd = Custom, Cols = 128, Rows = 64, Lcdname = "SSD1306" or InitLCD comes it stands. It does not reach print "4".
Activating the bus without the LCD works. An i2c scanner also provides the correct address.
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 12:27 pm    Post subject: Reply with quote

the lcd lib was not written with multiple lcd in mind so it might need some changes.
your code looks good.
Also, for lcd speed is an issue so i assume that the hardware i2c is used.

i had a quick peek and the problem seems to be that the Z pointer is used by both the graphical lib and the multibus lib.
when you have a look inside the lcd lib you find and the begin:

[_GLCD]
$EXTERNAL _LPMBYTE, _GLOCATE
_Init_lcd:
_LCD_INIT:
_SET_DISPLAY:
#IF _XMEGA
rcall _XM_i2c_start ; send start to access the bus
#ELSE
call _i2c_start ; send start to access the bus
#ENDIF


this was to make the lib work for XMega. And xmega also uses Z pointer.

under the data table you find this code which is only for xmega:

#IF _XMEGA
_XM_i2c_start:
push r24
push r25
push r30
push r31
loadadr TWIC_CTRL,Z
ldi r25,1 ; TWIC
call _i2c_start
rjmp _xmi2c_exit

_XM_i2c_write:
push r24
push r25
push r30
push r31
loadadr TWIC_CTRL,Z
ldi r25,1 ; TWIC
call _i2c_write ; write data in r17
rjmp _xmi2c_exit

_xm_i2c_stop:
push r24
push r25
push r30
push r31
loadadr TWIC_CTRL,Z
ldi r25,1 ; TWIC
call _i2c_stop
; no code here !!

_xmi2c_exit:
pop r31
pop r30
pop r25
pop r24
Ret
#ENDIF

here you see that registers are saved, then function is called , and the regs are restored.
A similar construction is needed.
#IF _USE_MULTIBUS
_XMulti_i2c_start:
push r24
push r25
push r30
push r31
;;;;;; loadadr TWIC_CTRL,Z this can be removed
;;;;;;; ldi r25,1 ; TWIC this can be removed
call _i2c_start
rjmp _xmultii2c_exit

etc.
#ENDIF


and the other code :
#IF _XMEGA
rcall _XM_i2c_start ; send start to access the bus
#ELSE
call _i2c_start ; send start to access the bus
#ENDIF

would become:

#IF _XMEGA
rcall _XM_i2c_start ; send start to access the bus
#ELSEIF _USE_MULTIBUS
call _XMulti_i2c_start ; send start
#ELSE
call _i2c_start ; send start to access the bus
#ENDIF



when you add the rest in a similar way it should work.

a simpler way would be when you can alter the lcd hardware address.
that way they can be on the same bus and then the changes to the lib would be minimal.

_________________
Mark
Back to top
View user's profile Visit poster's website
O-Family

Bascom Expert



Joined: 23 May 2010
Posts: 243
Location: Japan

japan.gif
PostPosted: Mon Apr 26, 2021 2:32 pm    Post subject: Reply with quote

Since "i2c-multibus.lib" uses many registers other than the Z pointer (R30, R31), many libraries that control the LCD with I2C will not work.

This countermeasure requires an improvement to save many registers in each LCD library.

Therefore, I think it is better to save the register used by "i2c-multibus.lib".
Back to top
View user's profile Visit poster's website
Insanity

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Mon Apr 26, 2021 3:19 pm    Post subject: Reply with quote

I changed the lib as suggested.
The program remains at the config Graphlcd = Custom, Cols = 128, Rows = 64, Lcdname = "SSD1306"
Hang line.
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 3:24 pm    Post subject: Reply with quote

that is an option too. but under normal conditions there is no need for the multibus lib to save registers. the whole idea of all high level commands is that they may trash all registers.
only when you call high level statements from inside asm you get this problem.
so under normal conditions it is a waste of code.
I always prefer to change the lib that requires the save/restore.

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

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 3:37 pm    Post subject: Reply with quote

ok, well done.
there seem to be some more regs that need to be saved.
For the init procedrue this is R21

this code ;

ldi r21,26 ; 26 bytes
_lcd_init_lp:
call _lpmbyte ; get double command first byte
mov r17,r0

#IF _XMEGA
rcall _xm_i2c_write ; write
#ELSEIF _USE_MULTIBUS
PUSH R21
rcall _xMulti_i2c_write ; write
POP R21
#ELSE
call _i2c_write ; write
#ENDIF

dec r21
brne _Lcd_init_lp



would fix it. See the bold part

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

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Mon Apr 26, 2021 5:12 pm    Post subject: Reply with quote

A small success!
The display shows something.
They are just confused signs and they keep going through.
even if nothing is written.
Assembler is not my world.
Laughing
Back to top
View user's profile
albertsm

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 7:18 pm    Post subject: Reply with quote

ok, that means the init works.
i will check the rest.

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

Administrator



Joined: 09 Apr 2004
Posts: 5207
Location: Holland

blank.gif
PostPosted: Mon Apr 26, 2021 7:31 pm    Post subject: Reply with quote

ok, since the following registers are used by the i2c driver they need to be saved as well :

R20
R21
R22
R23

so when you save/restore these, it should work.

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

Bascom Member



Joined: 25 Apr 2021
Posts: 8

germany.gif
PostPosted: Mon Apr 26, 2021 9:27 pm    Post subject: Reply with quote

Mark, thank you very much.
It runs. Test with 2 displays. Super

Code:

' Insanity

' Versuch mit i2c Multibus und OLED

$Regfile="M328pdef.dat"
$Crystal=8000000
$hwstack=64
$swstack=64
$framesize=64


$baud = 9600
Config Com1 = Dummy, Synchrone = 0, Parity = None, Stopbits = 1, Databits = 8, Clockpol = 0

Const _USE_Multibus = 1

Config I2CDelay = 5
Config I2cbus = 0 , Scl = PortD.6 , Sda = Portd.5
i2cbus=0
I2cInit

Config I2cbus = 1 , Scl = PortB.1 , Sda = Portb.0
i2cbus=1
I2cInit

Waitms 100

$lib "neu_glcdSSD1306-I2C.lib"
Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
InitLCD

Setfont font6x8

i2cbus=0
Cls
i2cbus=1
Cls

Dim S as dword

Do
  incr s
  i2cbus=0
  Lcdat 4,1,s
  i2cbus=1
  Lcdat 4,1,s
Loop

End

$include "font6x8.font"
 
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
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