ARM: implement analog-arm.c.
Very simple, because the LPC1114 features a hardware scan mode,
which automatically scans a given set of pins in freerunning mode
and stores all the values separately. No need for an interrupt!
Not yet done: configure not PIO1_0 and PIO1_1, but the pins
actually defined in the board file.
For testing, add this to ifclock(clock_flag_1s) in clock.c:
uint8_t i;
for (i = 0; i <= 7; i++) {
sersendf_P(PSTR("%lu "), analog_read(i));
}
serial_writechar('\n');
This should print all 8 ADC values repeatedly. Only two pins are
actually set up, these values should change depending on the
thermistor temperature. More precisely: depending on the voltage
on the pin.
This commit is contained in:
parent
56f6b381fd
commit
f81000a4b6
|
|
@ -100,8 +100,9 @@ TARGET = $(PROGRAM).hex
|
|||
SOURCES = mendel.c cpu.c serial.c sermsg.c sersendf.c delay.c
|
||||
SOURCES += gcode_parse.c gcode_process.c pinio.c timer.c clock.c
|
||||
SOURCES += dda_queue.c dda_maths.c dda_kinematics.c dda.c dda_lookahead.c
|
||||
SOURCES += analog.c
|
||||
# Sources left:
|
||||
# analog.c home.c crc.c intercom.c debug.c spi.c usb_serial.c
|
||||
# home.c crc.c intercom.c debug.c spi.c usb_serial.c
|
||||
# graycode.c pff.c temp.c watchdog.c heater.c pff_diskio.c
|
||||
|
||||
ifeq ($(MCU), lpc1114)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
/** \file
|
||||
\brief Analog subsystem, ARM specific part.
|
||||
|
||||
Nice feature of the LPC11xx is, it features a hardware scan mode, which scans
|
||||
a given set of ADC pins over and over again, without need for an interrupt
|
||||
to switch between channels. Our code becomes pretty simple: set this
|
||||
mechanism up at init time and be done for the time being.
|
||||
|
||||
Unlike ATmegas, LPC1114 features no analog voltage reference selector, it
|
||||
always compares against Vdd. This is the equivalent of REFERENCE_AVCC on AVR.
|
||||
*/
|
||||
|
||||
#if defined TEACUP_C_INCLUDE && defined __ARMEL__
|
||||
|
||||
#include "cmsis-lpc11xx.h"
|
||||
#include "arduino.h"
|
||||
#include "temp.h"
|
||||
|
||||
|
||||
/** Inititalise the analog subsystem.
|
||||
|
||||
Initialise the ADC and start hardware scan loop for all used sensors.
|
||||
|
||||
LPC111x User Manual recommends an ADC clock of 4.5 MHz ("typically"), still
|
||||
we reduce this to 1 MHz, because we're not nearly as much in a hurry. A
|
||||
conversion needs 11 ADC clocks per channel, so we still get many thousand
|
||||
conversions/second; we need just 100/s.
|
||||
*/
|
||||
void analog_init() {
|
||||
|
||||
if (NUM_TEMP_SENSORS) { // At least one channel in use.
|
||||
|
||||
LPC_SYSCON->PDRUNCFG &= ~(1 << 4); // Turn on ADC clock.
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); // Turn on ADC power.
|
||||
|
||||
/**
|
||||
Register name mapping from LPC111x User Manual to CMSIS headers:
|
||||
|
||||
chap. 25.5 cmsis-lpc11xx.h description
|
||||
|
||||
AD0CR LPC_ADC->CR A/D control register.
|
||||
AD0GDR LPC_ADC->GDR A/D global data register.
|
||||
AD0INTEN LPC_ADC->INTEN A/D interrupt enable register.
|
||||
AD0DRn LPC_ADC->DR[n] A/D channel n data register.
|
||||
AD0STAT LPC_ADC->STAT A/D status register.
|
||||
*/
|
||||
// TODO: enable only the channels we use.
|
||||
LPC_ADC->CR = (0xFF << 0) // All pins on (for now).
|
||||
| ((F_CPU / 1000000) << 8) // 1 MHz ADC clock.
|
||||
| (1 << 16) // Hardware scan mode.
|
||||
| (0x0 << 17) // Maximum accuracy.
|
||||
| (0x0 << 24); // Clear START.
|
||||
|
||||
LPC_ADC->INTEN = 0; // No interrupt generation.
|
||||
|
||||
// TODO: set up the channels configured, not two arbitrary ones.
|
||||
LPC_IOCON->PIO1_0_CMSIS = (0x2 << 0) // Function AD1.
|
||||
| (0 << 3) // Pullup inactive.
|
||||
| (0 << 7); // Analog input mode.
|
||||
LPC_IOCON->PIO1_1_CMSIS = (0x2 << 0) // Function AD2.
|
||||
| (0 << 3) // Pullup inactive.
|
||||
| (0 << 7); // Analog input mode.
|
||||
}
|
||||
}
|
||||
|
||||
/** Read analog value.
|
||||
|
||||
\param channel Channel to be read.
|
||||
|
||||
\return Analog reading, 10-bit right aligned.
|
||||
|
||||
Hardware scan mode nicely saves all the converted values separately, so
|
||||
there's no need to hold them in a copy.
|
||||
*/
|
||||
uint16_t analog_read(uint8_t index) {
|
||||
return (LPC_ADC->DR[index] & 0xFFC0) >> 6;
|
||||
}
|
||||
|
||||
#endif /* defined TEACUP_C_INCLUDE && defined __ARMEL__ */
|
||||
2
analog.c
2
analog.c
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#define TEACUP_C_INCLUDE
|
||||
#include "analog-avr.c"
|
||||
//#include "analog-arm.c"
|
||||
#include "analog-arm.c"
|
||||
#undef TEACUP_C_INCLUDE
|
||||
|
||||
// No common code so far.
|
||||
|
|
|
|||
4
mendel.c
4
mendel.c
|
|
@ -39,8 +39,8 @@
|
|||
#include "watchdog.h"
|
||||
#include "debug.h"
|
||||
#include "heater.h"
|
||||
#include "analog.h"
|
||||
#endif /* __ARMEL_NOTYET__ */
|
||||
#include "analog.h"
|
||||
#include "pinio.h"
|
||||
#include "clock.h"
|
||||
#ifndef __ARMEL_NOTYET__
|
||||
|
|
@ -105,11 +105,11 @@ void init(void) {
|
|||
// set up dda
|
||||
dda_init();
|
||||
|
||||
#ifndef __ARMEL_NOTYET__
|
||||
// start up analog read interrupt loop,
|
||||
// if any of the temp sensors in your config.h use analog interface
|
||||
analog_init();
|
||||
|
||||
#ifndef __ARMEL_NOTYET__
|
||||
// set up temperature inputs
|
||||
temp_init();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue