📄 iportai_linuxc_mstxrx.c
字号:
else if (!strcmp(sig, "/MTC")) printf("Master transmit complete.\n"); else if (!strcmp(sig, "/MRC")) printf("Master recieve complete. Data: '%s'\n", data); else if (!strcmp(sig, "/STC")) printf("Slave transmit complete.\n"); else if (!strcmp(sig, "/CCC")) printf("Close connection complete.\n"); else if (!strcmp(sig, "/SRC")) { printf("Slave recieve complete. Data: '%s'. Calling handler...\n", data); strncpy(SLAVE_BUFFER_IN, (char *)data, MAX_DATA_SIZE); iPortAI_S_Recieve(); } else if (!strcmp(sig, "/GRC")) printf("General recieve complete. Data: '%s'\n", data); else if (!strcmp(sig, "/STR")) { printf("Slave transmit request. Calling handler...\n"); iPortAI_S_Send(); } else if (!strcmp(sig, "/SNA")) printf("Slave not acknowledging.\n"); else if (!strcmp(sig, "/I81")) printf("iPortAI busy.\n"); else if (!strcmp(sig, "/I83")) printf("Arbitration loss.\n"); else if (!strcmp(sig, "/I84")) printf("I2C bus error.\n"); else if (!strcmp(sig, "/I85")) printf("I2C bus timeout.\n"); else if (!strcmp(sig, "/I88")) printf("Connection closed.\n"); else if (!strcmp(sig, "/I89")) printf("Invalid command argument.\n"); else if (!strcmp(sig, "/I8A")) printf("Slave transfer request not active.\n"); else if (!strcmp(sig, "/I8F")) printf("Invalid command.\n"); else if (!strcmp(sig, "/I90")) printf("Recieve buffer overflow.\n"); else printf("Unknown message: %s%s\n", sig, data);}/**************************************** iPortAI Communication Routines*****************************************///Display an "action" phrase - just a way to easily format what we're doing//Takes:// s: char * - character string//Returns:// Nothingvoid printAction (char *s) { printf("> %s\n", s);}//Validate an address//Takes:// s: char * - character string, first two characters are the address (no null terminator necessary)//Returns:// 1 on success, 0 on failure//Notes:// Valid addresses are between 0x00 and 0xFF, non-inclusive, and must be even.int validateAddress (char *s) { //Convert the hex string to an integer char temp[3] = {0, 0, 0}; strncpy (temp, s, 2); int dec_num; sscanf(temp,"%x",&dec_num); //Make sure it's acceptable (between 0 and 0xFE, even) if (dec_num < 0 || dec_num > 0xFE || dec_num % 2 == 1) return 0; else return 1;}//Reset the iPortAI//Takes:// Nothing//Returns:// Nothingvoid iPortAI_reset () { printAction("Resetting..."); writeSerial("\x12\x12\x12"); usleep(20000); //20 ms}//Set the format of incoming data//Takes:// f: int - HEX_ONLY | ALLOW_ASCII//Returns:// Nothingvoid iPortAI_setFormat (int f) { if (f == HEX_ONLY) { printAction("Setting incoming data to be restricted to hex only..."); writeSerial("/h1\r"); } else if (f == ALLOW_ASCII) { printAction("Setting incoming data to be hex or ascii..."); writeSerial("/h0\r"); } else printAction("Bad format argument.");}//Set flow control//Takes:// f: int - HARDWARE | SOFTWARE//Returns:// Nothingvoid iPortAI_setFlow (int f) { if (f == SOFTWARE) { printAction("Setting software flow control..."); writeSerial("/f0\r"); } else if (f == HARDWARE) { printAction("Setting hardware flow control..."); writeSerial("/f1\r"); } else printAction("Bad flow control argument.");}//Set the address of the iPortAI//Takes:// address: char * - character string, first two characters are the desired address//Returns:// Nothingvoid iPortAI_setAddress (char *address) { printAction("Setting our own address..."); if (!validateAddress(address)) { printAction("Bad address."); return; } char temp[6] = "/i??\r"; strncpy(&temp[2], address, 2); writeSerial(temp);}//Select a slave//Takes:// address: char * - character string, first two characters are the desired address//Returns:// Nothingvoid iPortAI_selectSlave (char *address) { printAction("Selecting a slave..."); if (!validateAddress(address)) { printAction("Bad slave address."); return; } char temp[6] = "/d??\r"; strncpy(&temp[2], address, 2); writeSerial(temp);}//Open the I2C bus//Takes:// Nothing//Returns:// 1 on success, 0 on failureint iPortAI_open () { printAction("Opening the I2C bus..."); writeSerial("/o\r"); WATCHDOG = ON; while (!DATA_READY && !TIMEOUT); resetWatchdog(); if (!strcmp(sig, "/OCC")) return 1; else return 0;}//Close the I2C bus//Takes:// Nothing//Returns:// 1 on success, 0 on failureint iPortAI_close () { printAction("Closing the I2C bus..."); writeSerial("/c\r"); WATCHDOG = ON; while(!DATA_READY && !TIMEOUT); resetWatchdog(); if (!strcmp(sig, "/CCC")) return 1; else return 0;}//Master Tx//Takes:// s: char * - character string (null terminated)//Returns:// 1 on success, 0 on failureint iPortAI_MTx (char *s) { printAction("Sending data to a slave..."); writeSerial("/t"); writeSerial(s); writeSerial("\r"); WATCHDOG = ON; while(!DATA_READY && !TIMEOUT); resetWatchdog(); if (!strcmp(sig, "/MTC")) return 1; else return 0;}//Master Rx//Takes:// c: int - number of bytes to read//Returns:// 1 on success, 0 on failureint iPortAI_MRx (int c) { printAction("Recieving data from a slave..."); //Validate the number of bytes we're supposed to read if (c < 0 || c > MAX_DATA_SIZE - 4) { printAction("Number of bytes to read is out of range."); return 0; } //Send the message char temp[10]; sprintf(temp, "%d", c); writeSerial("/r"); writeSerial(temp); writeSerial("\r"); WATCHDOG = ON; while(!DATA_READY && !TIMEOUT); resetWatchdog(); if (!strcmp(sig, "/MRC")) return 1; else return 0;}//Slave Tx//Takes:// s: char * - character string (null terminated)//Returns:// 1 on success, 0 on failureint iPortAI_STx (char *s) { printAction("Sending data to a master..."); writeSerial("/s"); writeSerial(s); writeSerial("\r"); WATCHDOG = ON; while(!DATA_READY && !TIMEOUT); resetWatchdog(); if (!strcmp(sig, "/STC")) return 1; else return 0;}/**************************************** High Level iPortAI Wrappers*****************************************///Select a slave and send an MTx in one step//Takes:// address: char * - character string, first two characters are the desired address// s: char * - character string (null terminated)//Returns:// 1 on success, 0 on failureint iPortAI_M_Send (char *address, char *s) { iPortAI_selectSlave(address); return iPortAI_MTx(s);}//Select a slave and send an MRx in one step//Takes:// address: char * - character string, first two characters are the desired address// c: int - number of bytes to read//Returns:// 1 on success, 0 on failureint iPortAI_M_Recieve (char *address, int c) { iPortAI_selectSlave(address); return iPortAI_MRx(c);}//Select a slave, send an MTx, followed by an MRx, all in one step//Takes:// address: char * - character string, first two characters are the desired address// s: char * - character string (null terminated)// c: int - number of bytes to read//Returns:// 1 on success, 0 on failureint iPortAI_M_SendRecieve (char *address, char *s, int c) { iPortAI_selectSlave(address); if (!iPortAI_MTx(s)) return 0; else if (!iPortAI_MRx(c)) return 0; else return 1;}//Handle slave recieve requests//Takes:// Nothing, called automatically when a slave recieve request comes in//Returns:// Nothing//Notes:// The data coming in will be stored in SLAVE_BUFFER_IN as soon as it is caught.void iPortAI_S_Recieve () { //Copy the first 3 bytes from the incoming buffer into the outgoing buffer strncpy(SLAVE_BUFFER_OUT, SLAVE_BUFFER_IN, 3);}//Handle slave transfer requests//Takes:// Nothing, called automatically when a slave transfer request comes in//Returns:// Nothingvoid iPortAI_S_Send () { //Write our outgoing character out iPortAI_STx(SLAVE_BUFFER_OUT);}/**************************************** Watchdog Timer Routines*****************************************///Configure the watchdog timer//Takes:// Nothing//Returns:// Nothingvoid configureWatchdog () { //Configure the timer to update at WATCHDOG_FREQUENCY, in Hz struct itimerval timer1; timer1.it_interval.tv_sec = 0; timer1.it_interval.tv_usec = (__suseconds_t) ( (1.0 / (double) WATCHDOG_FREQUENCY) * 1000000); timer1.it_value.tv_sec = timer1.it_interval.tv_sec; timer1.it_value.tv_usec = timer1.it_interval.tv_usec; //Attach our handler to the ALRM signal signal(SIGALRM, handleWatchdog); //Start the timer setitimer(ITIMER_REAL, &timer1, NULL);}//Handle the watchdog timer//Takes:// status: int//Returns:// Nothing//Notes:// If WATCHDOG is on, then the watchdog's internal counter will increase. Once it// reaches WATCHDOG_TIMEOUT_COUNT, TIMEOUT will be set to 1, and the watchdog will// turn itself off.void handleWatchdog (int status) { if (WATCHDOG) { wt++; if (wt == WATCHDOG_TIMEOUT_COUNT) { wt = 0; TIMEOUT = 1; WATCHDOG = OFF; printf("! Timed out\n"); } }}//Reset the watchdog timer//Takes:// Nothing//Returns:// Nothing//Notes:// This resets the watchdog's internal counter, as well as turning TIMEOUT and the// watchdog itself off.void resetWatchdog () { wt = 0; TIMEOUT = 0; WATCHDOG = OFF;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -