Koichi Kurahashi
/
RPi_1114
Raspberry Pi Power Controller by LPC1114
main.cpp
- Committer:
- TareObjects
- Date:
- 2017-01-16
- Revision:
- 3:b7b9d3d4eed8
- Parent:
- 2:f6265132c464
- Child:
- 4:7117eb230044
File content as of revision 3:b7b9d3d4eed8:
#include "mbed.h" const int kMaxInteger = 32767; const float fFloatScaleValue = 1024.0; // factor to convert long <-> float // // common definition // #define kCommandAddress 0x50 // internal gpio map // // dp5 : SDA - RPi's SDA / pad // dp14 : on board LED // dp15 : rx - RPi's TXD // dp16 : tx - RPi's RXD // dp17 : out - RPi's power switch // dp23 : reset - RPi's GPIO24 // dp24 : isp - RPI's GPIO23 // dp25 : in - sw1 / pad // dp27 : SCL - RPi's SCL / pad // pad map // // dp1 digital Pwm : Pwm // dp2 digital Pwm : Pwm // dp4 digital analog : digital in // dp5 I2C(SDA) : RPi(master)'s SDA / pad // dp6 digital : digital in // dp9 digital analog : analog // dp10 digital analog : analog // dp11 digital analog : analog // dp13 digital analog // do18 digital Pwm : Pwm // dp25 digital in : sw1 / pad // dp26 digital : digital out // dp27 I2C(SCL) : RPi(master)'s SCL / pad // dp28 digital : digital out // // I2C typical command format // // [0] = command // [1] = target ch // [2] = format // 0 : binary // [3...] : long // 1 : ascii string // [3...] : c string // // endian : little endian // #define kCommandUp 0x10 // i2c command : RPi power on #define kCommandDown 0x11 // : RPi power off #define kCommandLED 0x20 // : led - on/off/flash #define kCommandAnalogRead 0x30 // : read analog port #define kCommandAnalogReset 0x31 // : reset read buffer #define kCommandAnalogStart 0x32 // : start fill buffer #define kCommandAnalogStop 0x33 // : stop fill buffer #define kCommandAnalogLoad 0x34 // : load analog data #define kCommandPwm 0x40 // : output Pwm #define kCommandPwmPeriod 0x41 // : set Pwm period in uSec #define kCommandDigitalIn 0x50 // : input digital #define kCommandDigitalOut 0x60 // : output digital #define kCommandModeBinary 0x00 // binary mode #define kCommandModeASCII 0x10 // ascii mode // // I2C // #define MaxReceiveBufferSize 100 // i2c receiving buffer length I2CSlave slave(dp5, dp27); // // RPi Power Controll // // [0] command // turn on : kCommandUp // turn off : kCommandDown // [1] ch // always 0 // [2] format // 0 : binary mode // 1 : c string mode // [3...] data // binary mode : little endian long // ascii mode : c string // DigitalOut rpiPower(dp17); DigitalOut led(dp14); int powerMode = kCommandUp; void powerOff() { rpiPower = 0; powerMode = kCommandDown; } void powerOn() { rpiPower = 1; powerMode = kCommandUp; } // led modes // // [0] command // led comtrol // [1] ch // always 0 // [2] mode // 0 : turn off // 1 : turn on // 2 : flash // #define kLED_Off 0 // LED off #define kLED_On 1 // LED on #define kLED_Flash 2 // LED flash int ledMode = kLED_Flash; void ledOn() { led = 1; ledMode = kLED_On; } void ledOff() { led = 0; ledMode = kLED_Off; } // // on board Switch // DigitalIn sw1(dp25); const int SW_OFF = 1; const int SW_ON = 0; // pull up int sw1Mode = SW_OFF; int waitForSw1Release = 0; // // ADC // #define kMaxAnalogChannels 3 // analog read channels .... never change #define kMinAnalogPeriod 10000 // 10mSec is minimum #define kMaxAnalogPeriod 10000000 // 10Sec is maximum const int kMaxAnalogBufferSize = 256; // analog read buffer size typedef struct { unsigned short count; unsigned short buffer[kMaxAnalogBufferSize]; } AnalogBuffer; AnalogBuffer analogBuffer[kMaxAnalogChannels]; AnalogIn analogIn[kMaxAnalogChannels] = {dp9, dp10, dp11}; Ticker analogTicker[kMaxAnalogChannels]; //Ticker t1, t2, t0; void analogTickerVectors(int ch) { if (ch >= 0 && ch < kMaxAnalogChannels) { AnalogBuffer *p = &analogBuffer[ch]; unsigned short count = p->count; if (count < (kMaxAnalogBufferSize-1)) { float f = analogIn[ch]; unsigned short v = f * fFloatScaleValue; p->buffer[count++] = v; p->count = count; } } } void analogTickerVector0() { analogTickerVectors(0); } void analogTickerVector1() { analogTickerVectors(1); } void analogTickerVector2() { analogTickerVectors(2); } float execAnalogIn(int ch) { if (ch >= 0 && kMaxAnalogChannels) { return analogIn[ch]; } return -1; } int execAnalogReset(int ch) { if (ch >= 0 && ch < kMaxAnalogChannels) { analogTicker[ch].detach(); analogBuffer[ch].count = 0; return 0; } return -1; } int execAnalogStart(int ch, long value) { if (ch >=0 && ch < kMaxAnalogChannels) { analogBuffer[ch].count = 0; value *= 1000; if (value < kMinAnalogPeriod || value > kMaxAnalogPeriod) { value = 1000; // 1 sec } switch (ch) { case 0: analogTicker[ch].attach_us(&analogTickerVector0, value); break; case 1: analogTicker[ch].attach_us(&analogTickerVector1, value); break; case 2: analogTicker[ch].attach_us(&analogTickerVector2, value); break; } return 0; } return -1; } int execAnalogStop(int ch) { if (ch >= 0 && ch < kMaxAnalogChannels) { analogTicker[ch].detach(); return 0; } return -1; } // // Digital Read // const int kMaxDigitalInChannels = 2; DigitalIn digitalIn[kMaxDigitalInChannels] = {dp4,dp6}; int execDigitalIn(int ch) { if (ch >= 0 && ch < kMaxDigitalInChannels) { return digitalIn[ch]; } return -1; } // // Digital Write // const int kMaxDigitalOutChannels = 2; DigitalOut digitalOut[kMaxDigitalOutChannels] = {dp26,dp28}; int execDigitalOut(int ch, long value) { if (ch >= 0 && ch < kMaxDigitalOutChannels) { digitalOut[ch] = value == 0 ? 0 : 1; return 0; } return -1; } // // Pwm // const int kMaxPwmChannels = 3; PwmOut Pwm[kMaxPwmChannels] = {dp1, dp2, dp18}; int execSetPwmPeriod(int ch, long value) { if (ch >= 0 && ch < kMaxPwmChannels && value >= 0 && value <= kMaxInteger) { Pwm[ch].period_us(value); return 0; } return -1; } int execPwmOut(int ch, long value) { if (ch >= 0 && ch < kMaxPwmChannels) { float f = value / fFloatScaleValue; Pwm[ch] = f; return 0; } return -1; } // // clock for RPi's timer and LED Flashing // Ticker second; long onTimer = -1; long offTimer = -1; void funcSecond() { if (onTimer > 0) { onTimer --; if (onTimer == 0) { powerOn(); onTimer = -1; } } if (offTimer > 0) { offTimer --; if (offTimer == 0) { powerOff(); offTimer = -1; } } if (ledMode == kLED_Flash) { led = 1; wait_ms(10); led = 0; } } // // main routine // static char buf[MaxReceiveBufferSize]; int main() { char strBuf[16]; char prevCommand = 0; char prevCh = 0; char prevMode = 0; for (int i = 0; i < kMaxAnalogChannels; i++) { analogBuffer[i].count = 0; } slave.address(kCommandAddress); second.attach(funcSecond, 1); sw1.mode(PullNone); powerOn(); while(1) { if (sw1 == SW_ON) { wait_ms(5); waitForSw1Release = 1; } if (waitForSw1Release && sw1 == SW_OFF) { if (powerMode == kCommandUp) { powerOff(); } else { powerOn(); } waitForSw1Release = 0; } int status = slave.receive(); long value = 0; switch (status) { case I2CSlave::WriteAddressed: { if (slave.read(buf, MaxReceiveBufferSize)) { char command = buf[0]; char ch = buf[1]; char mode = buf[2]; value = 0; if (mode == kCommandModeBinary) { long *p = (long *)buf+3; value = *p; if (value < 0) value = 0; } else if (mode == kCommandModeASCII) { value = atol(buf+3); } switch(command) { case kCommandUp: if (value > 0) { onTimer = value; } else if (value == 0) { powerOn(); } break; case kCommandDown: if (value > 0) { offTimer = value; } else if (value == 0) { powerOff(); } break; case kCommandLED: switch (mode) { case 0: ledOff(); break; case 1: ledOn(); break; case 2: ledMode = kLED_Flash; break; } break; case kCommandAnalogReset: execAnalogReset(ch); break; case kCommandAnalogStart: execAnalogStart(ch, value); break; case kCommandAnalogStop: execAnalogStop(ch); break; case kCommandPwm: execPwmOut(ch, value); break; case kCommandPwmPeriod: execSetPwmPeriod(ch, value); break; case kCommandDigitalOut: execDigitalOut(ch, value); break; case kCommandDigitalIn: case kCommandAnalogRead: case kCommandAnalogLoad: ledOn(); prevCommand = command; prevCh = ch; prevMode = mode; break; default: prevCommand = 0; break; } } break; } case I2CSlave::ReadAddressed: { switch(prevCommand) { case kCommandAnalogRead: float f = execAnalogIn(prevCh); if (prevMode == kCommandModeBinary) { value = f * fFloatScaleValue; // 10bit = 1024.0 slave.write((const char *)&value, sizeof(value)); } else { sprintf(strBuf, "%f", f); slave.write(strBuf, strlen(strBuf)+1); } break; case kCommandAnalogLoad: // no ascii mode if (prevCh < kMaxAnalogChannels) { AnalogBuffer *p = &analogBuffer[prevCh]; // __disable_irq(); unsigned short count = p->count; slave.write((const char *)p, sizeof(unsigned short)*(count+1)); // __enable_irq(); p->count = 0; } break; case kCommandDigitalIn: value = execDigitalIn(prevCh); if (prevMode == kCommandModeBinary) { slave.write((const char *)&value, sizeof(value)); } else { sprintf(strBuf, "%ld", value); slave.write((const char *)strBuf, strlen(strBuf)+1); } break; } slave.stop(); break; } default: wait_ms(1); break; } } }