C1541-III mbed edition

Dependencies:   mbed

Committer:
gertk
Date:
Mon Aug 22 21:11:59 2011 +0000
Revision:
1:0cbbb66a6100
Parent:
0:28557a4d2215
updated the nRESET pin to an interrupt capable pin (p29)

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 1:0cbbb66a6100 99 IEC_CLOCK_REL();
gertk 0:28557a4d2215 100 IEC_DATA_REL();
gertk 1:0cbbb66a6100 101 IEC_SRQ_REL();
gertk 0:28557a4d2215 102 EOI = FALSE;
gertk 0:28557a4d2215 103 TimeOut = FALSE;
gertk 0:28557a4d2215 104 }
gertk 0:28557a4d2215 105
gertk 0:28557a4d2215 106 void SetIEC_timings(unsigned char settings)
gertk 0:28557a4d2215 107 {
gertk 0:28557a4d2215 108 switch(settings)
gertk 0:28557a4d2215 109 {
gertk 0:28557a4d2215 110 case TIMINGS_VIC20: /*Timings for VIC-20 mode*/
gertk 0:28557a4d2215 111 { /*-----------------------*/
gertk 0:28557a4d2215 112 IEC_receive_delay = 52; /*set delay to ..uSec*/
gertk 0:28557a4d2215 113 IEC_send_delay = 60; /*set delay to ..uSec*/
gertk 0:28557a4d2215 114 break;
gertk 0:28557a4d2215 115 }
gertk 0:28557a4d2215 116
gertk 0:28557a4d2215 117 case TIMINGS_DTV: /*Timings for DTV (tuned IEC-bus speeds)*/
gertk 0:28557a4d2215 118 { /*--------------------------------------*/
gertk 0:28557a4d2215 119 IEC_receive_delay = 60; /*set delay to ..uSec*/
gertk 0:28557a4d2215 120 IEC_send_delay = 80; /*set delay to ..uSec*/
gertk 0:28557a4d2215 121 break;
gertk 0:28557a4d2215 122 }
gertk 0:28557a4d2215 123
gertk 0:28557a4d2215 124 default: /*Timings according (C64) IEC-specs*/
gertk 0:28557a4d2215 125 { /*---------------------------------*/
gertk 0:28557a4d2215 126 IEC_receive_delay = 70; /*set delay to ..uSec*/
gertk 0:28557a4d2215 127 IEC_send_delay = 80; /*set delay to ..uSec*/
gertk 0:28557a4d2215 128 break;
gertk 0:28557a4d2215 129 }
gertk 0:28557a4d2215 130 }
gertk 0:28557a4d2215 131 }
gertk 0:28557a4d2215 132
gertk 0:28557a4d2215 133 /*free the IEC bus for use by other devices, the bus is free'd until ATN is released*/
gertk 0:28557a4d2215 134 void FreeIEC(void)
gertk 0:28557a4d2215 135 {
gertk 0:28557a4d2215 136 IEC_ATN_REL();
gertk 1:0cbbb66a6100 137 IEC_CLOCK_REL();
gertk 0:28557a4d2215 138 IEC_DATA_REL();
gertk 0:28557a4d2215 139 while(IEC_ATN() == 0);
gertk 0:28557a4d2215 140 }
gertk 0:28557a4d2215 141
gertk 0:28557a4d2215 142
gertk 0:28557a4d2215 143 /*this routine will wait untill it receives one byte over the IEC-bus*/
gertk 0:28557a4d2215 144 unsigned char IEC_receive(unsigned char frame_handshake)
gertk 0:28557a4d2215 145 {
gertk 0:28557a4d2215 146 unsigned char data;
gertk 0:28557a4d2215 147 unsigned char bitcount;
gertk 0:28557a4d2215 148 unsigned long t;
gertk 0:28557a4d2215 149
gertk 0:28557a4d2215 150 EOI = FALSE; /*clear the EOI flag*/
gertk 0:28557a4d2215 151 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 152 data = 0; /*clear destination register*/
gertk 0:28557a4d2215 153 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 154
gertk 0:28557a4d2215 155 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 156 while (IEC_CLOCK() == 0); /*wait (endlessly) until we see some action on the bus, we may respond whenever we please*/
gertk 0:28557a4d2215 157
gertk 0:28557a4d2215 158 /*Step2:Ready for data--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 159 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 160
gertk 0:28557a4d2215 161 /*-----intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 162 t = 5000; /*timeout value for detecting an EOI condition*/
gertk 0:28557a4d2215 163 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 164 {
gertk 0:28557a4d2215 165 t--; /*when timed out, we have detected an EOI condition*/
gertk 0:28557a4d2215 166 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 167 {
gertk 0:28557a4d2215 168 EOI = TRUE; /*set the EOI flag*/
gertk 0:28557a4d2215 169 IEC_DATA_PULL(); /*acknowledge the EOI condition*/
gertk 0:28557a4d2215 170 DelayBigUs(IEC_receive_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 171 IEC_DATA_REL(); /*acknowledge the EOI condition*/
gertk 0:28557a4d2215 172 }
gertk 0:28557a4d2215 173 }
gertk 0:28557a4d2215 174
gertk 0:28557a4d2215 175 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 176 while (bitcount != 0) /*data is received with LSB first*/
gertk 0:28557a4d2215 177 {
gertk 0:28557a4d2215 178 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 179 bitcount--; /*decrement bitcounter by one*/
gertk 0:28557a4d2215 180 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 181 while (IEC_CLOCK() == 0); /*wait for the talker to release the clock line to signal "bit ready"*/
gertk 0:28557a4d2215 182 {
gertk 0:28557a4d2215 183 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 184 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 185 {
gertk 0:28557a4d2215 186 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 187 return(0); /*exit*/
gertk 0:28557a4d2215 188 }
gertk 0:28557a4d2215 189 }
gertk 0:28557a4d2215 190
gertk 0:28557a4d2215 191 if (IEC_DATA() == 1) /*test if bit is set or cleared (attention:documentation states that signals are inverted ?!?! error ?!?!*/
gertk 0:28557a4d2215 192 data = data + 128; /*make bit 7 high*/
gertk 0:28557a4d2215 193
gertk 0:28557a4d2215 194 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 195 while (IEC_CLOCK() == 1); /*wait for the talker to pulldown the clock line*/
gertk 0:28557a4d2215 196 {
gertk 0:28557a4d2215 197 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 198 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 199 {
gertk 0:28557a4d2215 200 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 201 return(0); /*exit*/
gertk 0:28557a4d2215 202 }
gertk 0:28557a4d2215 203 }
gertk 0:28557a4d2215 204 }
gertk 0:28557a4d2215 205
gertk 0:28557a4d2215 206 /*-----Step4:frame handshake--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 207 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 208 DelayBigUs(1250); /*delay for more then 1000 uSec*/
gertk 0:28557a4d2215 209
gertk 0:28557a4d2215 210 IEC_DATA_PULL();
gertk 0:28557a4d2215 211 return(data); /*exit with the received data*/
gertk 0:28557a4d2215 212 }
gertk 0:28557a4d2215 213
gertk 0:28557a4d2215 214
gertk 0:28557a4d2215 215 /*this routine will send one byte over the IEC-bus*/
gertk 0:28557a4d2215 216 unsigned char IEC_send(unsigned char data)
gertk 0:28557a4d2215 217 {
gertk 0:28557a4d2215 218 unsigned char bitcount;
gertk 0:28557a4d2215 219 unsigned long t;
gertk 0:28557a4d2215 220 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 221 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 222
gertk 0:28557a4d2215 223 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 224
gertk 0:28557a4d2215 225 IEC_CLOCK_REL(); /*indicate to the listener that we are ready to send*/
gertk 0:28557a4d2215 226
gertk 0:28557a4d2215 227 /*-----Step2:Ready for data--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 228 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 229
gertk 0:28557a4d2215 230 /*intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 231 if (EOI == TRUE)
gertk 0:28557a4d2215 232 {
gertk 0:28557a4d2215 233 DelayUs(200); /*delay for more then 200 uSec*/
gertk 0:28557a4d2215 234 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 235 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 236 {
gertk 0:28557a4d2215 237 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 238 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 239 {
gertk 0:28557a4d2215 240 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 241 return(FALSE); /*exit*/
gertk 0:28557a4d2215 242 }
gertk 0:28557a4d2215 243 }
gertk 0:28557a4d2215 244 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 245 while (IEC_DATA() == 0); /**/
gertk 0:28557a4d2215 246 {
gertk 0:28557a4d2215 247 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 248 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 249 {
gertk 0:28557a4d2215 250 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 251 return(FALSE); /*exit*/
gertk 0:28557a4d2215 252 }
gertk 0:28557a4d2215 253 }
gertk 0:28557a4d2215 254 /*EOI is acknowledged by the listener (computer)*/
gertk 0:28557a4d2215 255 }
gertk 0:28557a4d2215 256 IEC_CLOCK_PULL(); /*indicate to the listener (computer) that the transmission will start*/
gertk 0:28557a4d2215 257 DelayUs(IEC_send_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 258
gertk 0:28557a4d2215 259 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 260 while (bitcount != 0) /*data is transmitted with LSB first*/
gertk 0:28557a4d2215 261 {
gertk 0:28557a4d2215 262 IEC_CLOCK_PULL(); /*release the clockline in order to set the next bit on the data-line*/
gertk 0:28557a4d2215 263 DelayUs(IEC_send_delay); /*delay for .. uSec*/
gertk 0:28557a4d2215 264 bitcount--;
gertk 0:28557a4d2215 265 if (data & 0x01)
gertk 0:28557a4d2215 266 {
gertk 0:28557a4d2215 267 IEC_DATA_REL();
gertk 0:28557a4d2215 268 }
gertk 0:28557a4d2215 269 else
gertk 0:28557a4d2215 270 {
gertk 0:28557a4d2215 271 IEC_DATA_PULL();
gertk 0:28557a4d2215 272 }
gertk 0:28557a4d2215 273 IEC_CLOCK_REL(); /*indicate to the listener (computer) "bit ready"*/
gertk 0:28557a4d2215 274 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 275 DelayUs(IEC_send_delay); /*delay for at least 60uSec when a C64 is listening*/
gertk 0:28557a4d2215 276 }
gertk 0:28557a4d2215 277 IEC_CLOCK_PULL(); /*the whole byte has been transmitted*/
gertk 0:28557a4d2215 278 DelayUs(IEC_send_delay); /*delay for at least 60uSec when a C64 is listening*/
gertk 0:28557a4d2215 279 IEC_DATA_REL(); /*set clock and data in the correct order and wait for an acknowledge*/
gertk 0:28557a4d2215 280 DelayUs(25); /*wait a few uSec to prevent a false trigger*/
gertk 0:28557a4d2215 281
gertk 0:28557a4d2215 282 /*----Step4:frame handshake--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 283 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 284 while (IEC_DATA() == 1) /*wait for the listener (computer) to acknowledge this byte it must respond within 1 mSec*/
gertk 0:28557a4d2215 285 {
gertk 0:28557a4d2215 286 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 287 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 288 {
gertk 0:28557a4d2215 289 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 290 return(FALSE); /*exit*/
gertk 0:28557a4d2215 291 }
gertk 0:28557a4d2215 292 }
gertk 0:28557a4d2215 293 DelayUs(100); /*time between bytes is according IEC-specs at least 100 uSec*/
gertk 0:28557a4d2215 294 return(TRUE); /*the byte has been succesfully transmitted*/
gertk 0:28557a4d2215 295 }
gertk 0:28557a4d2215 296
gertk 0:28557a4d2215 297
gertk 0:28557a4d2215 298 /*this routine will wait untill it receives one byte over the IEC-bus*/
gertk 0:28557a4d2215 299 /*this routine does NOT generate any signals, it only listens... */
gertk 0:28557a4d2215 300 unsigned char IEC_monitor(void)
gertk 0:28557a4d2215 301 {
gertk 0:28557a4d2215 302 unsigned char data;
gertk 0:28557a4d2215 303 unsigned char bitcount;
gertk 0:28557a4d2215 304 unsigned long t;
gertk 0:28557a4d2215 305
gertk 0:28557a4d2215 306 EOI = FALSE; /*clear the EOI flag*/
gertk 0:28557a4d2215 307 TimeOut = FALSE; /*clear the timeout flag*/
gertk 0:28557a4d2215 308 data = 0; /*clear destination register*/
gertk 0:28557a4d2215 309 bitcount = 8; /*the number of bits within a byte are still eight*/
gertk 0:28557a4d2215 310
gertk 0:28557a4d2215 311 /*-----Step1:Ready to send--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 312 while (IEC_CLOCK() == 0); /*wait (endlessly) until we see some action on the bus, we may respond whenever we please*/
gertk 0:28557a4d2215 313
gertk 0:28557a4d2215 314 /*-----intermission:EOI--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 315 t = 5000; /*timeout value for detecting an EOI condition*/
gertk 0:28557a4d2215 316 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 317 {
gertk 0:28557a4d2215 318 t--; /*when timed out, we have detected an EOI condition*/
gertk 0:28557a4d2215 319 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 320 EOI = TRUE; /*set the EOI flag*/
gertk 0:28557a4d2215 321 }
gertk 0:28557a4d2215 322
gertk 0:28557a4d2215 323 /*-----Step3:receiving the bits--------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 324 while (bitcount != 0) /*data is received with LSB first*/
gertk 0:28557a4d2215 325 {
gertk 0:28557a4d2215 326 data>>=1; /*shift the byte one bit to the right*/
gertk 0:28557a4d2215 327 bitcount--; /*decrement bitcounter by one*/
gertk 0:28557a4d2215 328 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 329 while (IEC_CLOCK() == 0); /*wait for the talker to release the clock line to signal "bit ready"*/
gertk 0:28557a4d2215 330 {
gertk 0:28557a4d2215 331 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 332 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 333 {
gertk 0:28557a4d2215 334 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 335 return(0); /*exit*/
gertk 0:28557a4d2215 336 }
gertk 0:28557a4d2215 337 }
gertk 0:28557a4d2215 338
gertk 0:28557a4d2215 339 if (IEC_DATA() == 1) /*test if bit is set or cleared (attention:documentation states that signals are inverted ?!?! error ?!?!*/
gertk 0:28557a4d2215 340 data = data + 128; /*make bit 7 high*/
gertk 0:28557a4d2215 341
gertk 0:28557a4d2215 342 t = 5000; /*timeout value*/
gertk 0:28557a4d2215 343 while (IEC_CLOCK() == 1); /*wait for the talker to pulldown the clock line*/
gertk 0:28557a4d2215 344 {
gertk 0:28557a4d2215 345 t--; /*timeout detection is required to prevent "hanging" in case of data transmission erros*/
gertk 0:28557a4d2215 346 if (t == 0) /*timeout detected ?*/
gertk 0:28557a4d2215 347 {
gertk 0:28557a4d2215 348 TimeOut = TRUE; /*set the timeout flag*/
gertk 0:28557a4d2215 349 return(0); /*exit*/
gertk 0:28557a4d2215 350 }
gertk 0:28557a4d2215 351 }
gertk 0:28557a4d2215 352 }
gertk 0:28557a4d2215 353 return(data); /*exit with the received data*/
gertk 0:28557a4d2215 354 }
gertk 0:28557a4d2215 355
gertk 0:28557a4d2215 356
gertk 0:28557a4d2215 357 /*this routine will handle strings, for sending strings over the IEC-bus*/
gertk 0:28557a4d2215 358 void IEC_send_string(const unsigned char *inputstring)
gertk 0:28557a4d2215 359 {
gertk 0:28557a4d2215 360 unsigned char lp;
gertk 0:28557a4d2215 361
gertk 0:28557a4d2215 362 lp = 0;
gertk 0:28557a4d2215 363 while(inputstring[lp] != 0)
gertk 0:28557a4d2215 364 {
gertk 0:28557a4d2215 365 IEC_send(inputstring[lp]);
gertk 0:28557a4d2215 366 lp++;
gertk 0:28557a4d2215 367 }
gertk 0:28557a4d2215 368 }
gertk 0:28557a4d2215 369
gertk 0:28557a4d2215 370 void IEC_send_number_as_ASCII(unsigned char number)
gertk 0:28557a4d2215 371 {
gertk 0:28557a4d2215 372 unsigned char i;
gertk 0:28557a4d2215 373
gertk 0:28557a4d2215 374 i = 0x30 + (number/10); /*10's of the value*/
gertk 0:28557a4d2215 375 IEC_send(i);
gertk 0:28557a4d2215 376 i = 0x30 + (number%10); /*1's of the value*/
gertk 0:28557a4d2215 377 IEC_send(i);
gertk 0:28557a4d2215 378 }
gertk 0:28557a4d2215 379
gertk 0:28557a4d2215 380 /*this routine will reverse the direction of the bus*/
gertk 0:28557a4d2215 381 void IEC_turnaround(void)
gertk 0:28557a4d2215 382 {
gertk 0:28557a4d2215 383 while (IEC_ATN() == 0); /*wait (endlessly) until the computer releases ATN*/
gertk 0:28557a4d2215 384 while (IEC_CLOCK() == 0); /*wait (endlessly) until the computer releases the clock line*/
gertk 0:28557a4d2215 385 IEC_DATA_REL();
gertk 0:28557a4d2215 386 DelayUs(25); /*small delay... to make the timing look like the timing of a real drive*/
gertk 0:28557a4d2215 387 IEC_CLOCK_PULL();
gertk 0:28557a4d2215 388 DelayUs(160); /*Tda = 80 uSec minimum acknowledge time for acknowledging the device is now a talker*/
gertk 0:28557a4d2215 389 }
gertk 0:28557a4d2215 390
gertk 0:28557a4d2215 391
gertk 0:28557a4d2215 392 /*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 393 void IEC_undoturnaround(void)
gertk 0:28557a4d2215 394 {
gertk 0:28557a4d2215 395 // unsigned int timeout_cnt;
gertk 0:28557a4d2215 396 // DelayUs(50); /*Talk-Attention release (max. 100uS)*/
gertk 0:28557a4d2215 397 IEC_DATA_PULL();
gertk 0:28557a4d2215 398 IEC_CLOCK_REL();
gertk 0:28557a4d2215 399 DelayUs(25); /*small delay for .. uSec in order to prevent a false trigger*/
gertk 0:28557a4d2215 400 // timeout_cnt = 0;
gertk 0:28557a4d2215 401 // while (IEC_CLOCK() == 1) /*wait until the computer pulls down the clock line or we timeout*/
gertk 0:28557a4d2215 402 // {
gertk 0:28557a4d2215 403 // if (timeout_cnt == 1000)
gertk 0:28557a4d2215 404 // break; /*timeout exceeded, leave routine*/
gertk 0:28557a4d2215 405 // else
gertk 0:28557a4d2215 406 // timeout_cnt++;
gertk 0:28557a4d2215 407 // }
gertk 0:28557a4d2215 408 }
gertk 0:28557a4d2215 409
gertk 0:28557a4d2215 410 /*this routine will let the bus lines go, as Jim Butterfield described, both talker and listener 'letgo'*/
gertk 0:28557a4d2215 411 void IEC_letgo(void)
gertk 0:28557a4d2215 412 {
gertk 0:28557a4d2215 413 DelayUs(50); /*after a suitable pause*/
gertk 0:28557a4d2215 414 IEC_DATA_REL(); /*dataline and clockline are released*/
gertk 0:28557a4d2215 415 IEC_CLOCK_REL();
gertk 0:28557a4d2215 416 }
gertk 0:28557a4d2215 417
gertk 0:28557a4d2215 418 extern DigitalOut(myled3);
gertk 0:28557a4d2215 419
gertk 0:28557a4d2215 420 unsigned char CheckForCommand(unsigned char *outputcommand, unsigned char frame_handshake)
gertk 0:28557a4d2215 421 {
gertk 0:28557a4d2215 422 if(IEC_ATN() == 1) /* wait untill there is relevant info (a command is indicated by the attention signal) on the bus */
gertk 0:28557a4d2215 423 {
gertk 0:28557a4d2215 424 IEC_DATA_REL(); /*free the bus... (if not allready released)*/
gertk 0:28557a4d2215 425 return(FALSE); /*no command received, yet...*/
gertk 0:28557a4d2215 426 }
gertk 0:28557a4d2215 427
gertk 0:28557a4d2215 428 IEC_DATA_PULL(); /*join the bus...*/
gertk 0:28557a4d2215 429 *outputcommand = IEC_receive(frame_handshake); /*save the received command to a register specified by the caller of this routine*/
gertk 0:28557a4d2215 430 if ((TimeOut == FALSE) && (IEC_ATN() == 0))
gertk 0:28557a4d2215 431 {
gertk 0:28557a4d2215 432 if (*outputcommand == UNLISTEN) /*check for command:UNLISTEN, device:..., Attention-line must still be active*/
gertk 0:28557a4d2215 433 return(UNLISTEN);
gertk 0:28557a4d2215 434
gertk 0:28557a4d2215 435 if (*outputcommand == UNTALK) /*check for command:UNTALK, device:..., Attention-line must still be active*/
gertk 0:28557a4d2215 436 return(UNTALK);
gertk 0:28557a4d2215 437
gertk 0:28557a4d2215 438 if ((*outputcommand & 0xF0) == DATA) /*check for command:DATA, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 439 {
gertk 0:28557a4d2215 440 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 441 return(DATA);
gertk 0:28557a4d2215 442 }
gertk 0:28557a4d2215 443
gertk 0:28557a4d2215 444 if ((*outputcommand & 0xF0) == CLOSE) /*check for command:CLOSE, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 445 {
gertk 0:28557a4d2215 446 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 447 return(CLOSE);
gertk 0:28557a4d2215 448 }
gertk 0:28557a4d2215 449
gertk 0:28557a4d2215 450 if ((*outputcommand & 0xF0) == OPEN) /*check for command:OPEN, channel:..., Attention-line must still be active*/
gertk 0:28557a4d2215 451 {
gertk 0:28557a4d2215 452 channel = *outputcommand & 0x0F; /*(if send) the channel is stored in the low-nibble of the command*/
gertk 0:28557a4d2215 453 return(OPEN);
gertk 0:28557a4d2215 454 }
gertk 0:28557a4d2215 455
gertk 0:28557a4d2215 456 return(*outputcommand); /*when none of the above... it's for another device, return the entire command for further analasys*/
gertk 0:28557a4d2215 457 }
gertk 0:28557a4d2215 458 return(FALSE); /*code should never reach this point!!!*/
gertk 0:28557a4d2215 459 }
gertk 0:28557a4d2215 460
gertk 0:28557a4d2215 461
gertk 0:28557a4d2215 462 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 463 /* local functions */
gertk 0:28557a4d2215 464 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 465
gertk 0:28557a4d2215 466
gertk 0:28557a4d2215 467
gertk 0:28557a4d2215 468
gertk 0:28557a4d2215 469 /*
gertk 0:28557a4d2215 470 The person who writes their sourcecode without comments is either very smart or very stupid
gertk 0:28557a4d2215 471 */