C1541-III mbed edition

Dependencies:   mbed

Committer:
gertk
Date:
Mon Aug 22 05:48:51 2011 +0000
Revision:
0:28557a4d2215
Child:
1:0cbbb66a6100
very early test version, works only with FAT16 formatted sd cards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gertk 0:28557a4d2215 1 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 2 /*This is the lowlevel IEC-bus_driver, */
gertk 0:28557a4d2215 3 /* */
gertk 0:28557a4d2215 4 /*Note that this driver is dirty because it polls the drive for it's flags. The */
gertk 0:28557a4d2215 5 /*routines in this driver should therefore only be called from a low priority task */
gertk 0:28557a4d2215 6 /* */
gertk 0:28557a4d2215 7 /*Attention: routines tuned for 20MHz */
gertk 0:28557a4d2215 8 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 9 /* History:
gertk 0:28557a4d2215 10 --------
gertk 0:28557a4d2215 11 2007-04-28 KeepItSimpleStupid, so hanging on to this live style I removed the 'filter' from the IEC_receive routine (it was unneccessary nonsense anyway)
gertk 0:28557a4d2215 12 2007-04-25 CheckForCommand had an delay of 200uS to ensure the "frame to release of ATN'-time" of min 20uS, this is removed and now in the higher level IEC staemachine (main.c)
gertk 0:28557a4d2215 13 2007-04-23 IECundoturnaround() was checking for the clok, this is not reuiqed in this situation, that's why the timeout worked bettre then no timeout, simply because the CLOCK check is not required at THIS stage of the communication
gertk 0:28557a4d2215 14 2007-04-16 removed a semicolon in the acknowledge timeout check... there should not be a semicolon after the while :-) (oops)
gertk 0:28557a4d2215 15 2007-04-15 ADDED a ATN check on IEC_turnaround routine
gertk 0:28557a4d2215 16 2007-04-09 removed all code that was made commentary with //
gertk 0:28557a4d2215 17 2007-04-08 added the same 'filter' on FreeIEC and CheckForCommand... and then disabled the new code with "//" simply because the new improvements made it even worse...
gertk 0:28557a4d2215 18 2007-04-07 added some extra checks to make sure we trigger/test the clock/data signals correctly (software signal filtering).
gertk 0:28557a4d2215 19 this is required because sometimes the device triggers incorrectly on signals meant for other devices on the bus
gertk 0:28557a4d2215 20 which is best noticable during intense bus trafic. But it is very likely to happen at any moment (you can't predict glitches/spikes).
gertk 0:28557a4d2215 21 2007-04-01 the check IEC_CLOCK == 1 in UNDOTURNAROUND now has a time-out, simply to improve reliablillity... it helps a lot!
gertk 0:28557a4d2215 22 2006-11-01 the channel value was always extracted from the commandbyte, even if there was no channel value. This caused problems in the new statemachine (before the new statemachine the channel was used before the 3f/5f command so this problme was no problem then)
gertk 0:28557a4d2215 23 2006-10-31 added thefunction IEC_monitor this function can be used to monitor bus activity without interfering
gertk 0:28557a4d2215 24 removed the setdeviceaddress function, since this is handled in MAIN.C
gertk 0:28557a4d2215 25 2006-10-30 the data and open command are identical when the errorchannel (15) is addressed
gertk 0:28557a4d2215 26 2006-10-22 changed the channel-variable to a variable outside the IEC_bus code, so it can be used in MAIN.c where it is declared
gertk 0:28557a4d2215 27 2006-10-20 added a function to set the timings of the IEC-bus (required for 25% faster VIC20-mode)
gertk 0:28557a4d2215 28 2006-07-03 changed 'FreeIEC' routine, this routine caused busylooping at an unwanted level, the busy-loop waiting for ATN going low
gertk 0:28557a4d2215 29 is now located in main, so we can do other things while not communicating over the IEC-bus (manual file selection for instance)
gertk 0:28557a4d2215 30 2006-07-02 changed WaitForCommand into CheckForCommand, since the routine is no longer a while loop
gertk 0:28557a4d2215 31 2006-03-28 change in release and pulldown ATN-line routines, caused by new PCB design
gertk 0:28557a4d2215 32 2006-02-22 added frame_handshake signal for later use
gertk 0:28557a4d2215 33 2006-02-02 improvements in code layout... i.o.w. making it more readable
gertk 0:28557a4d2215 34 2005-10-18 start of IEC bus driver
gertk 0:28557a4d2215 35 2005-10-19 further details on EOI condition
gertk 0:28557a4d2215 36 2005-10-22 delay routines for IEC timing
gertk 0:28557a4d2215 37 2005-10-25 corrected the IEC-receive routine (without EOI detection)
gertk 0:28557a4d2215 38 2005-10-26 timeouts and EOI handling
gertk 0:28557a4d2215 39 2005-10-27 bus turnaround routines and testing of write routines. Optimisation of the send routines
gertk 0:28557a4d2215 40 2006-01-04 added IEC_send_string, is much more convinient then printf
gertk 0:28557a4d2215 41 2006-01-10 TALK and LISTEN definitions were mixed up, is corrected. FreeIEC-routine added and improved
gertk 0:28557a4d2215 42 2006-01-13 adjusted delay in waitforcommand routine, now external devices work
gertk 0:28557a4d2215 43 2006-01-16 rewritten the waitforcommand routine
gertk 0:28557a4d2215 44 */
gertk 0:28557a4d2215 45
gertk 0:28557a4d2215 46 /* TO DO:
gertk 0:28557a4d2215 47 ------
gertk 0:28557a4d2215 48 - EOI acknowledge delay, set/test this to correct timings for 20MHz
gertk 0:28557a4d2215 49
gertk 0:28557a4d2215 50 */
gertk 0:28557a4d2215 51
gertk 0:28557a4d2215 52 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 53
gertk 0:28557a4d2215 54 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 55 /* includes */
gertk 0:28557a4d2215 56 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 57 #include <mbed.h>
gertk 0:28557a4d2215 58
gertk 0:28557a4d2215 59 #include <stdio.h>
gertk 0:28557a4d2215 60 #include <IEC_bus.h>
gertk 0:28557a4d2215 61 #include <delay.h>
gertk 0:28557a4d2215 62 #include <hardware.h>
gertk 0:28557a4d2215 63
gertk 0:28557a4d2215 64 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 65 /* constants */
gertk 0:28557a4d2215 66 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 67 #define FALSE 0 /*FALSE*/
gertk 0:28557a4d2215 68 #define TRUE 1 /*TRUE*/
gertk 0:28557a4d2215 69
gertk 0:28557a4d2215 70 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 71 /* globals */
gertk 0:28557a4d2215 72 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 73 unsigned char IEC_receive_delay; /*set delay to ..uSec*/
gertk 0:28557a4d2215 74 unsigned char IEC_send_delay; /*set delay to ..uSec*/
gertk 0:28557a4d2215 75
gertk 0:28557a4d2215 76 /*external variables (variables also used in other .c files)*/
gertk 0:28557a4d2215 77 /*external variables (variables also used in other .c files)*/
gertk 0:28557a4d2215 78 extern bit EOI; /*End Of Indicator: this flag (when TRUE) indicates that the last byte is being transmitted or received*/
gertk 0:28557a4d2215 79 extern bit TimeOut; /*Timeout-flag*/
gertk 0:28557a4d2215 80 extern unsigned char channel; /*this register holds the channel value*/
gertk 0:28557a4d2215 81
gertk 0:28557a4d2215 82 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 83 /* local functions */
gertk 0:28557a4d2215 84 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 85
gertk 0:28557a4d2215 86
gertk 0:28557a4d2215 87 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 88 /* external functions */
gertk 0:28557a4d2215 89 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 90
gertk 0:28557a4d2215 91 //IEC_ATN : when IEC_ATN=0 it means that all devices must switch to listen (receive) mode immediatly
gertk 0:28557a4d2215 92
gertk 0:28557a4d2215 93
gertk 0:28557a4d2215 94 /*set all IEC_signal lines in the correct mode*/
gertk 0:28557a4d2215 95 void InitIEC(void)
gertk 0:28557a4d2215 96 {
gertk 0:28557a4d2215 97 SetIEC_timings(TIMINGS_DEFAULT); /*set timings according the default settings (C64 compatible mode)*/
gertk 0:28557a4d2215 98 IEC_ATN_REL();
gertk 0:28557a4d2215 99 IEC_CLOCK_REL();
gertk 0:28557a4d2215 100 IEC_DATA_REL();
gertk 0:28557a4d2215 101 EOI = FALSE;
gertk 0:28557a4d2215 102 TimeOut = FALSE;
gertk 0:28557a4d2215 103 }
gertk 0:28557a4d2215 104
gertk 0:28557a4d2215 105 void SetIEC_timings(unsigned char settings)
gertk 0:28557a4d2215 106 {
gertk 0:28557a4d2215 107 switch(settings)
gertk 0:28557a4d2215 108 {
gertk 0:28557a4d2215 109 case TIMINGS_VIC20: /*Timings for VIC-20 mode*/
gertk 0:28557a4d2215 110 { /*-----------------------*/
gertk 0:28557a4d2215 111 IEC_receive_delay = 52; /*set delay to ..uSec*/
gertk 0:28557a4d2215 112 IEC_send_delay = 60; /*set delay to ..uSec*/
gertk 0:28557a4d2215 113 break;
gertk 0:28557a4d2215 114 }
gertk 0:28557a4d2215 115
gertk 0:28557a4d2215 116 case TIMINGS_DTV: /*Timings for DTV (tuned IEC-bus speeds)*/
gertk 0:28557a4d2215 117 { /*--------------------------------------*/
gertk 0:28557a4d2215 118 IEC_receive_delay = 60; /*set delay to ..uSec*/
gertk 0:28557a4d2215 119 IEC_send_delay = 80; /*set delay to ..uSec*/
gertk 0:28557a4d2215 120 break;
gertk 0:28557a4d2215 121 }
gertk 0:28557a4d2215 122
gertk 0:28557a4d2215 123 default: /*Timings according (C64) IEC-specs*/
gertk 0:28557a4d2215 124 { /*---------------------------------*/
gertk 0:28557a4d2215 125 IEC_receive_delay = 70; /*set delay to ..uSec*/
gertk 0:28557a4d2215 126 IEC_send_delay = 80; /*set delay to ..uSec*/
gertk 0:28557a4d2215 127 break;
gertk 0:28557a4d2215 128 }
gertk 0:28557a4d2215 129 }
gertk 0:28557a4d2215 130 }
gertk 0:28557a4d2215 131
gertk 0:28557a4d2215 132 /*free the IEC bus for use by other devices, the bus is free'd until ATN is released*/
gertk 0:28557a4d2215 133 void FreeIEC(void)
gertk 0:28557a4d2215 134 {
gertk 0:28557a4d2215 135 IEC_ATN_REL();
gertk 0:28557a4d2215 136 IEC_CLOCK_REL();
gertk 0:28557a4d2215 137 IEC_DATA_REL();
gertk 0:28557a4d2215 138 while(IEC_ATN() == 0);
gertk 0:28557a4d2215 139 }
gertk 0:28557a4d2215 140
gertk 0:28557a4d2215 141
gertk 0:28557a4d2215 142 /*this routine will wait untill it receives one byte over the IEC-bus*/
gertk 0:28557a4d2215 143 unsigned char IEC_receive(unsigned char frame_handshake)
gertk 0:28557a4d2215 144 {
gertk 0:28557a4d2215 145 unsigned char data;
gertk 0:28557a4d2215 146 unsigned char bitcount;
gertk 0:28557a4d2215 147 unsigned long t;
gertk 0:28557a4d2215 148
gertk 0:28557a4d2215 149 EOI = FALSE; /*clear the EOI flag*/
gertk 0:28557a4d2215 150 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 151 data = 0; /*clear destination register*/
gertk 0:28557a4d2215 152 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 153
gertk 0:28557a4d2215 154 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 155 while (IEC_CLOCK() == 0); /*wait (endlessly) until we see some action on the bus, we may respond whenever we please*/
gertk 0:28557a4d2215 156
gertk 0:28557a4d2215 157 /*Step2:Ready for data--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 158 IEC_DATA_REL(); /*response to talker READY FOR DATA, this signal has no time-limit since we may be busy formatting a disk or printing out a chunk of text to paper*/
gertk 0:28557a4d2215 159
gertk 0:28557a4d2215 160 /*-----intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 161 t = 5000; /*timeout value for detecting an EOI condition*/
gertk 0:28557a4d2215 162 while (IEC_CLOCK() == 1) /*wait for the talker to indicate that the transmission will start (this signal must be received within 200uS, otherwise we may consider it as an EOI)*/
gertk 0:28557a4d2215 163 {
gertk 0:28557a4d2215 164 t--; /*when timed out, we have detected an EOI condition*/
gertk 0:28557a4d2215 165 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 166 {
gertk 0:28557a4d2215 167 EOI = TRUE; /*set the EOI flag*/
gertk 0:28557a4d2215 168 IEC_DATA_PULL(); /*acknowledge the EOI condition*/
gertk 0:28557a4d2215 169 DelayBigUs(IEC_receive_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 170 IEC_DATA_REL(); /*acknowledge the EOI condition*/
gertk 0:28557a4d2215 171 }
gertk 0:28557a4d2215 172 }
gertk 0:28557a4d2215 173
gertk 0:28557a4d2215 174 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 175 while (bitcount != 0) /*data is received with LSB first*/
gertk 0:28557a4d2215 176 {
gertk 0:28557a4d2215 177 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 178 bitcount--; /*decrement bitcounter by one*/
gertk 0:28557a4d2215 179 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 180 while (IEC_CLOCK() == 0); /*wait for the talker to release the clock line to signal "bit ready"*/
gertk 0:28557a4d2215 181 {
gertk 0:28557a4d2215 182 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 183 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 184 {
gertk 0:28557a4d2215 185 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 186 return(0); /*exit*/
gertk 0:28557a4d2215 187 }
gertk 0:28557a4d2215 188 }
gertk 0:28557a4d2215 189
gertk 0:28557a4d2215 190 if (IEC_DATA() == 1) /*test if bit is set or cleared (attention:documentation states that signals are inverted ?!?! error ?!?!*/
gertk 0:28557a4d2215 191 data = data + 128; /*make bit 7 high*/
gertk 0:28557a4d2215 192
gertk 0:28557a4d2215 193 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 194 while (IEC_CLOCK() == 1); /*wait for the talker to pulldown the clock line*/
gertk 0:28557a4d2215 195 {
gertk 0:28557a4d2215 196 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 197 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 198 {
gertk 0:28557a4d2215 199 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 200 return(0); /*exit*/
gertk 0:28557a4d2215 201 }
gertk 0:28557a4d2215 202 }
gertk 0:28557a4d2215 203 }
gertk 0:28557a4d2215 204
gertk 0:28557a4d2215 205 /*-----Step4:frame handshake--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 206 if (frame_handshake == FALSE) /*we must acknowledge within 1 mS that we have received the data, if not the talker knows there is something wrong*/
gertk 0:28557a4d2215 207 DelayBigUs(1250); /*delay for more then 1000 uSec*/
gertk 0:28557a4d2215 208
gertk 0:28557a4d2215 209 IEC_DATA_PULL();
gertk 0:28557a4d2215 210 return(data); /*exit with the received data*/
gertk 0:28557a4d2215 211 }
gertk 0:28557a4d2215 212
gertk 0:28557a4d2215 213
gertk 0:28557a4d2215 214 /*this routine will send one byte over the IEC-bus*/
gertk 0:28557a4d2215 215 unsigned char IEC_send(unsigned char data)
gertk 0:28557a4d2215 216 {
gertk 0:28557a4d2215 217 unsigned char bitcount;
gertk 0:28557a4d2215 218 unsigned long t;
gertk 0:28557a4d2215 219 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 220 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 221
gertk 0:28557a4d2215 222 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 223
gertk 0:28557a4d2215 224 IEC_CLOCK_REL(); /*indicate to the listener that we are ready to send*/
gertk 0:28557a4d2215 225
gertk 0:28557a4d2215 226 /*-----Step2:Ready for data--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 227 while (IEC_DATA() == 0); /*wait for the listener (computer) to release the data-line (ready to receive data), this may take forever... (according the IEC-bus definition)*/
gertk 0:28557a4d2215 228
gertk 0:28557a4d2215 229 /*intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 230 if (EOI == TRUE)
gertk 0:28557a4d2215 231 {
gertk 0:28557a4d2215 232 DelayUs(200); /*delay for more then 200 uSec*/
gertk 0:28557a4d2215 233 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 234 while (IEC_DATA() == 1); /*check for acknowledge of the EOI. The acknowledge is simply pulling the data-line down for a brief period*/
gertk 0:28557a4d2215 235 {
gertk 0:28557a4d2215 236 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 237 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 238 {
gertk 0:28557a4d2215 239 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 240 return(FALSE); /*exit*/
gertk 0:28557a4d2215 241 }
gertk 0:28557a4d2215 242 }
gertk 0:28557a4d2215 243 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 244 while (IEC_DATA() == 0); /**/
gertk 0:28557a4d2215 245 {
gertk 0:28557a4d2215 246 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 247 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 248 {
gertk 0:28557a4d2215 249 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 250 return(FALSE); /*exit*/
gertk 0:28557a4d2215 251 }
gertk 0:28557a4d2215 252 }
gertk 0:28557a4d2215 253 /*EOI is acknowledged by the listener (computer)*/
gertk 0:28557a4d2215 254 }
gertk 0:28557a4d2215 255 IEC_CLOCK_PULL(); /*indicate to the listener (computer) that the transmission will start*/
gertk 0:28557a4d2215 256 DelayUs(IEC_send_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 257
gertk 0:28557a4d2215 258 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 259 while (bitcount != 0) /*data is transmitted with LSB first*/
gertk 0:28557a4d2215 260 {
gertk 0:28557a4d2215 261 IEC_CLOCK_PULL(); /*release the clockline in order to set the next bit on the data-line*/
gertk 0:28557a4d2215 262 DelayUs(IEC_send_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 263 bitcount--;
gertk 0:28557a4d2215 264 if (data & 0x01)
gertk 0:28557a4d2215 265 {
gertk 0:28557a4d2215 266 IEC_DATA_REL();
gertk 0:28557a4d2215 267 }
gertk 0:28557a4d2215 268 else
gertk 0:28557a4d2215 269 {
gertk 0:28557a4d2215 270 IEC_DATA_PULL();
gertk 0:28557a4d2215 271 }
gertk 0:28557a4d2215 272 IEC_CLOCK_REL(); /*indicate to the listener (computer) "bit ready"*/
gertk 0:28557a4d2215 273 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 274 DelayUs(IEC_send_delay); /*delay for at least 60uSec when a C64 is listening*/
gertk 0:28557a4d2215 275 }
gertk 0:28557a4d2215 276 IEC_CLOCK_PULL(); /*the whole byte has been transmitted*/
gertk 0:28557a4d2215 277 DelayUs(IEC_send_delay); /*delay for at least 60uSec when a C64 is listening*/
gertk 0:28557a4d2215 278 IEC_DATA_REL(); /*set clock and data in the correct order and wait for an acknowledge*/
gertk 0:28557a4d2215 279 DelayUs(25); /*wait a few uSec to prevent a false trigger*/
gertk 0:28557a4d2215 280
gertk 0:28557a4d2215 281 /*----Step4:frame handshake--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 282 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 283 while (IEC_DATA() == 1) /*wait for the listener (computer) to acknowledge this byte it must respond within 1 mSec*/
gertk 0:28557a4d2215 284 {
gertk 0:28557a4d2215 285 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 286 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 287 {
gertk 0:28557a4d2215 288 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 289 return(FALSE); /*exit*/
gertk 0:28557a4d2215 290 }
gertk 0:28557a4d2215 291 }
gertk 0:28557a4d2215 292 DelayUs(100); /*time between bytes is according IEC-specs at least 100 uSec*/
gertk 0:28557a4d2215 293 return(TRUE); /*the byte has been succesfully transmitted*/
gertk 0:28557a4d2215 294 }
gertk 0:28557a4d2215 295
gertk 0:28557a4d2215 296
gertk 0:28557a4d2215 297 /*this routine will wait untill it receives one byte over the IEC-bus*/
gertk 0:28557a4d2215 298 /*this routine does NOT generate any signals, it only listens... */
gertk 0:28557a4d2215 299 unsigned char IEC_monitor(void)
gertk 0:28557a4d2215 300 {
gertk 0:28557a4d2215 301 unsigned char data;
gertk 0:28557a4d2215 302 unsigned char bitcount;
gertk 0:28557a4d2215 303 unsigned long t;
gertk 0:28557a4d2215 304
gertk 0:28557a4d2215 305 EOI = FALSE; /*clear the EOI flag*/
gertk 0:28557a4d2215 306 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 307 data = 0; /*clear destination register*/
gertk 0:28557a4d2215 308 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 309
gertk 0:28557a4d2215 310 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 311 while (IEC_CLOCK() == 0); /*wait (endlessly) until we see some action on the bus, we may respond whenever we please*/
gertk 0:28557a4d2215 312
gertk 0:28557a4d2215 313 /*-----intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 314 t = 5000; /*timeout value for detecting an EOI condition*/
gertk 0:28557a4d2215 315 while (IEC_CLOCK() == 1) /*wait for the talker to indicate that the transmission will start (this signal must be received within 200uS, otherwise we may consider it as an EOI)*/
gertk 0:28557a4d2215 316 {
gertk 0:28557a4d2215 317 t--; /*when timed out, we have detected an EOI condition*/
gertk 0:28557a4d2215 318 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 319 EOI = TRUE; /*set the EOI flag*/
gertk 0:28557a4d2215 320 }
gertk 0:28557a4d2215 321
gertk 0:28557a4d2215 322 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 323 while (bitcount != 0) /*data is received with LSB first*/
gertk 0:28557a4d2215 324 {
gertk 0:28557a4d2215 325 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 326 bitcount--; /*decrement bitcounter by one*/
gertk 0:28557a4d2215 327 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 328 while (IEC_CLOCK() == 0); /*wait for the talker to release the clock line to signal "bit ready"*/
gertk 0:28557a4d2215 329 {
gertk 0:28557a4d2215 330 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 331 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 332 {
gertk 0:28557a4d2215 333 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 334 return(0); /*exit*/
gertk 0:28557a4d2215 335 }
gertk 0:28557a4d2215 336 }
gertk 0:28557a4d2215 337
gertk 0:28557a4d2215 338 if (IEC_DATA() == 1) /*test if bit is set or cleared (attention:documentation states that signals are inverted ?!?! error ?!?!*/
gertk 0:28557a4d2215 339 data = data + 128; /*make bit 7 high*/
gertk 0:28557a4d2215 340
gertk 0:28557a4d2215 341 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 342 while (IEC_CLOCK() == 1); /*wait for the talker to pulldown the clock line*/
gertk 0:28557a4d2215 343 {
gertk 0:28557a4d2215 344 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 345 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 346 {
gertk 0:28557a4d2215 347 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 348 return(0); /*exit*/
gertk 0:28557a4d2215 349 }
gertk 0:28557a4d2215 350 }
gertk 0:28557a4d2215 351 }
gertk 0:28557a4d2215 352 return(data); /*exit with the received data*/
gertk 0:28557a4d2215 353 }
gertk 0:28557a4d2215 354
gertk 0:28557a4d2215 355
gertk 0:28557a4d2215 356 /*this routine will handle strings, for sending strings over the IEC-bus*/
gertk 0:28557a4d2215 357 void IEC_send_string(const unsigned char *inputstring)
gertk 0:28557a4d2215 358 {
gertk 0:28557a4d2215 359 unsigned char lp;
gertk 0:28557a4d2215 360
gertk 0:28557a4d2215 361 lp = 0;
gertk 0:28557a4d2215 362 while(inputstring[lp] != 0)
gertk 0:28557a4d2215 363 {
gertk 0:28557a4d2215 364 IEC_send(inputstring[lp]);
gertk 0:28557a4d2215 365 lp++;
gertk 0:28557a4d2215 366 }
gertk 0:28557a4d2215 367 }
gertk 0:28557a4d2215 368
gertk 0:28557a4d2215 369 void IEC_send_number_as_ASCII(unsigned char number)
gertk 0:28557a4d2215 370 {
gertk 0:28557a4d2215 371 unsigned char i;
gertk 0:28557a4d2215 372
gertk 0:28557a4d2215 373 i = 0x30 + (number/10); /*10's of the value*/
gertk 0:28557a4d2215 374 IEC_send(i);
gertk 0:28557a4d2215 375 i = 0x30 + (number%10); /*1's of the value*/
gertk 0:28557a4d2215 376 IEC_send(i);
gertk 0:28557a4d2215 377 }
gertk 0:28557a4d2215 378
gertk 0:28557a4d2215 379 /*this routine will reverse the direction of the bus*/
gertk 0:28557a4d2215 380 void IEC_turnaround(void)
gertk 0:28557a4d2215 381 {
gertk 0:28557a4d2215 382 while (IEC_ATN() == 0); /*wait (endlessly) until the computer releases ATN*/
gertk 0:28557a4d2215 383 while (IEC_CLOCK() == 0); /*wait (endlessly) until the computer releases the clock line*/
gertk 0:28557a4d2215 384 IEC_DATA_REL();
gertk 0:28557a4d2215 385 DelayUs(25); /*small delay... to make the timing look like the timing of a real drive*/
gertk 0:28557a4d2215 386 IEC_CLOCK_PULL();
gertk 0:28557a4d2215 387 DelayUs(160); /*Tda = 80 uSec minimum acknowledge time for acknowledging the device is now a talker*/
gertk 0:28557a4d2215 388 }
gertk 0:28557a4d2215 389
gertk 0:28557a4d2215 390
gertk 0:28557a4d2215 391 /*this routine will set the direction on the bus back to normal (the way it was when the computer was switched on)*/
gertk 0:28557a4d2215 392 void IEC_undoturnaround(void)
gertk 0:28557a4d2215 393 {
gertk 0:28557a4d2215 394 // unsigned int timeout_cnt;
gertk 0:28557a4d2215 395 // DelayUs(50); /*Talk-Attention release (max. 100uS)*/
gertk 0:28557a4d2215 396 IEC_DATA_PULL();
gertk 0:28557a4d2215 397 IEC_CLOCK_REL();
gertk 0:28557a4d2215 398 DelayUs(25); /*small delay for .. uSec in order to prevent a false trigger*/
gertk 0:28557a4d2215 399 // timeout_cnt = 0;
gertk 0:28557a4d2215 400 // while (IEC_CLOCK() == 1) /*wait until the computer pulls down the clock line or we timeout*/
gertk 0:28557a4d2215 401 // {
gertk 0:28557a4d2215 402 // if (timeout_cnt == 1000)
gertk 0:28557a4d2215 403 // break; /*timeout exceeded, leave routine*/
gertk 0:28557a4d2215 404 // else
gertk 0:28557a4d2215 405 // timeout_cnt++;
gertk 0:28557a4d2215 406 // }
gertk 0:28557a4d2215 407 }
gertk 0:28557a4d2215 408
gertk 0:28557a4d2215 409 /*this routine will let the bus lines go, as Jim Butterfield described, both talker and listener 'letgo'*/
gertk 0:28557a4d2215 410 void IEC_letgo(void)
gertk 0:28557a4d2215 411 {
gertk 0:28557a4d2215 412 DelayUs(50); /*after a suitable pause*/
gertk 0:28557a4d2215 413 IEC_DATA_REL(); /*dataline and clockline are released*/
gertk 0:28557a4d2215 414 IEC_CLOCK_REL();
gertk 0:28557a4d2215 415 }
gertk 0:28557a4d2215 416
gertk 0:28557a4d2215 417 extern DigitalOut(myled3);
gertk 0:28557a4d2215 418
gertk 0:28557a4d2215 419 unsigned char CheckForCommand(unsigned char *outputcommand, unsigned char frame_handshake)
gertk 0:28557a4d2215 420 {
gertk 0:28557a4d2215 421 if(IEC_ATN() == 1) /* wait untill there is relevant info (a command is indicated by the attention signal) on the bus */
gertk 0:28557a4d2215 422 {
gertk 0:28557a4d2215 423 IEC_DATA_REL(); /*free the bus... (if not allready released)*/
gertk 0:28557a4d2215 424 return(FALSE); /*no command received, yet...*/
gertk 0:28557a4d2215 425 }
gertk 0:28557a4d2215 426
gertk 0:28557a4d2215 427 IEC_DATA_PULL(); /*join the bus...*/
gertk 0:28557a4d2215 428 *outputcommand = IEC_receive(frame_handshake); /*save the received command to a register specified by the caller of this routine*/
gertk 0:28557a4d2215 429 if ((TimeOut == FALSE) && (IEC_ATN() == 0))
gertk 0:28557a4d2215 430 {
gertk 0:28557a4d2215 431 if (*outputcommand == UNLISTEN) /*check for command:UNLISTEN, device:..., Attention-line must still be active*/
gertk 0:28557a4d2215 432 return(UNLISTEN);
gertk 0:28557a4d2215 433
gertk 0:28557a4d2215 434 if (*outputcommand == UNTALK) /*check for command:UNTALK, device:..., Attention-line must still be active*/
gertk 0:28557a4d2215 435 return(UNTALK);
gertk 0:28557a4d2215 436
gertk 0:28557a4d2215 437 if ((*outputcommand & 0xF0) == DATA) /*check for command:DATA, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 438 {
gertk 0:28557a4d2215 439 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 440 return(DATA);
gertk 0:28557a4d2215 441 }
gertk 0:28557a4d2215 442
gertk 0:28557a4d2215 443 if ((*outputcommand & 0xF0) == CLOSE) /*check for command:CLOSE, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 444 {
gertk 0:28557a4d2215 445 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 446 return(CLOSE);
gertk 0:28557a4d2215 447 }
gertk 0:28557a4d2215 448
gertk 0:28557a4d2215 449 if ((*outputcommand & 0xF0) == OPEN) /*check for command:OPEN, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 450 {
gertk 0:28557a4d2215 451 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 452 return(OPEN);
gertk 0:28557a4d2215 453 }
gertk 0:28557a4d2215 454
gertk 0:28557a4d2215 455 return(*outputcommand); /*when none of the above... it's for another device, return the entire command for further analasys*/
gertk 0:28557a4d2215 456 }
gertk 0:28557a4d2215 457 return(FALSE); /*code should never reach this point!!!*/
gertk 0:28557a4d2215 458 }
gertk 0:28557a4d2215 459
gertk 0:28557a4d2215 460
gertk 0:28557a4d2215 461 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 462 /* local functions */
gertk 0:28557a4d2215 463 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 464
gertk 0:28557a4d2215 465
gertk 0:28557a4d2215 466
gertk 0:28557a4d2215 467
gertk 0:28557a4d2215 468 /*
gertk 0:28557a4d2215 469 The person who writes their sourcecode without comments is either very smart or very stupid
gertk 0:28557a4d2215 470 */