dev.nlited.com

>>

USB/COM

<<<< prev
next >>>>

2016-05-18 00:13:25 chip Page 1698 📢 PUBLIC

May 18 2016

See also:

0830> Today's task: Run the CDC example on my 5529 Jumppad board.

0856> The USBCDC_sendDataInBackground() call fails with USBCDC_BUS_NOT_AVAILABLE.

0956> Reading the Examples Guide document is good news and bad news. Good news: I (might) know why the USB operations are failing; the device is not being recognized by the host due to a missing and/or unsigned INF descriptor. Bad news: Microsoft has made life with Win8 more difficult by requiring the INF be signed and certified, which is impossible for experimental devices. The workaround is to enable "unsafe drivers" during boot. Worst news: this must be manually re-enabled for every boot.

CDC Device Driver not installed.

1008> Now would be a very good time to make a backup of the VS12 machine. ETA: 50 minutes.

1052> Backup complete, SSD0240_02.

1119> Fortunately, TI provides a signed INF for the sample CDC device. I open Control Panel > System > Change Settings > Hardware System Properties > Hardware > Device Manager > Ports (COM & LPT). Right-click "TI MSP430 USB" (with the yellow warning flag) and click "Update Driver", select "Browse my computer" and navigate to the USB_Config folder in the C0_SimpleSend project. Since this is a signed INF, it should update without complaints or rebooting. If all went well, the yellow warning flag should disappear and a new COM port named "TI MSP430 USB" should appear. I connect to COM8 using Putty and I can now see the output from the 5529.

TI MSP430 USB (COM8) COM8: TI MSP430 USB 5529 serial output via USB/COM8.

1131> Success! I now have serial output over USB/COM.

I need to see if I can send data to the 5529.

1205> Success! I now have two-way communication with the 5529 over USB/COM. The difficult part was installing and configuring all the software, actually sending and receiving data was trivial (apart from misleading documentation). My changes are in bold.


Main.c: #include <string.h> #include "driverlib.h" #include "USB_config/descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" //USB-specific functions #include "USB_API/USB_CDC_API/UsbCdc.h" #include "USB_app/usbConstructs.h" #include "hal.h" int convertTimeBinToASCII(uint8_t* str, int strCt); void initRTC(void); volatile uint8_t hour = 4, min = 30, sec = 00; // Real-time clock (RTC) values. 4:30:00 volatile uint8_t bSendTimeToHost = FALSE; // RTC-->main(): "send the time over USB" uint8_t timeStr[16]; // Stores the time as an ASCII string uint8_t RcvChr; //Character received from host. void main(void) { int ChrCt; WDT_A_hold(WDT_A_BASE); //Stop watchdog timer // Minimum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 PMM_setVCore(PMM_CORE_LEVEL_2); USBHAL_initPorts(); // Config GPIOS for low-power (output low) P1OUT= (P1OUT & ~0x01)|0x00; //LED1 off P4OUT= (P4OUT & ~0x80)|0x00; //LED2 off USBHAL_initClocks(8000000); // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz USB_setup(TRUE,TRUE); // Init USB & events; if a host is present, connect initRTC(); // Start the real-time clock __enable_interrupt(); // Enable interrupts globally P4OUT= (P4OUT & ~0x80)|0x80; //GRN led on while (1) { // Enter LPM0, which keeps the DCO/FLL active but shuts off the // CPU. For USB, you can't go below LPM0! __bis_SR_register(LPM0_bits + GIE); // If USB is present, sent the time to the host. Flag is set every sec if (bSendTimeToHost) { bSendTimeToHost = FALSE; ChrCt= convertTimeBinToASCII(timeStr,sizeof(timeStr)); // This function begins the USB send operation, and immediately // returns, while the sending happens in the background. // Send timeStr, 9 bytes, to intf #0 (which is enumerated as a // COM port). 1000 retries. (Retries will be attempted if the // previous send hasn't completed yet). If the bus isn't present, // it simply returns and does nothing. if (USBCDC_sendDataInBackground(timeStr, ChrCt, CDC0_INTFNUM, 1000)) { P1OUT= (P1OUT & ~0x01)|0x01; //ERROR: RED led on _NOP(); // If it fails, it'll end up here. Could happen if // the cable was detached after the connectionState() // check, or if somehow the retries failed } else { P1OUT= (P1OUT & ~0x01)|0x00; //RED led off. } } else if(USBCDC_getBytesInUSBBuffer(CDC0_INTFNUM)>0) { USBCDC_receiveDataInBuffer(&RcvChr,1,CDC0_INTFNUM); } } //while(1) } //main() void initRTC(void) { TA0CCR0 = 32768; TA0CTL = TASSEL_1+MC_1+TACLR; // ACLK, count to CCR0 then roll, clear TAR TA0CCTL0 = CCIE; // Gen int at rollover (TIMER0_A0 vector) } #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void) #else #error Compiler not found! #endif { if (sec++ == 60) { sec = 0; if (min++ == 60) { min = 0; if (hour++ == 24) { hour = 0; } } } bSendTimeToHost = TRUE; // Time to update __bic_SR_register_on_exit(LPM3_bits); // Exit LPM } int convertTwoDigBinToASCII(uint8_t bin, uint8_t* str) { *str++= (bin/10)+'0'; *str++= (bin%10)+'0'; return(2); } int convertTimeBinToASCII(uint8_t* str, int strCt) { int nDst= 0; nDst+= convertTwoDigBinToASCII(hour,&str[nDst]); str[nDst++]= ':'; nDst+= convertTwoDigBinToASCII(min,&str[nDst]); str[nDst++]= ':'; nDst+= convertTwoDigBinToASCII(sec,&str[nDst]); str[nDst++]= '|'; //Echo received keystrokes nDst+= convertTwoDigBinToASCII(RcvChr,&str[nDst]); str[nDst++]= '\r'; str[nDst++]= '\n'; str[nDst]= 0; return(nDst); } /* * ======== UNMI_ISR ======== */ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector = UNMI_VECTOR __interrupt void UNMI_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void) #else #error Compiler not found! #endif { switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG )) { case SYSUNIV_NONE: __no_operation(); break; case SYSUNIV_NMIIFG: __no_operation(); break; case SYSUNIV_OFIFG: UCS_clearFaultFlag(UCS_XT2OFFG); UCS_clearFaultFlag(UCS_DCOFFG); SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); break; case SYSUNIV_ACCVIFG: __no_operation(); break; case SYSUNIV_BUSIFG: // If the CPU accesses USB memory while the USB module is // suspended, a "bus error" can occur. This generates an NMI. If // USB is automatically disconnecting in your software, set a // breakpoint here and see if execution hits it. See the // Programmer's Guide for more information. SYSBERRIV = 0; // Clear bus error flag USB_disable(); // Disable } }

It is interesting that the official TI reference code counts time incorrectly. According to this, there are 61 seconds in every minute, 61 minutes in every hour, and 25 hours in every day.

Now that I have a KGR (Known Good Reference) for communicating with the 5529, I need to extract the minimum required to enable USB/COM in my own projects.

A New USB Project

1304> I am following the procedure from the "USB Programmer's Guide: 4.4 Adding USB into an Existing MSP430 Application." I am creating a new workspace in
EZ430\USB\Work\Motor\
And a new "Firmware" project:

New CCS project. New Motor firmware project, main.c
NOTE: I used the wrong MCU number, it should be 5529 not 5229.

The USB support code needs to be copied into the project manually. The reference files are found in the directory
D:\CL\TI\CCS613\msp430\MSPWare_3_30_00_18\usblib430\MSP430_USB_Software\MSP430_USB_API
I set this as the current directory for D:. The C0_SimpleSend project can be found in
examples\CDC_VirtualCOMport\C0_SimpleSend

I copy the USB_API directory to Firmware:
S:\Src\HQ\Dev\SB\Chip\EZ430\USB\Work\Motor\Firmware>xcopy /s D:USB_API\* USB_API\ D:USB_API\msp430USB.cmd D:USB_API\msp430USB.ld D:USB_API\USB_CDC_API\UsbCdc.c D:USB_API\USB_CDC_API\UsbCdc.h D:USB_API\USB_Common\defMSP430USB.h D:USB_API\USB_Common\device.h D:USB_API\USB_Common\types.h D:USB_API\USB_Common\usb.c D:USB_API\USB_Common\usb.h D:USB_API\USB_Common\usbdma.c D:USB_API\USB_Common\UsbIsr.h D:USB_API\USB_HID_API\UsbHid.c D:USB_API\USB_HID_API\UsbHid.h D:USB_API\USB_HID_API\UsbHidReq.c D:USB_API\USB_HID_API\UsbHidReq.h D:USB_API\USB_MSC_API\UsbMsc.h D:USB_API\USB_MSC_API\UsbMscReq.c D:USB_API\USB_MSC_API\UsbMscReq.h D:USB_API\USB_MSC_API\UsbMscScsi.c D:USB_API\USB_MSC_API\UsbMscScsi.h D:USB_API\USB_MSC_API\UsbMscStateMachine.c D:USB_API\USB_MSC_API\UsbMscStateMachine.h D:USB_API\USB_PHDC_API\UsbPHDC.c D:USB_API\USB_PHDC_API\UsbPHDC.h 24 File(s) copied

I copy the USB_config directory from the C0_SimpleSend project. This includes the KGR signed TI INF file and the USB Vendor/Product ID codes. These will need to change if/when the product goes to production, but re-using the signed INF saves a lot of headaches.
S:\Src\HQ\Dev\SB\Chip\EZ430\USB\Work\Motor\Firmware>xcopy /s D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\* USB_config\ D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\descriptors.c D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\descriptors.h D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\msp430_cdc.cat D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\msp430_ti_signed.inf D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_config\UsbIsr.c 5 File(s) copied

Copy the usbConstructs.c and usbConstruct.h into the project source directory.
S:\Src\HQ\Dev\SB\Chip\EZ430\USB\Work\Motor\Firmware>xcopy /s D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_app\* USB_app\ D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_app\usbConstructs.c D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_app\usbConstructs.h D:examples\CDC_virtualCOMport\C0_SimpleSend\USB_app\usbEventHandling.c 3 File(s) copied

Copy driverlib
S:\Src\HQ\Dev\SB\Chip\EZ430\USB\Work\Motor\Firmware>xcopy /s D:driverlib\* driverlib\ D:driverlib\APIS_REMOVED.html D:driverlib\release_notes.html D:driverlib\MSP430F5xx_6xx\adc10_a.c D:driverlib\MSP430F5xx_6xx\adc10_a.h D:driverlib\MSP430F5xx_6xx\adc12_a.c D:driverlib\MSP430F5xx_6xx\adc12_a.h ... D:driverlib\MSP430F5xx_6xx\inc\version.h 83 File(s) copied

Add the core USB include files to main.c:

Include: #include "driverlib.h" #include "descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer return 0; }

Open the Firmware project properties and add the USB directories to the include path. Add the root project directory (Firmware), and driverlib\MSP430F5xx_6xx

Adding USB include direcrories. Project include files.

1410> I should now be able to build the (empty) project. Now I begin amalgamating the SimpleSend and JumpMtr projects into the new project. I want to be able to control the speed of the motor using Putty.

First step is to stub in the hardware initialization code. Most of this code will be copied from the SimpleSend project.

Main_stubs: #include "driverlib.h" #include "descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" void __inline led_RedOff(void) { P1OUT&= ~0x01; } void __inline led_RedOn(void) { P1OUT|= 0x01; } void __inline led_GrnOff(void) { P4OUT&= ~0x80; } void __inline led_GrnOn(void) { P4OUT|= 0x80; } void initClocks(uint32_t hz); void initPorts(void); void initRTC(void); void sendTime(void); void recvText(void); volatile uint8_t doSend= 0; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer PMM_setVCore(PMM_CORE_LEVEL_2); //Minimum power for USB operation. initPorts(); //Configure GPIO ports led_RedOff(); //Turn error lamp off led_GrnOff(); //Turn OK lamp off initClocks(8000000); //MCLK=SMCLK=FLL=8MHz USB_setup(TRUE,TRUE); //USB on initRTC(); //Start real time clock led_GrnOn(); //Tell the world we are open for business. __enable_interrupt(); //Start listening while(1) { //Return to LPM0, minimum level for USB operations. __bis_SR_register(LPM0_bits|GIE); if(USBCDC_getBytesInUSBBuffer(CDC0_INTFNUM)>0) recvText(); if(doSend) sendTime(); } return 0; } void initClocks(uint32_t hz) { } void initPorts(void) { } void initRTC(void) { TA0CCR0= 32768; //Assuming 32KHz crystal on REF0. TA0CTL= TASSEL_1|MC_1|TACLR; TA0CCTL0= CCIE; //Interrupt on each rollover (1 second) } void sendTime(void) { } void recvText(void) { }

The compiler complains that USBCDC_getBytesInUSBBuffer() is not declared; I need to add the CDC include files:

Include CDC: #include "USB_API/USB_CDC_API/UsbCdc.h" #include "USB_app/usbConstructs.h"

The initClocks() code is copied from the example hal.c:

initClocks: void initClocks(uint32_t hz) { UCS_initClockSignal(UCS_FLLREF,UCS_REFOCLK_SELECT,UCS_CLOCK_DIVIDER_1); UCS_initClockSignal(UCS_ACLK,UCS_REFOCLK_SELECT,UCS_CLOCK_DIVIDER_1); UCS_initFLLSettle(hz/1000,hz/32768); }

The initPorts() code is copied from my test code.

initPorts: uint8_t StepMode= 3; //0=Full step, 3= 1/8 microstep ... void initPorts(void) { P1SEL= P1SEL & ~0x70; //P1.4 as gpio (MTR_STEP_X) P1DIR= P1DIR | 0x70; //P1.4 as output P1OUT= (P1OUT & 0x70)|0x40; //MTR_DIR_X=1= Clockwise P2SEL= 0x00; //P2.0:7 as gpio P2DIR= (P2DIR & ~0x02)|0x10; //P2.1 as input, 2.4 as output. P2REN= 0x02; //Enable pull resistor on P2.1 P2OUT|= 0x02; //Set P2.1 pull resistor to up. P3SEL= (P3SEL & ~0x80)|0x00; P3DIR= (P3DIR & ~0x80)|0x80; P3OUT= (P3OUT & ~0x80)|0x80; P4DIR|= 0x88; //P4.3,7 as output P4SEL&= ~0x88; //P4.3,7 as gpio P4OUT|= 0x88; //Turn LED2 on //Set stepping mode, P8.1-2. P8SEL= P8SEL & ~0x06; P8DIR= P8DIR|0x06; P8REN|= 0x06; P8OUT= (P8OUT & ~0x06)|(StepMode<<1); //Microstepping mode. }

The TimerA RTC interrupt is copied from the USB example, dropping the IAR stuff.

RTC Interrupt: volatile uint8_t hour=4,minute=30,second=0; ... #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { if(++second>=60) { second= 0; if(++minute>=60) { minute= 0; if(++hour>=24) { hour= 0; } } } doSend= TRUE; __bic_SR_register_on_exit(LPM3_bits); //Power UP }

The UNMI interrupt is copied from SimpleSend.

UNMI Interrupt: #pragma vector=UNMI_VECTOR __interrupt void UNMI_ISR(void) { swtich(__even_in_range(SYSUNIV,SYSUNIV_BUSIFG)) { case SYSUNIV_NONE: __no_operation(); break; case SYSUNIV_NMIIFG: __no_operation(); break; case SYSUNIV_OFIFG: Overflow(); break; case SYSUNIV_ACCVIFG: __no_operation(); break; case SYSUNIV_BUSIFG: BusError(); break; } } void Overflow(void) { UCS_clearFaultFlag(UCS_XT2OFFG); UCS_clearFaultFlag(UCS_DCOFFG); SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); } void BusError(void) { SYSBERRIV= 0; //Clear bus error flag USB_disable(); //Kill the UBS led_RedOn(); //Error lamp }

The sendTime() and recvText() functions are copied (and rewritten) from my modified SimpleSend.

Send and Receive: int writeByte(uint8_t value, char *pDst, int DstSz); int writeChr(char Src, char *pDst, int DstSz); int writeStr(const char *pSrc, char *pDst, int DstSz); int writeTime(char *pDst, int DstSz); ... volatile uint8_t hour=4,minute=30,second=0; char RcvChr; //Received from host char timeText[16]; //Current time as text ... void sendTime(void) { int ChrCt= 0; doSend= FALSE; ChrCt= writeTime(timeText,sizeof(timeText)); if(USBCDC_sendDataInBackground((uint8_t*)timeText,ChrCt,CDC0_INTFNUM,1000)) { led_RedOn(); //Error lamp _NOP(); } else { led_RedOff(); //Error lamp off. } } void recvText(void) { USBCDC_receiveDataInBuffer((uint8_t*)&RcvChr,1,CDC0_INTFNUM); } ... int writeByte(uint8_t value, char *pDst, int DstSz) { int ChrCt= 0; if(value>=100 && ChrCt<DstSz) pDst[ChrCt++]= (value/100)%10 + '0'; if(ChrCt<DstSz) pDst[ChrCt++]= (value/10)%10 + '0'; if(ChrCt<DstSz) pDst[ChrCt++]= value%10 + '0'; return(ChrCt); } int writeChr(char Src, char *pDst, int DstSz) { if(DstSz<=0) return(0); *pDst= Src; return(1); } int writeStr(const char *pSrc, char *pDst, int DstSz) { int ChrCt= 0; while(ChrCt<DstSz && (pDst[ChrCt++]= *pSrc++)); return(ChrCt); } int writeTime(char *pDst, int DstSz) { int ChrCt= 0; ChrCt+= writeByte(hour,&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeChr(':',&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeByte(minute,&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeChr(':',&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeByte(second,&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeChr('|',&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeByte(RcvChr,&pDst[ChrCt],DstSz-ChrCt); ChrCt+= writeStr("\r\n",&pDst[ChrCt],DstSz-ChrCt); pDst[ChrCt]= 0; return(ChrCt); }

If I run this, I should see a slightly improved version of the clock.

1538> Success! The USB clock is running in its new home.

I copy the motor functions from the JumpMtr project.

MotorPWM: void PWM_Config(unsigned int period) { unsigned int pulse; period= period*(8>>StepMode); pulse= period/10; TA0CCTL3= OUTMOD_7; //Toggle/Reset TA0CTL= TASSEL_2 + MC_1; //Use SM clock (1us) TA0CCR0= period-pulse; //Period (minimum 180) TA0CCR3= pulse; //Pulse width (minimum 10) P1DIR|= 0x10; //Output P1SEL|= 0x10; //Select TA0.3 }

There is now a conflict between the RTC interrupt and MotorX, both use TimerA. I change the RTC to use TimerB0. TODO: Use the real hardware RTC.

RTC Using TimerB: void initRTC(void) { TB0CCR0= 32768; //Assuming 32KHz crystal on REF0. TB0CTL= TBSSEL_1|MC_1|TBCLR; TB0CCTL0= CCIE; //Interrupt on each rollover (1 second) } #pragma vector=TIMER0_B0_VECTOR __interrupt void TIMER0_B0_ISR(void) { ... }

Just to prove that both are working, I start up the motor.

MotorOn: void main(void) { ... initRTC(); //Start real time clock led_GrnOn(); //Tell the world we are open for business. __enable_interrupt(); //Start listening PWM_Config(1000); while(1) { ... } }

Something is not right, it sounds like the motor is trying to run too fast. The new project is configuring SMCLK for 8MHz, 8X faster than JumpMtr. I bump the period in PWM_Config() from 1000 to 8000 and the motor turns as expected.

The final step is to control the motor using commands from the host.

RemoteControl: void recvText(void) { USBCDC_receiveDataInBuffer((uint8_t*)&RcvChr,1,CDC0_INTFNUM); switch(RcvChr) { case '1': mtrStep(); break; case '2': mtrRun(16000); break; case '3': mtrRun(8000); break; case '-': mtrReverse(); break; case '+': mtrForward(); break; } } void mtrRun(unsigned int period) { unsigned int pulse; period= period*(8>>StepMode); pulse= period/10; TA0CCTL3= OUTMOD_7; //Toggle/Reset TA0CTL= TASSEL_2 + MC_1; //Use SM clock (1us) TA0CCR0= period-pulse; //Period (minimum 180) TA0CCR3= pulse; //Pulse width (minimum 10) P1DIR|= 0x10; //Output P1SEL|= 0x10; //Select TA0.3 } void mtrStep(void) { TA0CCTL3= OUTMOD_0; //Disable PWM P1OUT&= ~0x10; //P1.4=MTR_X_STEP low __delay_cycles(100); P1OUT|= 0x10; //HIGH __delay_cycles(100); P1OUT&= ~0x10; //LOW } void mtrReverse(void) { P1OUT|= 0x40; //P1.6=MTR_X_DIR } void mtrForward(void) { P1OUT&= ~0x40; }

I renamed PWM_Config() to mtrRun() to be consistent.

1612> Woot! Success! I am now able to drive my stepper motor using keyboard commands from my Windows machine!

1639> It took a while to figure out why I could not transition from Run to Step modes... I needed to set P1.4 back to normal GPIO mode.

Step Working: void mtrStop(void) { TA0CTL= TASSEL_2|MC_0; //Stop TimerA P4OUT&= ~0x08; //MTR_/RESET in reset } void mtrRun(unsigned int period) { unsigned int pulse; P8OUT= (P8OUT & ~0x06)|(StepMode<1); P4OUT|= 0x08; //MTR_/RESET off period= period*(8>>StepMode); pulse= period/10; TA0CCTL3= OUTMOD_7; //Toggle/Reset TA0CTL= TASSEL_2 + MC_1; //Use SM clock (1us) TA0CCR0= period-pulse; //Period (minimum 180) TA0CCR3= pulse; //Pulse width (minimum 10) P1DIR|= 0x10; //Output P1SEL|= 0x10; //Select TA0.3 } void mtrStep(void) { TA0CTL= TASSEL_2|MC_0; //Stop TimerA P1SEL&= ~0x10; //P1.4 is again a normal GPIO P4OUT|= 0x08; //MTR_/RESET off P8OUT= (P8OUT & ~0x06); //Step mode=FULL P1OUT&= ~0x10; //P1.4=MTR_X_STEP low __delay_cycles(10000); //This is just guess P1OUT|= 0x10; //HIGH __delay_cycles(10000); P1OUT&= ~0x10; //LOW } void mtrReverse(void) { P1OUT|= 0x40; //P1.6=MTR_X_DIR } void mtrForward(void) { P1OUT&= ~0x40; }

1640> Woot! Woot! I now have everything I need to control the motors over the USB link.

The firmware was 11410 code bytes, using about 11K of 128K. Plenty of room left for a G-Code interpreter. The entire Main.c:

TODO: Replace the pseudo-RTC TimerB with the real RTC.

I haven't seen anything from Bay Area Circuits about the CtrlMtr boards. The order was placed 11:26am last Thursday with a 5-day turn, and this is the fifth day. I guess the first day doesn't count, no matter how early in the day the order was placed. With 2 days in transit, it may be Monday before they arrive.



WebV7 (C)2018 nlited | Rendered by tikope in 111.476ms | 3.137.216.227