News:

Let's find out together what makes a PIC Tick!

Main Menu

I2COut does it really need 'Control?

Started by Ecoli-557, Mar 14, 2025, 07:54 PM

Previous topic - Next topic

Pepe

This is what is on the data sheet

Ecoli-557

Yes, Pepe.  I have read that many times.  I have even tried adding a high-order 8-bit to determine WR or RD.  No help.
I feel that the same 0x4D and 0x00 over and over is telling me something, but I just can't see what.
Also, why isn't I2COut sending 24 bits?
In my Procedure, I state the size of the variables - so, it should send 24 bits, right??
'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
     low CODEC_CS
     I2Cout SDA_Pin, SCL_Pin, 0x9A, [CODECReg, I2OutData]
     high CODEC_CS
EndProc

Pepe

I think that the $1a has to be moved 1 bit to the left and do or with 1 if it is writing and with 0 it is reading then it would be $34 to read and $35 to write

Ecoli-557

I am slightly more ahead.    Some packets are 24 bit, and some are 16 bit???  New Analyzer image:
I2C to CODEC-2.PNG

Pepe

This is what is in a bookcase in C

#define WM8940_I2C_ADDRESS (0x1A << 1)

#define WM8940_REG_WRITE(handle, reg, val) MyI2C_Write(handle, WM8940_I2C_ADDRESS, reg, val)
#define WM8940_REG_READ(handle, reg) MyI2C_Read(handle, WM8940_I2C_ADDRESS, reg)


Ecoli-557

I will try that in a bit.
Thank you for your wanting to help and for your help.
I will muddle on as I am certain you have more important things to take care of.
I will post what happens from the bit shift experiment.
Regards,
Steve

Ecoli-557

Pepe-
Still no joy at all, nutz.
May push away for a bit, maybe get some dinner..... and perhaps an Adult Beverage?
Here is what I used:
'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
     low CODEC_CS
     I2Cout SDA_Pin, SCL_Pin, (0x1A<<1), [CODECReg, I2OutData]
'      I2Cout SDA_Pin, SCL_Pin,0x90, [CODECReg, I2OutData]
high CODEC_CS
EndProc

And this is what I send to the 8940:
I2C to CODEC-3.PNG

Pepe

to write is ($1a<<1)+1 which is $35
To read is $34

Pepe

#28

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 18F67K40

Config_Start
'-------------------------------------------------------------------------------
'**** Added by Fuse Configurator ****
'Use the Fuse Configurator plug-in to change these settings
FEXTOSC = OFF    ;Oscillator not enabled
RSTOSC = HFINTOSC_64MHZ    ;HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
CLKOUTEN = OFF    ;CLKOUT function is disabled
CSWEN = On    ;Writing to NOSC and NDIV is allowed
FCMEN = OFF    ;Fail-Safe Clock Monitor disabled
MCLRE = EXTMCLR    ;If LVP = 0, MCLR pin is MCLR; If LVP = 1, RG5 pin function is MCLR
PWRTE = On    ;Power up timer enabled
LPBOREN = OFF    ;ULPBOR disabled
BOREN = SBORDIS    ;Brown-out Reset enabled , SBOREN bit is ignored
BORV = VBOR_285    ;Brown-out Reset Voltage (VBOR) set to 2.85V
ZCD = OFF    ;ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
PPS1WAY = OFF    ;PPSLOCK bit can be set and cleared repeatedly (subject to the unlock sequence)
STVREN = On    ;Stack full/underflow will cause Reset
Debug = OFF    ;Background debugger disabled
XINST = OFF    ;Extended Instruction Set and Indexed Addressing Mode disabled
WDTCPS = WDTCPS_31    ;Divider ratio 1:65536; software control of WDTPS
WDTE = OFF    ;WDT Disabled
WDTCWS = WDTCWS_7    ;window always open (100%); software control; keyed access not required
WDTCCS = LFINTOSC    ;WDT reference clock is the 31.0 kHz LFINTOSC
WRT0 = OFF    ;Block 0 (000800-003FFFh) not write-protected
WRT1 = OFF    ;Block 1 (004000-007FFFh) not write-protected
WRT2 = OFF    ;Block 2 (008000-00BFFFh) not write-protected
WRT3 = OFF    ;Block 3 (00C000-00FFFFh) not write-protected
WRT4 = OFF    ;Block 4 (010000-013FFFh) not write-protected
WRT5 = OFF    ;Block 5 (014000-017FFFh) not write-protected
WRT6 = OFF    ;Block 6 (018000-01BFFFh) not write-protected
WRT7 = OFF    ;Block 7 (01C000-01FFFFh) not write-protected
WRTC = OFF    ;Configuration registers (300000-30000Bh) not write-protected
WRTB = OFF    ;Boot Block (000000-0007FFh) not write-protected
WRTD = OFF    ;Data EEPROM not write-protected
SCANE = On    ;Scanner module is available for use, SCANMD bit can control the module
LVP = OFF    ;HV on MCLR/VPP must be used for programming
Cp = OFF    ;UserNVM code protection disabled
CPD = OFF    ;DataNVM code protection disabled
EBTR0 = OFF    ;Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
EBTR1 = OFF    ;Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
EBTR2 = OFF    ;Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
EBTR3 = OFF    ;Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
EBTR4 = OFF    ;Block 4 (010000-013FFFh) not protected from table reads executed in other blocks
EBTR5 = OFF    ;Block 5 (014000-017FFFh) not protected from table reads executed in other blocks
EBTR6 = OFF    ;Block 6 (018000-01BFFFh) not protected from table reads executed in other blocks
EBTR7 = OFF    ;Block 7 (01C000-01FFFFh) not protected from table reads executed in other blocks
EBTRB = OFF    ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
'**** End of Fuse Configurator Settings ****

Declare Xtal = 64
Declare Optimiser_Level = 0 'DISABLES the Optimiser
Declare Create_Coff On

Declare Watchdog Off

Symbol SDA_Pin = PORTE.4                'Pin To use For the I2C data
Symbol SCL_Pin = PORTE.7                'Pin To use For the I2C clock
Symbol CODEC_CS = PORTD.2                'Pin To use For the I2C CS
          

' WM8940 I²C address (changed to $1A)
Symbol WM8940R = $34      '  WM8940 read address
Symbol WM8940W = $35      '  WM8940 write address


' WM8940 register definitions
Symbol WM8940_REG_RESET      = $00  ' Reset register
Symbol WM8940_REG_OSC_CTRL    = $19  ' Oscillator control
Symbol WM8940_REG_CLOCK_CTRL  = $1A  ' Clock control
Symbol WM8940_REG_POWER_CTRL  = $1E  ' Power control
Symbol WM8940_REG_DAC_CTRL    = $0A  ' DAC control
Symbol WM8940_REG_AUDIO_CTRL  = $31  ' Audio control

 
 Dim lec As Word
 
WM8940_init()
' Main loop
Do
    ' Add necessary operations inside the loop
     lec= WM8940_Read(WM8940_REG_RESET)
     DelayMS 400
Loop

' WM8940 initialization with I²C address $1A
Proc WM8940_init()
WM8940_Write(WM8940_REG_RESET, $0000)        ' Reset
WM8940_Write(WM8940_REG_OSC_CTRL, $0002)    ' Enable internal oscillator
WM8940_Write(WM8940_REG_CLOCK_CTRL, $0001)  ' Set clock divider
WM8940_Write(WM8940_REG_POWER_CTRL, $0000)  ' Set system clock

WM8940_Write(WM8940_REG_DAC_CTRL, $00FF)    ' Configure output gain
WM8940_Write(WM8940_REG_AUDIO_CTRL, $00C0)  ' Enable DAC and audio output
EndProc

' Procedure to write to the WM8940 using I²C address $35
Proc WM8940_Write(Register As Byte, Dato As Word)
    Low CODEC_CS
    HBusOut  WM8940W, [Register, Dato]
    High CODEC_CS
EndProc
' Procedure to read to the WM8940 using I²C address $34
Proc WM8940_Read(Register As Byte) ,Word
Dim dato As Word
    Low CODEC_CS
    HBusIn  WM8940R, register, [dato]
    High CODEC_CS
    Result = dato
EndProc

Ecoli-557

Good evening Pepe-
I made the change in the Write Procedure:
'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
    low CODEC_CS
    I2Cout SDA_Pin, SCL_Pin, 0x35, [CODECReg, I2OutData]
'      I2Cout SDA_Pin, SCL_Pin,0x90, [CODECReg, I2OutData]
high CODEC_CS
EndProc
But it did not help.  I noticed you are using the older and no longer supported HBusOut verb while I am using I2COut verb.  Does that make a difference?
Also, please explain to me where and how you are getting the addresses you set for the 'Control' address?  I want to learn this.
I have another analyzer screen grab, just click on the image and it will show you the data in hex.  If too small, hold CTRL and click on the image - it zooms in.
Thanks again for trying to help.
Regards,
Steve
I2C to CODEC-4.PNG

Pepe

$1A = 0b00011010
($1A <<1)= 0b00110100 = $34
($1A <<1)|1= 0b00110101 = $35

Ecoli-557

OK, its 11:28PM, and my procedure seems to work.
'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
    low CODEC_CS
    I2Cout SDA_Pin, SCL_Pin, 0x35, [CODECReg, I2OutData]
    high CODEC_CS
EndProc
My InitWM8940:
' Initialize the WM8940 CODEC
InitWM8940:
'NEW WAY - page 64 of WM8940
WriteWM8940(CODEC_RST, 0x1248)              'Reg 0x00 - write anything will Reset the chip
WriteWM8940(CODEC_Pwr1, 0x0003)              'Reg 0x01 - VNID=1, Level Shifters=1
WriteWM8940(CODEC_Clk, 0x0080)              'Reg 0x06 - Clock Source to MCLK
WriteWM8940(CODEC_AddlCntl, 0x0060)          'Reg 0x07 - Enable Power On Bias Control,VMID soft start
WriteWM8940(CODEC_Pwr3, 0x0060)              'Reg 0x03 - Enable SPKPEN, SPKNRN
WriteWM8940(CODEC_Pwr1, 0x0001)              'Reg 0x01 - VMID set for 50k
WriteWM8940(CODEC_Pwr1, 0x000A)              'Reg 0x01 - Enable Analog Amp Bias Control, VMID buffer
WriteWM8940(CODEC_AddlCntl, 0x0010)          'Reg 0x07 - Disable Power on Bias Control, VMID Softstart
WriteWM8940(CODEC_Pwr3, 0x0005)              'Reg 0x03 - Enable DAC, and Spkr Mixer
WriteWM8940(CODEC_SpkrMix, 0x0000)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=-57dB
WriteWM8940(CODEC_SpkrMix, 0x0004)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0008)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x000C)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0010)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0014)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0020)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0028)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0030)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0034)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrVol, 0x0039)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=0dB
WriteWM8940(CODEC_DAC, 0x0000)              'Reg 0x0A - Disable DAC SOft Mute
Return
I do have I2C slow bus ON,but will try it with it OFF later.
All I did was change the MODE on this WM8940 CODEC to a 2-wire I2C communication.  I will need to use the 3-wire in the final design but at least I can get to understand this chip using 2-wire I2C.
Analyzer image below, just click and to expand, use CTRL and mouse click.
A big THANKS to Pepe for hanging with me on this - I still have some questions but the WM8940 seems to take the commands - it still does not work from an audio point of view but some progress at least.

I2C to CODEC-5_works_as_2-wire.PNG

Pepe

#32
So I read from the manual when using 2 wires as the address is fixed and you can't use the enable pin to select the codec you need to use an i2c multiplexer like the PCA9548A

This would be an example to use

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 18F67K40

Config_Start
'-------------------------------------------------------------------------------
'**** Added by Fuse Configurator ****
'Use the Fuse Configurator plug-in to change these settings
FEXTOSC = OFF    ;Oscillator not enabled
RSTOSC = HFINTOSC_64MHZ    ;HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
CLKOUTEN = OFF    ;CLKOUT function is disabled
CSWEN = On    ;Writing to NOSC and NDIV is allowed
FCMEN = OFF    ;Fail-Safe Clock Monitor disabled
MCLRE = EXTMCLR    ;If LVP = 0, MCLR pin is MCLR; If LVP = 1, RG5 pin function is MCLR
PWRTE = On    ;Power up timer enabled
LPBOREN = OFF    ;ULPBOR disabled
BOREN = SBORDIS    ;Brown-out Reset enabled , SBOREN bit is ignored
BORV = VBOR_285    ;Brown-out Reset Voltage (VBOR) set to 2.85V
ZCD = OFF    ;ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
PPS1WAY = OFF    ;PPSLOCK bit can be set and cleared repeatedly (subject to the unlock sequence)
STVREN = On    ;Stack full/underflow will cause Reset
Debug = OFF    ;Background debugger disabled
XINST = OFF    ;Extended Instruction Set and Indexed Addressing Mode disabled
WDTCPS = WDTCPS_31    ;Divider ratio 1:65536; software control of WDTPS
WDTE = OFF    ;WDT Disabled
WDTCWS = WDTCWS_7    ;window always open (100%); software control; keyed access not required
WDTCCS = LFINTOSC    ;WDT reference clock is the 31.0 kHz LFINTOSC
WRT0 = OFF    ;Block 0 (000800-003FFFh) not write-protected
WRT1 = OFF    ;Block 1 (004000-007FFFh) not write-protected
WRT2 = OFF    ;Block 2 (008000-00BFFFh) not write-protected
WRT3 = OFF    ;Block 3 (00C000-00FFFFh) not write-protected
WRT4 = OFF    ;Block 4 (010000-013FFFh) not write-protected
WRT5 = OFF    ;Block 5 (014000-017FFFh) not write-protected
WRT6 = OFF    ;Block 6 (018000-01BFFFh) not write-protected
WRT7 = OFF    ;Block 7 (01C000-01FFFFh) not write-protected
WRTC = OFF    ;Configuration registers (300000-30000Bh) not write-protected
WRTB = OFF    ;Boot Block (000000-0007FFh) not write-protected
WRTD = OFF    ;Data EEPROM not write-protected
SCANE = On    ;Scanner module is available for use, SCANMD bit can control the module
LVP = OFF    ;HV on MCLR/VPP must be used for programming
Cp = OFF    ;UserNVM code protection disabled
CPD = OFF    ;DataNVM code protection disabled
EBTR0 = OFF    ;Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
EBTR1 = OFF    ;Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
EBTR2 = OFF    ;Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
EBTR3 = OFF    ;Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
EBTR4 = OFF    ;Block 4 (010000-013FFFh) not protected from table reads executed in other blocks
EBTR5 = OFF    ;Block 5 (014000-017FFFh) not protected from table reads executed in other blocks
EBTR6 = OFF    ;Block 6 (018000-01BFFFh) not protected from table reads executed in other blocks
EBTR7 = OFF    ;Block 7 (01C000-01FFFFh) not protected from table reads executed in other blocks
EBTRB = OFF    ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End
'**** End of Fuse Configurator Settings ****

Declare Xtal = 64
Declare I2C_Slow_Bus On 
Declare Optimiser_Level = 0 'DISABLES the Optimiser
Declare Create_Coff On
Declare Watchdog Off

Dim Channel As Byte
Dim CODECReg As Byte                    'WM8940 register
Dim ReadValue1 As Word
Dim ReadValue2 As Word
Dim ReadValue3 As Word
Dim ReadValue4 As Word
Dim ReadValue5 As Word
Dim ReadValue6 As Word
Dim ReadValue7 As Word
Dim ReadValue8 As Word

' I²C addresses
Symbol PCA9548AW = $71  ' PCA9548A I²C write address (Multiplexer)
Symbol PCA9548AR = $70  ' PCA9548A I²C read address (Multiplexer)
Symbol WM8940W = $35    ' WM8940 write address
Symbol WM8940R = $3     ' WM8940 read address


Symbol CODEC_RST          0x00        'Soft reset
Symbol CODEC_Pwr1         0x01        'Power Mgmt-1
Symbol CODEC_Pwr2         0x02        'Power Mgmt-2
Symbol CODEC_Pwr3         0x03        'Power Mgmt-3
Symbol CODEC_AudInt       0x04        'Audio Interface
Symbol CODEC_CompCtl      0x05        'Companding Control
Symbol CODEC_Clk          0x06        'Clock Gen COntrol
Symbol CODEC_AddlCntl     0x07        'Additional COntrol
Symbol CODEC_GPIO         0x08        'GPIO stuff
Symbol CODEC_CtlInt       0x09        'Control Interface
Symbol CODEC_DAC          0x0A        'DAC Control
Symbol CODEC_DACvol       0x0B        'DAC Digital volume

Symbol CODEC_ADC          0x0E        'ADC Control
Symbol CODEC_ADCvol       0x0F        'ADC Digital volume
Symbol CODEC_Notch1       0x10        'Notch Filter-1
Symbol CODEC_Notch2       0x11        'Notch Filter-2
Symbol CODEC_Notch3       0x12        'Notch Filter-3
Symbol CODEC_Notch4       0x13        'Notch Filter-4
Symbol CODEC_Notch5       0x14        'Notch Filter-5
Symbol CODEC_Notch6       0x15        'Notch Filter-6
Symbol CODEC_Notch7       0x16        'Notch Filter-7
Symbol CODEC_Notch8       0x17        'Notch Filter-8
Symbol CODEC_DACLim1      0x18        'DAC Limiter-1
Symbol CODEC_DACLim2      0x19        'DAC Limiter-2

Symbol CODEC_ALC1         0x20        'ALC Control-1
Symbol CODEC_ALC2         0x21        'ALC Control-2
Symbol CODEC_ALC3         0x22        'ALC COntrol-3
Symbol CODEC_NGate        0x23        'Noise Gate
Symbol CODEC_PLLN         0x24        'PLL N
Symbol CODEC_PLLK1        0x25        'PLL K-1
Symbol CODEC_PLLK2        0x26        'PLL K-2
Symbol CODEC_PLLK3        0x27        'PLL K-3

Symbol CODEC_ALC4         0x2A        'ALC Control-4

Symbol CODEC_InCtl        0x2C        'Input Control
Symbol CODEC_InPGAGain    0x2D        'Input PGA Gain Control

Symbol CODEC_ADCBOOST     0x2F        'ADC Boost Control

Symbol CODEC_OutCtl       0x31        'Output Control
Symbol CODEC_SpkrMix      0x32        'Speaker Mixer Control

Symbol CODEC_SpkrVol      0x36        'Speaker Volume Control

Symbol CODEC_MonoMix      0x38        'Mono Mixer Control

Symbol CODEC_CacheRegNum  0x57

'/* Clock divider Id's */
Symbol BCLKDIV          0
Symbol MCLKDIV          1
Symbol OPCLKDIV         2

'/* MCLK clock dividers */
Symbol MCLKDIV_1        0
Symbol MCLKDIV_1_5      1
Symbol MCLKDIV_2        2
Symbol MCLKDIV_3        3
Symbol MCLKDIV_4        4
Symbol MCLKDIV_6        5
Symbol MCLKDIV_8        6
Symbol MCLKDIV_12       7

'/* BCLK clock dividers */
Symbol BCLKDIV_1        0
Symbol BCLKDIV_2        1
Symbol BCLKDIV_4        2
Symbol BCLKDIV_8        3
Symbol BCLKDIV_16       4
Symbol BCLKDIV_32       5

'/* PLL Out Dividers */
Symbol OPCLKDIV_1      0
Symbol OPCLKDIV_2      1
Symbol OPCLKDIV_3      2
Symbol OPCLKDIV_4      3
       
' Define I²C pins

Symbol SDA_Pin = PORTE.4                'Pin To use For the I2C data
Symbol SCL_Pin = PORTE.7                'Pin To use For the I2C clock

'PORT D IN USE
ANSELD  = %00000000    'Set all analog pins to digital.
TRISD  = %01000010    'Port D set to outputs except bits 1 & 6
WPUD    = %11111100    'Weak pull-ups enabled except for 0 & 1
ODCOND  = %00000000    '1 = Open Drain, 0 = Push/Pull drive
PORTD  = %00001000    'Clear register. D.3 = 1
LATD    = %00001000    'Clear register. D.3 = 1
SLRCOND = %11111111    'Slew rate limited
INLVLD  = %00000000    '1 = Schmitt Trigger input used for PORT reads and interrupt-on-change
                        '0 = TTL input used for PORT reads and interrupt-on-change

'PORT E IN USE
TRISE = %01100001      'PORTE is mixed
WPUD  = %10010001      'Weak pull-ups enabled except for 0, 4, and 7
ANSELE  = %01100000    ; Set all analog pins to digital EXCEPT BITS 5,6,
TRISE  = %01100001    ; Port E set to Outputs except bits 0,5,6.
WPUE    = %10011111    ; Weak pull-ups enabled except bits 5 & 6
ODCONE  = %00000000    ; 1 = Open Drain, 0 = Push/Pull drive.
PORTE  = %10011111    ; Initialize register.
LATE    = %10011111    ; Set outputs high.
SLRCONE = %11111111    ; Slew rate limited.
INLVLE  = %00000000    ; 1 = Schmitt Trigger input used for PORT reads and interrupt-on-change
                        ; 0 = TTL input used for PORT reads and interrupt-on-change       
       
InitWM8940()

    ' Read id chip from all 8 WM8940 codecs and store results in separate variables
    ReadValue1 = ReadWM8940(0, $0)   ' Read from register 0x00 of WM8940 #1
    ReadValue2 = ReadWM8940(1, $0)   ' Read from register 0x00 of WM8940 #2
    ReadValue3 = ReadWM8940(2, $0)   ' Read from register 0x00 of WM8940 #3
    ReadValue4 = ReadWM8940(3, $0)   ' Read from register 0x00 of WM8940 #4
    ReadValue5 = ReadWM8940(4, $0)   ' Read from register 0x00 of WM8940 #5
    ReadValue6 = ReadWM8940(5, $0)   ' Read from register 0x00 of WM8940 #6
    ReadValue7 = ReadWM8940(6, $0)   ' Read from register 0x00 of WM8940 #7
    ReadValue8 = ReadWM8940(7, $0)   ' Read from register 0x00 of WM8940 #8

    ' Process the read values as needed (for example, print or use them)
Do

Loop

' Initialize the WM8940 CODEC
Proc InitWM8940()
For Channel = 0 To 7
WriteWM8940(Channel, CODEC_RST, 0x1248)              'Reg 0x00 - write anything will Reset the chip
WriteWM8940(Channel, CODEC_Pwr1, 0x0003)             'Reg 0x01 - VNID=1, Level Shifters=1
WriteWM8940(Channel, CODEC_Clk, 0x0080)              'Reg 0x06 - Clock Source to MCLK
WriteWM8940(Channel, CODEC_AddlCntl, 0x0060)         'Reg 0x07 - Enable Power On Bias Control,VMID soft start
WriteWM8940(Channel, CODEC_Pwr3, 0x0060)             'Reg 0x03 - Enable SPKPEN, SPKNRN
WriteWM8940(Channel, CODEC_Pwr1, 0x0001)             'Reg 0x01 - VMID set for 50k
WriteWM8940(Channel, CODEC_Pwr1, 0x000A)             'Reg 0x01 - Enable Analog Amp Bias Control, VMID buffer
WriteWM8940(Channel, CODEC_AddlCntl, 0x001)          'Reg 0x07 - Disable Power on Bias Control, VMID Softstart
WriteWM8940(Channel, CODEC_Pwr3, 0x0005)             'Reg 0x03 - Enable DAC, and Spkr Mixer
WriteWM8940(Channel, CODEC_SpkrMix, 0x0000)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=-57dB
WriteWM8940(Channel, CODEC_SpkrMix, 0x0004)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0008)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x000C)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0010)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0014)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0020)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0028)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0030)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrMix, 0x0034)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(Channel, CODEC_SpkrVol, 0x0039)          'Reg 0x32 - Disable Spkr Mute, Spkr Vol=0dB
WriteWM8940(Channel, CODEC_DAC, 0x0000)              'Reg 0x0A - Disable DAC SOft Mute
Next Channel
EndProc

' Procedure to select the PCA9548A channel
Proc Select_I2C_Channel(Channel As Byte)
    I2COut SDA_Pin, SCL_Pin, PCA9548AW, [1 << Channel]  ' Select the codec by channel
EndProc

'Procedure to send data to WM8940
Proc WriteWM8940(Channel As Byte, CODECReg As Byte, I2OutData As Word)
    Select_I2C_Channel(Channel)  ' Select the WM8940 to use
    I2COut SDA_Pin, SCL_Pin, WM8940W, [CODECReg, I2OutData]  ' Write to the register
EndProc

' Procedure to read from the WM8940
Proc ReadWM8940(Channel As Byte,CODECReg As Byte), Word
    Select_I2C_Channel(Channel)  ' Select the WM8940 to use
    I2CIn SDA_Pin, SCL_Pin, WM8940R, CODECReg, [Result]  ' Read data from the register
    Return Result
EndProc



Ecoli-557

#33
Pepe, I agree, but the 8940 manual does state you CAN use 3-wire I2C which is where I eventually need to be.
I have an idea based on what happened at midnite last night and will let you know - regarding using the 3-wire approach.
UPDATE:
I tried this:
I2Cout SDA_Pin, SCL_Pin, CODECReg, [I2OutData]
but it did not work either.
I will do more research on this 3-wire timing and try to understand how to get it to work with the compiler:

Ecoli-557

I will do more research on this 3-wire timing and try to understand how to get it to work with the compiler:
3-wire timing.PNG

Ecoli-557

#35
I don't know if anyone is still following, but, I could not find any examples for I2C for the timing in Figure 35 (below) but it looks a lot like SPI but a 3-wire version.
So, I re-configured code for my Procedure:
'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
     low CODEC_CS
'     I2Cout SDA_Pin, SCL_Pin, 0x35, [CODECReg, I2OutData]
     shout SDA_Pin, SCL_Pin, 5, [CODECReg\8, I2OutData\16]
     high CODEC_CS
EndProc
My InitWM8940 stayed exactly the same:
' Initialize the WM8940 CODEC
InitWM8940:
'NEW WAY - page 64 of WM8940
WriteWM8940(CODEC_RST, 0x1248)               'Reg 0x00 - write anything will Reset the chip
WriteWM8940(CODEC_Pwr1, 0x0003)              'Reg 0x01 - VNID=1, Level Shifters=1
WriteWM8940(CODEC_Clk, 0x0080)               'Reg 0x06 - Clock Source to MCLK
WriteWM8940(CODEC_AddlCntl, 0x0060)          'Reg 0x07 - Enable Power On Bias Control,VMID soft start
WriteWM8940(CODEC_Pwr3, 0x0060)              'Reg 0x03 - Enable SPKPEN, SPKNRN
WriteWM8940(CODEC_Pwr1, 0x0001)              'Reg 0x01 - VMID set for 50k
WriteWM8940(CODEC_Pwr1, 0x000A)              'Reg 0x01 - Enable Analog Amp Bias Control, VMID buffer
WriteWM8940(CODEC_AddlCntl, 0x0010)          'Reg 0x07 - Disable Power on Bias Control, VMID Softstart
WriteWM8940(CODEC_Pwr3, 0x0005)              'Reg 0x03 - Enable DAC, and Spkr Mixer
WriteWM8940(CODEC_SpkrMix, 0x0000)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=-57dB
WriteWM8940(CODEC_SpkrMix, 0x0004)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0008)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x000C)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0010)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0014)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0020)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0028)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0030)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrMix, 0x0034)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=
WriteWM8940(CODEC_SpkrVol, 0x0039)           'Reg 0x32 - Disable Spkr Mute, Spkr Vol=0dB
WriteWM8940(CODEC_DAC, 0x0000)               'Reg 0x0A - Disable DAC SOft Mute
Return


3-wire timing.PNG

And you can see the 8-bit address is shown 1st in the analyzer and followed by the 16-bit data.  It appears I am giving the WM8940 the data it needs?
My result from my analyzer, click on image to view and to zoom in to see data, just CTRL + click:

3-wire SPI - works.PNG

Pepe

#36
According to the data sheet the CSB pulse is always high and at the end one clock cycle goes down

'Procedure to send data to WM8940
Proc WriteWM8940 (CODECReg As byte, I2outData As Word)
     high CODEC_CS
     shout SDA_Pin, SCL_Pin, 5, [CODECReg\8, I2OutData\16]
     low CODEC_CS
     delayus 1
     high CODE_CS
EndProc

tumbleweed

3-wire is SPI, 2-wire is I2C.
No chip select with I2C mode.

flosigud

This chip has two modes, 2 wire and 3 wire. If using three wires you cant use any IIC commands, that's for the two wires. There is no command for SPI.

Pepe

Proc WM8940_Write(CODECReg As Byte, I2OutData As Word)
    High  SBC
    SHOut SDA_Pin, SCL_Pin, 5, [CODECReg\8, I2OutData\16]
    Low SBC
    DelayUS 1
    High SBC
EndProc
' Procedure to read to the WM8940
Proc WM8940_Read(CODECReg As Byte) ,Word
Dim wdata As Word
    High  SBC
    SHOut SDA_Pin, SCL_Pin, 5, [CODECReg\8]
    Low SBC
    DelayUS 1
    High SBC
    SHIn SDA_Pin,SCL_Pin, 5, [ wdata\16]
    Result = wdata
EndProc