View previous topic :: View next topic |
Author |
Message |
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Sun Apr 25, 2021 9:14 am Post subject: Experiment with i2c Multibus and SSD1306 OLED |
|
|
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 |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Sun Apr 25, 2021 5:05 pm Post subject: |
|
|
I2C address or CS (chip select)?
E |
|
Back to top |
|
|
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Mon Apr 26, 2021 7:03 am Post subject: |
|
|
I do not understand your question |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 8:36 am Post subject: |
|
|
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 |
|
|
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Mon Apr 26, 2021 10:10 am Post subject: |
|
|
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 |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 12:27 pm Post subject: |
|
|
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 |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Mon Apr 26, 2021 2:32 pm Post subject: |
|
|
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 |
|
|
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Mon Apr 26, 2021 3:19 pm Post subject: |
|
|
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 |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 3:24 pm Post subject: |
|
|
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 |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 3:37 pm Post subject: |
|
|
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 |
|
|
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Mon Apr 26, 2021 5:12 pm Post subject: |
|
|
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.
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 7:18 pm Post subject: |
|
|
ok, that means the init works.
i will check the rest. _________________ Mark |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 26, 2021 7:31 pm Post subject: |
|
|
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 |
|
|
Insanity
Joined: 25 Apr 2021 Posts: 8
|
Posted: Mon Apr 26, 2021 9:27 pm Post subject: |
|
|
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 |
|
|
|
|
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
|
|