mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Now store Pin state (fix for #13 on F1 parts, F4 still looks broken)
This commit is contained in:
parent
af2e652801
commit
1085a3af8c
@ -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)
|
||||
|
||||
@ -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
|
||||
""");
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user