Advertisement
Guest User

Untitled

a guest
Mar 16th, 2012
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.66 KB | None | 0 0
  1.  /*
  2.  
  3.   Arduino program for interfacing the Sony XDR-F1HD Receiver to RDS Spy.
  4.   (Tested on both ATMEGA168 and ATMEGA328 based Arduinos.)
  5.  
  6.   (c) 2010-2011 by Ray H. Dees
  7.  
  8.   Version   Modified By     Date         Comments
  9.   .10       R. Dees      12/23/2010      Initial Release.
  10.   .11       R. Dees      01/04/2011      Modified to support RDS Spy (Version 0.94) "RESET" command.
  11.   .12       R. Dees      04/10/2011      Modified to support Arduinos running at 16mHz on 3.3v.
  12.  
  13.  
  14.   Inputs:
  15.  
  16.   Serial Data (SDA)  -  Arduino Digital Pin 2.
  17.   Serial Clock (SCK) -  Arduino Digital Pin 3.
  18.  
  19.   Ouputs:
  20.  
  21.   RDS data formatted in RDS Spy protocol via the Arduino USB port.
  22.  
  23.   Setup:
  24.  
  25.   RDS Spy should be configured as follows:
  26.  
  27.   Select Configure,
  28.   Select RDS Source,
  29.   Select P75/P175 FM Analyzer,
  30.   Set Connection Type RS232/USB,
  31.   Select the RS232 COM Port that your Arduino appears as.
  32.  
  33.   You may use this program for personal purposes only.  The use of this program
  34.   in a commercial product requires explicit written permission from the author.
  35.   The author is not responsible or liable for damage or loss that may be caused
  36.   by the use of this program.
  37.  
  38. */
  39. #include <WProgram.h>
  40. //
  41. //  Definitions
  42. //
  43. #define SDA              2
  44. #define SCK              3
  45. #define BUFFER_LENGTH   64
  46. #define DELAY  asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
  47. //
  48. enum {IDLE, START, RCVG, STOP};
  49. //
  50. //  Global variables
  51. //
  52. byte* rxBuffer = 0;
  53. volatile byte rxBufferIndex = 0;
  54. volatile byte rxBits = 0;
  55. volatile byte rxComplete = 0;
  56. volatile byte rxCount = 0;
  57. volatile byte rxState = 0;
  58. //
  59. word address = 0;
  60. word data = 0;
  61. byte block = 0;
  62. word block_1;
  63. word block_2;
  64. word block_3;
  65. word block_4;
  66. byte group_complete = 0;
  67. byte synchronized = 0;
  68. //
  69. //  Setup begins here.
  70. //
  71. void setup()
  72. {
  73.   delay(500);      //  A 500ms delay, change this to suit your taste!
  74.   pinMode(SDA, INPUT);
  75.   digitalWrite(SDA, HIGH);
  76.   pinMode(SCK, INPUT);
  77.   digitalWrite(SCK, HIGH);
  78.   delay(100);  
  79.   initialize();    // Call initialize to set everything up.
  80.   delay(100);
  81.   Serial.begin(19200);
  82. }
  83. //
  84. //  Main Program Loop.
  85. //
  86. void loop()
  87. {
  88.    while(1)
  89.     {
  90.       if (rxComplete)
  91.         {
  92.           update_blocks();
  93.           rxComplete = 0;
  94.         }  
  95.            
  96.       if (group_complete)
  97.         {
  98.           send_data();
  99.           group_complete = 0;
  100.         }
  101.     }      
  102. }    
  103. //
  104. //  RDS Blocks get updated and sorted here.  First the register address, then the corresponding data.
  105. //
  106. void update_blocks()
  107. {
  108.   if (rxBuffer[0] != 0x38)  //  This version does not support HD, return.
  109.     return;
  110.  
  111.   if (rxBuffer[4] == 0xC4)  //  Any write to address 0xC4 is a channel change.
  112.     {
  113.       clear();              //  Reset RDS Spy.
  114.       return;
  115.     }  
  116.  
  117.   if (rxBuffer[3] == 0x30)  
  118.     {
  119.       address = 0x0000 | rxBuffer[5] << 8 | rxBuffer[6];
  120.       synchronized = 1;
  121.      
  122.       switch (address)
  123.         {
  124.           case 0x0080:
  125.             block = 1;
  126.             break;
  127.          
  128.           case 0x0084:
  129.             block = 2;
  130.             break;
  131.          
  132.           case 0x0088:
  133.             block = 3;
  134.             break;
  135.            
  136.           case 0x008C:
  137.             block = 4;
  138.             break;
  139.            
  140.           default:
  141.             block = 0;
  142.             synchronized = 0;
  143.         }      
  144.       return;
  145.     }
  146.  
  147.   if (!synchronized)
  148.     return;
  149.    
  150.   if (rxBuffer[3] == 0x31)
  151.     {
  152.       data = 0x0000 | rxBuffer[5] << 8 | rxBuffer[6];
  153.      
  154.       switch (block)
  155.         {
  156.           case 1:
  157.             block_1 = data;
  158.             break;
  159.          
  160.           case 2:
  161.             block_2 = data;
  162.             break;    
  163.          
  164.           case 3:
  165.             block_3 = data;
  166.             break;
  167.          
  168.           case 4:
  169.             block_4 = data;
  170.             group_complete = 1;
  171.             break;
  172.        }
  173.     }    
  174. }
  175. //
  176. //  Send the data to RDS Spy.
  177. //
  178. void send_data()
  179. {
  180.   Serial.println("G:");
  181.   printHex(block_1);
  182.   printHex(block_2);
  183.   printHex(block_3);
  184.   printHex(block_4);
  185.   Serial.println();
  186.   Serial.println();
  187. }  
  188. //
  189. //  Four digit hexadecimal print routine.
  190. //
  191. void printHex(word value)
  192. {
  193.   Serial.print(value >> 12 & 0x0F, HEX);
  194.   Serial.print(value >>  8 & 0x0F, HEX);
  195.   Serial.print(value >>  4 & 0x0F, HEX);
  196.   Serial.print(value >>  0 & 0x0F, HEX);
  197. }
  198. //
  199. //  This routine resets RDS Spy.
  200. //
  201. void clear()
  202. {
  203.   Serial.println("G:");
  204.   Serial.println("RESET");
  205.   Serial.println();
  206.   rxState = IDLE;
  207.   group_complete = 0;
  208. }  
  209. //
  210. //  Setup the microprocessor.
  211. //
  212. void initialize()
  213. {
  214.   cli();   //  Disable global interrupts while we make our changes.
  215.      
  216.   EICRA |= (1 << ISC11 | 1 << ISC10 | 1 << ISC00);  //  Setup Interrupt 0 & 1.
  217.   EIMSK |= (1 << INT1 | 1 << INT0);  //  Enable Interrupt 0 & 1;
  218.  
  219.   ADCSRA &= ~(1 << ADEN);    //  Disable the analog comparator.
  220.   TIMSK0 &= ~(1 << TOIE0);   //  Disable Timer 0.
  221.   TIMSK1 &= ~(1 << TOIE1);   //  Disable Timer 1 - Turns Off PWM.
  222.   TIMSK2 &= ~(1 << TOIE2);   //  Disable Timer 2.
  223.  
  224.   rxBuffer = (uint8_t*) calloc(BUFFER_LENGTH, sizeof(uint8_t));  //  Initialize the receive buffer.
  225.  
  226.   sei();    //  Enable global interrupts.
  227. }
  228. //
  229. //  Interrupt 0 Service Routine - Triggered on the Rising and Falling edge of Serial Data.
  230. //
  231. ISR(INT0_vect, ISR_NOBLOCK)
  232. {
  233.   byte mask = (PIND & 0x0C);
  234.  
  235.   switch (rxState)
  236.     {
  237.       case IDLE:
  238.         if (mask != 0x08)
  239.           return;
  240.         rxBufferIndex = 0;
  241.         rxState = START;
  242.         break;
  243.                
  244.       case START:
  245.         rxBits = 0;
  246.         rxCount = 0;
  247.         rxState = RCVG;
  248.         break;
  249.        
  250.       case RCVG:
  251.         if (mask == 0x08)
  252.           {
  253.             rxState = START;
  254.             return;
  255.           }  
  256.      
  257.       case STOP:    
  258.         if (mask != 0x0C)
  259.           return;
  260.         rxComplete = 1;
  261.         rxState = IDLE;
  262.         break;
  263.        
  264.       default:
  265.         rxState = IDLE;
  266.         break;    
  267.     }
  268. }
  269. //
  270. //  Interrupt 1 Service Routine - Triggered on the Rising edge of Serial Clock.
  271. //
  272. ISR(INT1_vect, ISR_NOBLOCK)
  273. {
  274.   DELAY;
  275.   switch (rxCount)
  276.     {
  277.       case 0:
  278.       case 1:
  279.       case 2:
  280.       case 3:
  281.       case 4:
  282.       case 5:
  283.       case 6:
  284.       case 7:
  285.         if (PIND & _BV(2))
  286.           bitSet(rxBits, (7 - rxCount));
  287.         rxCount++;
  288.         break;
  289.       case 8:
  290.         rxBuffer[rxBufferIndex] = rxBits;
  291.         rxBufferIndex++;
  292.         rxBits = 0;
  293.         rxCount = 0;
  294.         break;
  295.       default:
  296.         rxState = IDLE;
  297.         break;  
  298.     }
  299. }
  300. //
  301. //  That's all.
  302. //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement