Now store Pin state (fix for #13 on F1 parts, F4 still looks broken)

This commit is contained in:
Gordon Williams 2013-12-06 18:30:04 +00:00
parent af2e652801
commit 1085a3af8c
7 changed files with 120 additions and 19 deletions

View File

@ -26,6 +26,7 @@
Now remember I2C state (partial fix for #13)
Replace 'pow' function with a smaller version - save ~2kb
Shaved another 1200 bytes off jslTokenAsString
Now store Pin state (fix for #13 on F1 parts, F4 still looks broken)
1v42 : [ebirger] allowing 'new' with no brackets
Allow built-in functions with variable numbers of arguments (fix #83)

View File

@ -216,22 +216,39 @@ codeOut("");
codeOut("#define IOBUFFERMASK 31 // (max 255) amount of items in event buffer - events take ~9 bytes each")
codeOut("#define TXBUFFERMASK 31 // (max 255)")
codeOut("");
codeOutDevice("LED1")
codeOutDevice("LED2")
codeOutDevice("LED3")
codeOutDevice("LED4")
codeOutDevice("LED5")
codeOutDevice("LED6")
codeOutDevice("LED7")
codeOutDevice("LED8")
codeOutDevice("BTN1")
codeOutDevice("BTN2")
codeOutDevice("BTN3")
codeOutDevice("BTN4")
simpleDevices = [
"LED1","LED2","LED3","LED4","LED5","LED6","LED7","LED8",
"BTN1","BTN2","BTN3","BTN4"];
usedPinChecks = ["false"];
ledChecks = ["false"];
btnChecks = ["false"];
for device in simpleDevices:
if device in board.devices:
codeOutDevice(device)
check = "(PIN)==" + toPinDef(board.devices[device]["pin"])
if device[:3]=="LED": ledChecks.append(check)
if device[:3]=="BTN": btnChecks.append(check)
# usedPinChecks.append(check)
# Actually we don't care about marking used pins for LEDs/Buttons
if "USB" in board.devices:
if "pin_disc" in board.devices["USB"]: codeOutDevicePin("USB", "pin_disc", "USB_DISCONNECT_PIN")
for device in ["USB","SD","LCD"]:
if device in board.devices:
for entry in board.devices[device]:
if entry[:3]=="pin": usedPinChecks.append("(PIN)==" + toPinDef(board.devices[device][entry])+"/* "+device+" */")
codeOut("")
codeOut("// definition to avoid compilation when Pin/platform config is not defined")
codeOut("#define IS_PIN_USED_INTERNALLY(PIN) ("+")||(".join(usedPinChecks)+")")
codeOut("#define IS_PIN_A_LED(PIN) ("+")||(".join(ledChecks)+")")
codeOut("#define IS_PIN_A_BUTTON(PIN) ("+")||(".join(btnChecks)+")")
codeOut("""
#endif // _PLATFORM_CONFIG_H
""");

View File

@ -85,6 +85,9 @@ typedef enum {
JSHPINSTATE_USART_OUT,
JSHPINSTATE_DAC_OUT,
JSHPINSTATE_I2C,
JSHPINSTATE_MASK = NEXT_POWER_2(JSHPINSTATE_I2C)-1,
JSHPINSTATE_PIN_IS_ON = JSHPINSTATE_MASK+1,
} PACKED_FLAGS JshPinState;
#define JSHPINSTATE_IS_OUTPUT(state) ( \
@ -96,9 +99,15 @@ typedef enum {
state==JSHPINSTATE_I2C \
)
/// Is the pin state manual (has the user asked us explicitly to change it?)
bool jshGetPinStateIsManual(Pin pin);
/// Is the pin state manual (has the user asked us explicitly to change it?)
void jshSetPinStateIsManual(Pin pin, bool manual);
/// Set the pin state
void jshPinSetState(Pin pin, JshPinState state);
/** Get the pin state (only accurate for simple IO - won't return JSHPINSTATE_USART_OUT for instance).
* Note that you should use JSHPINSTATE_MASK as other flags may have been added */
JshPinState jshPinGetState(Pin pin);
bool jshPinInput(Pin pin);

View File

@ -546,6 +546,30 @@ void jsiAppendHardwareInitialisation(JsVar *str, bool addCallbacks) {
jsiAppendDeviceInitialisation(str, jshGetDeviceString(EV_SPI1+i));
for (i=0;i<I2CS;i++)
jsiAppendDeviceInitialisation(str, jshGetDeviceString(EV_I2C1+i));
// pins
Pin pin;
for (pin=0;jshIsPinValid(pin) && pin<255;pin++) {
if (IS_PIN_USED_INTERNALLY(pin)) continue;
JshPinState state = jshPinGetState(pin);
JshPinState statem = state&JSHPINSTATE_MASK;
if (statem == JSHPINSTATE_GPIO_OUT) {
bool isOn = (state&JSHPINSTATE_PIN_IS_ON)!=0;
if (!isOn && IS_PIN_A_LED(pin)) continue;
jsvAppendString(str, "digitalWrite(");
jsvAppendPin(str, pin);
jsvAppendString(str, ",");
jsvAppendInteger(str, isOn?1:0);
jsvAppendString(str, ");\n");
} else if (/*statem == JSHPINSTATE_GPIO_IN ||*/statem == JSHPINSTATE_GPIO_IN_PULLUP || statem == JSHPINSTATE_GPIO_IN_PULLDOWN) {
// don't bother with normal inputs, as they come up in this state (ish) anyway
jsvAppendString(str, "pinMode(");
jsvAppendPin(str, pin);
jsvAppendString(str, ",\"input");
if (statem == JSHPINSTATE_GPIO_IN_PULLUP) jsvAppendString(str, "_pullup");
if (statem == JSHPINSTATE_GPIO_IN_PULLDOWN) jsvAppendString(str, "_pulldown");
jsvAppendString(str, "\");\n");
}
}
}
// Used when shutting down before flashing

View File

@ -160,10 +160,12 @@ JsVarInt jswrap_io_digitalRead(JsVar *pinVar) {
}*/
void jswrap_io_pinMode(Pin pin, JsVar *mode) {
JshPinState m = JSHPINSTATE_UNDEFINED;
if (jsvIsStringEqual(mode, "input")) m = JSHPINSTATE_GPIO_IN;
if (jsvIsStringEqual(mode, "input_pullup")) m = JSHPINSTATE_GPIO_IN_PULLUP;
if (jsvIsStringEqual(mode, "input_pulldown")) m = JSHPINSTATE_GPIO_IN_PULLDOWN;
if (jsvIsStringEqual(mode, "output")) m = JSHPINSTATE_GPIO_OUT;
if (jsvIsString(mode)) {
if (jsvIsStringEqual(mode, "input")) m = JSHPINSTATE_GPIO_IN;
if (jsvIsStringEqual(mode, "input_pullup")) m = JSHPINSTATE_GPIO_IN_PULLUP;
if (jsvIsStringEqual(mode, "input_pulldown")) m = JSHPINSTATE_GPIO_IN_PULLDOWN;
if (jsvIsStringEqual(mode, "output")) m = JSHPINSTATE_GPIO_OUT;
}
if (m != JSHPINSTATE_UNDEFINED) {
jshSetPinStateIsManual(pin, true);
jshPinSetState(pin, m);

View File

@ -284,6 +284,13 @@ void jshPinSetState(Pin pin, JshPinState state) {
#endif
}
JshPinState jshPinGetState(Pin pin) {
#ifdef SYSFS_GPIO_DIR
return gpioState[pin] = state;
#endif
return JSHPINSTATE_UNDEFINED;
}
void jshPinSetValue(Pin pin, bool value) {
#ifdef SYSFS_GPIO_DIR
char path[64] = SYSFS_GPIO_DIR"/gpio";

View File

@ -480,9 +480,9 @@ bool jshGetPinStateIsManual(Pin pin) {
void jshSetPinStateIsManual(Pin pin, bool manual) {
if (manual)
jshPinStateIsManual |= 1<<pin;
jshPinStateIsManual = jshPinStateIsManual | (1ULL<<pin);
else
jshPinStateIsManual &= ~(1<<pin);
jshPinStateIsManual = jshPinStateIsManual & ~(1ULL<<pin);
}
void jshPinSetState(Pin pin, JshPinState state) {
@ -523,6 +523,47 @@ void jshPinSetState(Pin pin, JshPinState state) {
GPIO_Init(stmPort(pin), &GPIO_InitStructure);
}
JshPinState jshPinGetState(Pin pin) {
GPIO_TypeDef* port = stmPort(pin);
uint16_t pinn = stmPin(pin);
int pinNumber = pinInfo[pin].pin;
bool isOn = (port->ODR&pinn) != 0;
#ifdef STM32F1
unsigned int crBits = ((pinNumber < 8) ? (port->CRL>>(pinNumber*4)) : (port->CRH>>((pinNumber-8)*4))) & 15;
unsigned int mode = crBits &3;
unsigned int cnf = (crBits>>2)&3;
if (mode==0) { // input
if (cnf==0) return JSHPINSTATE_ADC_IN;
else if (cnf==1) return JSHPINSTATE_GPIO_IN;
else /* cnf==2, 3=reserved */
return isOn ? JSHPINSTATE_GPIO_IN_PULLUP : JSHPINSTATE_GPIO_IN_PULLDOWN;
} else { // output
if (cnf&2) // af
return (cnf&1) ? JSHPINSTATE_AF_OUT/*_OPENDRAIN*/ : JSHPINSTATE_AF_OUT;
else { // normal
return ((cnf&1) ? JSHPINSTATE_GPIO_OUT_OPENDRAIN : JSHPINSTATE_GPIO_OUT) |
(isOn ? JSHPINSTATE_PIN_IS_ON : 0);
}
}
#else
int mode = (port->MODER >> (pinNumber*2)) & 3;
if (mode==0) { // input
int pupd = (port->PUPDR >> (pinNumber*2)) & 3;
if (pupd==1) return JSHPINSTATE_GPIO_IN_PULLUP;
if (pupd==2) return JSHPINSTATE_GPIO_IN_PULLDOWN;
return JSHPINSTATE_GPIO_IN;
} else if (mode==1) { // output
return ((port->OTYPER&pinn) ? JSHPINSTATE_GPIO_OUT_OPENDRAIN : JSHPINSTATE_GPIO_OUT) |
(isOn ? JSHPINSTATE_PIN_IS_ON : 0);
} else if (mode==2) { // AF
return JSHPINSTATE_AF_OUT;
} else { // 3, analog
return JSHPINSTATE_ADC_IN;
}
#endif
// GPIO_ReadOutputDataBit(port, pinn);
}
static inline void jshPinSetFunction(Pin pin, JshPinFunction func) {
if (JSH_PINFUNCTION_IS_USART(func)) {
if ((func&JSH_MASK_INFO)==JSH_USART_RX)
@ -1334,7 +1375,7 @@ void jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq) { // if freq
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // for negated
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(value*TIM_TimeBaseStructure.TIM_Period);
if (func & JSH_TIMER_NEGATED) TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period-(TIM_OCInitStructure.TIM_Pulse+1);
if (func & JSH_TIMER_NEGATED) TIM_OCInitStructure.TIM_Pulse = (uint16_t)(TIM_TimeBaseStructure.TIM_Period-(TIM_OCInitStructure.TIM_Pulse+1));
if ((func&JSH_MASK_TIMER_CH)==JSH_TIMER_CH1) {
TIM_OC1Init(TIMx, &TIM_OCInitStructure);