bool Gpio::setStateRange(int state, int startPin, int endPin) { if (!mInit){ fprintf(stderr, "GPIO not initialised\n"); return false; } int pwmVal; if (state == 0) pwmVal = 0; else pwmVal = 100000; for (std::list<Gpio*>::iterator iter = mOutputList.begin(); iter != mOutputList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); if (obj->getType() == OUT_PIN && pin >= startPin && pin <= endPin) digitalWrite(obj->getPin(), state); } for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); if (obj->getType() == PWM && pin >= startPin && pin <= endPin){ if (mLastValue[pin] != pwmVal) resetPwm(pin, pwmVal); } } return true; }
void main_remi() { char buf[27] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm' ,'n', 'o', 'p' ,'q' ,'r', 's','t','u','v','w','x','y','z',' '}; // Setup STM32 system (clock, PLL and Flash configuration) SystemInit(); Gpio *gpioA = STM32F103::getGpioA(); // Set default port behavior GpioConfiguration portConfig(Gpio::AF_PUSH_PULL_OUTPUT | Gpio::OUTPUT_SPEED_50MHZ); gpioA->configure(portConfig); Uart *uart1 = STM32F103::getUart1(); UartConfiguration uart1Config; uart1Config.baudrate = 9600; uart1Config.stopBit = Uart::UART_1_STOPBIT; uart1Config.parityEnable = Uart::UART_PARITY_DISABLE; uart1Config.wordLenght = Uart::UART_WORD_LENGTH_8BIT; uart1->configure(uart1Config); //Uart *uart2 = STM32F103::getUart2(); // Uart2 config // Tag each Uart with their respective source uart1->setTag(Peripheral::Controller); //uart2->setTag(Peripheral::Drive); // Configure blinking led GpioPinConfiguration ledPinConfig; ledPinConfig.pin = Gpio::GP_PUSH_PULL_OUTPUT | Gpio::OUTPUT_SPEED_50MHZ; gpioA->getPin(0)->configure(ledPinConfig); GpioPin *led = gpioA->getPin(0); // Blink led while(1) { led->setHigh(); // On for(uint32_t i=0; i<1000000; i++){ uart1->poll(); } uart1->write((char *)buf, 27); led->setLow(); // Off for(uint32_t i=0; i<1000000; i++){ uart1->poll(); } } }
/** * Start a thread to constantly monitor all the input pins we are * interested in. When a state change is detected we store the * time of the change. This creates a buffer so we can still see * changes that happened a short time ago (so we don't miss any). * * It also writes PWM outputs and is responsible for writing random * data, sine waves etc. to these outputs. */ bool Gpio::startMonitor() { if (!mInit){ fprintf(stderr, "GPIO not initialised\n"); return false; } // Do we have anything to monitor? if (mMonitorList.size() == 0) return true; bool usingPwm = false; for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); if (obj->getType() == PWM){ // Don't start outputting PWM until we execute a relevant command mMonType[pin] = INACTIVE; mMonMutex[pin] = PTHREAD_MUTEX_INITIALIZER; // Set to full range initially (range map is in millis) mRangeMapMin[pin] = 0; mRangeMapMax[pin] = 100000; usingPwm = true; } else { // Input pins are always monitored initMonitorInput(pin); } } if (usingPwm){ // Start ServoBlaster. We use this instead of hardware // PWM as there is only one hardware PWM pin on the Pi // and hardware PWM interferes with analog audio. if (!startServoBlaster()) return false; } // Start monitor thread if (pthread_create(&mMonitorId, NULL, monitor, NULL) != 0){ fprintf(stderr, "** Failed to start gpio monitor\n"); return false; } // Wait for monitor to start for (int retries = 0; retries < 15; retries++){ if (mMonitorRunning) return true; Engine::sleep(200); } printf("** Failed to start gpio monitor\n"); return false; }
void blinky() { // Setup STM32 system (clock, PLL and Flash configuration) SystemInit(); Gpio *gpioA = STM32F103::getGpioA(); // Configure blinking led GpioPinConfiguration ledPinConfig; ledPinConfig.pin = Gpio::GP_PUSH_PULL_OUTPUT | Gpio::OUTPUT_SPEED_50MHZ; gpioA->getPin(0)->configure(ledPinConfig); GpioPin *led = gpioA->getPin(0); while(1) { led->setHigh(); // On for(uint32_t i=0; i<1000000; i++); led->setLow(); // Off for(uint32_t i=0; i<1000000; i++); } }
bool Gpio::stopPwmRange(int startPin, int endPin) { if (!mInit){ fprintf(stderr, "GPIO not initialised\n"); return false; } for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); if (mMonType[pin] != MON_IN && pin >= startPin && pin <= endPin) resetPwm(pin, -1); } return true; }
bool Gpio::startPwmRange(MonitorType pwmType, int startPin, int endPin, int param1, int param2, int param3, int param4, int param5, bool loop) { bool res = true; for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); if (mMonType[pin] != MON_IN && pin >= startPin && pin <= endPin){ if (!obj->startPwm(pwmType, param1, param2, param3, param4, param5, loop)) { res = false; } } } return res; }
/** * Runs in a separate thread */ void *Gpio::monitor(void *arg) { mMonitorRunning = true; while (mMonitorRunning){ double now = Engine::timeNow(); for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; int pin = obj->getPin(); switch (mMonType[pin]) { case INACTIVE: break; case MON_IN: monitorInput(pin, now); break; case PWM_RANDOM: monitorPwmRandom(pin, now); break; case PWM_LINEAR: monitorPwmLinear(pin, now); break; case PWM_SINE: monitorPwmSine(pin, now); break; default: printf("Unknown monitor pin type\n", mMonType[pin]); mMonitorRunning = false; pthread_exit(NULL); } } Engine::sleep(10); } pthread_exit(NULL); }
void main_francois() { // Setup STM32 system (clock, PLL and Flash configuration) SystemInit(); Gpio *gpioA = STM32F103::getGpioA(); Gpio *gpioB = STM32F103::getGpioB(); Gpio *gpioC = STM32F103::getGpioC(); // Set default port behavior GpioConfiguration portConfig(Gpio::FLOATING_INPUT); gpioA->configure(portConfig); // Configure blinking led GpioPinConfiguration ledPinConfig; ledPinConfig.pin = Gpio::GP_PUSH_PULL_OUTPUT | Gpio::OUTPUT_SPEED_50MHZ; gpioA->getPin(0)->configure(ledPinConfig); GpioPin *led = gpioA->getPin(0); // Create the usb port Usb* usb = STM32F103::getUsb(); // Create a new NES controller interface AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_DISABLE; // JTAG remap NesControllerInterface* nesInterface = new NesControllerInterface(gpioB->getPin(3), gpioB->getPin(4), gpioC->getPin(5)); usb->addEventListener(nesInterface); usb->listenForDevice(); while(!usb->deviceDetected()); //debug // Blink led fast led->setHigh(); // On for(uint32_t i=0; i<100000; i++); led->setLow(); // Off for(uint32_t i=0; i<100000; i++); usb->enumerateDevice(); // Blink led while(1) { //if(usb->deviceDetected()) { /*led->setHigh(); // On for(uint32_t i=0; i<100000; i++); led->setLow(); // Off for(uint32_t i=0; i<100000; i++);*/ //if(!usb->deviceEnumerated()) { //debug // Blink led fast /*GPIOA->BSRR |= 0x01; // On for(uint32_t i=0; i<100000; i++); GPIOA->BRR |= 0x01; // Off for(uint32_t i=0; i<100000; i++); usb->enumerateDevice();*/ //} //else { usb->serviceHid(); //} //} /* led->setHigh(); // On for(uint32_t i=0; i<1000000; i++); led->setLow(); // Off for(uint32_t i=0; i<1000000; i++); */ // Simulate an external interrupt //EXTI->SWIER |= EXTI_SWIER_SWIER1; } }
bool Gpio::startServoBlaster() { // Stop ServoBlaster if it's already running mServoBlasterPid = Engine::findProcess(SB_COMMAND); if (mServoBlasterPid != -1) stopServoBlaster(); if (Engine::displayOn) printf("Starting ServoBlaster (%s)\n", SB_COMMAND); mServoBlasterPid = fork(); if (mServoBlasterPid == -1){ fprintf(stderr, "** Failed to create ServoBlaster process\n"); return false; } if (mServoBlasterPid != 0){ // This is the parent process // Make sure ServoBlaster started int status; for (int retries = 0; retries < 15; retries++){ if (waitpid(mServoBlasterPid, &status, WNOHANG) != -1){ sleep(1); mServoBlasterOut = open(SB_DEVICE, O_WRONLY|O_SYNC); if (mServoBlasterOut == -1){ fprintf(stderr, "** Failed to open %s\n", SB_DEVICE); return false; } return true; } Engine::sleep(200); } fprintf(stderr, "ServoBlaster failed to start\n"); return false; } // Make ServoBlaster use same pin mapping as wiringPi. // We are mapping wiringPi pin number to physical pin number. const int pinMap[] = {11,12,13,15,16,18,22,7,3,5,24,26,19,21,23,8,10}; int servoBlasterPin[MAX_PWM_PINS]; // ServoBlaster needs to know which pins we are using for PWM for (int i = 0; i < MAX_PWM_PINS; i++) servoBlasterPin[i] = 0; for (auto iter = mMonitorList.begin(); iter != mMonitorList.end(); iter++) { Gpio *obj = *iter; if (obj->getType() == PWM){ int pin = obj->getPin(); servoBlasterPin[pin] = pinMap[pin]; } } // First arg is the pin list char argv1[256]; sprintf(argv1, "--p1pins=%d", servoBlasterPin[0]); char addStr[64]; for (int i = 1; i < MAX_PWM_PINS; i++){ sprintf(addStr, ",%d", servoBlasterPin[i]); strcat(argv1, addStr); } // Second arg is the cycle time char argv2[256]; sprintf(argv2, "--cycle-time=%dus", SB_CYCLE_TIME); const char *argv[16]; argv[0] = SB_COMMAND; argv[1] = argv1; argv[2] = argv2; for (int i = 0;; i++){ argv[i+3] = SB_PARAMS[i]; if (SB_PARAMS[i] == NULL) break; } // redirect stdout and stderr freopen("/tmp/servoblaster.log", "w", stdout); freopen("/tmp/servoblaster.log", "w", stderr); // Try from current dir first char command[256]; sprintf(command, "./%s", SB_COMMAND); execv(command, (char* const*)argv); // execv only returns if an error occurs // Now try from PATH execvp(SB_COMMAND, (char* const*)argv); // execv only returns if an error occurs fprintf(stderr, "** Failed to start ServoBlaster using command:\n"); fprintf(stderr, "%s", SB_COMMAND); for (int i = 0; argv[i] != NULL; i++) fprintf(stderr, " %s", argv[i]); fprintf(stderr, "\n"); return true; }