func (g *GPIO) PinMap() ([]PinDef, error) { desc, err := embd.DescribeHost() if err != nil { return nil, err } // wrap pinmap in a struct to make the json easier to parse on the other end embdMap := desc.GPIODriver().PinMap() pinMap := make([]PinDef, len(embdMap)) // convert to PinDef format for i := 0; i < len(embdMap); i++ { pinDesc := embdMap[i] caps := make([]string, 0) if pinDesc.Caps&embd.CapDigital != 0 { caps = append(caps, "Digital") } if pinDesc.Caps&embd.CapAnalog != 0 { caps = append(caps, "Analog") } if pinDesc.Caps&embd.CapPWM != 0 { caps = append(caps, "PWM") } if pinDesc.Caps&embd.CapI2C != 0 { caps = append(caps, "I2C") } if pinDesc.Caps&embd.CapUART != 0 { caps = append(caps, "UART") } if pinDesc.Caps&embd.CapSPI != 0 { caps = append(caps, "SPI") } if pinDesc.Caps&embd.CapGPMC != 0 { caps = append(caps, "GPMC") } if pinDesc.Caps&embd.CapLCD != 0 { caps = append(caps, "LCD") } pinMap[i] = PinDef{ pinDesc.ID, pinDesc.Aliases, caps, pinDesc.DigitalLogical, pinDesc.AnalogLogical, } } return pinMap, nil }
func (g *GPIO) PinInit(pinId string, dir Direction, pullup PullUp, name string) error { var pin interface{} state := byte(0) if dir == PWM { host, _, err := embd.DetectHost() if err != nil { return err } if host == embd.HostRPi { // use pi blaster pin log.Println("Creating PWM pin on Pi") // get the host descriptor desc, err := embd.DescribeHost() if err != nil { return err } // get the pinmap embdMap := desc.GPIODriver().PinMap() // lookup the pinId in the map var pinDesc *embd.PinDesc for i := range embdMap { pd := embdMap[i] if pd.ID == pinId { pinDesc = pd break } for j := range pd.Aliases { if pd.Aliases[j] == pinId { pinDesc = pd break } } } if pinDesc != nil { // we found a pin with that name....what is its first Alias? pinIdInt, err := strconv.Atoi(pinDesc.Aliases[0]) if err != nil { log.Println("Failed to parse int from alias : ", pinDesc.Aliases[0]) return err } p := NewBlasterPin(pinIdInt) pin = p } else { log.Println("Failed to find Pin ", pinId) return errors.New("Failed to find pin " + pinId) } } else { // bbb, so use embd since pwm pins work there p, err := embd.NewPWMPin(pinId) if err != nil { log.Println("Failed to create PWM Pin using key ", pinId, " : ", err.Error()) return err } pin = p } } else { // add a pin p, err := embd.NewDigitalPin(pinId) if err != nil { return err } pin = p err = p.SetDirection(embd.Direction(dir)) if err != nil { return err } if pullup == Pull_Up { err = p.PullUp() // pullup and down not implemented on rpi host so we need to manually set initial states // not ideal as a pullup really isn't the same thing but it works for most use cases if err != nil { log.Println("Failed to set pullup on " + pinId + " setting high state instead : " + err.Error()) // we failed to set pullup, so lets set initial state high instead err = p.Write(1) state = 1 if err != nil { return err } } } else if pullup == Pull_Down { err = p.PullDown() if err != nil { log.Println("Failed to set pulldown on " + pinId + " setting low state instead : " + err.Error()) err = p.Write(0) state = 1 if err != nil { return err } } } } // test to see if we already have a state for this pin existingPin, exists := g.pinStates[pinId] if exists { existingPin.Pin = pin existingPin.Name = name existingPin.Dir = dir existingPin.State = state existingPin.Pullup = pullup g.pinStates[pinId] = existingPin g.pinStateChanged <- existingPin g.pinRemoved <- pinId g.pinAdded <- g.pinStates[pinId] } else { g.pinStates[pinId] = PinState{pin, pinId, dir, state, pullup, name} g.pinAdded <- g.pinStates[pinId] } return nil }