/* Raspberry Pi LPC1114 I/O Processor Expansion Board timer test program */ // Copyright (C)2013-2018, Philip Munts, President, Munts AM Corp. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include #include #include #include #include #define SERVERNAME ((argc == 2) ? argv[1] : "localhost") static void ResetLPC1114(void) { system(CMDRESET); } static void check_error(int line, char *func, int32_t error) { if (error) { fprintf(stderr, "ERROR: %s() failed at line %d, %s\n", func, line - 1, strerror(error)); exit(1); } } // spiagent_timer_id_t static char *TIMERS[] = { "CT32B0", "CT32B1", NULL }; // spiagent_timer_mode_t static char *MODES[] = { "DISABLED", "RESET", "PCLK", "RISING", "FALLING", "BOTH", NULL }; // spiagent_timer_capture_edge_t static char *EDGES[] = { "NONE", "RISING", "FALLING", "BOTH", NULL }; // spiagent_timer_match_output_action_t static char *ACTIONS[] = { "NONE", "CLEAR", "SET", "TOGGLE", NULL }; // Boolean enables static char *ENABLES[] = { "NO", "YES", NULL }; static int lookup(char *table[], char *target) { int i; if (target == NULL) return -1; if (strlen(target) == 0) return -1; for (i = 0; table[i] != NULL; i++) if (!strcasecmp(table[i], target)) return i; return -1; } int main(int argc, char *argv[]) { char buf[256]; int TimerID = -1; int TimerMode = -1; int Prescaler = -1; int CaptureEdge = -1; int CaptureInterrupt = -1; int MatchRegister = -1; int MatchValue = -1; int MatchInterrupt = -1; int MatchReset = -1; int MatchStop = -1; int MatchAction = -1; int32_t error; uint32_t pin; uint32_t counter_value; uint32_t capture_value; uint32_t capture_delta; printf("\nRaspberry Pi LPC1114 I/O Processor Expansion Board Timer Test\n"); // Reset the LPC1114 now ResetLPC1114(); // Reset the LPC1114 when we exit atexit(ResetLPC1114); // Get timer ID do { printf("Enter timer ID (CT32B0|CT32B1): "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; TimerID = lookup(TIMERS, buf); } while (TimerID < 0); // Get timer mode do { printf("Enter timer mode (PCLK|RISING|FALLING|BOTH): "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; TimerMode = lookup(MODES, buf); } while (TimerMode < 0); // Get prescaler value do { printf("Enter prescale divisor value: "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; Prescaler = atoi(buf); } while (Prescaler < 1); // Get capture input edge if (TimerMode != LPC1114_TIMER_MODE_PCLK) CaptureEdge = LPC1114_TIMER_CAPTURE_EDGE_DISABLED; else { do { printf("Enter capture input edge (NONE|RISING|FALLING|BOTH): "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; CaptureEdge = lookup(EDGES, buf); } while (CaptureEdge < 0); } // Get interrupt on capture if (CaptureEdge == LPC1114_TIMER_CAPTURE_EDGE_DISABLED) CaptureInterrupt = false; else { do { printf("Interrupt on capture (YES|NO)? "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; CaptureInterrupt = lookup(ENABLES, buf); } while (CaptureInterrupt < 0); } // Get match register number do { printf("Enter match register (NONE or 0-3): "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; if (!strcasecmp(buf, "NONE")) { MatchRegister = -1; break; } MatchRegister = atoi(buf); } while ((MatchRegister < 0) || (MatchRegister > 3)); // Get match parameters if (MatchRegister == -1) { MatchValue = 0; MatchInterrupt = false; MatchReset = false; MatchStop = false; MatchAction = LPC1114_TIMER_MATCH_OUTPUT_DISABLED; } else { // Get match value do { printf("Enter match register value: "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; } while (strlen(buf) == 0); MatchValue = atoi(buf); // Get interrupt on match do { printf("Interrupt on match (YES|NO)? "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; MatchInterrupt = lookup(ENABLES, buf); } while (MatchInterrupt < 0); // Get reset on match do { printf("Reset on match (YES|NO)? "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; MatchReset = lookup(ENABLES, buf); } while (MatchReset < 0); // Get stop on match do { printf("Stop on match (YES|NO)? "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; MatchStop = lookup(ENABLES, buf); } while (MatchStop < 0); // Get match output action if (TimerID != LPC1114_CT32B1) MatchAction = LPC1114_TIMER_MATCH_OUTPUT_DISABLED; else { do { printf("Enter match output action (NONE|CLEAR|SET|TOGGLE): "); memset(buf, 0, sizeof(buf)); fgets(buf, sizeof(buf), stdin); while (strlen(buf) && isspace(buf[strlen(buf)-1])) buf[strlen(buf)-1] = 0; if (strlen(buf) == 0) continue; MatchAction = lookup(ACTIONS, buf); } while (MatchAction < 0); } } // Initialize the SPI Agent services library spiagent_open(SERVERNAME, &error); check_error(__LINE__, "spiagent_open", error); // Initialize CT32B1 spiagent_timer_init(TimerID, &error); // Configure the timer check_error(__LINE__, "spiagent_timer_init", error); spiagent_timer_configure_mode(TimerID, LPC1114_TIMER_MODE_RESET, &error); check_error(__LINE__, "spiagent_timer_configure_mode", error); spiagent_timer_configure_prescaler(TimerID, Prescaler, &error); check_error(__LINE__, "spiagent_timer_configure_prescaler", error); if (CaptureEdge != LPC1114_TIMER_CAPTURE_EDGE_DISABLED) { spiagent_timer_configure_capture(TimerID, CaptureEdge, CaptureInterrupt, &error); check_error(__LINE__, "spiagent_timer_configure_capture", error); } if (MatchRegister >= 0) { spiagent_timer_configure_match(TimerID, MatchRegister, MatchValue, MatchAction, MatchInterrupt, MatchReset, MatchStop, &error); check_error(__LINE__, "spiagent_timer_configure_match", error); } spiagent_timer_configure_mode(TimerID, TimerMode, &error); check_error(__LINE__, "spiagent_timer_configure_mode", error); // Enable interrupt monitoring on Raspberry Pi INT (GPIO4) spiagent_interrupt_enable(&error); check_error(__LINE__, "spiagent_interrupt_enable", error); puts("Press CONTROL-C to quit\n"); for (;;) { spiagent_interrupt_wait(1000, &pin, &error); if (error == EINTR) { break; } else if ((error == 0) && (pin == 0)) { spiagent_timer_get(TimerID, &counter_value, &error); check_error(__LINE__, "spiagent_timer_get", error); spiagent_timer_get_capture(TimerID, &capture_value, &error); check_error(__LINE__, "spiagent_timer_get_capture", error); spiagent_timer_get_capture_delta(TimerID, &capture_delta, &error); check_error(__LINE__, "spiagent_timer_get_capture_delta", error); printf("TC:%d CR0:%d CR0 delta:%d\n", counter_value, capture_value, capture_delta); fflush(stdout); } else if (error == 0) { printf("Received interrupt on Raspberry Pi GPIO pin %d\n", pin); fflush(stdout); } else { check_error(__LINE__ - 18, "spiagent_interrupt_wait", error); } } // Disable interrupt monitoring on Raspberry Pi INT (GPIO4) spiagent_interrupt_disable(&error); check_error(__LINE__, "spiagent_interrupt_disable", error); // Close the SPI Agent Firmware transport library spiagent_close(&error); check_error(__LINE__, "spiagent_close", error); exit(0); }