Reference Material:
AVR1600: Using the XMEGA Quadrature Decoder
http://www.atmel.com/dyn/resources/prod_documents/doc8109.pdf
http://www.atmel.com/dyn/resources/prod_documents/AVR1600.zip
AVR492: BLDC Motor control in sensor mode using AT90PWM3/3B
http://www.atmel.com/dyn/resources/prod_documents/doc7518.pdf
http://www.atmel.com/dyn/resources/prod_documents/avr492.zip
AVR1607: Brushless DC Motor (BLDC) Control in Sensor mode using ATxmega128A1 and ATAVRMC323
http://www.atmel.com/dyn/resources/prod_documents/doc8311.pdf
http://www.atmel.com/dyn/resources/prod_documents/AVR1607.zip
AVR435: BLDC/BLAC Motor Control Using a Sinus Modulated PWM Algorithm on AT90PWM3B
http://www.atmel.com/dyn/resources/prod_documents/doc7671.pdf
http://www.atmel.com/dyn/resources/prod_documents/AVR435_1_0_0.zip
AVR325: High-Speed Interface to Host Enhanced Parallel Port (EPP) using tinyAVR and megaAVR devices
http://www.atmel.com/dyn/resources/prod_documents/doc2506.pdf
http://www.atmel.com/dyn/resources/prod_documents/AVR325.zip
XMega100 Breakout
http://www.sparkfun.com/products/9546
http://www.watterott.com/de/ATxmega128A1-Breakoutboard
http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=120
http://www.olimex.com/dev/index.html (click AVR, find AVR-HX128A1)
Level Translators
http://focus.ti.com/lit/ds/symlink/sn74lvc4245a.pdf
SN74CBTD3861: 10 bit fet bus switch with level shifting
GTL2010: 10bit, 1.0 - 5.0V, no dir pin
Some of the Todo items:
Design a 5V to 3.3V PC parallel port to ATxmega interface
Develop software for LinuxCNC EPP master and ATxmega EPP slave, layout register or command/data protocol
spp.comp
component spp "u32 output to parallel port";
pin in u32 sppin; "Input to send to parallel port" pin out u32 meter; "Output pin allows Halmeter to see what the port address is" function _; license "GPL"; ;; #include <asm/io.h> // Needed for outb
int ioaddr; RTAPI_MP_INT(ioaddr,"Address of parallel port"); // See RTAPI_MP's in http://www.linuxcnc.org/docview/html/, still seems like magic to me (KW) FUNCTION(_) { outb(sppin, ioaddr); // Loads Data port, see http://www.beyondlogic.org/spp/parallel.htm#5 meter = ioaddr; // Lets Halmeter check ioaddr }
loadrt spp ioaddr=0x21c0 // Only takes one address at this time addf spp.0 servo-thread net SpindleSpeedPWMcmd conv-float-u32.0.out spp.0.sppin
Develop ATxmega single PWM/dir (and step/dir?) app for brushed DC motor amp, and amp hardware (3.3V to 5V) interface
Develop ATxmega single quadrature decoder/counter app, and encoder hardware interface
Develop ATxmega single BLDC three phase half bridge app with Hall input, and hardware
Integrate encoder data for sinus BLDC output
Explore scaling motor/encoder system to three axes per ATxmega
To have a fast 3.3V interface consider an FPGA.
avr32-objcopy -O ihex eth-01.elf eth-01.hex dfu-programmer at32uc3a0512 erase dfu-programmer at32uc3a0512 flash --suppress-bootloader-mem eth-01.hex dfu-programmer at32uc3a0512 reset
This section will cover using an ATmega32 with a Modbus RTU connection similar to a VFD Modbus application. So far, I have an RS232 connection from a serial port on the LinuxCNC PC running to a MAX232 based RS232 to TTL converter, then to the ATmega32 serial port. The LinuxCNC software components are a serial Modbus driver based on the gs2_vfd.c driver: http://git.linuxcnc.org/gitweb?p=linuxcnc.git;a=blob;f=src/hal/user_comps/gs2_vfd.c;h=17ed97b78e681c673ab768eb2e0e62bb0b7daf73;hb=e0fbe2669c1bc7b320b738f72ee15abe868aa5a9 , and a set of configuration files to HAL connect the driver pins to a machine application.
The AVR components are the FreeMODBUS AVR API: http://freemodbus.berlios.de/index.php , and the demo.c program included in the FreeMODBUS package.
The LinuxCNC driver, let's say m32_mbrtu.c , could be made by copying the gs2_vfd.c file linked above to your LinuxCNC subdirectory such as ~/linuxcnc/m32_mbrtu/ . Then copy modbus.c , modbus.h , and Makefile from here: http://git.mah.priv.at/gitweb/vfs11-vfd.git/tree (thanks to Michael Haberler). Rename gs2_vfd.c to m32_mbrtu.c and edit to change the names and variables to match the m32's demo program. Currently, the demo has four 16 bit Input registers starting at register address 1000 (0x03E7) that can be read with Mobus function 4, so the "retval = read_holding_registers(param, slavedata->slave,..." will need to be changed to "retval = read_input_registers(param, slavedata->slave,...". The write function is not needed for the demo program until the demo has writable registers. modbus.c and modbus.h are left alone. The Makefile needs to have every "vfs11_vfd" replaced with "m32_mbrtu", then run "make && sudo make install". If successful, you will have an HAL userspace component that can be loaded in a .hal file with "loadusr m32_mbrtu ..." plus the proper option settings. Next, a LinuxCNC configuration needs to be added to ~/linuxcnc/configs/ and the loadusr added to a .hal file. For testing the pins don't need to be connected because we can see the register values with halmeter or halscope.
For the m32 part, download the FreeMODBUS AVR package: http://freemodbus.berlios.de/index.php?idx=5 . I created a m32_mbdemo directory under ~/linuxcnc/ to make ~/linuxcnc/m32_mbdemo/, then I copied from the package's linux directory; demo.c, Makefile and /port . demo.c and /port should not need any changes. Makefile needs to have the .cof bits removed, such as remove "$(TARGET).cof" from "all: $(TARGET).elf $(TARGET).cof $(TARGET).hex $(TARGET).eep". cof seems to have something to do with debugging and isn't compatible or essential to this project. "MCU = atmega168" needs to be changed to match the processor being used, "MCU = atmega32" in my case. "CC=...", "OBJCOPY=...", and "AVRDUDE=..." need to be changed to point to the location of these programs on your PC. I used a 10MHz crystal, so I changed "-DF_CPU=20000000UL" to "-DF_CPU=10000000UL", plus changed the fuse bits to match. I believe I removed all of the "../.." because I copied my files to different directory locations. It might be best to try to use the standard locations. The flash section: "flash: $(AVRDUDE) -p m168 -c stk200 -U flash:w:$(TARGET).hex" needs to be changed to match your device and programmer, I used "flash: $(AVRDUDE) -p m32 -c usbtiny -U flash:w:$(TARGET).hex". "make" should compile and create the needed files. "make flash" should upload the hex file to the AVR. It is mentioned in the FreeMODBUS demo documentation that EEPROM is used to store some data, but I didn't see that the EEPROM space was programmed after the upload, and the demo functions, so this is a mystery to me.
After starting LinuxCNC, the m32_mbrtu component will poll the serial port. This can be verified using a serial port sniffer. I used jpnevulator: http://jpnevulator.snarl.nl/ (warning: one of the options uses an offensive, to me at least, term). jpnevulator seems to need to be started (in its own terminal) before the application being sniffed, so start LinuxCNC after the sniffer. Also transmit and receive need to be connected together (after disconnecting the ATmega somewhere down the line) to loop the Tx back to the Rx, because the sniffer only sniffs the receive input. The sniffer should show something like "0A 04 03 E7 00 04..." repeated as long as LinuxCNC is running. "A0" is the slave ID, 10 in this case. "04" is the Modbus function 4, then two bytes of register address, 1000 or "03 E7" in this case. Then two bytes of the number of registers to send, or 4 in this case. Then two bytes for the packet CRC check sum. This shows what is being sent to the ATmega, but doesn't consider what the ATmega will send back. For that we remove tha Tx Rx jumper and connect the serial cable back on the ATmega. The sniffer should then show the return packets, or some thing like "0A 04 xx xx 00 00 00 00 00 ...". The "xx xx" will be the changing value of register 1. The other registers remain at 0. If you get "0A 84 xx", this the ATmega telling you that there is an error with the exception code of "xx". The codes can be seen here: http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf , on page 16 (section 6.4). I used modpoll to fill in for LinuxCNC as a Modbus master during trouble shooting: http://www.modbusdriver.com/modpoll.html . This will show the return register values, but it might also be handy to sniff modpoll to get more details. Just remember to start the sniffer in its own terminal before starting modpoll.
There is a lot more to do to make a useful application, but this might be a base to start from. The above is more of a note to myself to remind me of what I did to make the demo work. There are most likely, bits missing, not accurate, or poorly done. If anyone can improve this text, please feel free to edit this section, Kirk Wallace 2011/03/24.