Page 1 of 25 1234511 ... LastLast
Results 1 to 30 of 736

Thread: E/X-Mag Microcontroller Programming (Atmel AT90S2313)

  1. #1
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365

    Exclamation E/X-Mag Microcontroller Programming (Atmel AT90S2313)

    I am a student at UW-Milwaukee and have chosen to do an Independent Study for my final semester to write my own software for my X-Mag. One of the bigest problems was finding the connectors and making the wire harness to connect the Programmer to the Gun. I was finally able to do that and spent quite a bit of time and money but after that it's all in the code... I actually purchased the crimping tool necessary to make the cables, so if anyone else is interested in trying to program their own gun send me a Private Message or an email and we can discuss getting you setup with the hardware. (I'll tell you what to buy, you have it shipped to Me and i'll make the wire harness for you, test it and then ship it to you.)

    I am opening this thread for anyone who wishes to discuss any programming problems or ideas. I had been just sending Private messages to Miscue and several others but it was pointed out to me that i should open a thread since other people might have the same questions. Hopefully this thread can follow my progress and act as a beginners guide for anyone who wishes to write their own software.

    To start there are several documents you'll need
    1. Atmel At90S2313 User Guide
    2. Atmel Instruction Set
    3. Agilent HCMS-2912 Data Sheet (Alphanumeric Display)
    4. Agilent HCMS-29xx/HCMS-39xx LED Displays Character Set

    Once you have browsed through the documents and have the ability to flash in your own code you will have to start writing it. to start Look at the example files that come with AVR Studio, particularily tutor1.asm and avr108.asm which should be in the appnotes folder under the install directory. Once you assimilate this concentrate on the I/O Ports Section of the AT90S2313 User Guid (page 50) You'll need to know what devices are connected to which ports.

    Here is a list of what i found when doing a pinnout of the Board. If anyone wants a full pinnout of the Microcontroller or a reverse engineered schematic on the board let me know and i'll either email it to you or post it if i get enough requests.

    Port B
    PB7 - N/C
    PB6 - ACE
    PB5 - Tournament Lock
    PB4 - Display RS
    PB3 - Display DATA IN
    PB2 - Display CLOCK
    PB1 - Low Voltage
    PB0 - N/C

    Port D
    PD7 - N/C
    PD6 - Display CE
    PD5 - Bottom Button
    PD4 - Top Button
    PD3 - Solenoid/Warp Feed (at the same time)
    PD2 - Trigger (HES)
    PD1 - N/C
    PD0 - N/C

    Can someone double check these? I haven't gotten far enough in the code to use all of them yet and it would be extreemly frustrating if i had this part wrong. Send Me a PM and i'll edit my post so as not to confuse anyone who reads this later.
    Last edited by LorneCash; 03-02-2006 at 03:35 PM.

  2. #2
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    I understand there is not a real time clock and that i will have to set up timers based on the clock speed. How do i go about doing that? Is there an internal counter of the number of clock cycles since power on, or do i have to incrament a register and do it all myself or what? Since i know i will need many timers is there a way to set up at least part of it as a function or subroutine or will i have to repete the code for every timer i need.

  3. #3
    Join Date
    Feb 2005
    Location
    Texas
    Posts
    9,305
    Good work. Ihave always been interested in this. Keep us posted on the progress.

    Oh, another thing I was wondering, is it possible to download the code off of the controller board and look at it?

  4. #4
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    Quote Originally Posted by BigEvil
    Good work. Ihave always been interested in this. Keep us posted on the progress.

    Oh, another thing I was wondering, is it possible to download the code off of the controller board and look at it?
    Yes, Kinda... you can download the code from one gun and copy it to another or reload it on that gun later and you can look at the code but the AVR Studio compiles it to a hex file. You can load this hex file back into the Studio and it will translate it back to assembly language but it's not really too helpful because about Even though its back to assembly there are no comments and about 25% of the stuff you do in the Studio is a function and generates assembly code that you never wrote and won't need to. Maybe it would be more useful to a more advenced programmer but I really couldn't make much of it.

  5. #5
    Join Date
    May 2005
    Location
    Virginia
    Posts
    205

    Timing on the AVR

    You were asking about timing ... the AVR has 8 and 16 bit timers (depending on the variant) that can be configured to time at different rates, based on the oscillator. Depending on how the prescalers are configured, you can choose the rate that it "counts" at. I've written quite a bit of code for the AVR series micro (Tiny15, 4433, Mega8, Mega16, Mega32), and could get you started on some of the low-level routines to configure the peripherals if you like.

    bit-wizard

  6. #6
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365

    ACE Functionality

    Can someone please explain to me how to check the ACE for a signal? I tried checking it the same way i checked the Trigger (HES) but it didn't give me a signal... Do i need to send power to it somehow first and then check it?

  7. #7
    Join Date
    Feb 2005
    Location
    Texas
    Posts
    9,305
    Quote Originally Posted by LorneCash
    Can someone please explain to me how to check the ACE for a signal? I tried checking it the same way i checked the Trigger (HES) but it didn't give me a signal... Do i need to send power to it somehow first and then check it?

    Im pretty sure the ACE is always powered when the marker is on. I know from pics where you can see the IR light comming from the emmitter that it was 'on' eventhough the ACE was set to 0.

    There should be 2 wires going to the ace board that are used: one is a +5v and the other is SIG. The board, like the rest of the gun, uses the frame as a ground, (probably the screw that hold the ACE in.)

    As far as checking it for a signal, I am guessing that you would have to have the ACE set to 1 and then cover the eye sensor. Im not sure, but I would be that the SIG wire would be where you need to check. However, I am not sure of the value that you would be looking for. I dont know if its a +5v or much smaller. Remember, I am only guessing

  8. #8
    Join Date
    Jan 2002
    Location
    Halifax, N.S., Canada
    Posts
    8,039
    Since the Atmel works with a 5v supply on the board, I would assume a 0 to 5v signal from the ACE to indicate an on or off condition.
    Except for the Automag in front, its usually the man behind the equipment that counts.

  9. #9
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by LorneCash
    Can someone please explain to me how to check the ACE for a signal? I tried checking it the same way i checked the Trigger (HES) but it didn't give me a signal... Do i need to send power to it somehow first and then check it?
    No... it's always on. Should be pretty straight forward to get input from the ACE.
    Last edited by Miscue; 10-21-2005 at 11:16 PM.

  10. #10
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by BigEvil
    Good work. Ihave always been interested in this. Keep us posted on the progress.

    Oh, another thing I was wondering, is it possible to download the code off of the controller board and look at it?
    If the chip was locked, no (assuming there isn't a hack). Otherwise yes...

    I think it's easier to look at what the program does on the simulator than to figure out what it's doing by looking at the assembly. Although... yeah, you can figure out exactly how it works by examining the hex file. I don't know why you would want to go through that trouble though.

  11. #11
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    PB1 - ??? (warp feed maybe)
    This is the low voltage line. There is no dedicated pin going from the microcontroller to the warp feed specifically. The Intellifeed port shares the same line as the output line going to the solenoid.

    One of the things you'll want to do is: Prime the loader if the ACE does not detect a ball... kinda makes sense... no ball = try to feed a ball! To do this, it's the same as firing the marker... but you only send a signal to the solenoid line for a short duration... just enough for your loader to pick it up... but not nearly enough to fire the marker.

    This line sharing also infers that you can fire the marker via the Intellifeed cable. Also... if your loader has a problem... it can fire your marker. It is very possible to locate a cheater board in your loader.

    Cable a bunch of EMags together through the Intellifeed port... fire one marker and they all shoot in unison!
    Last edited by Miscue; 10-21-2005 at 11:24 PM.

  12. #12
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by LorneCash
    I understand there is not a real time clock and that i will have to set up timers based on the clock speed. How do i go about doing that? Is there an internal counter of the number of clock cycles since power on, or do i have to incrament a register and do it all myself or what? Since i know i will need many timers is there a way to set up at least part of it as a function or subroutine or will i have to repete the code for every timer i need.
    Total number of clock cycles since power on? Not that I know of.

    Yeah... you can write a subroutine for the timer stuff. When the built-in timer rolls over... it results in an interrupt... have it go to a subroutine then.
    Last edited by Miscue; 10-21-2005 at 11:39 PM.

  13. #13
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Starts off kinda like this to do your timer interrupt routine.

    .CSEG ; Start Code Segment
    .ORG 0 ; Set Program Counter to 0
    rjmp RESET ; Reset Handler
    .ORG OVF0addr
    rjmp timerInt

    timerInt:
    push r16
    in r16,SREG
    etc. etc.



    Low Battery...

    sbis PINB, 1
    rjmp lowBatt

    ACE...

    sbis PINB, 6
    rjmp resetACE2
    Last edited by Miscue; 10-21-2005 at 10:46 PM.

  14. #14
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by LorneCash

    Port B
    PB7 - N/C
    PB6 - ACE
    PB5 - N/C
    PB4 - Display RS
    PB3 - Display DATA IN
    PB2 - Display CLOCK
    PB1 - ??? (warp feed maybe)
    PB0 - N/C

    Port D
    PD7 - N/C
    PD6 - Display CE
    PD5 - Bottom Button
    PD4 - Top Button
    PD3 - Solenoid
    PD2 - Trigger (HES)
    PD1 - N/C
    PD0 - N/C

    Can someone double check these? I haven't gotten far enough in the code to use all of them yet and it would be extreemly frustrating if i had this part wrong. Send Me a PM and i'll edit my post so as not to confuse anyone who reads this later.
    Those are correct... PB1 = Low Voltage signal like I mentioned.

  15. #15
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Something I wrote in '03... if it gives you any ideas on how you might want to do your timer scheme.

    My shot buffering and timing scheme is completely different. What I have now is a leaky bucket approach. I have a bunch of timers that are independent of each other, instead of one clock timer. These timers are at all times counting down to 0, decremented after an interrupt. These timers are filled up to appropriate values when the trigger is pulled. About a dozen instructions control all of these timers, which greatly simplifies things.

    If like timer A is not 0 (the bucket hasn't leaked out completely yet), event A cannot happen yet... it just skips that part.

    So like, I'd have timers A, B, C:

    If A timer = 0
    turn off solenoid (event A)
    if B timer = 0
    can look at trigger for new shot(event B)
    if C timer = 0
    shoot ball if buffered (event C)

    Stuff like that. These events can me mixed up, it doesn't matter what order they are in really. Before, stuff had to happen sequentially... and basing everything off of one timer had it's problems - made coding larger, clumsy, and more difficult.

    Also, there is now no distinction between a buffered shot and a non-buffered shot... everything is a 'buffered' shot I suppose - and my code checks the trigger only once (rather than multiple times like in Q1.1), regardless of what stage of the cycle it is in. The rule is: A shot can be buffered when the debounce timer has expired. If this is your first shot, then it's already at 0. If during a cycle, you can buffer a shot after the debounce timer expires. Now, this shot cannot be fired until the ROF timer is at 0. For your first shot, it is already 0. Otherwise it must wait for the ROF timer to expire.

    This probably doesn't make sense... I'd have to use diagrams to explain it better.

  16. #16
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365

    Still having ACE problems

    Miscue,

    Thanks for the timer help, and I like your bucket analogy that's a good way to explain it.
    can you help me a bit more with the ACE?
    I had tried this a few days ago but it didn't seem to work:

    sbis PINB, ACE ; See if ACE is ready (ACE=6)
    rjmp ACE_Ready ; If ace is ready do the code

    I noticed at the bottom of the timer code you had this exact same thing but you jumped to resetACE. How exactly does that work do i have to continuously be resetting the line to a low and a high means that it saw something since the last time i reset it?

    I figured there must be a little more to it then just what I had because if it was just a matter of sensing a ball or not sensing a ball how could the difference be between ACE-1 and ACE-2. Could you please elaborate on that too? thanks.
    Last edited by LorneCash; 10-22-2005 at 03:05 AM.

  17. #17
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by LorneCash
    Miscue,

    Thanks for the timer help, and I like your bucket analogy that's a good way to explain it.
    can you help me a bit more with the ACE?
    I had tried this a few days ago but it didn't seem to work:

    sbis PINB, ACE ; See if ACE is ready (ACE=6)
    rjmp ACE_Ready ; If ace is ready do the code

    I noticed at the bottom of the timer code you had this exact same thing but you jumped to resetACE. How exactly does that work do i have to continuously be resetting the line to a low and a high means that it saw something since the last time i reset it?

    I figured there must be a little more to it then just what I had because if it was just a matter of sensing a ball or not sensing a ball how could the difference be between ACE-1 and ACE-2. Could you please elaborate on that too? thanks.
    "ACE 1" just needed one successful read from the ACE. "ACE 2" needed like... X number of successful reads. So that ResetAce2 thing was... to reset the number of successful reads that it counted. Does it make any difference? Not that I can tell... "ACE 1" seems to be sufficient and "ACE 2" does no harm. I put two modes in there just in case...

    I don't know what's wrong with your ACE.
    Did you set the port resistors correctly?

    ldi r18, 0b00011100 ; Register Select = PB4, Data In = PB3, Clock = PB2
    out DDRB, r18 ; Set LED pins to output - all else input

  18. #18
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Oh yeah... PB5 is for the tourny lock jumper.

  19. #19
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    OK here's what I have and I have no idea why it's not working:

    ...

    ldi R_temp,0b11111111
    out PORTB,R_temp

    ldi R_temp,0b00011100 ; Set Data Direction Register(Port B)
    out DDRB,R_temp

    ...

    ACE_Ready:
    ldi ZH,high(2*MESSAGE2) ; Change Message displayed (part1)
    ldi ZL,low(2*MESSAGE2) ; Change Message displayed (part2)
    rcall loadbyte ; Load Message to screen
    sbi PORTD,DS1_CE
    rjmp Loop1_1

    ...

    Loop1_1:
    sbis PINB, ACE ; See if ACE is ready
    rjmp ACE_Ready ; If ace is ready do the code

    sbis PIND, BTN_1 ; See if Top Button is pushed again
    rjmp Button1_2 ; If Top Button is pushed jump to SUB
    sbis PIND, TRIGGER ; If Trigger is pulled exit Button1 Loop
    ret
    rjmp Loop1_1 ; Continue to display Button1 (Loop)


    If I switch the line to say "sbis PORTD, 5" it works fine when i push the bottom button so i don't think its a flaw in the logic just in how i access the ACE. All i'm trying to do is make it say READY on the Display when i have the ACE covered with my finger. I tried loading other software and the ACE works fine with that. I'm really stuck here.

  20. #20
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    I think your logic is backwards.

    Try cbis PINB, ACE ; See if ACE is ready
    instead of sbis PINB, ACE ; See if ACE is ready

    ACE = 6 right?

  21. #21
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    Quote Originally Posted by Miscue
    I think your logic is backwards.

    Try cbis PINB, ACE ; See if ACE is ready
    instead of sbis PINB, ACE ; See if ACE is ready

    ACE = 6 right?

    There is no instruction cbis do you mean cbi or sbic? I tried sbic... do i have to clear it or set it first to "prime" it or something? Yea, ACE=6. Just to remind you in your post #13 you used sbis to jump to resetACE... What's resetACE all doing, you said before you used some type of counter for ACE 2, but i don't have any idea what would need to be reset unless it's just the counter reset.

  22. #22
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by LorneCash
    There is no instruction cbis do you mean cbi or sbic? I tried sbic... do i have to clear it or set it first to "prime" it or something? Yea, ACE=6. Just to remind you in your post #13 you used sbis to jump to resetACE... What's resetACE all doing, you said before you used some type of counter for ACE 2, but i don't have any idea what would need to be reset unless it's just the counter reset.
    There is no priming. I told you the wrong instruction... tried to do it from memory and mixed up the instructions. Whatever is the opposite of sbis... probably sbic.

    All that my ACE 2 mode does is look for X number of successful reads from the ACE - the theory was that it might be a more reliable way of reading from the ACE. Turned out to be unnecessary as far as I could tell.

    Here is a silly question: Is your ACE plugged in to the board? I'd check your physical connections.

  23. #23
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    Quote Originally Posted by Miscue
    There is no priming. I told you the wrong instruction... tried to do it from memory and mixed up the instructions. Whatever is the opposite of sbis... probably sbic.

    All that my ACE 2 mode does is look for X number of successful reads from the ACE - the theory was that it might be a more reliable way of reading from the ACE. Turned out to be unnecessary as far as I could tell.

    Here is a silly question: Is your ACE plugged in to the board? I'd check your physical connections.
    It works fine with 3.2 and 4.01

  24. #24
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    I don't have any more suggestions for you other than... have fun debugging. You'll probably slap yourself when you discover what the problem is.

  25. #25
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    I got it, but i'm not sure i understand it completely... From what i got I had the pullup resistor for that bit on PORTB set wrong. Here's what i have now. Can you please check all 4 of the bytes i'm loading to confirm they're correct, and if you don't mind explain a bit about that.

    ldi R_temp,0b10111111 ; Set Pullup Resistors(Port B)
    out PORTB,R_temp ; Load them

    ldi R_temp,0b00011100 ; Set Data Direction Register(Port B)
    out DDRB,R_temp ; Load It

    ...

    ldi R_temp,0b10000000 ; Set Pullup Resistors(Port D)
    out PORTD,R_temp ; Lead them

    ldi R_temp,0b01001000 ; Set Data Direction Register(Port D)
    out DDRD,R_temp ; Load it
    Last edited by LorneCash; 10-25-2005 at 01:19 AM.

  26. #26
    Join Date
    Oct 2000
    Location
    Las Vegas, NV
    Posts
    7,105
    Quote Originally Posted by Miscue

    I don't know what's wrong with your ACE.
    Did you set the port resistors correctly?

  27. #27
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365
    Sorry for the runnaround I didn't understand what those 2 lines were doing... I understood the DDRx is setting the Direction, 0 is input and 1 is output, and it's not too hard to figure out if the device is input or output, but the resistors thing i don't get.

    In General, how do you know what the resistor should be set to? Even though I seem to have it set correctly now I would still like to understand why... comes with being an engineer... lol.

  28. #28
    Join Date
    May 2005
    Location
    Virginia
    Posts
    205
    The PORTx reg is a multipurpose register. When the DDRx reg has a '1' in a given port pin location, the port is an output, and the value placed in the corresponding PORTx bit is output on the equivalent micro pin. When the DDRx reg has a '0' in the given port pin location, the port pin is set to an input, and the value placed in the PORTx reg bit determines whether the pullup is active '1' or not '0'. If it is active, then a 20 to 100K resister internally connects the pin to VCC. This "pulls" the input up to the supply when nothing external pulls it down. So if the pin was not connected to anything externally, it would be pulled to 5V and would be prevented from being a floating input, which is a bad thing in terms of power consumption. Another reason to use pullups is if the external device that is connected to the pin is an open collector or open drain output.

    So it really boils down to what the external circuitry that is attached consists of as to whether or not you want the pullups on.

    I'm purely speculating since I haven't seen the schematic, but is is possible that the external device connected to the input that you had configured incorrectly as a pullup ('1') may have had an associated pulldown (external to the micro). The 2 resistors (pullup and pulldown) would look like a resistive divider on to the input pin, which could keep it from changing state depending on the relative values of the resistors.

    bit-wizard


    Quote Originally Posted by LorneCash
    Sorry for the runnaround I didn't understand what those 2 lines were doing... I understood the DDRx is setting the Direction, 0 is input and 1 is output, and it's not too hard to figure out if the device is input or output, but the resistors thing i don't get.

    In General, how do you know what the resistor should be set to? Even though I seem to have it set correctly now I would still like to understand why... comes with being an engineer... lol.

  29. #29
    Join Date
    Aug 2005
    Location
    Milwaukee WI
    Posts
    365

    Timers again

    OK midterms are over time to get back into this...

    I have been looking at the timer stuff again and was reading in the AT90S2313 User Guide about Timer/Counters. Because of the nature of the timers needed for this project (30ms) I thought it would be easier to just execute a loop for a certain number of cycles based on the frequency of the chip. If i remember correctly the chip is a 4MHz chip so 4 instructions should equal 1ms.

    Is this the best way to go about this or should i try to use the Counters?

  30. #30
    Join Date
    May 2005
    Location
    Virginia
    Posts
    205
    Definitely use the hardware timers. Cycle counting is possible, but accuracy depends on several factors. First, most AVR instructions are single cycle, but NOT ALL instructions. Jumps, for instance, can take more than 1 cycle. Second, if you are using interrupts, they would throw off your cycle-count based timing because they can occur unpredictably.

    Configuring the timers can be a bit of a pain initially, but it is well worth it in terms of the accuracy and flexibility that it allows. They make it much easier to change your code and functionality without having to count cycles by hand to make sure that you have just blown your timing by adding a few more instructions. In my experience, the overall project will be made much simpler in the long run if you use the hardware timers.


    bit-wizard

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •