Advertisement
Guest User

Arduino Floppy Reader (8us-12us widths)

a guest
Nov 2nd, 2011
3,363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.31 KB | None | 0 0
  1. // include the library code:
  2. #include <LiquidCrystal.h>
  3.  
  4. // initialize the library with the numbers of the interface pins
  5. LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  6.  
  7. //Mappings of floppy connector
  8. // <<NAME>> = pin#    //<<floppy pin#>> description
  9. //disabled a few pins to fit it all on an uno..
  10. //int DSKCHG = 50;    //34 Disk Change/Ready
  11. //int SIDE1 = 31;     //32 Head Select
  12. int RDATA = 6;        //30 Read data
  13. //int WPT = 35;       //28 Write protect
  14. int TRK00 = 7;        //26 Track 0
  15. //int WGATE = 39;     //24 Floppy Write Enable
  16. //int WDATA = 41;     //22 Write data
  17. int STEP = 8;         //20 Step
  18. int DIR = 9;          //18 Direction
  19. //int MOTEB = 47;     //16 motor enable a //twisted to 10 by cable twist
  20. //int DRVSA = 49;     //14 select drive a //twisted to 12 by cable twist
  21. //int DRVSB = 51;     //12 select drive b //twisted to 14 by cable twist
  22. //int MOTEA = 53;     //10 motor enable b //twisted to 16 by cable twist
  23. int INDEX = 10;       //08 index
  24.  
  25. //plus connect a few of the odd pins to gnd.. (pick some near the center)
  26.  
  27. //short MOTEB,MOTEA,DRVSA,DRVSB to gnd, to select 'both' drives..
  28. //saves a few pins on the arduino...
  29.  
  30. int iatoval=0;
  31. int maxloop=4; //how many times to move the head.
  32. int maxtrack=80;
  33. int currenttrack=-1; //set track to -1 to start, will cause us to try to locate track0
  34.  
  35. #define IDLE 255
  36. #define HEADSEEK 0
  37. #define INITFORREAD 1
  38. #define TIMEDATA 2
  39. byte state = HEADSEEK;
  40.  
  41. void setup()
  42. {
  43.   Serial.begin(115200);
  44.   Serial.println("Floppy reader.. test");
  45.   Serial.println();
  46.  
  47.   // set up the LCD's number of columns and rows:
  48.   lcd.begin(16, 2);
  49.   // Print a message to the LCD.
  50.   lcd.print("SETUP.");
  51.  
  52.   //Outputs
  53.   //pinMode(SIDE1, OUTPUT);
  54.   //pinMode(WGATE, OUTPUT);
  55.   //pinMode(WDATA, OUTPUT);
  56.   pinMode(DIR, OUTPUT);
  57.   pinMode(STEP, OUTPUT);
  58.   //pinMode(MOTEA, OUTPUT);
  59.   //pinMode(MOTEB, OUTPUT);
  60.   //pinMode(DRVSA, OUTPUT);
  61.   //pinMode(DRVSB, OUTPUT);
  62.  
  63.   //Inputs (all require a pullup)
  64.   pinMode(INDEX, INPUT);
  65.   digitalWrite(INDEX, HIGH);
  66.   pinMode(TRK00, INPUT);
  67.   digitalWrite(TRK00, HIGH);
  68. //  pinMode(WPT, INPUT);
  69. //  digitalWrite(INDEX, HIGH);  
  70.   pinMode(RDATA, INPUT);
  71.   digitalWrite(RDATA, HIGH);  
  72. //  pinMode(DSKCHG, INPUT);
  73. //  digitalWrite(INDEX, HIGH);
  74.  
  75.   //Floppy drive uses inverse logic
  76. //  digitalWrite(SIDE1, LOW);   //select a head.. don't know which
  77. //  digitalWrite(WGATE, HIGH);  //set the write gate high (disables write)
  78. //                              //may want to hook this to 5v for safety..
  79.   digitalWrite(DIR, HIGH);    //HIGH=toward edge, LOW=toward center
  80.   digitalWrite(STEP, HIGH);   // no step at the mo.
  81. //  digitalWrite(MOTEA, HIGH);  // stop the drive spinning
  82. //  digitalWrite(MOTEB, LOW);   // start the drive spinning
  83. //  digitalWrite(DRVSA, HIGH);
  84. //  digitalWrite(DRVSB, LOW);   //select drive b.. pc drives are wired as 'b'
  85. //                              //and use cable twist to flip to 'a'
  86.  
  87.   delay(1000); //wait for spin up.
  88.   lcd.setCursor(0,0);
  89.   lcd.print("                ");
  90.   //jiggle the head to init the trk0 sensor..
  91.   stepForward();
  92.   stepForward();
  93.   stepBackward();
  94.   stepBackward();
  95.   //wait a short while.
  96.   delay(100);
  97. }
  98.  
  99. void stepBackward(){
  100.       digitalWrite(DIR, HIGH);
  101.       digitalWrite(STEP, LOW);
  102.       delayMicroseconds(1);
  103.       digitalWrite(STEP, HIGH);
  104.       delayMicroseconds(3000);
  105. }
  106.  
  107. void stepForward(){
  108.       digitalWrite(DIR, LOW);
  109.       digitalWrite(STEP, LOW);
  110.       delayMicroseconds(1);
  111.       digitalWrite(STEP, HIGH);
  112.       delayMicroseconds(3000);
  113. }
  114.  
  115. boolean idxflip=true;
  116. long lastidx=-1;
  117. int indexcount=0;
  118. void doheadseek(){
  119.       iatoval = !digitalRead(TRK00);
  120.    
  121.     if(digitalRead(INDEX) != idxflip){
  122.       idxflip = !idxflip;        
  123.       long currentmillis = millis();
  124.        
  125.       if(lastidx==-1)
  126.         lastidx=currentmillis;
  127.        
  128.       if((currentmillis - lastidx) > 20){ //ignore the idx pulse width, we are tracking the space..
  129.         indexcount++;
  130.         if(indexcount>999)
  131.           indexcount=0;
  132.          
  133.         lcd.setCursor(7,1);
  134.         lcd.print(indexcount);
  135.        
  136.         lcd.setCursor(11,1);
  137.         lcd.print( (currentmillis - lastidx) );
  138.         lastidx = currentmillis;
  139.       }
  140.     }
  141.    
  142.  
  143.      
  144.     //debug iato val to lcd
  145.     if(iatoval){
  146.       lcd.setCursor(15,0);
  147.       lcd.print("0");
  148.     }else{
  149.       lcd.setCursor(15,0);
  150.       lcd.print(".");
  151.     }
  152.      
  153.     if(currenttrack<0 && !iatoval){
  154.       lcd.setCursor(14,0);
  155.       lcd.print("B");
  156.            
  157.       stepBackward();
  158.       currenttrack=currenttrack-1;
  159.     }
  160.    
  161.     if(currenttrack<0 && iatoval){
  162.       if(currenttrack<-95){
  163.         lcd.setCursor(14,0);
  164.         lcd.print("f");
  165.         //we have stepped backward enough that our track is now 0.. but TRK0 didnt fire.
  166.       }
  167.       if(iatoval){
  168.         lcd.setCursor(14,0);
  169.         lcd.print("F");
  170.         //we have stepped backward enough that TRK0 has told us where to stop
  171.       }
  172.      
  173.       currenttrack=0;
  174.       maxloop=maxloop-1;
  175.       if(maxloop==0){
  176.         state=INITFORREAD;
  177.       }
  178.      
  179.       lcd.setCursor(0,1);
  180.       lcd.print(" 00             ");
  181.     }
  182.    
  183.     if(maxloop>0)
  184.     {
  185.       if(currenttrack>maxtrack){        
  186.         currenttrack=-1; //will flip us to seek backwards..
  187.         lcd.setCursor(14,0);
  188.         lcd.print(" ");
  189.         lcd.setCursor(0,1);
  190.         lcd.print("BACK-0");
  191.       }
  192.    
  193.       if(currenttrack>=0 ){
  194.         //lcd.setCursor(0,0);
  195.         //lcd.print(iatoval);
  196.         lcd.setCursor(0,1);
  197.         lcd.print("TRK ");
  198.         lcd.setCursor(4,1);
  199.         lcd.print(currenttrack);
  200.        
  201.         stepForward();
  202.         currenttrack=currenttrack+1;
  203.       }
  204.     }
  205. }
  206.  
  207. #define GAPLIST 64
  208. #define GAPMAX 63
  209.  
  210. boolean timerdata=true;
  211. byte maxcount=32;
  212. byte rdatacount=0;
  213. int gap[GAPLIST];
  214. int *gapptr=&gap[0];
  215. long newmicros;
  216. long lastrdata=0;
  217. boolean rdataflip=true;
  218.  
  219. void loop()
  220. {
  221.   switch(state){
  222.     case HEADSEEK: {
  223.       doheadseek();
  224.       break;
  225.     }
  226.     case INITFORREAD: {
  227.       state = TIMEDATA;
  228.       break;
  229.     }
  230.     case TIMEDATA: {
  231.       //look for state changes on rdata  
  232.       //if(digitalRead(RDATA) != rdataflip){
  233.       if( ( PORTD & _BV(RDATA) ) != rdataflip){
  234.         newmicros=micros();
  235.         //record new state
  236.         rdataflip = !rdataflip;  
  237.         rdatacount++;    
  238.         if(rdatacount>GAPMAX){
  239.           //at some point, we have to dump some data,
  240.           //as the uno doesnt have space to store a track
  241.           //While dumping, we're going to miss data going past
  242.           //so the next gap is going to be a bit on the large side (~16k)          
  243.           rdatacount=0;     //reset counter for next loop round
  244.           gapptr = &gap[0]; //reset gapptr for data output
  245.          
  246.           //dump the array to the serial..
  247.           for(int i=0; i<GAPMAX; i++){
  248.             Serial.print(gap[i]);
  249.             Serial.print(" ");
  250.           }
  251.           Serial.print("\n");
  252.          
  253.           //when maxcount hits zero, we've done enough, for now.
  254.           maxcount--;
  255.           if(maxcount==0){
  256.             state=IDLE;
  257.           }
  258.         }          
  259.         *gapptr=newmicros-lastrdata;
  260.         gapptr++;
  261.      
  262.         lastrdata=newmicros;  
  263.       }
  264.  
  265.       break;
  266.     }
  267.     case IDLE:{
  268.       break;
  269.     }
  270.   }
  271. }
  272.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement