Test code for proving multi-NCO implementation on Altera FPGA using DEO Nano development board
Dependencies: MODSERIAL mbed-rtos mbed
Revision 0:7f5b51873953, committed 2014-04-24
- Comitter:
- JonFreeman
- Date:
- Thu Apr 24 15:35:38 2014 +0000
- Commit message:
- For testing numerically controlled oscillators implemented in Altera FPGA fitted to DEO Nan0 development board
Changed in this revision
diff -r 000000000000 -r 7f5b51873953 MODSERIAL.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Sissors/code/MODSERIAL/#f42def64c4ee
diff -r 000000000000 -r 7f5b51873953 cnc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cnc.h Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,52 @@ +/** +Programme COPIED FROM "cnc__machine_driver_3" +Author Jon Freeman + +Designed to compile and run on: + Mbed LPC1768 + Freescale KL25Z + Freescale KL46Z +*/ +using namespace std; + +typedef float fl_typ; // + +//#define SPI_Enable +#define I2C_Enable +#define ESTOP 0x100 // bits used in input reading KX3 limit and EStop switches +#define XLIM 1 +#define YLIM 2 +#define ZLIM 4 +#define UNKN 8 + +const fl_typ TWO_PI = 8.0 * atan(1.0); +const fl_typ epsilon = 1e-5; +struct pirbufgrain { + fl_typ x, + y, + z, + distance_code, + f_rate; + } ; + +struct singleGparam { // Place to put all we know about 'x' or 'j' etc parameter from G Code line + fl_typ flt; + unsigned long ul; + int i, c; + bool changed; // Flagged true when new value for this axis found in Gcode line, false otherwise +} ; + +struct Gparams { // Where possibly messy G code line gets ordered and sorted into + struct singleGparam x, y, z, i, j, r, a, b, c, d; // After sorting, know where to find any X, Y etc values ! +} ; + +const int NumofGParams = sizeof(struct Gparams) / sizeof(struct singleGparam); + +#define clken XDi +#define d_in_isr XSt +#define d_in_osr YDi +#define ld_osr YSt +#define ld_pir ZDi +#define sclk ZSt +#define sclr ADi +
diff -r 000000000000 -r 7f5b51873953 command_interpreter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/command_interpreter.cpp Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,264 @@ +#include "mbed.h" +#include "rtos.h" +#include "MODSERIAL.h" +#include "cnc.h" +#include <cctype> + +extern MODSERIAL pc; +extern void report_inputs () ; + +#if defined I2C_Enable +extern I2CSlave slave;//(PTE0, PTE1); on KL25 + +int i2c_checksumchecker (char * buf, int len) { + int k, i = 0x01; + for (k = 0; k < len; k++) + i += buf[k]; + i &= 0x0ff; + return i; +} + +int i2c_checksumchecker (char * buf) { + return i2c_checksumchecker (buf, strlen(buf)); +} + +char * add_csum (char * buf, int len) { // Adds checksum to end of binary string of known length + int j; + char cs = 0; + for (j = 0; j < len; j++) { + cs += buf[j]; + } + buf[len] = 0xff - cs; + buf[len + 1] = 0; + return buf; +} + +char * add_csum (char * buf) { // Adds checksum to end of null terminated string + return add_csum (buf, strlen(buf)); +} + +void i2c_handler (void const * name) +{ + const int i2buflen = 16; + int err = 0; + char buf[i2buflen]; + char msg[20] = "Message 2snd\0"; + add_csum(msg); + slave.address(0xc0); + err = slave.write(msg, strlen(msg) + 1); // Includes null char // returns 0 on success, nz otherwise + while (true) { + int i = slave.receive(); + switch (i) { + case I2CSlave::NoData: // Happens most of the time NoData - the slave has not been addressed + osThreadYield(); // Using RTOS on this project + break; + case I2CSlave::ReadAddressed: // - the master has requested a read from this slave + err = slave.write(msg, strlen(msg) + 1); // Includes null char // returns 0 on success, nz otherwise + pc.printf("RdAddr'd "); + break; + case I2CSlave::WriteGeneral: // - the master is writing to all slave + err = slave.read(buf, i2buflen); // returns 0 on success, nz otherwise + pc.printf("i=%d, - the master is writing to all slave %s\r\n", i, buf); + break; + case I2CSlave::WriteAddressed: // - the master is writing to this slave + err = slave.read(buf, i2buflen); // returns 0 on success, nz otherwise + pc.printf("M wr-> [%s]", buf); + for (int z = 0; z < strlen(buf); z++) + pc.printf("%2x, ", buf[z]); + pc.printf("cs %2x\r\n", i2c_checksumchecker(buf)); + break; + default: + pc.printf("Unknown I2C code %d\r\n"); + break; + } // end of switch (i) upon result of slave.receive() + if (err) { + pc.printf("Err %d with i = %d\r\n", err, i); + err = 0; + } + memset (buf, 0, i2buflen); // Clear buffer + } // end of while (true) +} // end of void i2c_handler (void const * name) + +#endif + +extern char const * target_str_addr (void) ; +void target_cmd (struct singleGparam * a) { + pc.printf("Computer is %s\r\n", target_str_addr()); +} + +//extern void FPGA_bit (int whichbit, int hiorlo) ; + +extern void setpir_cmd (struct singleGparam * a) ; +extern void setcmd_cmd (struct singleGparam * a) ; +extern void getdro_cmd (struct singleGparam * a) ; +extern void getpir_cmd (struct singleGparam * a) ; +extern void clrpir_cmd (struct singleGparam * a) ; +extern void clrdro_cmd (struct singleGparam * a) ; +extern void setdro_cmd (struct singleGparam * a) ; + + +void report_ins_cmd (struct singleGparam * a) { + report_inputs(); +} +void menucmd (struct singleGparam * a); +struct kb_command { + const char * cmd_word; // points to text e.g. "menu" + const char * explan; + void (*f)(struct singleGparam *); // points to function +} ; + +struct kb_command const * command_list_ptr = NULL; // Pointer switched between 'input_syntax_check' and 'command_execute' + +struct kb_command const input_syntax_check [] = { + {"menu", "Lists available commands, same as ls", menucmd}, + {"ls", "Lists available commands, same as menu", menucmd} + } ; + +struct kb_command const command_execute[] = { + {"menu", "Lists available commands, same as ls", menucmd}, + {"ls", "Lists available commands, same as menu", menucmd}, + {"inputs", "Report State of Input bits", report_ins_cmd}, + {"pir", "Send number to FPGA pir", setpir_cmd}, + {"cmd", "Send command to FPGA command reg", setcmd_cmd}, + {"rddro", "Read DRO from FPGA", getdro_cmd}, + {"rdpir", "Read PIR from FPGA", getpir_cmd}, + {"clrpir", "Zero PIR", clrpir_cmd}, + {"clrdro", "Zero DRO", clrdro_cmd}, + {"setdro", "Set DRO", setdro_cmd}, + {"target", "Identify computer device", target_cmd}, +}; + +int numof_menu_items; +void menucmd (struct singleGparam * a) +{ + pc.printf("At menucmd function - listing commands:-\r\n"); + for(int i = 0; i < numof_menu_items; i++) + pc.printf("[%s]\t\t%s\r\n", command_list_ptr[i].cmd_word, command_list_ptr[i].explan); + pc.printf("End of List of Commands\r\n"); +} + +extern void grain_clr (struct singleGparam & g) ; + +void command_line_interpreter (void const * name) +{ +const int MAX_PARAMS = 10, MAX_CMD_LEN = 120; +static char cmd_line[MAX_CMD_LEN + 4]; +static struct singleGparam params[MAX_PARAMS + 1]; +static int cl_index = 0, lastalpha = 0; +static fl_typ fracmul; + if (true) { + command_list_ptr = command_execute; + numof_menu_items = sizeof(command_execute) / sizeof(kb_command); + } + else { + command_list_ptr = input_syntax_check; + numof_menu_items = sizeof(input_syntax_check) / sizeof(kb_command); + } + while (true) { + while (pc.readable()) { + int ch; + if (cl_index > MAX_CMD_LEN) { // trap out stupidly long command lines + pc.printf ("Keyboard Error!! Killing stupidly long command line"); + cl_index = 0; + } + ch = tolower(pc.getc()); + if (ch == '\r' || ch >= ' ' && ch <= 'z') + pc.printf("%c", ch); +// else { // Using <Ctrl>+ 'F', 'B' for Y, 'L', 'R' for X, 'U', 'D' for Z +// cl_index = 0; // 6 2 12 18 21 4 +// pc.printf("[%d]", ch); +// nudger (ch); +// } + if(ch != '\r') // was this the 'Enter' key? + cmd_line[cl_index++] = ch; // added char to command being assembled + else { // key was CR, may or may not be command to lookup + cmd_line[cl_index] = 0; // null terminate command string + if(cl_index) { // If have got some chars to lookup + int i, wrdlen; + for (i = 0; i < numof_menu_items; i++) { // Look for input match in command list + wrdlen = strlen(command_list_ptr[i].cmd_word); + if(strncmp(command_list_ptr[i].cmd_word, cmd_line, wrdlen) == 0 + && !isalpha(cmd_line[wrdlen])) { // If match found + bool negflag = false; + int state = 0, paramindex; + // pc.printf("Found match for word [%s]\r\n", kbc[i].wrd); + for(paramindex = 0; paramindex < MAX_PARAMS; paramindex++) + grain_clr (params[paramindex]); + paramindex = 0; + // read any parameters from command line here + // Using parameters[0] as count of parameters to follow + while (wrdlen <= cl_index) { + ch = cmd_line[wrdlen++]; + if(isalpha(ch)) lastalpha = ch; + if(ch == '-') negflag = true; + if(ch == '+') negflag = false; + switch (state) { + case 0: // looking for start of a number string + if(isdigit(ch)) { // found first digit of a number string + paramindex++; + if(paramindex > MAX_PARAMS) { + wrdlen = cl_index; // exit condition + pc.printf("WARNING - too many parameters, ignoring extra\r\n"); + } else { + params[paramindex].i = ch - '0'; + params[paramindex].c = lastalpha; + state = 1; // Found first digit char of number string + } + } + break; + case 1: // looking for end of a number string + if(isdigit(ch)) { // accumulating integer from string + params[paramindex].i *= 10; + params[paramindex].i += ch - '0'; + } else { // found non-digit terminating number + if (ch == '.') { + state = 2; + fracmul = 0.1; + params[paramindex].flt = (fl_typ)params[paramindex].i; + } else { + params[0].i++; // count of validated parameters + state = 0; // Have read past last digit of number string + if(negflag) { + params[paramindex].i = -params[paramindex].i; + negflag = false; + } + params[paramindex].flt = (fl_typ)params[paramindex].i; + } + } + break; + case 2: // looking for fractional part of double + if(isdigit(ch)) { // accumulating fractional part from string + params[paramindex].flt += (fl_typ)((ch - '0') * fracmul); + fracmul /= 10.0; + } else { // found non-digit terminating double precision number + params[0].i++; // count of validated parameters + state = 0; // Have read past last digit of number string + if(negflag) { + params[paramindex].i = -params[paramindex].i; + params[paramindex].flt = -params[paramindex].flt; + negflag = false; + } + } + break; + default: + break; + } // end of switch state + } // end of while wrdlen < cl_index + // pc.printf("Found match to [%s] with %d parameters\r\n", command_list_ptr[i].wrd, paramindex); + command_list_ptr[i].f(params); // execute command + i = numof_menu_items + 1; // to exit for loop + } + } // End of for numof_menu_items + if(i == numof_menu_items) + pc.printf("No Match Found for CMD [%s]\r\n", cmd_line); + } // End of If have got some chars to lookup + pc.printf("\r\n>"); + cl_index = lastalpha = 0; + } // End of else key was CR, may or may not be command to lookup + } // End of while (pc.readable()) + osThreadYield(); // Using RTOS on this project + } +} + +////} cli; +
diff -r 000000000000 -r 7f5b51873953 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,510 @@ +#include "mbed.h" +#include "rtos.h" +#include "MODSERIAL.h" +#include "cnc.h" +extern void i2c_handler (void const *); +extern void command_line_interpreter (void const *) ; +extern fl_typ feed_rate; // float type is 'float' +extern signed long spindle_rpm; + +const int BAUD = 38400; +MODSERIAL pc(USBTX, USBRX); // tx, rx to pc via usb lead +Ticker msec; // Ticker updating global millisecs counter + +bool running = false, + new_run_pending = false, + idle = false, + move_ended = false; + +unsigned long millisecs = 0L; // 32 bit + +#if defined (TARGET_KL25Z) + const char Target[] = "KL25Z"; // Note need PTE0 (sda) and PTE1 (scl) + DigitalOut intled (PTD7); //(PTE1); //J2p19, was 20 + DigitalOut charge_pumpD25pin1 (PTD6); //(PTE0); //J2p17, was 18 + DigitalIn D25pin10_EStop (PTE20); //j10p1 KL25 J10 is KL46 j4 + DigitalIn D25pin11_XLim (PTE21); //j10p3 + DigitalIn D25pin12_YLim (PTE22); //j10p5 + DigitalIn D25pin13_ZLim (PTE23); //j10p7 + DigitalIn D25pin15_unkn (PTE30); //j10p11 +#if defined I2C_Enable + I2CSlave slave(PTE0, PTE1); // PTE0 sda, (yellow) PTE1 scl (blue) +#endif +#if defined SPI_Enable + SPI spi(PTD2, PTD3, PTD1, PTD0); // mosi, miso, sclk (uses p11, p12, p13 on mbed LPC1768) +#endif + // J2p08,J2p10,J2p12, J2p06 + #define STEPPER_PORT PortC + const int PortBitXSt = 3, // Port bit num X Step J1P05 D25pin 2 + PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 + PortBitYSt = 5, // Port bit num Y Step J1P09 D25pin 4 + PortBitYDi = 6, // Port bit num Y Dir J1P11 D25pin 5 + PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 + PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 + PortBitASt = 12, // Port bit num A Step J2P01 D25pin 8 + PortBitADi = 13, // Port bit num A Dir J2P03 D25pin 9 + PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 + PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 +#endif + + + +#if defined (TARGET_KL46Z) + const char Target[] = "KL46Z"; + DigitalOut intled (PTE1); //J2p20 checked + + + DigitalOut charge_pumpD25pin1 (PTE0); //J2p18 checked +// InterruptIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 + DigitalIn D25pin10_EStop (PTE20); // j4p1 KL46 J4 is KL25 J10 checked + DigitalIn D25pin11_XLim (PTE21); // j4p3 checked + DigitalIn D25pin12_YLim (PTE22); // j4p5 checked + DigitalIn D25pin13_ZLim (PTE23); // j4p7 checked + DigitalIn D25pin15_unkn (PTE30); // j4p11 checked +#if defined I2C_Enable + I2CSlave slave(p9, p10); +#endif +#if defined SPI_Enable + SPI spi(PTA16, PTA17, PTA15, PTA14); // mosi, miso, sclk, ssel (uses p11, p12, p13, p? on mbed LPC) +#endif + // J2p13, J2p15, J2p11, J2p09 + // Easy way to allocate port bits for + // output of stepper motor Step and DIR sigs + #define STEPPER_PORT PortC + const int PortBitXSt = 0, // Port bit num X Step J1P05 D25pin 2 checked + PortBitXDi = 4, // Port bit num X Dir J1P07 D25pin 3 checked + PortBitYSt = 6, // Port bit num Y Step J1P09 D25pin 4 checked + PortBitYDi = 7, // Port bit num Y Dir J1P11 D25pin 5 checked + PortBitZSt = 10, // Port bit num Z Step J1P13 D25pin 6 checked + PortBitZDi = 11, // Port bit num Z Dir J1P15 D25pin 7 checked + PortBitASt = 13, // Port bit num A Step J2P01 D25pin 8 checked + PortBitADi = 16, // Port bit num A Dir J2P03 D25pin 9 checked + PortBitSSt = 8, // Port bit num Spin Step J1P14 D25pin 14 checked + PortBitSDi = 9; // Port bit num Spin Dir J1P16 D25pin 16 checked +#endif +#if defined (TARGET_MBED_LPC1768) + const char Target[] = "MBED LPC1768"; + DigitalOut intled(LED2); // Correct + DigitalOut charge_pumpD25pin1 (p25); // +// InterruptIn D25pin10_EStop (p26); //P2.0 + DigitalIn D25pin10_EStop (p26); //P2.0 + DigitalIn D25pin11_XLim (p24); //P2.2 + DigitalIn D25pin12_YLim (p23); //P2.3 + DigitalIn D25pin13_ZLim (p19); //P1.30 + DigitalIn D25pin15_unkn (p20); //P1.31 +#if defined I2C_Enable + I2CSlave slave(p9, p10); +#endif +//#if defined SPI_Enable + SPI spi(p5, p6, p7); +//#endif + // Easy way to allocate port bits + // output of stepper motor Step and DIR sigs + #define STEPPER_PORT Port0 + /* Port 0 bits routed to DIP pins as follows:- + P0.00 p09 Reserve SDA + P0.01 p10 Reserve SCL + P0.04 p30 CAN rd - USE X Step D25pin 2 + P0.05 p29 CAN td - USE X Dir D25pin 3 + P0.10 p28 SDA - USE Y Step D25pin 4 + P0.11 p27 SCL - USE Y Dir D25pin 5 + P0.15 p13 Tx - USE Z Step D25pin 6 + P0.16 p14 Rx - USE Z Dir D25pin 7 + P0.17 p12 miso - USE A Step D25pin 8 + P0.18 p11 mosi - Use A Dir D25pin 9 + P0.23 p15 A In - Use S Step D25pin 14 + P0.24 p16 A In - Use S Dir D25pin 16 + P0.25 p17 Reserve A In + P0.26 p18 Reserve A Out + */ + const int PortBitXSt = 4, // Port bit num X Step + PortBitXDi = 5, // Port bit num X Dir + PortBitYSt = 10, // Port bit num Y Step + PortBitYDi = 11, // Port bit num Y Dir + PortBitZSt = 15, // Port bit num Z Step + PortBitZDi = 16, // Port bit num Z Dir + PortBitASt = 17, // Port bit num A Step + PortBitADi = 18, // Port bit num A Dir + PortBitSSt = 23, // Port bit num Spin Step + PortBitSDi = 24; // Port bit num Spin Dir +#endif + +const long // Assemble mask bits from now known port bit positions + XSt = 1 << PortBitXSt, // X axis Step signal + XDi = 1 << PortBitXDi, // X axis Direction signal + YSt = 1 << PortBitYSt, // Y axis Step, etc + YDi = 1 << PortBitYDi, + ZSt = 1 << PortBitZSt, // Z axis + ZDi = 1 << PortBitZDi, + ASt = 1 << PortBitASt, // A axis, not implemented in full, for e.g. rotary axis + ADi = 1 << PortBitADi, + SDi = 1 << PortBitSDi, // Spindle, also driven by Step and Dir signals up to 5kHz + SSt = 1 << PortBitSSt, // for 5000 RPM + + SM_MASK = (XSt | XDi | YSt | YDi | ZSt | ZDi | ASt | ADi | SDi | SSt); +// direction_swappers = XDi | YDi | ZDi | SDi; // include bit to swap direction + + PortOut Steppers (STEPPER_PORT, SM_MASK); + +int freq_to_n (int freq) { + const double factor = (1 << 25) / 390625.0; +// unsigned long long ll = ((1 << 31) * freq) / 50000000; + double ll = factor * (double)freq; + return (long) ll; +} +// freq = (50E6 * 'n' / 2**BUS_WIDTH) +// 'n' = freq * 2**BUS_WIDTH / 50000000 +// 'n' = freq * 2**31 / 25000000 +// 'n' = freq * 2**30 / 12500000 +// 'n' = freq * 2**29 / 6250000 +// 'n' = freq * 2**25 / 390625 + +int pirs[8], dros[8]; + +void FPGA_bit (int whichbit, int hiorlo) { + int port = Steppers; + if (hiorlo) port |= whichbit; + else port &= ~whichbit; + Steppers = port; +} + +void FPGA_setup () { + int port = Steppers; + port |= sclr | clken; + Steppers = port; + port &= ~sclr; + port &= ~clken; + port &= ~ld_osr; + port &= ~ld_pir; + Steppers = port; + for (int i = 0; i < 8; i++) + pirs[i] = dros[i] = 0; +} + +/* +-- About Use of 16 bit Command Word +-- bit 0 - '1' causes zero reset of phase_inc_reg +-- bit 1 - '1' causes zero reset of dro_udcounter +-- bit 2 - '1' causes load of phase_inc_reg from input shift reg +-- bit 3 - '1' causes load of dro_udcounter from input shift reg +-- bit 4 - '1' causes dro_udcounter --> shift reg ready to read dro value +-- bit 5 - '1' causes phase_inc_reg --> shift reg ready to read pir value +-- bit 6 - '1' causes reset everything to 0 +-- +-- bit 15 - '1' causes reset of command_word to all 0 after one clock + +*/ +#define zero_pir 0x8001 +#define zero_dro 0x8002 +#define load_pir_from_sr 0x8004 +#define load_dro_from_sr 0x8008 +#define load_dro_into_sr 0x8010 +#define load_pir_into_sr 0x8020 + +void FPGA_cmd (int command_word) { + int port = Steppers; + int spirx[8], command_copy = command_word; +// pc.printf("At FPGA_cmd, sending %d\r\n", command_word); + port |= sclr; // cmdhi_datalo set to 1 + Steppers = port; // + spirx[0] = spi.write(command_copy >> 8); + spirx[1] = spi.write(command_copy); + port &= ~sclr; // cmdhi_datalo set to 0 + Steppers = port; // +// pc.printf("Read spi %x %x\r\n", spirx[0], spirx[1]); +} + +void setcmd_cmd (struct singleGparam * a) { + FPGA_cmd (a[1].i); +} + +//#define load_pir_from_sr 0x8004 +//#define load_dro_into_sr 0x8010 + +// DigitalIn D25pin15_unkn (p20); //P1.31 use this to read osr +int FPGA_rdandwr (int tosend) { // send 32 bits to in_sr, read 32 bits from out_sr + int torecv = 0, port = Steppers, tmp; +// tosend = freq_to_n(tosend); + for (int j = 3; j >= 0; j--) { + torecv <<= 8; + tmp = tosend >> (j << 3); + torecv |= spi.write(tmp); + } + return torecv; +} + +const int numof_ncos = 4; + +void setdro_cmd (struct singleGparam * a) { + int recd[numof_ncos + 1]; + pc.printf("At setdro with values "); + FPGA_cmd(load_dro_into_sr); + for (int k = 0; k < numof_ncos; k++) { + recd[k] = FPGA_rdandwr (a[k + 1].i); + pc.printf("%d, ", a[k + 1].i); + } + FPGA_cmd(load_dro_from_sr); + pc.printf("end\r\n"); +} + +void setpir_cmd (struct singleGparam * a) { + int recd[numof_ncos + 1]; + pc.printf("At setpir with values "); + FPGA_cmd(load_dro_into_sr); + for (int k = 0; k < numof_ncos; k++) { + recd[k] = FPGA_rdandwr (a[k + 1].i); + pc.printf("%d, ", a[k + 1].i); + } + FPGA_cmd(load_pir_from_sr); + pc.printf("end\r\n"); +} + +void getdro_cmd (struct singleGparam * a) { + int read_dro[numof_ncos + 1]; + pc.printf("At rddro, retrieved values "); + FPGA_cmd(load_dro_into_sr); + for (int k = 0; k < numof_ncos; k++) { + read_dro[k] = FPGA_rdandwr (0); + pc.printf("%d, ", read_dro[k]); + } + pc.printf(" end\r\n"); +} + +void getpir_cmd (struct singleGparam * a) { + int read_pir[numof_ncos + 1]; + pc.printf("At rdpir, retrieved values "); + FPGA_cmd(load_pir_into_sr); + for (int k = 0; k < numof_ncos; k++) { + read_pir[k] = FPGA_rdandwr (0); + pc.printf("%d, ", read_pir[k]); + } + pc.printf(" end\r\n"); +} + +void clrpir_cmd (struct singleGparam * a) { + FPGA_cmd(zero_pir); + getpir_cmd(a); +} + +void clrdro_cmd (struct singleGparam * a) { + FPGA_cmd(zero_dro); + getdro_cmd(a); +} + + +char const * target_str_addr () { + return Target; +} + +void grain_clr (struct singleGparam & g) { + g.flt = 0.0; + g.ul = 0L; + g.i = g.c = 0; + g.changed = false; +} +void Gparams_clr (struct Gparams & p) { + grain_clr (p.x); grain_clr (p.y); grain_clr (p.z); grain_clr (p.i); grain_clr (p.j); + grain_clr (p.r); grain_clr (p.a); grain_clr (p.b); grain_clr (p.c); grain_clr (p.d); +} + +class digital_readout_stuff { // class does not need to be named here + private: + char * readout (char * txt, long p) // p has running subtotal of all pulses issued to stepper driver + { + txt[0] = '+'; // constructs string e.g. "+123.456" + txt[8] = 0; // null terminated + if (p < 0) { + txt[0] = '-'; + p = -p; + } + p *= 1000; +//?? p /= pulses_per_mm; + if (p > 999999) { + sprintf(txt + 1, "OVRANGE"); + return txt; + } + for(int k = 7; k > 0; k--) { + if (k == 4) + txt[k] = '.'; + else { + txt[k] = '0' + (p % 10); + p /= 10; + } + } + return txt; // Returns pointer unaltered for subsequent use by e.g. cout + } + public: + signed long x, y, z, a; // Could easily expand up to six or more dros +// bool dro_output; // To enabe / disable output to terminal + void init () { + x = y = z = a = 0; // These dro registers count pulses delivered to stepper motor driver +// dro_output = true; + } + void update () { + static long t = 300; // Prevent display immediately upon startup + if (millisecs < t) + return; +// if(!idle && dro_output) { + if(!idle) { + char txt[12]; + pc.printf("dros X %s,", readout(txt, x)); // dro.n has running subtotal of all pulses issued to stepper driver.n + pc.printf(" Y %s, Z ", readout(txt, y)); + pc.printf("%s, %s\r\n", readout(txt, z), running ? "R":"idle"); + if(!running) idle = true; // Purpose of idle flag is to stop dro updates JUST AFTER run completes. + t = millisecs + 350; // Schedule next update after this non-blocking delay + } + } +} dro_out ; // single instance of class digital_readout_stuff + +void millisec_update_ISR () { + millisecs++; +} + +/*#define STEP_IDLE_HI // Choose IDLE_HI or LO to suit any power save function of stepper motor drive units +//#define STEP_IDLE_LO +void Numerically_Controlled_Oscillators_ISR () { // services Ticker 'NCO_gen' generated interrupts ***ISR*** + static const long step_mask = ASt | XSt | YSt | ZSt, // Added 6th Feb 14 Mask Does NOT include spindle bits + dir_mask = ADi | XDi | YDi | ZDi; // Added 6th Feb 14 Mask Does NOT include spindle bits + static signed long // 27 Feb 14 changed from unsigned +#if defined Fourth_Axis + acc_a = 0L, pir_a = 0L, +#endif + acc_x = 0L, // acc Accumuloators + pir_x = 0L, // pir Phase Increment Registers + acc_y = 0L, pir_y = 0L, + acc_z = 0L, pir_z = 0L, + acc_spin = 0L, // separate acc for spindle rotation NCO + inc_x = 1L, // inc_x, y, z for updating DRO registers + inc_y = 1L, inc_z = 1L, + dir_bits = 0L, // direction flags for up to four axes + oldSteps = 0L; // + long tmp, newSteps = 0L; + + intled = 1; // LED on for duration of interrupt service - point for scope probing + ticks++; // count of interrupts serviced, vital to time end of movement + charge_pumpD25pin1 = ticks & 0x01; // Can use 0x01 or 0x02 here to alter charge pump freq + tmp = Steppers ^ direction_swappers; +#if defined STEP_IDLE_LO + tmp &= ~step_mask; // Step bits prepared for idle lo +#endif +#if defined STEP_IDLE_HI + tmp |= step_mask; // Step bits prepared for idle hi +#endif + acc_spin += pir_spin; // Spindle NCO + if (acc_spin < 0) tmp |= SSt; + else tmp &= ~SSt; + if (!running) Steppers = tmp ^ direction_swappers; // Axes not moving, spindle may be turning or not + else { // running == true, Further manipulation of tmp follows, prior to rewriting to 'Steppers' IO Port +// newSteps = 0L; // Added 6th Feb 14 +#if defined Fourth_Axis + acc_a += pir_a; + if (acc_a < 0) newSteps |= ASt;// Added 6th Feb 14 +#endif + acc_x += pir_x; // Update phase of signals in accumulators + if (acc_x < 0) newSteps |= XSt;// Added 6th Feb 14 + acc_y += pir_y; + if (acc_y < 0) newSteps |= YSt;// Added 6th Feb 14 + acc_z += pir_z; + if (acc_z < 0) newSteps |= ZSt;// Added 6th Feb 14 + // newSteps has copy of all 4 'acc' MSBs shifted into port bit positions + oldSteps ^= newSteps; // Any bit of stbits set to initiate a Step pulse + tmp ^= oldSteps; + Steppers = tmp ^ direction_swappers; // Output signals to stepper motor drivers, next update dros from 'clocked' bits CLOCK IDLES HIGH + if(oldSteps & XSt) dro_out.x += inc_x; // got clk edge for axis X + if(oldSteps & YSt) dro_out.y += inc_y; // got clk edge for axis Y + if(oldSteps & ZSt) dro_out.z += inc_z; // got clk edge for axis Z + oldSteps = newSteps; // Added 6th Feb 14 + if (tickrun <= ticks & !new_run_pending) { // End of a machine movement detected, start next move here if possible + running = false; + move_ended = true; + pir_x = 0L; // stop all stepper motors + pir_y = 0L; + pir_z = 0L; +#if defined Fourth_Axis + pir_a = 0L; +#endif + // ticks = 0L; // Simply to avoid having to think about overflow problems + } // end of if (tickrun <= ticks) { + } // end of else is (running) { + if (!running & new_run_pending) { // Start axis movement + dir_bits= dir_bits_next; +#if defined Fourth_Axis + pir_a = pir_a_next; +#endif + pir_x = pir_x_next; + pir_y = pir_y_next; + pir_z = pir_z_next; + inc_x = inc_x_next; + inc_y = inc_y_next; + inc_z = inc_z_next; + tmp = Steppers ^ direction_swappers; // read output lines + tmp &= ~dir_mask; + tmp |= dir_bits; + Steppers = tmp ^ direction_swappers; + tickrun = ticks + ticks_next; + running = true; // Start the new run + new_run_pending = false; // Clear the flag which initiated this update + idle = false; + } // end of else { // Not running. Grab next data here when or if available + intled = 0; // LED off +} // end of interrupt handler +*/ +/* +* End of Interrupt Service Routine +*/ +/*bool spindle_running () { +*/ +class inputsreaderstuff { + private: + long ins_now;//, ins_old, ins_changed; + public: + void init () { ins_now = 0L;}//ins_old = ins_changed = 0L; } + long read () { + ins_now = 0; + if (D25pin10_EStop) ins_now |= ESTOP; + if (D25pin11_XLim) ins_now |= XLIM; + if (D25pin12_YLim) ins_now |= YLIM; + if (D25pin13_ZLim) ins_now |= ZLIM; + if (D25pin15_unkn) ins_now |= UNKN; +// ins_changed = ins_now ^ ins_old; +// ins_old = ins_now; + return ins_now; + } +// long changed () { return ins_changed; } + } Inputs_From_Machine; + +void report_inputs () { + long i = Inputs_From_Machine.read(); + pc.printf("Inputs: EStop %d, XLim %d, YLim %d, ", i & ESTOP ? 1:0, i & XLIM ? 1:0, i & YLIM ? 1:0); + pc.printf("ZLim %d, unkn %d\r\n", i & ZLIM ? 1:0, i & UNKN ? 1:0); +} + +int main() { + long ins, ins_old, ins_changed = 0; + pc.baud(BAUD); // comms to 'PuTTY' serial terminal via mbed usb + spi.format (8,0); // use 8 bit format for compatibility with Freescale KLxxZ + spi.frequency(12000000); // 12MHz, fast enough + dro_out.init (); + FPGA_setup(); + pc.printf("\r\n*\n*\nFound Computer %s\r\n", Target); + + msec.attach_us(&millisec_update_ISR, 1001); + + Thread comlin (command_line_interpreter, (void *)"cli"); // Read any instructions arriving via serial port and act upon them +//#if defined I2C_Enable +// Thread i2cstuff (i2c_handler, (void *)"i2c thing"); +//#endif + ins = ins_old = Inputs_From_Machine.read (); + move_ended = true; // Needed to kickstart system + + while(1) { // Round Robin loop + dro_out.update (); // Update DRO readings if, and as often as needed + ins = Inputs_From_Machine.read (); + ins_changed = ins ^ ins_old; + ins_old = ins; + if (ins_changed) + pc.printf("Inputs Have Changed 0x%x, read 0x%x\r\n", ins_changed, ins); + osThreadYield(); // + } // end of Round Robin loop +} // end of int main() +
diff -r 000000000000 -r 7f5b51873953 mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#4ef72665e2c8
diff -r 000000000000 -r 7f5b51873953 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Apr 24 15:35:38 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/6473597d706e \ No newline at end of file