#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
#
-# Updates:
+# Updates:
# Arthur Wolf & Adam Green in 2011 - Updated to work with mbed.
###############################################################################
# USAGE:
# LIBS_SUFFIX: List of library/object files to append to mbed.ar capi.ar libs.
# GCC4MBED_TYPE: Type of build to produce. Allowed values are:
# Debug - Build for debugging. Disables optimizations and
-# links in debug MRI runtime. Best debugging
+# links in debug MRI runtime. Best debugging
# experience.
# Release - Build for release with no debug support.
# Checked - Release build with debug support. Due to
# LIBS_SUFFIX=
#
# include ../../build/gcc4mbed.mk
-#
+#
###############################################################################
# Check for undefined variables.
INCDIRS += $(PROJINCS) $(GCC4MBED_DIR)/mri $(EXTERNAL_DIR)/mbed $(EXTERNAL_DIR)/mbed/LPC1768
# DEFINEs to be used when building C/C++ code
-DEFINES = -DTARGET_LPC1768
-DEFINES += -DMRI_ENABLE=$(MRI_ENABLE) -DMRI_INIT_PARAMETERS='"$(MRI_INIT_PARAMETERS)"'
+DEFINES = -DTARGET_LPC1768 -D__LPC17XX__
+DEFINES += -DMRI_ENABLE=$(MRI_ENABLE) -DMRI_INIT_PARAMETERS='"$(MRI_INIT_PARAMETERS)"'
DEFINES += -DMRI_BREAK_ON_INIT=$(MRI_BREAK_ON_INIT) -DMRI_SEMIHOST_STDIO=$(MRI_SEMIHOST_STDIO)
# Libraries to be linked into final binary
MBED_LIBS = $(EXTERNAL_DIR)/mbed/LPC1768/GCC_ARM/libmbed.a $(EXTERNAL_DIR)/mbed/LPC1768/GCC_ARM/libcapi.a
SYS_LIBS = -lstdc++ -lsupc++ -lm -lgcc -lc -lgcc -lc -lnosys
-LIBS = $(LIBS_PREFIX)
+LIBS = $(LIBS_PREFIX)
ifeq "$(MRI_ENABLE)" "1"
LIBS += $(GCC4MBED_DIR)/mri/mri.ar
DEPFLAGS = -MMD -MP
# Compiler Options
-GPFLAGS = -O$(OPTIMIZATION) -g3 -mcpu=cortex-m3 -mthumb -mthumb-interwork
-GPFLAGS += -ffunction-sections -fdata-sections -fno-exceptions
-GPFLAGS += $(patsubst %,-I%,$(INCDIRS))
-GPFLAGS += $(DEFINES)
-GPFLAGS += $(DEPFLAGS)
-GPFLAGS += -Wall -Wextra -Wno-unused-parameter -Wcast-align -Wpointer-arith -Wredundant-decls -Wcast-qual -Wcast-align
-GCFLAGS = $(GPFLAGS)
-
-# Setup wraps for newlib read/writes to redirect to MRI debugger.
+
+# C/C++ flags
+GCFLAGS = -O$(OPTIMIZATION) -g -mcpu=cortex-m3 -mthumb -mthumb-interwork
+GCFLAGS += -ffunction-sections -fdata-sections -fno-exceptions
+GCFLAGS += $(patsubst %,-I%,$(INCDIRS))
+GCFLAGS += $(DEFINES)
+GCFLAGS += $(DEPFLAGS)
+GCFLAGS += -Wall -Wextra -Wno-unused-parameter -Wcast-align -Wpointer-arith -Wredundant-decls -Wcast-qual -Wcast-align
+
+# C++ only flags
+GPFLAGS = $(GCFLAGS)
+# uncomment the next line for extra fun ;)
+GPFLAGS += -std=gnu++0x
+# GPFLAGS += ...
+
+# Setup wraps for newlib read/writes to redirect to MRI debugger.
ifeq "$(MRI_ENABLE)" "1"
MRI_WRAPS=,--wrap=_read,--wrap=_write,--wrap=semihost_connected
else
endif
#########################################################################
-.PHONY: all clean deploy
+.PHONY: all clean deploy size
-all:: $(PROJECT).hex $(PROJECT).bin $(OUTDIR)/$(PROJECT).disasm
+all:: $(PROJECT).hex $(PROJECT).bin $(OUTDIR)/$(PROJECT).disasm size
$(PROJECT).bin: $(PROJECT).elf
- $(OBJCOPY) -O binary $(PROJECT).elf $(PROJECT).bin
+ @echo " OBJCOPY " $@
+ @$(OBJCOPY) -O binary $(PROJECT).elf $(PROJECT).bin
$(PROJECT).hex: $(PROJECT).elf
- $(OBJCOPY) -R .stack -O ihex $(PROJECT).elf $(PROJECT).hex
-
+ @echo " OBJCOPY " $@
+ @$(OBJCOPY) -R .stack -O ihex $(PROJECT).elf $(PROJECT).hex
+
$(OUTDIR)/$(PROJECT).disasm: $(PROJECT).elf
- $(OBJDUMP) -d -f -M reg-names-std $(PROJECT).elf >$(OUTDIR)/$(PROJECT).disasm
-
+ @echo " DISASM " $@
+ @$(OBJDUMP) -d -f -M reg-names-std $(PROJECT).elf >$(OUTDIR)/$(PROJECT).disasm
+
$(PROJECT).elf: $(LSCRIPT) $(OBJECTS)
- $(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(PROJECT).elf
- $(SIZE) $(PROJECT).elf
+ @echo " LD " $@
+ @$(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(PROJECT).elf
+ @$(SIZE) $(PROJECT).elf
clean:
- $(REMOVE) -f $(call convert-slash,$(OBJECTS)) $(QUIET)
- $(REMOVE) -f $(call convert-slash,$(DEPFILES)) $(QUIET)
- $(REMOVE_DIR) $(OUTDIR) $(QUIET)
- $(REMOVE) -f $(call convert-slash,$(OUTDIR)/$(PROJECT).map) $(QUIET)
- $(REMOVE) -f $(call convert-slash,$(OUTDIR)/$(PROJECT).disasm) $(QUIET)
- $(REMOVE) -f $(PROJECT).bin $(QUIET)
- $(REMOVE) -f $(PROJECT).hex $(QUIET)
- $(REMOVE) -f $(PROJECT).elf $(QUIET)
+ @echo " RM " "*.o"
+ @$(REMOVE) -f $(call convert-slash,$(OBJECTS)) $(QUIET)
+ @echo " RM " "*.dep"
+ @$(REMOVE) -f $(call convert-slash,$(DEPFILES)) $(QUIET)
+ @echo " RM " $(OUTDIR)/
+ @$(REMOVE_DIR) $(OUTDIR) $(QUIET)
+ @echo " RM " "$(PROJECT).map"
+ @$(REMOVE) -f $(call convert-slash,$(OUTDIR)/$(PROJECT).map) $(QUIET)
+ @echo " RM " "$(PROJECT).disasm"
+ @$(REMOVE) -f $(call convert-slash,$(OUTDIR)/$(PROJECT).disasm) $(QUIET)
+ @echo " RM " "$(PROJECT).bin"
+ @$(REMOVE) -f $(PROJECT).bin $(QUIET)
+ @echo " RM " "$(PROJECT).hex"
+ @$(REMOVE) -f $(PROJECT).hex $(QUIET)
+ @echo " RM " "$(PROJECT).elf"
+ @$(REMOVE) -f $(PROJECT).elf $(QUIET)
+
+size: $(PROJECT).elf
+ @echo
+ @echo $$' \033[1;4m SIZE LPC1769 \033[0m'
+ @$(OBJDUMP) -h $^ | perl -MPOSIX -ne '/.(text|rodata)\s+([0-9a-f]+)/ && do { $$a += eval "0x$$2" }; END { printf " FLASH %6d bytes %2d%% of %3dkb\n", $$a, ceil($$a * 100 / (512 * 1024)), 512 }'
+ @$(OBJDUMP) -h $^ | perl -MPOSIX -ne '/.(data|bss)\s+([0-9a-f]+)/ && do { $$a += eval "0x$$2" }; END { printf " RAM %6d bytes %2d%% of %3dkb\n", $$a, ceil($$a * 100 / ( 16 * 1024)), 16 }'
-include $(DEPFILES)
# and assemble .s files to .o
$(OUTDIR)/gcc4mbed.o : $(GCC4MBED_DIR)/src/gcc4mbed.c
- $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
- $(GPP) $(GPFLAGS) -c $< -o $@
+ @echo " CC " $<
+ @$(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
+ @$(GPP) $(GPFLAGS) -c $< -o $@
$(OUTDIR)/%.o : %.cpp
- $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
- $(GPP) $(GPFLAGS) -c $< -o $@
+ @echo " CC " $<
+ @$(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
+# if you want to see the whole compile command, remove the @ preceding the line below
+ @$(GPP) $(GPFLAGS) -c $< -o $@
$(OUTDIR)/%.o : %.c
- $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
- $(GCC) $(GCFLAGS) -c $< -o $@
+ @echo " CC " $<
+ @$(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
+ @$(GCC) $(GCFLAGS) -c $< -o $@
$(OUTDIR)/%.o : %.S
- $(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
- $(AS) $(ASFLAGS) -c $< -o $@
+ @echo " AS " $<
+ @$(MKDIR) $(call convert-slash,$(dir $@)) $(QUIET)
+ @$(AS) $(ASFLAGS) -c $< -o $@
#########################################################################
_status = NO_INIT;\r
connect();\r
// USBDevice::connect();\r
- setSense(SENSE_NO_SENSE, 0x00, 0x00);\r
+ setSense(SENSE_NO_SENSE, 0x00, 0x00);\r
USBHAL::connect();\r
}\r
\r
}\r
\r
int USBCDCMSC::printf(const char* format, ...) {\r
- va_list args;\r
- int slen;\r
- uint8_t *result, *current;\r
+ va_list args;\r
+ int slen;\r
+ uint8_t *result, *current;\r
\r
- va_start (args, format);\r
- slen = vasprintf ((char **)&result, format, args);\r
- va_end (args);\r
+ va_start (args, format);\r
+ slen = vasprintf ((char **)&result, format, args);\r
+ va_end (args);\r
\r
- current = result;\r
+ current = result;\r
\r
- // Send full-size packets as many times as needed\r
- while(slen > MAX_CDC_REPORT_SIZE) {\r
- send(current, MAX_CDC_REPORT_SIZE);\r
- current += MAX_CDC_REPORT_SIZE;\r
- slen -= MAX_CDC_REPORT_SIZE;\r
- }\r
+ // Send full-size packets as many times as needed\r
+ while(slen > MAX_CDC_REPORT_SIZE) {\r
+ send(current, MAX_CDC_REPORT_SIZE);\r
+ current += MAX_CDC_REPORT_SIZE;\r
+ slen -= MAX_CDC_REPORT_SIZE;\r
+ }\r
\r
- // send a full packet followed by Zero Length Packet\r
- if(slen == MAX_CDC_REPORT_SIZE) {\r
- send(current, MAX_CDC_REPORT_SIZE);\r
- send(current, 0);\r
- }\r
+ // send a full packet followed by Zero Length Packet\r
+ if(slen == MAX_CDC_REPORT_SIZE) {\r
+ send(current, MAX_CDC_REPORT_SIZE);\r
+ send(current, 0);\r
+ }\r
\r
- // send a partial packet if needed to finish\r
- if(slen < MAX_CDC_REPORT_SIZE) {\r
- send(current, slen);\r
- }\r
- free(result);\r
- return 0;\r
+ // send a partial packet if needed to finish\r
+ if(slen < MAX_CDC_REPORT_SIZE) {\r
+ send(current, slen);\r
+ }\r
+ free(result);\r
+ return 0;\r
}\r
\r
bool USBCDCMSC::writeBlock(uint8_t * buf, uint16_t size) {\r
\r
bool USBCDCMSC::readFormatCapacity() {\r
uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,\r
- (BlockCount >> 24) & 0xff,\r
- (BlockCount >> 16) & 0xff,\r
- (BlockCount >> 8) & 0xff,\r
- (BlockCount >> 0) & 0xff,\r
-\r
- 0x02,\r
- (BlockSize >> 16) & 0xff,\r
- (BlockSize >> 8) & 0xff,\r
- (BlockSize >> 0) & 0xff,\r
- };\r
+ ((uint8_t) ((BlockCount >> 24) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 0) & 0xff)),\r
+\r
+ 0x02,\r
+ ((uint8_t) ((BlockSize >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 0) & 0xff)),\r
+ };\r
if (!msd_write(capacity, sizeof(capacity))) {\r
return false;\r
}\r
\r
bool USBCDCMSC::readCapacity (void) {\r
uint8_t capacity[] = {\r
- ((BlockCount - 1) >> 24) & 0xff,\r
- ((BlockCount - 1) >> 16) & 0xff,\r
- ((BlockCount - 1) >> 8) & 0xff,\r
- ((BlockCount - 1) >> 0) & 0xff,\r
-\r
- (BlockSize >> 24) & 0xff,\r
- (BlockSize >> 16) & 0xff,\r
- (BlockSize >> 8) & 0xff,\r
- (BlockSize >> 0) & 0xff,\r
+ ((uint8_t) (((BlockCount - 1) >> 24) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 16) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 8) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 0) & 0xff)),\r
+\r
+ ((uint8_t) ((BlockSize >> 24) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 0) & 0xff)),\r
};\r
if (!msd_write(capacity, sizeof(capacity))) {\r
return false;\r
sense.sense_key = sense_key;\r
sense.additional_sense_length = 0x0a;\r
sense.asc = asc;\r
- sense.ascq = ascq; \r
+ sense.ascq = ascq;\r
}\r
\r
bool USBCDCMSC::requestSense (void) {\r
if (!msd_write((uint8_t *)&sense, sizeof(sense))) {\r
return false;\r
}\r
- \r
+\r
return true;\r
}\r
\r
void USBCDCMSC::mediaRemoval() {\r
- csw.Status = CSW_PASSED;\r
- sendCSW();\r
+ csw.Status = CSW_PASSED;\r
+ sendCSW();\r
}\r
\r
void USBCDCMSC::fail() {\r
case READ_FORMAT_CAPACITIES:\r
readFormatCapacity();\r
break;\r
- case MEDIA_REMOVAL:\r
- mediaRemoval();\r
- break;\r
+ case MEDIA_REMOVAL:\r
+ mediaRemoval();\r
+ break;\r
case READ_CAPACITY:\r
readCapacity();\r
break;\r
}\r
\r
int USBCDCMSC::disk_write(const char *buffer, int block_number) {\r
- return _sd->disk_write(buffer, block_number); \r
+ return _sd->disk_write(buffer, block_number);\r
}\r
\r
-int USBCDCMSC::disk_read(char *buffer, int block_number) { \r
- return _sd->disk_read(buffer, block_number); \r
+int USBCDCMSC::disk_read(char *buffer, int block_number) {\r
+ return _sd->disk_read(buffer, block_number);\r
}\r
\r
int USBCDCMSC::disk_status() {\r
}\r
\r
int USBCDCMSC::disk_sectors() {\r
- return _sd->disk_sectors(); \r
+ return _sd->disk_sectors();\r
}\r
int USBCDCMSC::disk_size() {\r
return _sd->disk_sectors() * 512;\r
if( this->has_char('\n') ){\r
string received;\r
while(1){\r
- char c;\r
- this->buffer.pop_front(c);\r
- if( c == '\n' ){\r
- struct SerialMessage message; \r
+ char c;\r
+ this->buffer.pop_front(c);\r
+ if( c == '\n' ){\r
+ struct SerialMessage message;\r
message.message = received;\r
message.stream = this;\r
- this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message ); \r
- return;\r
+ this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message );\r
+ return;\r
}else{\r
received += c;\r
}\r
}\r
}\r
-\r
}\r
\r
void USBCDCMSC::on_serial_char_received(){\r
char received = this->_getc();\r
// convert CR to NL (for host OSs that don't send NL)\r
if( received == '\r' ){ received = '\n'; }\r
- this->buffer.push_back(received); \r
+ this->buffer.push_back(received);\r
}\r
\r
}\r
* @returns true if there is no error, false otherwise\r
*/\r
virtual int _putc(int c);\r
- \r
+\r
/**\r
* Send a formatted string.\r
*/\r
* @returns character read\r
*/\r
virtual int _getc();\r
- \r
+\r
/**\r
* Check the number of bytes available.\r
*\r
* @returns the number of bytes available\r
*/\r
- uint8_t available(); \r
- \r
+ uint8_t available();\r
+\r
/**\r
- * Write a block of data. \r
+ * Write a block of data.\r
*\r
* For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written.\r
*\r
bool writeBlock(uint8_t * buf, uint16_t size);\r
\r
/**\r
- * Attach a member function to call when a packet is received. \r
+ * Attach a member function to call when a packet is received.\r
*\r
* @param tptr pointer to the object to call the member function on\r
* @param mptr pointer to the member function to be called\r
RingBuffer<char,256> buffer; // Receive buffer\r
\r
protected:\r
- \r
+\r
/*\r
* Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.\r
*\r
* @returns pointer to the device descriptor\r
*/\r
virtual uint8_t * deviceDesc();\r
- \r
+\r
/*\r
* Get string product descriptor\r
*\r
* @returns pointer to the string product descriptor\r
*/\r
virtual uint8_t * stringIproductDesc();\r
- \r
+\r
/*\r
* Get string interface descriptor\r
*\r
* @returns pointer to the configuration descriptor\r
*/\r
virtual uint8_t * configurationDesc();\r
- \r
+\r
/*\r
* Send a buffer\r
*\r
* @returns true if successful\r
*/\r
bool send(uint8_t * buffer, uint16_t size);\r
- \r
+\r
/*\r
* Read a buffer from a certain endpoint. Warning: blocking\r
*\r
* @returns true if successful\r
*/\r
bool readEP(uint8_t * buffer, uint16_t * size);\r
- \r
+\r
/*\r
* Read a buffer from a certain endpoint. Warning: non blocking\r
*\r
uint8_t Status;\r
} PACK_STRUCT_STRUCT CSW;\r
\r
- // sense\r
+ // sense\r
typedef PACK_STRUCT_BEGIN struct {\r
uint8_t error;\r
uint8_t resvd;\r
\r
// CSW which will be sent\r
CSW csw;\r
- \r
- // Current sense\r
- SENSE sense;\r
+\r
+ // Current sense\r
+ SENSE sense;\r
\r
// addr where will be read or written data\r
uint32_t addr;\r
bool modeSense6 (void);\r
void testUnitReady (void);\r
bool requestSense (void);\r
- void setSense (uint8_t sense_key, uint8_t asc, uint8_t ascq);\r
+ void setSense (uint8_t sense_key, uint8_t asc, uint8_t ascq);\r
void memoryVerify (uint8_t * buf, uint16_t size);\r
void memoryWrite (uint8_t * buf, uint16_t size);\r
void mediaRemoval(void);\r
\r
int disk_initialize();\r
int disk_write(const char *buffer, int block_number);\r
- int disk_read(char *buffer, int block_number); \r
+ int disk_read(char *buffer, int block_number);\r
int disk_status();\r
int disk_sectors();\r
int disk_size();\r
channel_config = (channel_nb == 1) ? CHANNEL_M : CHANNEL_L + CHANNEL_R;\r
\r
SOF_handler = false;\r
- \r
+\r
buf_stream = NULL;\r
\r
// connect the device\r
16, // bBitResolution\r
0x01, // bSamFreqType\r
LSB(FREQ), // tSamFreq\r
- (FREQ >> 8) & 0xff, // tSamFreq\r
- (FREQ >> 16) & 0xff, // tSamFreq\r
+ ((uint8_t) ((FREQ >> 8) & 0xff)), // tSamFreq\r
+ ((uint8_t) ((FREQ >> 16) & 0xff)), // tSamFreq\r
\r
// Endpoint - Standard Descriptor\r
ENDPOINT_DESCRIPTOR_LENGTH + 2, // bLength\r
\r
\r
/*string offset*/\r
-#define STRING_OFFSET_LANGID (0) \r
+#define STRING_OFFSET_LANGID (0)\r
#define STRING_OFFSET_IMANUFACTURER (1)\r
#define STRING_OFFSET_IPRODUCT (2)\r
#define STRING_OFFSET_ISERIAL (3)\r
#define USB_VERSION_2_0 (0x0200)\r
\r
/* Least/Most significant byte of short integer */\r
-#define LSB(n) ((n)&0xff)\r
-#define MSB(n) (((n)&0xff00)>>8)\r
+#define LSB(n) ((uint8_t)((n)&0xff))\r
+#define MSB(n) ((uint8_t)(((n)&0xff00)>>8))\r
\r
/* Convert physical endpoint number to descriptor endpoint number */\r
#define PHY_TO_DESC(endpoint) (((endpoint)>>1) | (((endpoint) & 1) ? 0x80:0))\r
\r
bool USBMSD::readFormatCapacity() {\r
uint8_t capacity[] = { 0x00, 0x00, 0x00, 0x08,\r
- (BlockCount >> 24) & 0xff,\r
- (BlockCount >> 16) & 0xff,\r
- (BlockCount >> 8) & 0xff,\r
- (BlockCount >> 0) & 0xff,\r
-\r
- 0x02,\r
- (BlockSize >> 16) & 0xff,\r
- (BlockSize >> 8) & 0xff,\r
- (BlockSize >> 0) & 0xff,\r
+ ((uint8_t) ((BlockCount >> 24) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockCount >> 0) & 0xff)),\r
+\r
+ 0x02,\r
+ ((uint8_t) ((BlockSize >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 0) & 0xff)),\r
};\r
if (!write(capacity, sizeof(capacity))) {\r
return false;\r
\r
bool USBMSD::readCapacity (void) {\r
uint8_t capacity[] = {\r
- ((BlockCount - 1) >> 24) & 0xff,\r
- ((BlockCount - 1) >> 16) & 0xff,\r
- ((BlockCount - 1) >> 8) & 0xff,\r
- ((BlockCount - 1) >> 0) & 0xff,\r
-\r
- (BlockSize >> 24) & 0xff,\r
- (BlockSize >> 16) & 0xff,\r
- (BlockSize >> 8) & 0xff,\r
- (BlockSize >> 0) & 0xff,\r
+ ((uint8_t) (((BlockCount - 1) >> 24) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 16) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 8) & 0xff)),\r
+ ((uint8_t) (((BlockCount - 1) >> 0) & 0xff)),\r
+\r
+ ((uint8_t) ((BlockSize >> 24) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 16) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 8) & 0xff)),\r
+ ((uint8_t) ((BlockSize >> 0) & 0xff)),\r
};\r
if (!write(capacity, sizeof(capacity))) {\r
return false;\r
/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
+ This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
+ Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libs/Module.h"
#define extruder_dir_pin_checksum 57277
#define extruder_en_pin_checksum 8017
-/* The extruder module controls a filament extruder for 3D printing : http://en.wikipedia.org/wiki/Fused_deposition_modeling
- * It can work in two modes : either the head does not move, and the extruder moves the filament at a specified speed ( SOLO mode here )
- * or the head moves, and the extruder moves plastic at a speed proportional to the movement of the head ( FOLLOW mode here ).
+/* The extruder module controls a filament extruder for 3D printing: http://en.wikipedia.org/wiki/Fused_deposition_modeling
+* It can work in two modes : either the head does not move, and the extruder moves the filament at a specified speed ( SOLO mode here )
+* or the head moves, and the extruder moves plastic at a speed proportional to the movement of the head ( FOLLOW mode here ).
*/
Extruder::Extruder() {
this->kernel->slow_ticker->attach( this->kernel->stepper->acceleration_ticks_per_second , this, &Extruder::acceleration_tick );
// Stepper motor object for the extruder
- this->stepper_motor = this->kernel->step_ticker->add_stepper_motor( new StepperMotor(this->step_pin,this->dir_pin,this->en_pin) );
- this->stepper_motor->attach(this, &Extruder::stepper_motor_finished_move );
+ this->stepper_motor = this->kernel->step_ticker->add_stepper_motor( new StepperMotor(this->step_pin,this->dir_pin,this->en_pin) );
+ this->stepper_motor->attach(this, &Extruder::stepper_motor_finished_move );
}
// Get config
void Extruder::on_config_reload(void* argument){
- this->microseconds_per_step_pulse = this->kernel->config->value(microseconds_per_step_pulse_checksum)->by_default(5)->as_number();
- this->steps_per_millimeter = this->kernel->config->value(extruder_steps_per_mm_checksum )->by_default(1)->as_number();
- this->feed_rate = this->kernel->config->value(default_feed_rate_checksum )->by_default(1000)->as_number();
- this->acceleration = this->kernel->config->value(extruder_acceleration_checksum )->by_default(1000)->as_number();
-
- this->step_pin = this->kernel->config->value(extruder_step_pin_checksum )->by_default("nc" )->as_pin()->as_output();
- this->dir_pin = this->kernel->config->value(extruder_dir_pin_checksum )->by_default("nc" )->as_pin()->as_output();
- this->en_pin = this->kernel->config->value(extruder_en_pin_checksum )->by_default("nc" )->as_pin()->as_output()->as_open_drain();
+ this->microseconds_per_step_pulse = this->kernel->config->value(microseconds_per_step_pulse_checksum)->by_default(5)->as_number();
+ this->steps_per_millimeter = this->kernel->config->value(extruder_steps_per_mm_checksum )->by_default(1)->as_number();
+ this->feed_rate = this->kernel->config->value(default_feed_rate_checksum )->by_default(1000)->as_number();
+ this->acceleration = this->kernel->config->value(extruder_acceleration_checksum )->by_default(1000)->as_number();
+
+ this->step_pin = this->kernel->config->value(extruder_step_pin_checksum )->by_default("nc" )->as_pin()->as_output();
+ this->dir_pin = this->kernel->config->value(extruder_dir_pin_checksum )->by_default("nc" )->as_pin()->as_output();
+ this->en_pin = this->kernel->config->value(extruder_en_pin_checksum )->by_default("nc" )->as_pin()->as_output()->as_open_drain();
}
if( this->mode == SOLO ){
// In solo mode we take the block so we can move even if the stepper has nothing to do
-
+
this->target_position = this->current_position + this->travel_distance ;
-
+
//int32_t steps_to_step = abs( int( floor(this->steps_per_millimeter*this->target_position) - floor(this->steps_per_millimeter*this->current_position) ) );
int old_steps = this->current_steps;
this->current_steps = target_steps;
if( steps_to_step != 0 ){
-
+
// We take the block, we have to release it or everything gets stuck
block->take();
this->current_block = block;
-
- this->stepper_motor->move( ( this->travel_distance > 0 ), steps_to_step);
+
+ this->stepper_motor->move( ( this->travel_distance > 0 ), steps_to_step);
}
}else if( this->mode == FOLLOW ){
// In non-solo mode, we just follow the stepper module
-
+
this->current_block = block;
this->target_position = this->current_position + ( this->current_block->millimeters * this->travel_ratio );
int target_steps = int( floor(this->steps_per_millimeter*this->target_position) );
int steps_to_step = target_steps - old_steps ;
this->current_steps = target_steps;
-
-
- if( steps_to_step != 0 ){
+
+
+ if( steps_to_step != 0 ){
//printf("taken for extruder: %u \r\n", steps_to_step);
-
+
block->take();
-
+
//printf("spm:%f td:%f steps:%d ( %f - %f ) \r\n", this->steps_per_millimeter, this->travel_distance, steps_to_step, this->target_position, this->current_position );
- this->stepper_motor->move( ( steps_to_step > 0 ), abs(steps_to_step) );
+ this->stepper_motor->move( ( steps_to_step > 0 ), abs(steps_to_step) );
}else if( this->mode == OFF ){
// No movement means we must reset our speed
-
+
//this->stepper_motor->set_speed(0);
-
+
}
}
uint32_t current_rate = this->stepper_motor->steps_per_second;
uint32_t target_rate = int(floor((this->feed_rate/60)*this->steps_per_millimeter));
-
+
if( current_rate < target_rate ){
uint32_t rate_increase = int(floor((this->acceleration/this->kernel->stepper->acceleration_ticks_per_second)*this->steps_per_millimeter));
current_rate = min( target_rate, current_rate + rate_increase );
}
if( current_rate > target_rate ){ current_rate = target_rate; }
- this->stepper_motor->set_speed(max(current_rate, this->kernel->stepper->minimum_steps_per_minute/60));
-
+ this->stepper_motor->set_speed(max(current_rate, this->kernel->stepper->minimum_steps_per_minute/60));
+
return 0;
}
if( this->current_block == NULL || this->paused || this->mode != FOLLOW || this->stepper_motor->moving != true ){ return; }
/*
- * nominal block duration = current block's steps / ( current block's nominal rate / 60 )
- * nominal extruder rate = extruder steps / nominal block duration
- * actual extruder rate = nominal extruder rate * ( ( stepper's steps per minute / 60 ) / ( current block's nominal rate / 60 ) )
- * or : actual extruder rate = ( ( extruder steps * ( current block's nominal_rate / 60 ) ) / current block's steps ) * ( ( stepper's steps per minute / 60 ) / ( current block's nominal rate / 60 ) )
- * or simplified : ( extruder steps * ( stepper's steps per minute / 60 ) ) / current block's steps
- * or even : ( stepper steps per minute / 60 ) * ( extruder steps / current block's steps )
+ * nominal block duration = current block's steps / ( current block's nominal rate / 60 )
+ * nominal extruder rate = extruder steps / nominal block duration
+ * actual extruder rate = nominal extruder rate * ( ( stepper's steps per minute / 60 ) / ( current block's nominal rate / 60 ) )
+ * or actual extruder rate = ( ( extruder steps * ( current block's nominal_rate / 60 ) ) / current block's steps ) * ( ( stepper's steps per minute / 60 ) / ( current block's nominal rate / 60 ) )
+ * or simplified : extruder steps * ( stepper's steps per minute / 60 ) ) / current block's steps
+ * or even : ( stepper steps per minute / 60 ) * ( extruder steps / current block's steps )
*/
-
- this->stepper_motor->set_speed( max( ( this->kernel->stepper->trapezoid_adjusted_rate /60L) * ( (double)this->stepper_motor->steps_to_move / (double)this->current_block->steps_event_count ), this->kernel->stepper->minimum_steps_per_minute/60 ) );
+
+ this->stepper_motor->set_speed( max( ( this->kernel->stepper->trapezoid_adjusted_rate /60L) * ( (double)this->stepper_motor->steps_to_move / (double)this->current_block->steps_event_count ), this->kernel->stepper->minimum_steps_per_minute/60 ) );
}
/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
+ This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
+ Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libs/Module.h"
void Laser::on_module_loaded() {
if( !this->kernel->config->value( laser_module_enable_checksum )->by_default(false)->as_bool() ){ return; }
//read maximum allowable power
- laser_max_power = this->kernel->config->value(laser_module_max_power_checksum)->by_default(0.3)->as_number() ;
- //register for events
+ laser_max_power = this->kernel->config->value(laser_module_max_power_checksum)->by_default(0.3)->as_number() ;
+ //register for events
this->register_for_event(ON_GCODE_EXECUTE);
this->register_for_event(ON_SPEED_CHANGE);
this->register_for_event(ON_PLAY);
}
}
if ( gcode->has_letter('S' )){
- this->laser_max_power = gcode->get_value('S');
-// this->kernel->streams->printf("Adjusted laser power to %d/100\r\n",(int)(this->laser_max_power*100.0+0.5));
+ this->laser_max_power = gcode->get_value('S');
+// this->kernel->streams->printf("Adjusted laser power to %d/100\r\n",(int)(this->laser_max_power*100.0+0.5));
}
}
void Laser::set_proportional_power(){
if( this->laser_on && this->kernel->stepper->current_block ){
- // adjust power to maximum power and actual velocity
+ // adjust power to maximum power and actual velocity
this->laser_pin = double (this->laser_max_power) * double(this->kernel->stepper->trapezoid_adjusted_rate) / double(this->kernel->stepper->current_block->nominal_rate);
}
}
-
-
void set_proportional_power();
mbed::PwmOut laser_pin; // PWM output to regulate the laser power
- bool laser_on; // Laser status
- float laser_max_power; // maximum allowed laser power to be output on the pwm pin
+ bool laser_on; // Laser status
+ float laser_max_power; // maximum allowed laser power to be output on the pwm pin
};
-
-
-
#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
+/*
+ This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
+ Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
*/
case cd_command_checksum : this->cd_command( get_arguments(possible_command), new_message.stream ); break;
case pwd_command_checksum : this->pwd_command( get_arguments(possible_command), new_message.stream ); break;
case cat_command_checksum : this->cat_command( get_arguments(possible_command), new_message.stream ); break;
- case play_command_checksum : this->play_command(get_arguments(possible_command), new_message.stream ); break;
+ case play_command_checksum : this->play_command(get_arguments(possible_command), new_message.stream ); break;
case reset_command_checksum : this->reset_command(get_arguments(possible_command),new_message.stream ); break;
}
}
// Convert a path indication ( absolute or relative ) into a path ( absolute )
string SimpleShell::absolute_from_relative( string path ){
if( path[0] == '/' ){ return path; }
- if( path[0] == '.' ){ return this->current_path; }
+ if( path[0] == '.' ){ return this->current_path; }
return this->current_path + path;
}
if( folder[folder.length()-1] != '/' ){ folder += "/"; }
DIR *d;
d = opendir(folder.c_str());
- if(d == NULL) {
- stream->printf("Could not open directory %s \r\n", folder.c_str() );
+ if(d == NULL) {
+ stream->printf("Could not open directory %s \r\n", folder.c_str() );
}else{
this->current_path = folder;
}
// Output the contents of a file, first parameter is the filename, second is the limit ( in number of lines to output )
void SimpleShell::cat_command( string parameters, StreamOutput* stream ){
-
- // Get parameters ( filename and line limit )
+
+ // Get parameters ( filename and line limit )
string filename = this->absolute_from_relative(shift_parameter( parameters ));
string limit_paramater = shift_parameter( parameters );
int limit = -1;
if( limit_paramater != "" ){ limit = int(atof(limit_paramater.c_str())); }
-
- // Open file
+
+ // Open file
FILE *lp = fopen(filename.c_str(), "r");
if(lp == NULL) {
- stream->printf("File not found: %s\r\n", filename.c_str());
- return;
+ stream->printf("File not found: %s\r\n", filename.c_str());
+ return;
}
string buffer;
int c;
- int newlines = 0;
-
+ int newlines = 0;
+
// Print each line of the file
while ((c = fgetc (lp)) != EOF){
- buffer.append((char *)&c, 1);
+ buffer.append((char *)&c, 1);
if( char(c) == '\n' ){
- newlines++;
- stream->printf("%s", buffer.c_str());
- buffer.clear();
+ newlines++;
+ stream->printf("%s", buffer.c_str());
+ buffer.clear();
}
if( newlines == limit ){ break; }
- };
+ };
fclose(lp);
}
// Play a gcode file by considering each line as if it was received on the serial console
void SimpleShell::play_command( string parameters, StreamOutput* stream ){
-
+
// Get filename
string filename = this->absolute_from_relative(shift_parameter( parameters ));
stream->printf("Playing %s\r\n", filename.c_str());
string options = shift_parameter( parameters );
-
+
this->current_file_handler = fopen( filename.c_str(), "r");
if(this->current_file_handler == NULL)
{
- stream->printf("File not found: %s\r\n", filename.c_str());
- return;
+ stream->printf("File not found: %s\r\n", filename.c_str());
+ return;
}
this->playing_file = true;
if( options.find_first_of("Qq") == string::npos ){
void SimpleShell::on_main_loop(void* argument){
- if( this->playing_file ){
+ if( this->playing_file ){
string buffer;
int c;
// Print each line of the file
while ((c = fgetc(this->current_file_handler)) != EOF){
if (c == '\n'){
this->current_stream->printf("%s\n", buffer.c_str());
- struct SerialMessage message;
+ struct SerialMessage message;
message.message = buffer;
message.stream = this->current_stream;
// wait for the queue to have enough room that a serial message could still be received before sending
this->kernel->player->wait_for_queue(2);
- this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
+ this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
buffer.clear();
return;
}else{
buffer += c;
}
- };
+ };
fclose(this->current_file_handler);
this->playing_file = false;