Rob

Members
  • Content count

    25
  • Joined

  • Last visited

  • Days Won

    1

Rob last won the day on February 5 2013

Rob had the most liked content!

Community Reputation

1 Neutral

About Rob

  • Rank
    Member

Profile Information

  • Gender
    Male
  1. Rob

    Xilinx ISE error - new to FPGA

    I'm not sure if this will help or not, but I ran into a similar problem when I first started (not that long ago). My problem turned out to be that Xilinx dropped support for the sparten3e in ISE Webpack version 14.4,. Installing ISE Webpack 14.3 solved my problem, maybe it will solve your problem too? Alvie knows what he's doing though, I bet he can help if that doesn't work.
  2. SketchDuino! OTOH, I might be delirious still, that flu was rough!
  3. After I read my last post again this morning, I realized that may have come across wrong. My apologies if it did. What I meant to say was: I didn't know either *_until_* I spent the last week or so digging through those documents.
  4. When I started, Altium was the cheaper of the design tools. Back then it was called Protel. Compared to a seat for Cadence or Mentor it was cheap! Also, I don't have a copy at home, to expensive like you said. I use Eagle if I need to do anything at the house. Since I skipped the whole FPGA thing for so long, I would actually like to check out one of the "Altium LiveDesign" boards. I looked on the net to get an idea what they cost, but nobody is selling one anymore, and I have no idea what they are worth. Hit me with a price, and if I can budget that in, I'll take it. Rob P.S. Sorry for derailing your thread Jack, that wasn't my intention.
  5. I didn't know either! I just spent the last week or so digging through the ATmega103 datasheet, the vhdl for the softcore and the papilio-arduino interface code. It was fun, and I learned a lot. Oh, can't forget the help from Jack, that put it over the top.
  6. Ya, that last example uses the default interrupt method (it's defined in the ardiuno enviroment), It bypasses the attachInterrupt function and accesses the AVR registers directly. Give it a spin, it should work, I tested before uploading. Thanks for the tips on gists. I'll go read up on that. Jack, I forked this version from github: https://github.com/GadgetFactory/Arduino-Soft-Core It has some files missing and won't build synthesize, is there a better version to fork for inclusion into the main branch?
  7. I have never tried the ISE editor, I use Altium at work. I'll have to give that a spin. Sweet! Thanks again. Rob
  8. Wow, that is going to make a very powerful prototyping system for the Papilio. I'm going to go read up on the Wishbone spec, should be fun to design a few wishbone peripherals. What software are you using for the schematic editor? Eagle? P.S. Do you have an ETA on when you might have more stock of the Arcade MegaWing? I'd really like to buy one
  9. Thank you for the kind words Jack. I'm Happy to share. The time you spent helping me out last week was very helpful, and really helped solidify the concepts I needed to do this. That small bit of time was very productive for me I'd be honored to have this included in the Github branch. I'm going to go read the tutorial now. I'm also thinking about porting this into the "shifty" branch. I need to study it a bit more first though. Rob P.S. I feel silly that I didn't think to zip the files up!
  10. An example of directly accessing the interrupt registers. #define PIN_IRQ_IN A4volatile unsigned int count = 0;void setup() { pinMode(PIN_IRQ_IN, INPUT); Serial.begin(9600); EIMSK |= (1 << INT4); // Enable external interrupt INT0 GICR //EICR |= (0 << ISC41) | (0 << ISC40); // Trigger INT4 on low level EICR |= (1 << ISC41) | (0 << ISC40); // Trigger INT4 on falling egde //EICR |= (1 << ISC41) | (1 << ISC40); // Trigger INT4 on rising edge}void loop() { Serial.print("Count ="); Serial.print(count); Serial.print("\r\n");}ISR(INT4_vect) { count++;} Ok, I think I'm done for the night.
  11. An example of using attachInterrupt function. Probably the minimal sketch to make interrupts work. #define PIN_IRQ_IN A4volatile unsigned int count = 0;void setup() { pinMode(PIN_IRQ_IN, INPUT); Serial.begin(9600); attachInterrupt(4, irqcount, LOW);}void loop() { Serial.print("Count ="); Serial.print(count); Serial.print("\r\n");}void irqcount(void) { count++;}
  12. Here is a debug sketch, for the irq controller. don't forget to set the board to the custom board. #define PIN_IRQ_IN A4volatile unsigned int count = 0;void setup() { pinMode(PIN_IRQ_IN, INPUT); Serial.begin(9600); attachInterrupt(4, irqcount, LOW);}void loop() { // get registers from core unsigned int EIMSK_TMP = EIMSK; unsigned int EIFR_TMP = EIFR; unsigned int EICR_TMP = EICR; Serial.print("EIMSK ="); Serial.print(EIMSK_TMP); Serial.print("\r\n"); Serial.print("EIFR ="); Serial.print(EIFR_TMP); Serial.print("\r\n"); Serial.print("EICR ="); Serial.print(EICR_TMP); Serial.print("\r\n"); Serial.print("Count ="); Serial.print(count); Serial.print("\r\n");}void irqcount(void) { count++;} this sketch is using interrupt 4 on pin 4 of port a. more sketches soon.
  13. Ok, back at it. One last change to the papilio-arduino code before we can run a sketch. In WInterrupts.c, find ATmega 103 section of the attachInterrupt function and change it to look like this: #elif defined(__AVR_ATmega103__) //interrupts 0 to 3 are level triggered (active low) and do not use the sense bits in EICR case 0: //EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT0); break; case 1: //EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); EIMSK |= (1 << INT1); break; case 2: //EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT2); break; case 3: //EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); EIMSK |= (1 << INT3); break; case 4: EICRA = (EICRA & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40); EIMSK |= (1 << INT4); break; case 5: EICRA = (EICRA & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50); EIMSK |= (1 << INT5); break; case 6: EICRA = (EICRA & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60); EIMSK |= (1 << INT6); break; case 7: EICRA = (EICRA & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70); EIMSK |= (1 << INT7); break; #else That will allow us to use the attachInterrupt function for our sketchs. I should explain that there are 8 total interrupts numbered 0 to 7. However, interrupts 0 to 3 do not have EICR bits and are therefore low level triggered only. Interrupts 4 to 7 do have EICR bits and can be triggered by low level, falling edge, or rising edge. Sketches soon...
  14. Part 4, pulling it all together. This part has a lot of small steps, I'm not going to try to explain them all in this post. If you have any questions just let me know. Step 1. Add the following line to the peripherial control settings in Papilio_AVR8.vhd: constant CImplExtIRQ : boolean := TRUE; --AVR8 Interrupt Unit You should have settings that look like this now: -- Use these setting to control which peripherals you want to include with your custom AVR8 implementation.constant CImplPORTA : boolean := TRUE; constant CImplPORTB : boolean := TRUE;constant CImplPORTC : boolean := TRUE;constant CImplPORTD : boolean := TRUE;constant CImplPORTE : boolean := TRUE;constant CImplPORTF : boolean := TRUE;constant CImplUART : boolean := TRUE; --AVR8 UART peripheralconstant CImplTmrCnt : boolean := TRUE; --AVR8 Timerconstant CImplExtIRQ : boolean := TRUE; --AVR8 Interrupt Unitconstant CImplpapilio_core_template : boolean := FALSE; --An example User Core, use this template to make your own custom peripherals. You DO NOT have to turn off any of the GPIO ports. the interrupt controller can be connected to any port and still have normal port operation. Step 2, Add some signal definitions to Papilio_AVR8.vhd (same file): -- Ext IRQ Controllersignal extirq_dbusout : std_logic_vector (7 downto 0);signal extirq_out_en : std_logic;signal ext_irqlines : std_logic_vector(7 downto 0); I added them around line 308, after the signals for the timer counter, but before signals for uart. -- Timer/Countersignal tc_dbusout : std_logic_vector (7 downto 0);signal tc_out_en : std_logic;-- Ext IRQ Controllersignal extirq_dbusout : std_logic_vector (7 downto 0);signal extirq_out_en : std_logic;signal ext_irqlines : std_logic_vector(7 downto 0);-- UARTsignal uart_dbusout : std_logic_vector (7 downto 0);signal uart_out_en : std_logic; Step 3: Free up interrupt lines. around line 379, after the user core comment the following two lines: core_irqlines(7 downto 4) <= ( others => '0');core_irqlines(3 downto 0) <= ( others => '0'); you should have this now: -- Unused IRQ lines--core_irqlines(7 downto 4) <= ( others => '0');--core_irqlines(3 downto 0) <= ( others => '0');core_irqlines(13 downto 10) <= ( others => '0');core_irqlines(16) <= '0';core_irqlines(22 downto 20) <= ( others => '0');-- ************************ Step 4: Free up output enable lines just under the IRQ lines are the enable lines you need to just change the 10 to an 11 in both lines. -- Unused out_enio_port_out_en(10 to 15) <= (others => '0');io_port_out(10 to 15) <= (others => (others => '0')); You should have this now: -- Unused out_enio_port_out_en(11 to 15) <= (others => '0');io_port_out(11 to 15) <= (others => (others => '0'));Step 5 Connect the IRQ controller to porta. Add this to the bottom of porta's port map irqlines => ext_irqlines Port A should look like this now: PORTA_COMP:component pport generic map(PPortNum => 0) port map( -- AVR Control ireset => core_ireset, cp2 => clk16M, -- clk, adr => core_adr, dbus_in => core_dbusout, dbus_out => porta_dbusout, iore => core_iore, iowe => core_iowe, out_en => porta_out_en, -- External connection portx => PortAReg, ddrx => DDRAReg, pinx => porta, irqlines => ext_irqlines);Step 6 clean up dangling lines on other ports. Add the following to the other port maps (all of the remaining ones, B - F) irqlines => open Port B - F should look like this now (except for the port letter) PORTB_Impl:if CImplPORTB generatePORTB_COMP:component pport generic map (PPortNum => 1) port map( -- AVR Control ireset => core_ireset, cp2 => clk16M, -- clk, adr => core_adr, dbus_in => core_dbusout, dbus_out => portb_dbusout, iore => core_iore, iowe => core_iowe, out_en => portb_out_en, -- External connection portx => PortBReg, ddrx => DDRBReg, pinx => portb, irqlines => open);Step 7: Add the port map for the interrupt controller. I added it after the last port and before the timer counter, around line 668. --****************** External IRQ Controller**************************ExtIRQ_Impl:if CImplExtIRQ generateExtIRQ_Inst:component ExtIRQ_Controller port map( -- AVR Control nReset => core_ireset, clk => clk16M, -- clk, clken => vcc, irq_clken => vcc, adr => core_adr, dbus_in => core_dbusout, dbus_out => extirq_dbusout, iore => core_iore, iowe => core_iowe, out_en => extirq_out_en, ------------------------------------------------ extpins => ext_irqlines, INTx => core_irqlines(7 downto 0)); -- ExtIRQ connection to the external multiplexer io_port_out(10) <= extirq_dbusout;io_port_out_en(10) <= extirq_out_en; end generate;That's it. save your work. Synthesize it, and copy it to the custom bit files. I'll upload some example sketches to run in a few, I've gotta take a break first though.
  15. Part 3: Add the new Interrupt controller vhd file: Step 1: Right click on your project and click add new source. I called the File ExtIRQ_Controller.vhd. Step 2: Add the following code to your new file. --**********************************************************************************************-- External Interrupt Controller Block Peripheral for the AVR Core-- Version 1.00-- Created 01.26.2013-- Designed by Rob Brown--**********************************************************************************************library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;use WORK.AVRuCPackage.all;entity ExtIRQ_Controller is Port( -- begin Signals required by AVR8 for this core, do not modify. nReset : in STD_LOGIC; clk : in STD_LOGIC; adr : in STD_LOGIC_VECTOR (15 downto 0); dbus_in : in STD_LOGIC_VECTOR (7 downto 0); dbus_out : out STD_LOGIC_VECTOR (7 downto 0); iore : in STD_LOGIC; iowe : in STD_LOGIC; out_en : out STD_LOGIC; -- end Signals required by AVR8 for this core, do not modify. clken : in STD_LOGIC; irq_clken : in STD_LOGIC; extpins : in STD_LOGIC_VECTOR(7 downto 0); INTx : out STD_LOGIC_VECTOR(7 downto 0) );end ExtIRQ_Controller;-----------------------------------------------------------------------architecture Behavioral of ExtIRQ_Controller is-- Registerssignal EIMSK : std_logic_vector(7 downto 0);signal EIFR : std_logic_vector(7 downto 0);signal EICR : std_logic_vector(7 downto 0);-- EIMSK Bitsalias INT0 : std_logic is EIMSK(0);alias INT1 : std_logic is EIMSK(1);alias INT2 : std_logic is EIMSK(2);alias INT3 : std_logic is EIMSK(3);alias INT4 : std_logic is EIMSK(4);alias INT5 : std_logic is EIMSK(5);alias INT6 : std_logic is EIMSK(6);alias INT7 : std_logic is EIMSK(7);-- EIFR Bitsalias INTF0 : std_logic is EIFR(0);alias INTF1 : std_logic is EIFR(1);alias INTF2 : std_logic is EIFR(2);alias INTF3 : std_logic is EIFR(3);alias INTF4 : std_logic is EIFR(4);alias INTF5 : std_logic is EIFR(5);alias INTF6 : std_logic is EIFR(6);alias INTF7 : std_logic is EIFR(7); -- EICR Bitsalias ISC40 : std_logic is EICR(0);alias ISC41 : std_logic is EICR(1);alias ISC50 : std_logic is EICR(2);alias ISC51 : std_logic is EICR(3);alias ISC60 : std_logic is EICR(4);alias ISC61 : std_logic is EICR(5);alias ISC70 : std_logic is EICR(6);alias ISC71 : std_logic is EICR(7); -- Risign/falling edge detectors signal INTxRE : std_logic_vector (7 downto 0); -- Rising edge of external input INTxsignal INTxFE : std_logic_vector (7 downto 0); -- Falling edge of external input INT0signal INTxLatched : std_logic_vector (7 downto 0); -- Synchronizer signalssignal INTxSA : std_logic_vector (7 downto 0);signal INTxSB : std_logic_vector (7 downto 0); -- Output of the synchronizer for INTxsignal TRGR : std_logic_vector(7 downto 0);--constant EIMSK_Address : std_logic_vector(IOAdrWidth-1 downto 0) := CAVRIOAdr(16#39#);--constant EIFR_Address : std_logic_vector(IOAdrWidth-1 downto 0) := CAVRIOAdr(16#38#);--constant EICR_Address : std_logic_vector(IOAdrWidth-1 downto 0) := CAVRIOAdr(16#3A#);begin-- SynchronizersSyncDFFs:process(clk,nReset) begin if (nReset='0') then -- Reset INTxSA <= (others => '0'); INTxSB <= (others => '0'); elsif (clk='1' and clk'event) then -- Clock if (irq_clken='1') then -- Clock Enable(Note 2) INTxSA <= extpins; INTxSB <= INTxSA; end if; end if; end process;-- Edge Detectoredge_detect:for i in INTxSB'range generate INTxRE(i) <= (not INTxSB(i) and extpins(i)); INTxFE(i) <= (INTxSB(i) and not extpins(i)); INTxLatched(i) <= INTxSB(i);end generate;-- Interrupt ProcessINT_Proc:process(clk,nReset)begin if (nReset='0') then INTx(3 downto 0) <= (others => '0'); elsif (clk='1' and clk'event) then if (clken='1') then -- Clock Enable -- interrupts 0 through 3 do not set their corresponding EIFR flag! See Atmega103 Data Sheet top of page 31. -- these four interrupts also do not use EICR bits. They are always level triggered, active low. TRGR(0) <= (INT0 and not INTxLatched(0)); TRGR(1) <= (INT1 and not INTxLatched(1)); TRGR(2) <= (INT2 and not INTxLatched(2)); TRGR(3) <= (INT3 and not INTxLatched(3)); -- interrupts 4 through 7's triggers are sensitive to EICR bits -- 00 low level trigger, 10 falling edge trigger, 11 rising edge trigger, 01 is reserved. -- See Atmega103 Data Sheet page 30 and 31. TRGR(4) <= (INT4 and ((not ISC41 and not ISC40 and not INTxLatched(4)) or (ISC41 and not ISC40 and INTxFE(4)) or (ISC41 and ISC40 and INTxRE(4)))); TRGR(5) <= (INT5 and ((not ISC51 and not ISC50 and not INTxLatched(5)) or (ISC51 and not ISC50 and INTxFE(5)) or (ISC51 and ISC50 and INTxRE(5)))); TRGR(6) <= (INT6 and ((not ISC61 and not ISC60 and not INTxLatched(6)) or (ISC61 and not ISC60 and INTxFE(6)) or (ISC61 and ISC60 and INTxRE(6)))); TRGR(7) <= (INT7 and ((not ISC71 and not ISC70 and not INTxLatched(7)) or (ISC71 and not ISC70 and INTxFE(7)) or (ISC71 and ISC70 and INTxRE(7)))); INTx <= TRGR; end if; end if; end process;-- Write EIMSK bitsEIMSK_Bits:process(clk,nReset)begin if (nReset='0') then EIMSK <= (others => '0'); elsif (clk='1' and clk'event) then if (clken='1') then -- Clock Enable if (adr=EIMSK_Address and iowe='1') then EIMSK <= dbus_in; end if; end if; end if; end process;-- Write EIFR bitsEIFR_Bits:process(clk,nReset)begin if (nReset='0') then EIFR <= (others => '0'); elsif (clk='1' and clk'event) then if (clken='1') then -- Clock Enable if (adr=EIFR_Address and iowe='1') then EIFR(7 downto 4) <= dbus_in(7 downto 4); EIFR(3 downto 0) <= "0000"; -- in Atmega103, these bits are reserved and always read '0', See Atmega103 Data Sheet top of page 31. else EIFR(7 downto 4) <= TRGR(7 downto 4); EIFR(3 downto 0) <= "0000"; -- in Atmega103, these bits are reserved and always read '0', See Atmega103 Data Sheet top of page 31. end if; end if; end if; end process;-- Write EICR bitsEICR_Bits:process(clk,nReset)begin if (nReset='0') then EICR <= (others => '0'); elsif (clk='1' and clk'event) then if (clken='1') then -- Clock Enable if (adr=EICR_Address and iowe='1') then EICR <= dbus_in; end if; end if; end if; end process;-- Output Enable out_en <= '1' when ((adr=EIMSK_Address or adr=EIFR_Address or adr=EICR_Address) and iore='1') else '0'; -- Read register dbus_out <= EIMSK when (adr=EIMSK_Address) else EIFR when (adr=EIFR_Address) else EICR when (adr=EICR_Address) else "ZZZZZZZZ"; end Behavioral; Save your work, that's it for part 3.