General fixes for LPC1768 (#7834)

* fixed some include paths

* LPC1768: Fix Serial API

Add missing serial methods used if TX_BUFFER_SIZE is set
Change return value of HalSerial:read to match Arduino API

* LPC1768: add filters to ADC

This is to try and compensate for hardware issue and oversensitivity to noise

* LPC1768: remove the polling section of delayMicroseconds

* LPC1768: lock usb mass storage device while device accesses it.

Currently only applicable to persistent store,
The device always has priority and will unmount the sd card from the host, Windows then tries to automount again so it can look like the explorer window freezes. Linux Mint, by default, just closes the Nemo window.

* Add timeout to make sure if Serial never connects that Marlin still boots

* Remove unneeded ifdef CPU_32_BIT

In general the need for ifdef CPU_32_BIT blocks means that something is missing from the HAL API or a Platform, in this case HAL_TICKS_PER_US was missing from the AVR Platform

* LPC1768: relocate RE-ARM debug_extra_script.py
This commit is contained in:
Chris Pepper
2017-10-04 21:40:54 +01:00
committed by Scott Lahteine
parent 7258218f89
commit 46b2773e13
14 changed files with 268 additions and 66 deletions

View File

@ -29,7 +29,7 @@
#ifndef _HAL_H
#define _HAL_H
#include "src/inc/SPI.h"
#include "../inc/SPI.h"
#ifdef __AVR__
#include "HAL_AVR/HAL_AVR.h"

View File

@ -105,6 +105,7 @@ extern "C" {
#define HAL_TIMER_RATE ((F_CPU) / 8.0)
#define HAL_STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE INT0_PRESCALER
#define HAL_TICKS_PER_US (((F_CPU) / 8) / 1000000) // Can not be of type double
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)

View File

@ -113,6 +113,7 @@ void HAL_adc_enable_channel(int pin) {
};
}
uint8_t active_adc = 0;
void HAL_adc_start_conversion(const uint8_t adc_pin) {
if (adc_pin >= (NUM_ANALOG_INPUTS) || adc_pin_map[adc_pin].port == 0xFF) {
usb_serial.printf("HAL: HAL_adc_start_conversion: no pinmap for %d\n", adc_pin);
@ -121,14 +122,52 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
LPC_ADC->ADCR &= ~0xFF; // Reset
SBI(LPC_ADC->ADCR, adc_pin_map[adc_pin].adc); // Select Channel
SBI(LPC_ADC->ADCR, 24); // Start conversion
active_adc = adc_pin;
}
bool HAL_adc_finished(void) { return LPC_ADC->ADGDR & ADC_DONE; }
bool HAL_adc_finished(void) {
return LPC_ADC->ADGDR & ADC_DONE;
}
// possible config options if something similar is extended to more platforms.
#define ADC_USE_MEDIAN_FILTER // filter out erroneous readings
#define ADC_USE_LOWPASS_FILTER // filter out high frequency noise
#define ADC_LOWPASS_K_VALUE 4 // how much to smooth out noise (1:8)
struct MedianFilter {
uint16_t values[3];
uint8_t next_val;
MedianFilter() {
next_val = 0;
values[0] = values[1] = values[2] = 0;
}
uint16_t update(uint16_t value) {
values[next_val++] = value;
next_val = next_val % 3;
return max(min(values[0], values[1]), min(max(values[0], values[1]), values[2])); //median
}
};
uint16_t lowpass_filter(uint16_t value) {
const uint8_t k_data_shift = ADC_LOWPASS_K_VALUE;
static uint32_t data_delay[NUM_ANALOG_INPUTS] = { 0 };
uint32_t &active_filter = data_delay[active_adc];
active_filter = active_filter - (active_filter >> k_data_shift) + value;
return (uint16_t)(active_filter >> k_data_shift);
}
uint16_t HAL_adc_get_result(void) {
uint32_t data = LPC_ADC->ADGDR;
CBI(LPC_ADC->ADCR, 24); // Stop conversion
return (data & ADC_OVERRUN) ? 0 : (data >> 6) & 0x3FF; // 10bit
CBI(LPC_ADC->ADCR, 24); // Stop conversion
if (data & ADC_OVERRUN) return 0;
#ifdef ADC_USE_MEDIAN_FILTER
static MedianFilter median_filter[NUM_ANALOG_INPUTS];
data = median_filter[active_adc].update((uint16_t)data);
#endif
#ifdef ADC_USE_LOWPASS_FILTER
data = lowpass_filter((uint16_t)data);
#endif
return ((data >> 6) & 0x3ff); // 10bit
}
#define SBIT_CNTEN 0

View File

@ -57,20 +57,9 @@ void delayMicroseconds(uint32_t us) {
us = us % 1000;
}
if (us < 5) { // burn cycles, time in interrupts will not be taken into account
loops = us * nop_factor;
while (loops > 0) --loops;
}
else { // poll systick, more accurate through interrupts
uint32_t start = SysTick->VAL;
uint32_t load = SysTick->LOAD;
uint32_t end = start - (load / 1000) * us;
if (end >> 31)
while (!(SysTick->VAL > start && SysTick->VAL < (load + end))) __NOP();
else
while (SysTick->VAL > end) __NOP();
}
// burn cycles, time in interrupts will not be taken into account
loops = us * nop_factor;
while (loops > 0) --loops;
}
extern "C" void delay(const int msec) {

View File

@ -0,0 +1,21 @@
Import("env")
env.AddPostAction(
"$BUILD_DIR/firmware.hex",
env.VerboseAction(" ".join([
"sed", "-i.bak",
"s/:10040000FFFFFFFFFFFFFFFFFFFFFFFFDEF9FFFF23/:10040000FFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFD/",
"$BUILD_DIR/firmware.hex"
]), "Fixing $BUILD_DIR/firmware.hex secure flash flags"))
env.AddPreAction(
"upload",
env.VerboseAction(" ".join([
"echo",
"'h\\nloadfile $BUILD_DIR/firmware.hex\\nr\\nq\\n'",
">$BUILD_DIR/aux.jlink"
]), "Creating auxiliary files"))
env.Replace(
UPLOADHEXCMD=
'JLinkExe -device MK20DX256xxx7 -speed 4000 -if swd -autoconnect 1 -CommanderScript $BUILD_DIR/aux.jlink -SkipProgOnCRCMatch = 1 -VerifyDownload = 1'
)

View File

@ -9,6 +9,9 @@
#include "chanfs/diskio.h"
#include "chanfs/ff.h"
extern uint32_t MSC_Aquire_Lock();
extern uint32_t MSC_Release_Lock();
namespace HAL {
namespace PersistentStore {
@ -16,14 +19,20 @@ FATFS fat_fs;
FIL eeprom_file;
bool access_start() {
f_mount(&fat_fs, "", 1);
MSC_Aquire_Lock();
if(f_mount(&fat_fs, "", 1)){
MSC_Release_Lock();
return false;
}
FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
if(res) MSC_Release_Lock();
return (res == FR_OK);
}
bool access_finish() {
f_close(&eeprom_file);
f_unmount("");
MSC_Release_Lock();
return true;
}

View File

@ -100,6 +100,7 @@ public:
}
char read() {
if(receive_buffer.empty()) return -1;
return (char)receive_buffer.read();
}
@ -117,6 +118,17 @@ public:
}
void flush() {
receive_buffer.clear();
}
uint8_t availableForWrite(void){
return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free();
}
void flushTX(void){
if(host_connected) {
while(transmit_buffer.available());
}
}
void printf(const char *format, ...) {

View File

@ -681,7 +681,8 @@ void setup() {
#endif
MYSERIAL.begin(BAUDRATE);
while(!MYSERIAL);
uint32_t serial_connect_timeout = millis() + 1000;
while(!MYSERIAL && PENDING(millis(), serial_connect_timeout));
SERIAL_PROTOCOLLNPGM("start");
SERIAL_ECHO_START();

View File

@ -23,7 +23,7 @@
#ifndef ULCDST7920_H
#define ULCDST7920_H
#include <src/Marlin.h>
#include "../../Marlin.h"
#if ENABLED(U8GLIB_ST7920)

View File

@ -323,13 +323,8 @@ void Stepper::isr() {
HAL_TIMER_TYPE ocr_val;
#ifdef CPU_32_BIT
#define ENDSTOP_NOMINAL_OCR_VAL 1500 * HAL_TICKS_PER_US // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
#define OCR_VAL_TOLERANCE 500 * HAL_TICKS_PER_US // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
#else
#define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
#define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
#endif
#define ENDSTOP_NOMINAL_OCR_VAL 1500 * HAL_TICKS_PER_US // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
#define OCR_VAL_TOLERANCE 500 * HAL_TICKS_PER_US // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
// Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)