mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Move pin defs into auto-generated header file - allows us to optimise a bit better
This commit is contained in:
parent
30327a9f99
commit
a79cff3fcd
8
Makefile
8
Makefile
@ -732,7 +732,7 @@ endif
|
||||
|
||||
ifdef ARM
|
||||
LINKER_FILE = gen/linker.ld
|
||||
PININFOFILE=$(ROOT)/gen/jshardware_pininfo.c
|
||||
PININFOFILE=$(ROOT)/gen/jspininfo
|
||||
DEFINES += -DARM
|
||||
INCLUDE += -I$(ROOT)/targetlibs/arm
|
||||
OPTIMIZEFLAGS += -fno-common -fno-exceptions -fdata-sections -ffunction-sections
|
||||
@ -751,7 +751,7 @@ export CCPREFIX=arm-none-eabi-
|
||||
endif # ARM
|
||||
|
||||
ifdef PININFOFILE
|
||||
SOURCES += $(PININFOFILE)
|
||||
SOURCES += $(PININFOFILE).c
|
||||
endif
|
||||
|
||||
ifdef CARAMBOLA
|
||||
@ -842,9 +842,9 @@ $(WRAPPERFILE): scripts/build_jswrapper.py $(WRAPPERSOURCES)
|
||||
$(Q)python scripts/build_jswrapper.py $(WRAPPERSOURCES) $(DEFINES)
|
||||
|
||||
ifdef PININFOFILE
|
||||
$(PININFOFILE): scripts/build_pininfo.py
|
||||
$(PININFOFILE).c $(PININFOFILE).h: scripts/build_pininfo.py
|
||||
@echo Generating pin info
|
||||
$(Q)python scripts/build_pininfo.py $(BOARD) $(PININFOFILE)
|
||||
$(Q)python scripts/build_pininfo.py $(BOARD) $(PININFOFILE).c $(PININFOFILE).h
|
||||
endif
|
||||
|
||||
$(LINKER_FILE): scripts/build_linker.py
|
||||
|
||||
@ -32,12 +32,14 @@ import pinutils;
|
||||
|
||||
# Now scan AF file
|
||||
print "Script location "+scriptdir
|
||||
if len(sys.argv)!=3:
|
||||
print "ERROR, USAGE: build_pininfo.py BOARD_NAME PININFO_FILENAME"
|
||||
if len(sys.argv)!=4:
|
||||
print "ERROR, USAGE: build_pininfo.py BOARD_NAME jspininfo.c jspininfo.h"
|
||||
exit(1)
|
||||
boardname = sys.argv[1]
|
||||
pininfoFilename = sys.argv[2]
|
||||
print "PININFO_FILENAME"+pininfoFilename
|
||||
pininfoSourceFilename = sys.argv[2]
|
||||
pininfoHeaderFilename = sys.argv[3]
|
||||
print "PININFO_SOURCE_FILENAME"+pininfoSourceFilename
|
||||
print "PININFO_HEADER_FILENAME"+pininfoHeaderFilename
|
||||
print "BOARD "+boardname
|
||||
# import the board def
|
||||
|
||||
@ -50,15 +52,31 @@ pins = board.get_pins()
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
pininfoFile = open(pininfoFilename, 'w')
|
||||
def writepininfo(s): pininfoFile.write(s+"\n");
|
||||
pininfoSourceFile = open(pininfoSourceFilename, 'w')
|
||||
pininfoHeaderFile = open(pininfoHeaderFilename, 'w')
|
||||
def writesource(s): pininfoSourceFile.write(s+"\n");
|
||||
def writeheader(s): pininfoHeaderFile.write(s+"\n");
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
pinInfoFunctionCount = 0
|
||||
# work out pin functions (and how many we need)
|
||||
for pin in pins:
|
||||
functions = [ ]
|
||||
for afname in pin["functions"]:
|
||||
af = pin["functions"][afname]
|
||||
if afname in pinutils.ALLOWED_FUNCTIONS:
|
||||
functions.append("JSH_AF"+str(af)+"|"+pinutils.ALLOWED_FUNCTIONS[afname]);
|
||||
pin["jshFunctions"] = functions
|
||||
if len(functions)>pinInfoFunctionCount: pinInfoFunctionCount = len(functions)
|
||||
|
||||
|
||||
writesource("// auto-generated pin info file")
|
||||
writesource("// for board "+boardname)
|
||||
writesource("#include \"jspininfo.h\"")
|
||||
writesource("")
|
||||
writesource("const JshPinInfo pinInfo[JSH_PIN_COUNT] = {")
|
||||
|
||||
writepininfo("// auto-generated pin info file")
|
||||
writepininfo("// for board "+boardname)
|
||||
writepininfo("#include \"jshardware_pininfo.h\"")
|
||||
writepininfo("")
|
||||
writepininfo("const int pinInfoCount = "+str(len(pins))+";")
|
||||
writepininfo("const JshPinInfo pinInfo[] = {")
|
||||
for pin in pins:
|
||||
analog = "JSH_ANALOG_NONE";
|
||||
for function in pin["functions"]:
|
||||
@ -67,20 +85,11 @@ for pin in pins:
|
||||
adc = function[3:inpos]
|
||||
channel = function[inpos+3:]
|
||||
analog = "JSH_ANALOG"+adc+"|JSH_ANALOG_CH"+channel;
|
||||
function = pin["jshFunctions"]
|
||||
while len(functions)<pinInfoFunctionCount: functions.append("0")
|
||||
|
||||
functions = [ ]
|
||||
for afname in pin["functions"]:
|
||||
af = pin["functions"][afname]
|
||||
if afname in pinutils.ALLOWED_FUNCTIONS:
|
||||
functions.append("JSH_AF"+str(af)+"|"+pinutils.ALLOWED_FUNCTIONS[afname]);
|
||||
|
||||
if len(functions)>pinutils.MAX_ALLOWED_FUNCTIONS:
|
||||
print "ERROR: Too many functions for pin "+pin["name"]+" ("+str(len(functions))+" functions)";
|
||||
exit(1)
|
||||
while len(functions)<pinutils.MAX_ALLOWED_FUNCTIONS: functions.append("0")
|
||||
|
||||
writepininfo("/* "+pin["name"].ljust(4)+" */ { JSH_PORT"+pin["port"]+", JSH_PIN"+pin["num"]+", "+analog+", "+', '.join(functions)+" },")
|
||||
writepininfo("};")
|
||||
writesource("/* "+pin["name"].ljust(4)+" */ { JSH_PORT"+pin["port"]+", JSH_PIN"+pin["num"]+", "+analog+", "+', '.join(functions)+" },")
|
||||
writesource("};")
|
||||
|
||||
portinfo = {}
|
||||
|
||||
@ -99,9 +108,29 @@ if boardname=="OLIMEXINO_STM32":
|
||||
elif port=="D": portinfo[port] = { 'count' : 39, 'offset' : 0 }
|
||||
else: portinfo[port] = { 'count' : 0, 'offset' : -1 }
|
||||
|
||||
for port in pinutils.ALLOWED_PORTS:
|
||||
writepininfo("const int JSH_PORT"+port+"_COUNT = "+str(portinfo[port]['count'])+";")
|
||||
for port in pinutils.ALLOWED_PORTS:
|
||||
writepininfo("const int JSH_PORT"+port+"_OFFSET = "+str(portinfo[port]['offset'])+";")
|
||||
writesource("")
|
||||
|
||||
|
||||
writeheader("// auto-generated pin info file")
|
||||
writeheader("// for board "+boardname)
|
||||
writeheader("")
|
||||
writeheader("#include \"jspin.h\"")
|
||||
writeheader("")
|
||||
writeheader("#define JSH_PIN_COUNT "+str(len(pins)));
|
||||
writeheader("")
|
||||
for port in pinutils.ALLOWED_PORTS:
|
||||
writeheader("#define JSH_PORT"+port+"_COUNT "+str(portinfo[port]['count']))
|
||||
for port in pinutils.ALLOWED_PORTS:
|
||||
writeheader("#define JSH_PORT"+port+"_OFFSET "+str(portinfo[port]['offset']))
|
||||
writeheader("")
|
||||
writeheader("#define JSH_PININFO_FUNCTIONS "+str(pinInfoFunctionCount))
|
||||
writeheader("")
|
||||
writeheader("typedef struct JshPinInfo {")
|
||||
writeheader(" JsvPinInfoPort port;")
|
||||
writeheader(" JsvPinInfoPin pin;")
|
||||
writeheader(" JsvPinInfoAnalog analog; // TODO: maybe we don't need to store analogs separately")
|
||||
writeheader(" JshPinFunction functions[JSH_PININFO_FUNCTIONS];")
|
||||
writeheader("} PACKED_FLAGS JshPinInfo;")
|
||||
writeheader("")
|
||||
writeheader("extern const JshPinInfo pinInfo[JSH_PIN_COUNT];");
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ import json;
|
||||
import sys;
|
||||
import os;
|
||||
|
||||
MAX_ALLOWED_FUNCTIONS = 6
|
||||
ALLOWED_PORTS = "ABCDEFGH";
|
||||
ALLOWED_FUNCTIONS = {}
|
||||
CLASSES = {}
|
||||
|
||||
@ -20,8 +20,9 @@
|
||||
#include "jsutils.h"
|
||||
#include "jsvar.h"
|
||||
#include "jsdevices.h"
|
||||
#include "jspin.h"
|
||||
#ifndef LINUX
|
||||
#include "jshardware_pininfo.h"
|
||||
#include "jspininfo.h"
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
50
src/jspin.h
50
src/jspin.h
@ -1,25 +1,22 @@
|
||||
#ifndef JSHARDWARE_PININFO
|
||||
#define JSHARDWARE_PININFO
|
||||
/*
|
||||
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
|
||||
*
|
||||
* Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Utilities and definitions for handling Pins
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef JSPIN_H
|
||||
#define JSPIN_H
|
||||
|
||||
#include "jsutils.h"
|
||||
|
||||
extern const int JSH_PORTA_COUNT;
|
||||
extern const int JSH_PORTB_COUNT;
|
||||
extern const int JSH_PORTC_COUNT;
|
||||
extern const int JSH_PORTD_COUNT;
|
||||
extern const int JSH_PORTE_COUNT;
|
||||
extern const int JSH_PORTF_COUNT;
|
||||
extern const int JSH_PORTG_COUNT;
|
||||
extern const int JSH_PORTH_COUNT;
|
||||
extern const int JSH_PORTA_OFFSET;
|
||||
extern const int JSH_PORTB_OFFSET;
|
||||
extern const int JSH_PORTC_OFFSET;
|
||||
extern const int JSH_PORTD_OFFSET;
|
||||
extern const int JSH_PORTE_OFFSET;
|
||||
extern const int JSH_PORTF_OFFSET;
|
||||
extern const int JSH_PORTG_OFFSET;
|
||||
extern const int JSH_PORTH_OFFSET;
|
||||
|
||||
typedef enum {
|
||||
JSH_PORT_NONE,
|
||||
JSH_PORTA=1,
|
||||
@ -141,6 +138,7 @@ typedef enum {
|
||||
JSH_USARTMAX = JSH_USART6,
|
||||
|
||||
// ---------------------------- JSH_MASK_INFO
|
||||
|
||||
JSH_TIMER_CH1 = 0x0000,
|
||||
JSH_TIMER_CH2 = 0x1000,
|
||||
JSH_TIMER_CH3 = 0x2000,
|
||||
@ -184,16 +182,4 @@ typedef enum {
|
||||
(((F)&JSH_MASK_TYPE)<=JSH_SPIMAX))
|
||||
|
||||
|
||||
#define JSH_PININFO_FUNCTIONS 6
|
||||
|
||||
typedef struct JshPinInfo {
|
||||
JsvPinInfoPort port;
|
||||
JsvPinInfoPin pin;
|
||||
JsvPinInfoAnalog analog; // TODO: maybe we don't need to store analogs separately
|
||||
JshPinFunction functions[JSH_PININFO_FUNCTIONS];
|
||||
} PACKED_FLAGS JshPinInfo;
|
||||
|
||||
extern const int pinInfoCount;
|
||||
extern const JshPinInfo pinInfo[];
|
||||
|
||||
#endif //JSHARDWARE_PININFO
|
||||
#endif //JSPIN_H
|
||||
|
||||
@ -277,6 +277,12 @@ typedef enum LEX_TYPES {
|
||||
LEX_R_LIST_END /* always the last entry */
|
||||
} LEX_TYPES;
|
||||
|
||||
// To handle variable size bit fields
|
||||
#define BITFIELD_DECL(BITFIELD, N) unsigned int BITFIELD[(N+31)/32]
|
||||
#define BITFIELD_GET(BITFIELD, N) ((BITFIELD[(N)>>5] >> ((N)&31))&1)
|
||||
#define BITFIELD_SET(BITFIELD, N, VALUE) (BITFIELD[(N)>>5] = (BITFIELD[(N)>>5]& (unsigned int)~(1 << ((N)&31))) | (unsigned int)((VALUE)?(1 << ((N)&31)):0) )
|
||||
|
||||
|
||||
static inline bool isWhitespace(char ch) {
|
||||
return (ch==' ') || (ch=='\t') || (ch=='\n') || (ch=='\r');
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
#endif
|
||||
|
||||
#include "jshardware.h"
|
||||
#include "jshardware_pininfo.h"
|
||||
#include "jsutils.h"
|
||||
#include "jsparse.h"
|
||||
#include "jsinteractive.h"
|
||||
@ -53,7 +52,7 @@
|
||||
Pin watchedPins[16];
|
||||
|
||||
// NOTE: Only works up to 64 IO pins
|
||||
unsigned long long jshPinStateIsManual = 0;
|
||||
BITFIELD_DECL(jshPinStateIsManual, JSH_PIN_COUNT);
|
||||
|
||||
#ifdef STM32F4
|
||||
#define WAIT_UNTIL_N_CYCLES 10000000
|
||||
@ -525,7 +524,7 @@ static void NO_INLINE jshPrintCapablePins(Pin existingPin, const char *functionN
|
||||
|
||||
Pin pin;
|
||||
int i,n=0;
|
||||
for (pin=0;pin<pinInfoCount;pin++) {
|
||||
for (pin=0;pin<JSH_PIN_COUNT;pin++) {
|
||||
bool has = false;
|
||||
#ifdef STM32F1
|
||||
int af = 0;
|
||||
@ -601,14 +600,11 @@ void jshDelayMicroseconds(int microsec) {
|
||||
}
|
||||
|
||||
bool jshGetPinStateIsManual(Pin pin) {
|
||||
return (jshPinStateIsManual>>pin)&1;
|
||||
return BITFIELD_GET(jshPinStateIsManual, pin);
|
||||
}
|
||||
|
||||
void jshSetPinStateIsManual(Pin pin, bool manual) {
|
||||
if (manual)
|
||||
jshPinStateIsManual = jshPinStateIsManual | (1ULL<<pin);
|
||||
else
|
||||
jshPinStateIsManual = jshPinStateIsManual & ~(1ULL<<pin);
|
||||
void jshSetPinStateIsManual(Pin pin, bool manual) {
|
||||
BITFIELD_SET(jshPinStateIsManual, pin, manual);
|
||||
}
|
||||
|
||||
inline void jshPinSetState(Pin pin, JshPinState state) {
|
||||
@ -739,7 +735,7 @@ inline bool jshPinGetValue(Pin pin) {
|
||||
}
|
||||
|
||||
bool jshIsPinValid(Pin pin) {
|
||||
return pin>=0 && pin < pinInfoCount && pinInfo[pin].port!=JSH_PORT_NONE;
|
||||
return pin>=0 && pin < JSH_PIN_COUNT && pinInfo[pin].port!=JSH_PORT_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -1202,7 +1198,7 @@ bool jshPinInput(Pin pin) {
|
||||
|
||||
JsVarFloat jshPinAnalog(Pin pin) {
|
||||
JsVarFloat value = 0;
|
||||
if (pin<0 || pin >= pinInfoCount || pinInfo[pin].analog==JSH_ANALOG_NONE) {
|
||||
if (pin<0 || pin >= JSH_PIN_COUNT || pinInfo[pin].analog==JSH_ANALOG_NONE) {
|
||||
jshPrintCapablePins(pin, "Analog Input", 0,0,0,0, true);
|
||||
return 0;
|
||||
}
|
||||
@ -1354,7 +1350,7 @@ void jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq) { // if freq
|
||||
if (value<0) value=0;
|
||||
if (value>1) value=1;
|
||||
JshPinFunction func = 0;
|
||||
if (pin>=0 && pin < pinInfoCount) {
|
||||
if (pin>=0 && pin < JSH_PIN_COUNT) {
|
||||
int i;
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
if (freq<=0 && JSH_PINFUNCTION_IS_DAC(pinInfo[pin].functions[i])) {
|
||||
@ -1467,7 +1463,7 @@ void jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq) { // if freq
|
||||
}
|
||||
|
||||
void jshPinWatch(Pin pin, bool shouldWatch) {
|
||||
if (pin>=0 && pin < pinInfoCount && pinInfo[pin].port!=JSH_PORT_NONE) {
|
||||
if (jshIsPinValid(pin)) {
|
||||
// TODO: check for DUPs, also disable interrupt
|
||||
/*int idx = pinToPinSource(IOPIN_DATA[pin].pin);
|
||||
if (pinInterrupt[idx].pin>PININTERRUPTS) jsError("Interrupt already used");
|
||||
@ -1499,7 +1495,7 @@ void jshPinWatch(Pin pin, bool shouldWatch) {
|
||||
bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
int exti = IOEVENTFLAGS_GETTYPE(device) - EV_EXTI0;
|
||||
Pin pin = watchedPins[exti];
|
||||
if (pin>=0 && pin < pinInfoCount)
|
||||
if (jshIsPinValid(pin))
|
||||
return GPIO_ReadInputDataBit(stmPort(pin), stmPin(pin));
|
||||
return false;
|
||||
}
|
||||
@ -1510,7 +1506,7 @@ bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
|
||||
/** Try and find a specific type of function for the given pin. Can be given an invalid pin and will return 0. */
|
||||
JshPinFunction NO_INLINE getPinFunctionForPin(Pin pin, JshPinFunction functionType) {
|
||||
if (pin<0 || pin>=pinInfoCount) return 0;
|
||||
if (!jshIsPinValid(pin)) return 0;
|
||||
int i;
|
||||
for (i=0;i<JSH_PININFO_FUNCTIONS;i++) {
|
||||
if ((pinInfo[pin].functions[i]&JSH_MASK_TYPE) == functionType)
|
||||
@ -1529,14 +1525,14 @@ Pin NO_INLINE findPinForFunction(JshPinFunction functionType, JshPinFunction fun
|
||||
Pin i;
|
||||
int j;
|
||||
// first, try and find the pin with an AF of 0 - this is usually the 'default'
|
||||
for (i=0;i<pinInfoCount;i++)
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_AF) == JSH_AF0 &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
return i;
|
||||
// otherwise just try and find anything
|
||||
for (i=0;i<pinInfoCount;i++)
|
||||
for (i=0;i<JSH_PIN_COUNT;i++)
|
||||
for (j=0;j<JSH_PININFO_FUNCTIONS;j++)
|
||||
if ((pinInfo[i].functions[j]&JSH_MASK_TYPE) == functionType &&
|
||||
(pinInfo[i].functions[j]&JSH_MASK_INFO) == functionInfo)
|
||||
@ -2331,7 +2327,7 @@ void jshPinPulse(Pin pin, bool pulsePolarity, JsVarFloat pulseTime) {
|
||||
// ---- SOFTWARE PULSE
|
||||
/* JsSysTime ticks = jshGetTimeFromMilliseconds(time);
|
||||
//jsPrintInt(ticks);jsPrint("\n");
|
||||
if (pin>=0 && pin < pinInfoCount && pinInfo[pin].port!=JSH_PORT_NONE) {
|
||||
if (jshIsPinValid(pin) {
|
||||
jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
|
||||
jshPinSetValue(pin, value);
|
||||
JsSysTime starttime = jshGetSystemTime();
|
||||
@ -2345,7 +2341,7 @@ void jshPinPulse(Pin pin, bool pulsePolarity, JsVarFloat pulseTime) {
|
||||
jshPinSetValue(pin, !value);
|
||||
} else jsError("Invalid pin!"); */
|
||||
// ---- USE TIMER FOR PULSE
|
||||
if (!(pin>=0 && pin < pinInfoCount && pinInfo[pin].port!=JSH_PORT_NONE)) {
|
||||
if (!jshIsPinValid(pin)) {
|
||||
jsError("Invalid pin!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
#endif
|
||||
#include "jsinteractive.h"
|
||||
#include "jshardware.h"
|
||||
#include "jshardware_pininfo.h"
|
||||
|
||||
extern void _VECTOR_TABLE;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user