Shop OBEX P1 Docs P2 Docs Learn Events
FM Receiver? — Parallax Forums

FM Receiver?

jmspaggijmspaggi Posts: 629
edited 2010-10-02 17:39 in Propeller 1
Hi all,

Is there any FM receiver we can connect to the propeller?

I'm building a OGG player for my car, and if I can add an FM received, I will be able to get rid of my existing sound-system...

Thanks,

JM

Comments

  • jazzedjazzed Posts: 11,803
    edited 2010-08-23 18:48
  • jmspaggijmspaggi Posts: 629
    edited 2010-08-24 09:23
    Wow!

    Super!

    Thanks folks.

    I will probably go with the one at SparkFun http://www.sparkfun.com/commerce/product_info.php?products_id=8972

    I'm adding so much features on my projects that I will maybe never finish it ;)

    JM
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-01 13:58
    Hi all,

    I finally received the WRL-08972 with the AR-1010 (http://www.sparkfun.com/commerce/product_info.php?products_id=8972).

    The example they have on the page is for Atmega. So I'm wondering if someone understand list language and can translate that to spin?

    I took a look into the code, and it seems to be talking to the AR-1010 with I2C.

    So can I "simply" use an IC2 object to talk to it, like http://obex.parallax.com/objects/26/ ?

    Thanks,

    JM
  • Mike GreenMike Green Posts: 23,101
    edited 2010-10-01 14:13
    You can "simply" use the Basic_I2C_Driver. You might look at i2cObjectv2 which uses the code from Basic_I2C_Driver to access a variety of I2C devices.

    In the documentation for the FM receiver, there should be a description of the format of the information to be sent to/from the receiver. You should be able to use the routines in i2cObjectv2 as a model for your receiver since the receiver behaves somewhat like a small memory with a set of memory locations (control registers) that get set and read to control the receiver and many other I2C devices behave the same way.
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-01 18:22
    It works!!!

    It took me some time, but it's working now ;)

    Thanks a lot! I modified i2cDemoApp to add AR1010 demo like this:
    PRI AR1010_Demo | tempvar,ackbit
        ' DEMO AR1010 FM receiver
        debug.strln(String("AR1010 Demo..."))
    
        ' wait tick or two
        waitcnt(clkfreq*2+cnt)
    
        i2cObject.start(i2cSCL)
        i2cObject.WriteByte(i2cSCL, AR1010Addr, $20, $13)
    
        ''i2cObject.start(i2cSCL)
        tempvar := i2cObject.readWord(i2cSCL, AR1010Addr, $21)
    
        debug.str(string("Status is %"))
        debug.bin (tempvar,8)
        debug.putc(13)
    

    Output should be:
    AR1010 Present       
    AR1010 Demo...       
    Status is %00100000  
    

    Where %00100000 mean "Seek/Tune complete flag, '1'=Complete, '0'=Incomplete"

    The documentation is awful! Missing many important information.

    Anyway, thanks a lot! I now have to try to get more than just the status ;)

    JM
  • jazzedjazzed Posts: 11,803
    edited 2010-10-01 18:25
    Congratulations.
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-01 19:33
    jazzed wrote: »
    Congratulations.

    Forget it, it's not working at all ;)

    It's just a change that this bit is at 1.

    I'm not using i2cObject the right way. Also, $20 is AR1010Addr. So I should not send it twice ;)

    Look like should use readLocation, but I'm not able to get that working too.

    So I'm still try... Also spent 4h on that with no success. But I will win! ;)

    JM
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-01 21:03
    Ok. Still not working.

    Looks like I will need some help.

    i2c scan is able to find my component at the right address.

    The challenge I'm facing is that Basic_I2C_Driver is talking bytes but I need words.

    Here is the C code for it :
    //Reads a memory register from the AR1000
    uint16_t ar1000_read(uint8_t address_to_read)
    {
    	char byte1 = 0, byte2 = 0;
    	char ack;
    	
    AGAIN:
    	i2c_SendStart(); //Send start condition 
    	ack = i2c_SendByte(AR1000_W);	 //Send slave device address with write
    	ack &= i2c_SendByte(address_to_read);	//Send address to read
    	if(ack == 0)
    	{
    		#ifdef I2CDEBUG
    			printf("!"); //No ACK!
    		#endif
    		goto AGAIN;
    	}
    	
    	
    	i2c_SendStart(); //Send start condition 
    	i2c_SendByte(AR1000_R);	 //Ask device to read the value at the requested address
    	
    	if(inb(TWSR) == TW_MR_SLA_ACK)
    	{
    		byte1 = i2c_ReceiveByte(TRUE);
    		byte2 = i2c_ReceiveByte(TRUE);
    	}
    	else
    	{
    		// device did not ACK it's address,
    		// data will not be transferred
    		// return error
    		//retval = I2C_ERROR_NODEV;
    		printf("\n\tAck failed!");
    	}
    
    	i2c_SendStop();
    	
    	//Combine two bytes into one 16-bit word
    	int16_t temp = byte1 << 8;	
    	temp |= byte2;
    	
    	return(temp);
    }
    

    It's very close to the readLocation method expect that we are ready only one byte. So I modified it that way:
    PUB readLocation(SCL,device_address, register) : value | temp1, temp2
      start(SCL)
      write(SCL,device_address | 0)
      write(SCL,register)
      start(SCL)
      write(SCL,device_address | 1)  
      temp1 := read(SCL,ACK)
      temp2 := read(SCL,ACK)
      stop(SCL)
      value := temp1 << 8
      value |= temp2
      return value
    

    I checked the device_address and it's equal to AR1000_W. Also, AR1000_R is device_address | 1.

    So those 2 pieces of code are very close.

    However, when I run this spin code:
      repeat 20
        tempvar := i2cObject.readLocation (i2cSCL, AR1010Addr, 0)
    
        debug.str(string("Status for 0 is %"))
        debug.bin (tempvar,16)
        debug.putc(13)
    

    It never returns the same value :(

    Ok, for a random generator, it's probably a good one ;) But not at all what I'm looking for for now.

    So. What's wrong? Is that correct to try to read 2 bytes from the i2c channel?

    If I loop 40 times, I can see that after 29, it's starting back to 0. Since the AR1010 only have 29 registers, that looks normal. That mean write(SCL,register) is not moving to the register I need? And then I'm reading all of them 1 by 1?

    Last thing, in the documentation, I have a 2-wires vs 3-wires options using BUSEN pin. I have configured it for 2-wires. Correct?

    Thanks for who will be able to help me...

    JM
  • jazzedjazzed Posts: 11,803
    edited 2010-10-02 08:14
    jmspaggi wrote: »
    The challenge I'm facing is that Basic_I2C_Driver is talking bytes but I need words.
    Try this: http://obex.parallax.com/objects/528/

    It has wrapper methods for word access.
  • GameHackerGameHacker Posts: 15
    edited 2010-10-02 17:03
    OR, you could try the Airoha AR1010 driver & demo that is already posted in the OBEX...

    http://obex.parallax.com/objects/466/
  • jazzedjazzed Posts: 11,803
    edited 2010-10-02 17:08
    GameHacker wrote: »
    OR, you could try the Airoha AR1010 driver & demo that is already posted in the OBEX...

    http://obex.parallax.com/objects/466/

    Very nice :)
  • jmspaggijmspaggi Posts: 629
    edited 2010-10-02 17:39
    :(:(:(:(

    I spent so many hours on the last few days!

    I did not even tought about searching AR1010 on OBEX!!!!!

    :(

    So.... It's working A1!

    There is few features that still need to be defined (Like Seek Forward, Seek Backward, etc.) but now I have a really good base to work with!

    Thanks a lot to all of you for your help!

    JM
Sign In or Register to comment.