Alex Whittemore
/
BURTDAQ
Program to run data acquisition and control for BU Rocket Team's MKII hybrid rocket motor
Revision 0:7fd45d2b5926, committed 2012-04-09
- Comitter:
- alexwhittemore
- Date:
- Mon Apr 09 16:39:50 2012 +0000
- Commit message:
- For some reason, this thing wont run serial interrupts and threads simultaneously without locking up.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastIO.h Mon Apr 09 16:39:50 2012 +0000 @@ -0,0 +1,146 @@ +#ifndef __FAST_IO_H +#define __FAST_IO_H + +#include "mbed.h" + +// Super-fast DigitalOut-like class for mbed +// by Igor Skochinsky + +// includes FastOut, FastPortOut and MaskedPortOut classes +// usage: +// FastOut<LED2> led2; +// FastPortOut<Port0, LED_MASK> ledport2; +// MaskedPortOut<Port0, LED_MASK> ledport3; +// led2 = 1; +// ledport2 = LED_MASK; +// ledport3 = LED_MASK; +// MaskedPortOut works the same way as FastPortOut, but it pre-sets the pin mask so that write can be done in one operation +// this makes things faster but you can't control other pins of the port, even with other classes + + +// pin definitions in PinNames.h start from LPC_GPIO0_BASE for P0_0 and there are 32 pins to a port (0 to 31) +// Thus: +// pin = LPC_GPIO0_BASE + port * 32 + bit +// port = (pin - LPC_GPIO0_BASE) / 32 +// bit = (pin - LPC_GPIO0_BASE) % 32 + +#define PORTNO(pin) (((pin) - P0_0)/32) +#define BITNO(pin) (((pin) - P0_0)%32) + +// calculate the GPIO port definition for the pin +// we rely on the fact that port structs are 0x20 bytes apart +#define PORTDEF(pin) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + PORTNO(pin)*0x20)) + +#define PORTDEFPORT(port) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + port*0x20)) + +// calculate the mask for the pin's bit in the port +#define PINMASK(pin) (1UL << BITNO(pin)) + +// each port takes two PINSEL registers (8 bytes or 64 bits) +// so there are 16 pins per PINSEL +#define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) +#define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) + +// usage: FastOut<LED2> led2; +// then use the same assignment operators as with DigitalOut +template <PinName pin> class FastOut +{ +public: + FastOut() + { + // set PINSEL bits to 0b00 (GPIO) + PINSELREG(pin) &= ~PINSELMASK(pin, 3); + // set FIODIR bit to 1 (output) + PORTDEF(pin)->FIODIR |= PINMASK(pin); + } + void write(int value) + { + if ( value ) + PORTDEF(pin)->FIOSET = PINMASK(pin); + else + PORTDEF(pin)->FIOCLR = PINMASK(pin); + } + int read() + { + return PORTDEF(pin)->FIOPIN & PINMASK(pin) != 0; + } + FastOut& operator= (int value) { write(value); return *this; }; + FastOut& operator= (FastOut& rhs) { return write(rhs.read()); }; + operator int() { return read(); }; +}; + +#define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) +#define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) + +// usage: FastPortOut<Port0, mask> led2; +// then use the same assignment operators as with DigitalOut +template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class FastPortOut +{ +public: + FastPortOut() + { + // init pins selected by the mask + uint32_t pin = LPC_GPIO0_BASE + port * 32; + for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) + { + if ( pinmask & 1 ) + { + // set PINSEL bits to 0b00 (GPIO) + PINSELREG(pin) &= ~PINSELMASK(pin, 3); + // set FIODIR bit to 1 (output) + PORTDEF(pin)->FIODIR |= PINMASK(pin); + } + pin++; + } + } + void write(int value) + { + PORTDEFPORT(port)->FIOSET = value & mask; + PORTDEFPORT(port)->FIOCLR = ~value & mask; + } + int read() + { + return PORTDEFPORT(port)->FIOPIN & mask; + } + FastPortOut& operator= (int value) { write(value); return *this; }; + FastPortOut& operator= (FastPortOut& rhs) { return write(rhs.read()); }; + operator int() { return read(); }; +}; + +// usage: MaskedPortOut<Port0, mask> led2; +// then use the same assignment operators as with DigitalOut +template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class MaskedPortOut +{ +public: + MaskedPortOut() + { + // init pins selected by the mask + uint32_t pin = LPC_GPIO0_BASE + port * 32; + for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) + { + if ( pinmask & 1 ) + { + // set PINSEL bits to 0b00 (GPIO) + PINSELREG(pin) &= ~PINSELMASK(pin, 3); + // set FIODIR bit to 1 (output) + PORTDEF(pin)->FIODIR |= PINMASK(pin); + } + pin++; + } + // set mask + PORTDEFPORT(port)->FIOMASK = mask; + } + void write(int value) + { + PORTDEFPORT(port)->FIOPIN = value; + } + int read() + { + return PORTDEFPORT(port)->FIOPIN; + } + MaskedPortOut& operator= (int value) { write(value); return *this; }; + MaskedPortOut& operator= (MaskedPortOut& rhs) { return write(rhs.read()); }; + operator int() { return read(); }; +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/burtdaq/burtdaq.h Mon Apr 09 16:39:50 2012 +0000 @@ -0,0 +1,48 @@ +// Pin function definitions for BURT MKII DAQ Main Board r1.0 +#ifndef BURTDAQ_H +#define BURTDAQ_H + +// XBee serial port +#define XBEETX p28 +#define XBEERX p27 + +// LCD serial port +#define LCDTX p9 +#define LCDRX p10 + +// SPI A +#define SPIA_MOSI p5 +#define SPIA_MISO p6 +#define SPIA_CLK p7 + +#define SPIA_P1_CS p8 // P0.6 +#define SPIA_P2_CS p14 // P0.16 +#define SPIA_P3_CS p30 // P0.4 +#define SPIA_P4_CS p29 // P0.5 + +#define SPIA_CS_PORT_MASK 0x10070 +#define SPIA_P1_CS_PORT_MASK 0x40 +#define SPIA_P2_CS_PORT_MASK 0x10000 +#define SPIA_P3_CS_PORT_MASK 0x10 +#define SPIA_P4_CS_PORT_MASK 0x20 + +// SPI B +#define SPIB_MOSI p11 +#define SPIB_MISO p12 +#define SPIB_CLK p13 + +#define SPIB_P1_CS p15 +#define SPIB_P2_CS p16 +#define SPIB_P3_CS p17 +#define SPIB_P4_CS p19 + +// H-Bridge Outputs +#define MOTOR1 p25 +#define MOTOR2 p24 +#define MOTOR3 p22 // NOTE: Motor3 and Motor4 are mixed up in schematic, so the pins are out of order +#define MOTOR4 p23 + +// Filter Clock Output +#define FILTCLK p26 + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Apr 09 16:39:50 2012 +0000 @@ -0,0 +1,144 @@ +#include "mbed.h" +#include "rtos.h" +#include "burtdaq.h" +#include <vector> +#include "FastIO.h" +#include <stdio.h> // printf +#include <string.h> // strcat +#include <stdlib.h> // strtol + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +//Serial pc(USBTX,USBRX); +Serial xbee(XBEETX,XBEERX); + +//Queue<uint8_t, 50> queue; + +#define kDisplayWidth 32 +char* pBinFill(long int x,char *so, char fillChar) +{ // fill in array from right to left + char s[kDisplayWidth+1]; + int i=kDisplayWidth; + s[i--]=0x00; // terminate string + do + { // fill in array from right to left + s[i--]=(x & 1) ? '1':'0'; + x>>=1; // shift right 1 bit + } while( x > 0); + while(i>=0) s[i--]=fillChar; // fill with fillChar + sprintf(so,"%s",s); + return so; +} + + +void bridgeReader(void const *argument) { + SPI spia(NC, SPIA_MISO, SPIA_CLK); + spia.format(16); + spia.frequency(1000000); + //DigitalOut spia_mosi(SPIA_MOSI); + FastOut<SPIA_MOSI> spia_mosi; + + FastPortOut<Port0, SPIA_CS_PORT_MASK> spiaCSPort; + //PortOut spiaCSPort(Port0, SPIA_CS_PORT_MASK); + unsigned int bridgeCSPinMasks[5] = {SPIA_P1_CS_PORT_MASK, SPIA_P2_CS_PORT_MASK, SPIA_P3_CS_PORT_MASK, SPIA_P4_CS_PORT_MASK}; + int deviceCount = 4; + + spiaCSPort = SPIA_CS_PORT_MASK; + + uint16_t outputs[4] = {0x0f0f, 0xf0f0, 0x0000, 0x0000}; + //bridgeCSPins = 3; + printf("ENTERING READ LOOP\n"); + while(true) { + __disable_irq(); + led2 = 1; + // READ BRIDGES + spia_mosi = 1; + int i = 0; // This constitutes ROUGHLY a 500ns delay + while(i<10) + i++; + for(i=0; i<deviceCount; i++){ + spiaCSPort = ~bridgeCSPinMasks[i]; + outputs[i] = spia.write(0x0); + } + spiaCSPort = SPIA_CS_PORT_MASK; + //spiaCSPort = 1; + spia_mosi = 0; + // END READING + + printf("%u, %u, %u, %u\n",outputs[0],outputs[1],outputs[2],outputs[3]); + led2 = 0; + __enable_irq(); + Thread::wait(5000); + } +} +void tcReader(void const *argument) { + SPI spib(SPIB_MOSI, SPIB_MISO, SPIB_CLK); + spib.format(16); + spib.frequency(1000000); + + DigitalOut spibCSPins[] = {SPIB_P1_CS, SPIB_P2_CS, SPIB_P3_CS}; + spibCSPins[0]=1; + spibCSPins[1]=1; + spibCSPins[2]=1; + + int numTCs = 3; + uint32_t rawTcData[3] = {0,0,0}; + uint32_t tcData[3] = {0,0,0}; + uint32_t ambientData[3] = {0,0,0}; + + float humanTcData[3] = {0,0,0}; + float humanAmbientData[3] = {0,0,0}; + + uint32_t buffer = 0; + char so[kDisplayWidth+1]; + while (true) { + __disable_irq(); + led3 = 1; + for(int i=0; i<numTCs; i++){ + rawTcData[i] = 0; + spibCSPins[i] = 0; + buffer = spib.write(0); + //printf("%s\n",binary_fmt(buffer,tmp)); + rawTcData[i] = (buffer << 16); + buffer = spib.write(0); + rawTcData[i] |= (buffer); + spibCSPins[i] = 1; + } + //printf("%s %s %s\n", byte_to_binary(tcData[0]), byte_to_binary(tcData[1]), byte_to_binary(tcData[2])); + //printf("Data is: %s %s %s\n",pBinFill(tcData[0], so, '0'), pBinFill(tcData[1], so, '0'), pBinFill(tcData[2], so, '0')); + + for(int i=0; i<numTCs; i++){ + tcData[i] = ((rawTcData[i] & 0xFFFC0000) >> 18); + ambientData[i] = ((rawTcData[i] & 0xFFF0) >> 4); + humanTcData[i] = (float) tcData[i] * .25; + humanAmbientData[i] = (float) ambientData[i]*.0625; + printf("Thermocouple %d ambient: %f, tc:%f\n",i,humanAmbientData[i],humanTcData[i]); + } + led3=0; + __enable_irq(); + Thread::wait(2000); + } +} + +void xbeeISR() { + led4 = !led4; +} + +int main() { + printf("Starting reader\n"); + Thread bridgeReader1(bridgeReader); + Thread tcReader1(tcReader); + //Thread actuatorController1(actuatorController); + + xbee.baud(115200); + xbee.attach(&xbeeISR); + int i = 0; + while(1){ + //xbee.printf("In Range: %d",i); + i++; + led1 = !led1; + Thread::wait(1000); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Apr 09 16:39:50 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479