Firmware2/Marlin/src/HAL/HAL_LPC1768/arduino.cpp

180 lines
5.5 KiB
C++
Raw Normal View History

2017-06-17 23:19:42 +02:00
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
2017-09-06 13:28:32 +02:00
#include "LPC1768_PWM.h"
2017-06-17 23:19:42 +02:00
#include <lpc17xx_pinsel.h>
2017-11-19 20:59:40 +01:00
#include "../../inc/MarlinConfig.h"
#include "../Delay.h"
2017-11-19 20:59:40 +01:00
2017-06-17 23:19:42 +02:00
// Interrupts
void cli(void) { __disable_irq(); } // Disable
void sei(void) { __enable_irq(); } // Enable
// Time functions
2017-09-27 11:57:33 +02:00
void _delay_ms(const int delay_ms) {
delay(delay_ms);
2017-06-17 23:19:42 +02:00
}
uint32_t millis() {
return _millis;
}
// This is required for some Arduino libraries we are using
2017-06-17 23:19:42 +02:00
void delayMicroseconds(uint32_t us) {
DELAY_US(us);
2017-06-17 23:19:42 +02:00
}
extern "C" void delay(const int msec) {
volatile millis_t end = _millis + msec;
SysTick->VAL = SysTick->LOAD; // reset systick counter so next systick is in exactly 1ms
// this could extend the time between systicks by upto 1ms
while PENDING(_millis, end) __WFE();
2017-06-17 23:19:42 +02:00
}
// IO functions
// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2)
void pinMode(const pin_t pin, const uint8_t mode) {
2017-11-19 21:12:45 +01:00
if (!VALID_PIN(pin)) return;
2017-06-17 23:19:42 +02:00
PINSEL_CFG_Type config = { LPC1768_PIN_PORT(pin),
LPC1768_PIN_PIN(pin),
2017-06-17 23:19:42 +02:00
PINSEL_FUNC_0,
PINSEL_PINMODE_TRISTATE,
PINSEL_PINMODE_NORMAL };
switch (mode) {
case INPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
break;
case OUTPUT:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin));
break;
case INPUT_PULLUP:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
config.Pinmode = PINSEL_PINMODE_PULLUP;
break;
case INPUT_PULLDOWN:
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin));
config.Pinmode = PINSEL_PINMODE_PULLDOWN;
break;
default: return;
2017-06-17 23:19:42 +02:00
}
PINSEL_ConfigPin(&config);
2017-06-17 23:19:42 +02:00
}
void digitalWrite(pin_t pin, uint8_t pin_status) {
2017-11-19 21:12:45 +01:00
if (!VALID_PIN(pin)) return;
2017-06-17 23:19:42 +02:00
if (pin_status)
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOSET = LPC_PIN(LPC1768_PIN_PIN(pin));
2017-06-17 23:19:42 +02:00
else
LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOCLR = LPC_PIN(LPC1768_PIN_PIN(pin));
pinMode(pin, OUTPUT); // Set pin mode on every write (Arduino version does this)
/**
* Must be done AFTER the output state is set. Doing this before will cause a
* 2uS glitch if writing a "1".
*
* When the Port Direction bit is written to a "1" the output is immediately set
* to the value of the FIOPIN bit which is "0" because of power up defaults.
*/
2017-06-17 23:19:42 +02:00
}
bool digitalRead(pin_t pin) {
2017-11-19 21:12:45 +01:00
if (!VALID_PIN(pin)) return false;
return LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOPIN & LPC_PIN(LPC1768_PIN_PIN(pin)) ? 1 : 0;
2017-06-17 23:19:42 +02:00
}
void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH
2017-11-19 21:12:45 +01:00
if (!VALID_PIN(pin)) return;
#define MR0_MARGIN 200 // if channel value too close to MR0 the system locks up
static bool out_of_PWM_slots = false;
uint value = MAX(MIN(pwm_value, 255), 0);
if (value == 0 || value == 255) { // treat as digital pin
LPC1768_PWM_detach_pin(pin); // turn off PWM
digitalWrite(pin, value);
}
else {
2018-01-05 17:10:55 +01:00
if (LPC1768_PWM_attach_pin(pin, 1, LPC_PWM1->MR0, 0xFF))
LPC1768_PWM_write(pin, map(value, 0, 255, 1, LPC_PWM1->MR0)); // map 1-254 onto PWM range
else { // out of PWM channels
2017-11-05 15:49:38 +01:00
if (!out_of_PWM_slots) SERIAL_ECHOPGM(".\nWARNING - OUT OF PWM CHANNELS\n.\n"); //only warn once
out_of_PWM_slots = true;
digitalWrite(pin, value); // treat as a digital pin if out of channels
}
2017-06-17 23:19:42 +02:00
}
}
extern bool HAL_adc_finished();
uint16_t analogRead(pin_t adc_pin) {
2017-06-17 23:19:42 +02:00
HAL_adc_start_conversion(adc_pin);
while (!HAL_adc_finished()); // Wait for conversion to finish
return HAL_adc_get_result();
}
// **************************
// Persistent Config Storage
// **************************
void eeprom_write_byte(unsigned char *pos, unsigned char value) {
}
unsigned char eeprom_read_byte(uint8_t * pos) { return '\0'; }
2018-02-25 07:13:46 +01:00
void eeprom_read_block(void *__dst, const void *__src, size_t __n) { }
2017-06-17 23:19:42 +02:00
2018-02-25 07:13:46 +01:00
void eeprom_update_block(const void *__src, void *__dst, size_t __n) { }
2017-06-17 23:19:42 +02:00
char *dtostrf (double __val, signed char __width, unsigned char __prec, char *__s) {
char format_string[20];
snprintf(format_string, 20, "%%%d.%df", __width, __prec);
sprintf(__s, format_string, __val);
return __s;
}
int32_t random(int32_t max) {
return rand() % max;
}
int32_t random(int32_t min, int32_t max) {
return min + rand() % (max - min);
}
void randomSeed(uint32_t value) {
srand(value);
}
int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
2017-06-17 23:19:42 +02:00
#endif // TARGET_LPC1768