|
|
1.1 ! root 1: /* ! 2: Hatari ! 3: ! 4: RS-232 Communications ! 5: ! 6: This is similar to the Printing functions, we open a direct file to the COM port and send bytes over it. ! 7: Using such method mimicks the ST exactly, and even allows us to connect to an actual ST! To wait for ! 8: incoming data, we create a thread which copies the bytes into an input buffer. This method fits in with ! 9: the internet code which also reads data into a buffer. ! 10: */ ! 11: ! 12: #include "main.h" ! 13: #include "debug.h" ! 14: #include "dialog.h" ! 15: #include "rs232.h" ! 16: #include "statusBar.h" ! 17: ! 18: BOOL bConnectedRS232=FALSE; // Connection to RS232? ! 19: //HANDLE hCom=NULL; // Handle to file ! 20: //HANDLE RS232Thread=NULL; // Thread handle for reading incoming data ! 21: long RS232ThreadID; ! 22: //DCB dcb; // Control block ! 23: unsigned char TempRS232InputBuffer[MAX_TEMP_RS232INPUT_BUFFER]; ! 24: unsigned char InputBuffer_RS232[MAX_RS232INPUT_BUFFER]; ! 25: int InputBuffer_Head=0,InputBuffer_Tail=0; ! 26: ! 27: //----------------------------------------------------------------------- ! 28: /* ! 29: Initialize RS-232, start thread to wait for incoming data (we will open a connection when first bytes are sent) ! 30: */ ! 31: void RS232_Init(void) ! 32: { ! 33: // Create thread to wait for incoming bytes over RS-232 ! 34: //FIXME RS232Thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RS232_ThreadFunc,0,NULL,&RS232ThreadID); ! 35: } ! 36: ! 37: //----------------------------------------------------------------------- ! 38: /* ! 39: Close RS-232 connection and stop checking for incoming data ! 40: */ ! 41: void RS232_UnInit(void) ! 42: { ! 43: // Close, kill thread and free resource ! 44: /* FIXME */ ! 45: /* ! 46: if (RS232Thread) { ! 47: TerminateThread(RS232Thread,FALSE); ! 48: CloseHandle(RS232Thread); ! 49: } ! 50: RS232_CloseCOMPort(); ! 51: */ ! 52: } ! 53: ! 54: //----------------------------------------------------------------------- ! 55: /* ! 56: Open file on COM port ! 57: */ ! 58: BOOL RS232_OpenCOMPort(void) ! 59: { ! 60: char szString[32]; ! 61: /* FIXME */ ! 62: /* ! 63: // Generate correct filename for COM port ! 64: sprintf(szString,"COM%d",ConfigureParams.RS232.nCOMPort+1); // 1,2... ! 65: ! 66: // Create our COM file for input/output ! 67: bConnectedRS232 = FALSE; ! 68: hCom = CreateFile(szString,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL ); ! 69: if (hCom!=INVALID_HANDLE_VALUE) { ! 70: // Get any early notifications, for thread ! 71: SetCommMask(hCom,EV_RXCHAR); ! 72: // Create input/output buffers ! 73: SetupComm(hCom,4096,4096); ! 74: // Purge buffers ! 75: PurgeComm(hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); ! 76: ! 77: // Set defaults ! 78: RS232_SetConfig(9600,0,UCR_1STOPBIT|UCR_PARITY|UCR_ODDPARITY); ! 79: ! 80: // Set all OK ! 81: bConnectedRS232 = TRUE; ! 82: } ! 83: */ ! 84: return(bConnectedRS232); ! 85: } ! 86: ! 87: //----------------------------------------------------------------------- ! 88: /* ! 89: Close file on COM port ! 90: */ ! 91: void RS232_CloseCOMPort(void) ! 92: { ! 93: /* FIXME */ ! 94: /* ! 95: // Do have file open? ! 96: if (bConnectedRS232) { ! 97: // Close ! 98: CloseHandle(hCom); ! 99: hCom=NULL; ! 100: ! 101: bConnectedRS232 = FALSE; ! 102: } ! 103: */ ! 104: } ! 105: ! 106: //----------------------------------------------------------------------- ! 107: /* ! 108: Set hardware configuration of RS-232 ! 109: ! 110: Ctrl:Communications parameters, (default 0)No handshake ! 111: Bit 0: XOn/XOff ! 112: Bit 1: RTS/CTS ! 113: ! 114: Ucr: USART Control Register ! 115: Bit 1:0-Odd Parity, 1-Even Parity ! 116: Bit 2:0-No Parity, 1-Parity ! 117: Bits 3,4: Start/Stop bits ! 118: 0 0 0-Start, 0-Stop Synchronous ! 119: 0 1 0-Start, 1-Stop Asynchronous ! 120: 1 0 1-Start, 1.5-Stop Asynchronous ! 121: 1 1 1-Start, 2-Stop Asynchronous ! 122: Bits 5,6: 'WordLength' ! 123: 0 0 ,8 Bits ! 124: 0 1 ,7 Bits ! 125: 1 0 ,6 Bits ! 126: 1 1 ,5 Bits ! 127: Bit 7: Frequency from TC and RC ! 128: */ ! 129: void RS232_SetConfig(int Baud,short int Ctrl,short int Ucr) ! 130: { ! 131: /* FIXME */ ! 132: /* ! 133: // Get current config ! 134: memset(&dcb,0x0,sizeof(DCB)); ! 135: GetCommState(hCom, &dcb); ! 136: // Set defaults ! 137: BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb); ! 138: ! 139: // Need XOn/XOff? ! 140: if (Ctrl&CTRL_XON_XOFF) { ! 141: dcb.fOutX = TRUE; ! 142: dcb.fInX = TRUE; ! 143: } ! 144: // And RTS/CTS? ! 145: if (Ctrl&CTRL_RTS_CTS) ! 146: dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; ! 147: ! 148: // Type of parity(if enabled) ! 149: if (Ucr&UCR_EVENPARITY) ! 150: dcb.Parity = EVENPARITY; ! 151: else ! 152: dcb.Parity = ODDPARITY; ! 153: // Need parity? ! 154: if (Ucr&UCR_PARITY) ! 155: dcb.fParity = TRUE; ! 156: // Number of stop bits ! 157: switch(Ucr&UCR_STARTSTOP) { ! 158: case UCR_0STOPBIT: // PC doesn't appear to have no stop bits? Eh? ! 159: case UCR_1STOPBIT: ! 160: dcb.StopBits = ONESTOPBIT; ! 161: break; ! 162: case UCR_15STOPBIT: ! 163: dcb.StopBits = ONE5STOPBITS; ! 164: break; ! 165: case UCR_2STOPBIT: ! 166: dcb.StopBits = TWOSTOPBITS; ! 167: break; ! 168: } ! 169: ! 170: // And set ! 171: SetCommState(hCom, &dcb); ! 172: */ ! 173: } ! 174: ! 175: //----------------------------------------------------------------------- ! 176: /* ! 177: Pass bytes from emulator to RS-232 ! 178: */ ! 179: BOOL RS232_TransferBytesTo(unsigned char *pBytes, int nBytes) ! 180: { ! 181: /* FIXME */ ! 182: /* ! 183: DWORD BytesWritten; ! 184: ! 185: // Do need to open a connection to RS232? ! 186: if (!bConnectedRS232) { ! 187: // Do have RS-232 enabled? ! 188: if (ConfigureParams.RS232.bEnableRS232) ! 189: bConnectedRS232 = RS232_OpenCOMPort(); ! 190: } ! 191: ! 192: // Have we connected to the RS232? ! 193: if (bConnectedRS232) { ! 194: // Send bytes directly to COM port ! 195: if (WriteFile(hCom,pBytes,nBytes,&BytesWritten,NULL)) { ! 196: FlushFileBuffers(hCom); ! 197: } ! 198: ! 199: // Show icon on status bar ! 200: StatusBar_SetIcon(STATUS_ICON_RS232,ICONSTATE_UPDATE); ! 201: ! 202: return(TRUE); //OK ! 203: } ! 204: else ! 205: */ return(FALSE); //Failed ! 206: ! 207: } ! 208: ! 209: //----------------------------------------------------------------------- ! 210: /* ! 211: Read characters from our internal input buffer(bytes from other machine) ! 212: */ ! 213: BOOL RS232_ReadBytes(unsigned char *pBytes, int nBytes) ! 214: { ! 215: /* FIXME */ ! 216: /* ! 217: int i; ! 218: ! 219: // Connected? ! 220: if (bConnectedRS232) { ! 221: // Read bytes out of input buffer ! 222: for(i=0; i<nBytes; i++) { ! 223: *pBytes++ = InputBuffer_RS232[InputBuffer_Head]; ! 224: InputBuffer_Head = (InputBuffer_Head+1)&MAX_RS232INPUT_BUFFER_MASK; ! 225: } ! 226: return(TRUE); ! 227: } ! 228: */ ! 229: return(FALSE); ! 230: ! 231: } ! 232: ! 233: //----------------------------------------------------------------------- ! 234: /* ! 235: Return TRUE if bytes waiting! ! 236: */ ! 237: BOOL RS232_GetStatus(void) ! 238: { ! 239: /* FIXME */ ! 240: /* ! 241: // Connected? ! 242: if (bConnectedRS232) { ! 243: // Do we have bytes in the input buffer? ! 244: if (InputBuffer_Head!=InputBuffer_Tail) ! 245: return(TRUE); ! 246: } ! 247: */ ! 248: // No, none ! 249: return(FALSE); ! 250: } ! 251: ! 252: //----------------------------------------------------------------------- ! 253: /* ! 254: Add incoming bytes from other machine into our input buffer ! 255: */ ! 256: void RS232_AddBytesToInputBuffer(unsigned char *pBytes, int nBytes) ! 257: { ! 258: int i; ! 259: ! 260: // Copy bytes into input buffer ! 261: for(i=0; i<nBytes; i++) { ! 262: InputBuffer_RS232[InputBuffer_Tail] = *pBytes++; ! 263: InputBuffer_Tail = (InputBuffer_Tail+1)&MAX_RS232INPUT_BUFFER_MASK; ! 264: } ! 265: } ! 266: ! 267: //----------------------------------------------------------------------- ! 268: /* ! 269: Thread to read incoming RS-232 data, and pass to emulator input buffer ! 270: */ ! 271: /* FIXME */ ! 272: /* ! 273: DWORD FAR PASCAL RS232_ThreadFunc(LPSTR lpData) ! 274: { ! 275: COMSTAT ComStat; ! 276: DWORD dwErrorFlags; ! 277: DWORD dwEvtMask; ! 278: DWORD dwLength; ! 279: ! 280: SetCommMask(hCom,EV_RXCHAR); ! 281: ! 282: // Check for any RS-232 incoming data ! 283: while(TRUE) { ! 284: if (hCom) { ! 285: // Halt here until we find some data coming through the RS-232 ! 286: dwEvtMask = 0; ! 287: WaitCommEvent(hCom,&dwEvtMask,NULL); ! 288: ! 289: // Chars awaiting? Read them in ! 290: if ((dwEvtMask&EV_RXCHAR)==EV_RXCHAR) { ! 291: // Only try to read number of bytes in queue - don't read more than our buffer allows ! 292: ClearCommError(hCom, &dwErrorFlags, &ComStat ); ! 293: dwLength = min(MAX_TEMP_RS232INPUT_BUFFER, ComStat.cbInQue); ! 294: // Read the bytes in, if we have any ! 295: if (dwLength!=0) { ! 296: // Read into temporary buffer ! 297: ReadFile(hCom,TempRS232InputBuffer,dwLength,&dwLength,NULL); ! 298: // And copy into our internal queue ! 299: RS232_AddBytesToInputBuffer(TempRS232InputBuffer,dwLength); ! 300: } ! 301: } ! 302: ! 303: // Sleep or a while ! 304: Sleep(2); ! 305: } ! 306: else { ! 307: // No RS-232 connection, sleep for 20ms ! 308: Sleep(20); ! 309: } ! 310: } ! 311: ! 312: return(TRUE); ! 313: } ! 314: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.