Hallo,

Er zijn op CO slechts drie topics over de Si4703, en vrijwel alles voor dit erg interessante chipje is geschreven voor de Arduino, een ding waarmee ik nog nooit iets heb gedaan. Dit topic is bedoeld voor ontwikkeling van het hele onderdeel.( Iets wat anderen misschien motiveert om het ook eens te proberen?)

De PIC18f452 en zijn I2C hardware bus werkt al prima, daar hangt ook een DS1307 aan die netjes de tijd en wat variabelen bijhoudt. Ook heb ik een werkend (grafisch) display.

Nu wil ik echter het tabblad "Radio" afmaken. Dit is dus met de Si4703 radio chip en dat gaat een beetje lastig. Door de enorme hoeveelheid registers die geconfigureerd moeten worden voordat ik de ledjes aan GPIO 2 of 3 kan laten branden is de kans dat het fout gaat aardig groot. Daarbij komt ook nog eens een opstartprocedure met een busmode selectie. Dat is waar de eerste vraag over gaat.

De bus heeft twee modes; 2 en 3 wire. Voordeel van 3-wire is dat je het adres dat je wilt aanspreken kan kiezen, terwijl dat bij 2-wire niet kan. Voordeel van 2-wire is dat je geen SEN-poort hoeft te timen, maar je mist de voordelen van 3-wire mode. Op dit moment heb ik voor 2-wire gekozen, maar dat kan aangepast worden als daar reden voor is. ( RST naar PIC, SEN op 3V3, GPIO3 aan kristal)

De opstartprocedure is nu, zover ik weet:
1. voeding aan
2. reset omhoog
3. Xtal aan
4. enable "1" schrijven
5. andere registers schrijven.

Maar met 2-wire zou ik even niet weten hoe ik dat correct uit voer. want dan moeten door ook alle andere registers geschreven worden. Is het handiger om eerst alle registers uit te lezen, vervolgens die bits te veranderen die je wilt, en daarna alles weer terug te schrijven? Of zal ik toch naar 3-wire busmode overschakelen, en iets bedenken om die SEN te timen.
Daarnaast heb ik het idee dat read en write operaties in 2-wire mode verschillen van de I2C standaard. Kan dat kloppen, of het ik dat verkeerd begrepen?

Datasheet, Programming Guide, en Link bordje.

EDIT: twee dingen die nog wel handig zijn om te weten; Ik programmeer in PICbasic en ik heb kan ook wat C maar dan niet icm. PICs.
En het doel vanhet topic is om dat ledje te laten branden, dan weet ik in ieder geval dat ik de registers kan instellen.

Zoals je in de diagrammen kunt zien (is wel wat verwarrend) is dit conform de I2C standaard..
Blokje D7-D0 heeft verkortingtekens " maar wordt gewoon afgesloten met een ack. dus gewoon 9 bit boundery excl. start/stop

Alleen van wie(slave or master) die ack komt maakt het verschil van read or write.(en het address natuurlijk)

http://i42.tinypic.com/ek00ut.jpg

http://i44.tinypic.com/2cz9bid.jpg

Het is de bedoeling dat je een "CommandPacket" samenstelt met als inhoud : command (Get_property or Set_property)
de arguments zoals de property index hi&low
en de response is dan prop_value [2bytes] zie pag 32 AN230

Bij sparkfun staat ook een code example "Si4703_Example.pde"
waar veel info in staat met name bij de error 'WTF' in proc
si4703_init(void). :-)

[Bericht gewijzigd door Arabel op (16%)]

Die commands zijn geloof ik niet verplicht, maar wel een optie als het niet lukt met registers schrijven. Aangezien het dus toch I2C is, probeer ik dat liever eerst.

Ik merk net dat ik SDA niet laag krijg tijdens het opstarten door gewoon de pin een lage waarde te geven in de code; moet ik daarvoor een extra FET plaatsen die ik heel even laat geleiden naar de grond als de reset hoog wordt?

In die file bij Si4703_init(void) staat het volgende, wat ik hopelijk heb vertaald in picbasic met wat indicators ertussen. Ik heb gelijk maar geprobeerd om de GPIO's aan te spreken. Ik zie alleen de leds aan de gpio's niet veranderen, dus dat werkt in elk geval niet. Maar zo merk ik ook niet of de chip correct opstart. Deze versie kan niet zelf zijn SDA laag maken dus doe ik dat maar handmatig, en daar wacht de processor op. LEDG knippert braaf. maar de LED's aan de Si module doen nogsteeds niets.

//To get the Si4703 inito 2-wire mode, SEN needs to be high and SDIO needs to be low after a reset
//The breakout board has SEN pulled high, but also has SDIO pulled high. Therefore, after a normal power up
//The Si4703 will be in an unknown state. RST must be controlled
void si4703_init(void) {
  Serial.println("Initializing I2C and Si4703");
  
  pinMode(resetPin, OUTPUT);
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
  digitalWrite(resetPin, LOW); //Put Si4703 into reset
  delay(1); //Some delays while we allow pins to settle
  digitalWrite(resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
  delay(1); //Allow Si4703 to come out of reset

  Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C

  si4703_readRegisters(); //Read the current register set
  //si4703_registers[0x07] = 0xBC04; //Enable the oscillator, from AN230 page 9, rev 0.5 (DOES NOT WORK, wtf Silicon Labs datasheet?)
  si4703_registers[0x07] = 0x8100; //Enable the oscillator, from AN230 page 9, rev 0.61 (works)
  si4703_updateRegisters(); //Update

  delay(500); //Wait for clock to settle - from AN230 page 9

  si4703_readRegisters(); //Read the current register set
  si4703_registers[POWERCFG] = 0x4001; //Enable the IC
  //  si4703_registers[POWERCFG] |= (1<<SMUTE) | (1<<DMUTE); //Disable Mute, disable softmute
  si4703_registers[SYSCONFIG1] |= (1<<RDS); //Enable RDS

#ifdef IN_EUROPE
    si4703_registers[SYSCONFIG1] |= (1<<DE); //50kHz Europe setup
  si4703_registers[SYSCONFIG2] |= (1<<SPACE0); //100kHz channel spacing for Europe
#else
  si4703_registers[SYSCONFIG2] &= ~(1<<SPACE1 | 1<<SPACE0) ; //Force 200kHz channel spacing for USA
#endif

  si4703_registers[SYSCONFIG2] &= 0xFFF0; //Clear volume bits
  si4703_registers[SYSCONFIG2] |= 0x0001; //Set volume to lowest
  si4703_updateRegisters(); //Update

  delay(110); //Max powerup time, from datasheet page 13
}

            PORTC.4 = 0    ; zou I2C I/O moeten zijn, maar dit werkt niet zo.
            LEDR = 1
            DelayMS 1000
            Rst = 1         ; Si uit reset
            LEDR = 1
            Repeat
            Until switch = 0  ; wachten tot SDA pin weer is losgelaten
            LEDR = 0
            LEDG = 1
            DelayMS 1000
            HBusIn %001000001, [ Radio[10], Radio[11], Radio[12], Radio[13], Radio[14], Radio[15], Radio[0], Radio[1], Radio[2], Radio[3], Radio[4], Radio[5], Radio[6], Radio[7], Radio[8], Radio[9] ]
            LEDG = 0
            DelayMS 1000
            Radio[7] = $8100       ; start osc
            HBusOut %001000000,[ Radio[2], Radio[3], Radio[4], Radio[5], Radio[6], Radio[7], Radio[8], Radio[9], Radio[10], Radio[11], Radio[12], Radio[13], Radio[14], Radio[15], Radio[0], Radio[1] ]
            LEDG = 1
            DelayMS 1000
            Radio[2] = $4001       ; enable
            HBusOut %001000000,[ Radio[2], Radio[3], Radio[4], Radio[5], Radio[6], Radio[7], Radio[8], Radio[9], Radio[10], Radio[11], Radio[12], Radio[13], Radio[14], Radio[15], Radio[0], Radio[1] ]
            LEDG = 0
            DelayMS 1000
            SetBit Radio[4],12     ; rds enable
            SetBit Radio[4],11      ; de-emph. europa
            ClearBit Radio[4],3       ; gpio
            ClearBit Radio[4],2       ;
            ClearBit Radio[4],1       ;
            SetBit Radio[4],0         ;
            
            SetBit Radio[5],4     ; europa spacing
            ClearBit Radio[5],3  ;
            ClearBit Radio[5],2       ;
            ClearBit Radio[5],1       ;
            SetBit Radio[5],0    ; Volume op bijna min
            HBusOut %001000000,[ Radio[2], Radio[3], Radio[4], Radio[5], Radio[6], Radio[7], Radio[8], Radio[9], Radio[10], Radio[11], Radio[12], Radio[13], Radio[14], Radio[15], Radio[0], Radio[1] ]
            LEDG = 1
            DelayUS 110

Radio[] is een 16-delige word-array.