Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 5 FirstFirst 1 2 3 4 5 LastLast
Results 51 to 75 of 110

Thread: Teensyduino 1.48 Beta #1

  1. #51
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,967
    @Paul:

    Did the Arduino folks somehow cause a break in this "Multiple libraries were found for" code in 1.8.10??

    Multiple libraries were found for "SerialFlash.h"
    Used: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/SerialFlash
    Multiple libraries were found for "Audio.h"
    Used: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Audio
    Multiple libraries were found for "Wire.h"
    Used: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Wire
    Multiple libraries were found for "SPI.h"
    Used: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/SPI
    Multiple libraries were found for "SD.h"
    Used: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/SD
    It triggers that often and only shows a single library name.

    pbgbg

  2. #52
    With USB Print Test on ManPro trashcan 12 core, 10.14.5:

    Arduino serial monitor
    =================
    210,000 - 250,000. Mostly down the lower end.

    Kernel Task : 185%
    teensy_serialmon: 65%
    Arduino: 37%
    Window Server: 15%


    cat /dev/cu.usbmodem61562001
    =========================
    240,000 - 250,000.

    Kernel Task: 200%
    Terminal : 60%

    Hangs after a few secs, Kernel Task stays at 130% until cat stopped


    screen /dev/cu.usbmodem61562001
    ============================
    240,000 - 250,000.

    Kernel Task: 200%
    Terminal : 110%
    Screen : 85%


    So pretty high CPU here but the Serial monitor and screen command seem to run fine.


    Edit: Looking into the hang here I knocked up some FILE* code here and get the hang, breaking into the debugger it is in __read_nocancel, interestingly continuing the debugger "fixes" the issue. Until the next time...

    Edit2: Using open(), read() with O_NONBLOCK gets rid of the hang.
    Last edited by AndyCap; 09-21-2019 at 09:52 AM.

  3. #53
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,591
    @bicycleguy - Yep it appears to crash hard...

    I mucked up the Setup function to output stuff to Serial port and I get nothing.
    Code:
    void setup() {
      // Backlight
    #if 0
      pinMode( BACKLIGHT_PIN, OUTPUT );
      analogWrite( BACKLIGHT_PIN, 1023 );
    #endif
      while(!Serial && millis() < 5000) ;
      Serial.begin(115200);
      Serial.println("Start DemoSouce");
      
      // Microphone
      pinMode( MIC_PIN, INPUT );
      Serial.println("Before TFT begin");
      delay(1000);
      tft.begin();
      Serial.println("After TFT begin"); Serial.flush();
      tft.setRotation( 3 );
      Serial.println("After Set Rotation"); Serial.flush();
      tft.fillScreen(ILI9341_BLACK);
      Serial.println("After fillScreen"); Serial.flush();
      delay(1000);
      // Serial
      if( DO_BENCHMARKS ) {
    ...
    And as you said it does run on 1.8.9, the only mod I did there, was to add the reset pin for tft on the constructor, in this case pin 8...

    @PaulStoffregen - This looks like another case where the setup is not being called. Not sure if it is hanging in some constructors code or even earlier... I may not have time until Monday or Tuesday to take a look.

    Kurt

  4. #54
    Senior Member
    Join Date
    Dec 2015
    Location
    LA
    Posts
    133
    @Kurt,
    Thanks, thought I was being ignored. But wait !! Another clue !!

    DemoSauce.ino runs on 1.8.10 if I set optimize to "Smallest Code" !

    This also makes the rest of my programs work that use the audioboard & its SD, and ILI9341_t3 together.

    Also realized that a bare T4 can be used for testing this issue, the LED flickers(SCK) and the terminal stays connected means it probably works, otherwise no LED and offline.

    Maybe not size related as the Teensy_Convolution_SDR works and it uses 242,064 bytes program and 430368 ram.
    Last edited by bicycleguy; 09-21-2019 at 04:32 PM.

  5. #55
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,591
    @bicycleguy - Sorry, sometimes hard for us who try to help out for the heck of it to see everything going on... As I mentioned, I don't have much time this weekend...

    Also this looks like a long list of things for @PaulStoffregen to look at, as it appears to be another screwy compile or link or load or??? That is if you turn on debug printing.
    (printf.h un-comment the #define PRINT_DEBUG_STUFF

    Then rebuilt... Not for sure that was enough or not, but I then also uncommented some comments in startup.c and hooked up debug cable to Serial4, and I got all of the debug output and started getting info out over USB... And then hooked up display again and it was working...

  6. #56
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    @KurtE @bicycleguy

    Well here is something else. I just tried demosauce with ILI9341_t3n and it crashes the same way. This is reminds me of the problem we were having with uncanny eyes as well.

    Can confirm using smallest code also seems to fix the problem using the ILI9341_t3n library as well. Other optimizations hang the code as well. Good catch @bicycleguy

    UPDATE: Same occurs with the ILI9488_t3 display
    Last edited by mjs513; 09-21-2019 at 04:59 PM.

  7. #57
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    Quote Originally Posted by KurtE View Post
    @bicycleguy - Sorry, sometimes hard for us who try to help out for the heck of it to see everything going on... As I mentioned, I don't have much time this weekend...

    Also this looks like a long list of things for @PaulStoffregen to look at, as it appears to be another screwy compile or link or load or??? That is if you turn on debug printing.
    (printf.h un-comment the #define PRINT_DEBUG_STUFF

    Then rebuilt... Not for sure that was enough or not, but I then also uncommented some comments in startup.c and hooked up debug cable to Serial4, and I got all of the debug output and started getting info out over USB... And then hooked up display again and it was working...
    @KurtE
    Tried to just un-comment the #define PRINT_DEBUG_STUFF and recompiled but demosauce still hung the T4. Maybe something else you un-commented?

  8. #58
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,591
    Some of the ones in startup.c like all the ones up to before and after call to setup

    Sorry I am not at my computer so can not give much more info

    Edit also remember I added prints in the sketch as I mentioned earlier.
    Last edited by KurtE; 09-21-2019 at 06:16 PM.

  9. #59
    Senior Member
    Join Date
    Dec 2015
    Location
    LA
    Posts
    133
    Commenting out the differences in startup.c between 1.8.9 and 1.8.10 seems to fix the problem.
    Click image for larger version. 

Name:	Screen Shot 2019-09-21 at 11.12.12 AM.jpg 
Views:	27 
Size:	97.2 KB 
ID:	17665
    No idea what it's meant to do or any other effects.

  10. #60
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,591
    @paul did that change 8 days ago to fix some issue of >2 interval timers...

    Not sure of its implications

  11. #61
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,233
    Quote Originally Posted by bicycleguy View Post
    Commenting out the differences in startup.c between 1.8.9 and 1.8.10 seems to fix the problem.
    Click image for larger version. 

Name:	Screen Shot 2019-09-21 at 11.12.12 AM.jpg 
Views:	27 
Size:	97.2 KB 
ID:	17665
    No idea what it's meant to do or any other effects.
    here is discussion associated with PIT changes in startup.c
    https://forum.pjrc.com/threads/57360...annels-Problem

    you could try adding line to turn PIT off
    Code:
      CCM_CCGR1 |= CCM_CCGR1_PIT(CCM_CCGR_ON);
      PIT_TCTRL0 = 0;
      PIT_TCTRL1 = 0;
      PIT_TCTRL2 = 0;
      PIT_TCTRL3 = 0;
      CCM_CCGR1 &= ~CCM_CCGR1_PIT(CCM_CCGR_ON);   //optional

  12. #62
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    Interesting --- just commenting out those lines and it still hanging on my T4. I am using pins 9-13, don't have anything else attached.

    EDIT: went back to 1.8.9 IDE with 1.47b5 and its still doing the same thing. 1,8.8 with TD1.45 same thing with the ILI9431_t3 lib. Guess maybe try t3n.
    Last edited by mjs513; 09-21-2019 at 08:01 PM.

  13. #63
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,233
    OK, i'm not sure i know how you guys are testing, but here is what i did on my linux64 box. installed 1.8.10 and 1.48-beta1, and ran a T4 intervaltimer sketch to verify i could get all 4 channels. OK. Then ran example DemoSauce from ILI9341_t3 lib ... production T4 froze (no ttyACM0), had to hit program button to load a new sketch.

    Went to startup.c and ifdef'd out newly added PIT lines. confirmed intervaltimer now only had 2 channels. DemoSauce now worked. (it printed something on monitor "TwistyText" ... -- i have nothing connectd to T4). I then re-enabled PIT lines in startup.c BUT commented out PIT_MCR =0; and now intervaltimer had 4 channels AND DemoSauce was working. Can someone else try that. PIT_MCR=0 actually enables PIT timer. That wasn't in my suggested fix discussed in
    https://forum.pjrc.com/threads/57360...annels-Problem
    Paul added that in his core update. Setting PIT_MCR to 0 actually enables the PIT timer, which I don't think you want to do. POR reset value is 2 for PIT_MCR.

    can someone else try commenting out PIT_MCR = 0;

    Not sure why that should make a difference -- i think ROM bootloader had PIT configured as free-running 64-bit timer, but i'm only guessin.

  14. #64
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    Quote Originally Posted by manitou View Post
    OK, i'm not sure i know how you guys are testing, but here is what i did on my linux64 box. installed 1.8.10 and 1.48-beta1, and ran a T4 intervaltimer sketch to verify i could get all 4 channels. OK. Then ran example DemoSauce from ILI9341_t3 lib ... production T4 froze (no ttyACM0), had to hit program button to load a new sketch.

    Went to startup.c and ifdef'd out newly added PIT lines. confirmed intervaltimer now only had 2 channels. DemoSauce now worked. (it printed something on monitor "TwistyText" ... -- i have nothing connectd to T4). I then re-enabled PIT lines in startup.c BUT commented out PIT_MCR =0; and now intervaltimer had 4 channels AND DemoSauce was working. Can someone else try that. PIT_MCR=0 actually enables PIT timer. That wasn't in my suggested fix discussed in
    https://forum.pjrc.com/threads/57360...annels-Problem
    Paul added that in his core update. Setting PIT_MCR to 0 actually enables the PIT timer, which I don't think you want to do. POR reset value is 2 for PIT_MCR.

    can someone else try commenting out PIT_MCR = 0;

    Not sure why that should make a difference -- i think ROM bootloader had PIT configured as free-running 64-bit timer, but i'm only guessin.
    @manitou

    I just reinstalled TD1.48beta1 and the ILI9341_t3 library. I then commented out PIT_MCR = 0; and it worked without issue. So the fix is exactly as you described to turn off the timer.

  15. #65
    Junior Member
    Join Date
    Jul 2013
    Posts
    19
    I've been following this and thread since I was hoping I had a similar problem. Unfortunately, that isn't the case, yet. When I set up the interval timer, I am only getting it to fire once. The code I am trying to use works on T3.2, T3.5, and T3.6 with minor timing tweaks between them, but not yet on the T4. Maybe someone in this thread can help? I can also start a new thread if needed.

    My problem occurred when I tried to update my Commodore 6581 (SID) player to use a T4.

    https://forum.pjrc.com/threads/42587...?highlight=SID

    I need a 1MHz clock and a timed chip select that lines up with the clock's rising edge and doesn't "walk" away from the clock between SID writes. That looks like the following:

    Click image for larger version. 

Name:	IMG_2569.JPG 
Views:	8 
Size:	120.9 KB 
ID:	17666

    The code needed to do this on previous Teensys is this:

    Code:
    #define CLK 4
    #define CS1 3
    #define NOP __asm__("nop\n\t")
    
    
    
    volatile long timetonext;
    volatile byte dataavailable;
    volatile unsigned long cycles_per_us;
    
    static inline void delayCycles(uint32_t cycles)
    { // MIN return in 7 cycles NEAR 20 cycles it gives wait +/- 2 cycles - with sketch timing overhead
      uint32_t begin = ARM_DWT_CYCCNT - 12; // Overhead Factor for execution
      while (ARM_DWT_CYCCNT - begin < cycles) ; // wait
    }
    
      
    IntervalTimer myTimer;
    
    void setup() {
      Serial.begin(115200);
      pinMode(CLK, OUTPUT);
      digitalWrite(CLK, HIGH);
      pinMode(CS1, OUTPUT);
      digitalWrite(CS1, HIGH);
    
    
      analogWriteFrequency(CLK, 1000000);               // set clock frequency to 1MHz
      analogWriteResolution(5);                         // PWM resolution
      analogWrite(CLK, 15);                             // PWM dutycycle
    
    
      myTimer.begin(DATA, 10);
      //myTimer.priority(64);
      cycles_per_us = F_BUS_ACTUAL / 1000000;
    }
    
    FASTRUN void loop() {                               
       while (1) {
        timetonext = 3;                                  //Change this to vary the number of CLK pulses between CS1 pulses                                   
        dataavailable = 1;
        PIT_LDVAL0 = timetonext * cycles_per_us - 1;     // reset the PIT timer in myTimer to the delay until the next write
        while (dataavailable == 1) {}                    // wait for myTimer to fire interrupt
      }
    }
    
    FASTRUN void DATA(void)
    {
      if (dataavailable >= 1) {
     
        digitalWriteFast(CS1, LOW);
    
        // 200ns Pulse on Teensy 4 @ 600MHz
        delayCycles(45);
     
        dataavailable = 0;
        digitalWriteFast(CS1, HIGH);
      }
    }
    The variable "timetonext" is the number of microseconds to wait before firing the interrupt and can be any number between 0 and 65535. I used PIT_LDVAL0 to change the start of the timer on the fly and it worked very well. Also, don't worry if the chip select doesn't line up with the clock in the example since that can be fixed with different amounts of delayCycles either in the interrupt routine or the main routine.

    Any ideas?

    David

  16. #66
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,233
    Quote Originally Posted by Dave47 View Post

    The variable "timetonext" is the number of microseconds to wait before firing the interrupt and can be any number between 0 and 65535. I used PIT_LDVAL0 to change the start of the timer on the fly and it worked very well. Also, don't worry if the chip select doesn't line up with the clock in the example since that can be fixed with different amounts of delayCycles either in the interrupt routine or the main routine.

    Any ideas?

    David
    you probably should start a new thread, BUT one problem you have is using F_BUS_ACTUAL. The PIT timer for IntervalTimer runs at 24MHz, not F_BUS_ACTUAL

    EDIT:
    also if you are not running 1.48-beta1, the first PIT channel you get for IntervalTimer is channel 2, so you need to use PIT_LDVAL2
    Last edited by manitou; 09-21-2019 at 11:42 PM.

  17. #67
    Junior Member
    Join Date
    Jul 2013
    Posts
    19
    Quote Originally Posted by manitou View Post
    you probably should start a new thread, BUT one problem you have is using F_BUS_ACTUAL. The PIT timer for IntervalTimer runs at 24MHz, not F_BUS_ACTUAL
    I will make note of that. I was using F_BUS for the previous Teensys, so I just updated when I got an error at compile time.




    Quote Originally Posted by manitou View Post
    EDIT:
    also if you are not running 1.48-beta1, the first PIT channel you get for IntervalTimer is channel 2, so you need to use PIT_LDVAL2
    I am using 1.48-beta1 at the moment. I got the disconnect/lockup behavior in 1.48. That was why I wondered if I should post in this thread or not. Can a mod move these to a new thread?

    David

  18. #68
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,967
    If you want to create a new thread it can get copied over to there yes

  19. #69
    Junior Member
    Join Date
    Jul 2013
    Posts
    19
    Quote Originally Posted by defragster View Post
    If you want to create a new thread it can get copied over to there yes
    Done! new thread is here...

    https://forum.pjrc.com/threads/57693...-on-a-Teensy-4

    David

  20. #70
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,967
    Seems you got the post copied over.

  21. #71
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,233
    Quote Originally Posted by mjs513 View Post
    @manitou

    I just reinstalled TD1.48beta1 and the ILI9341_t3 library. I then commented out PIT_MCR = 0; and it worked without issue. So the fix is exactly as you described to turn off the timer.
    Another observation: If i move the new PIT init code in startup.c to after the RTC initialization, the DemoSauce example works even with PIT_MCR = 0. I also modified startup.c in 1.8.8 with 1.47. The results were the same -- either remove PIT_MCR = 0, or move the PIT init code to after the RTC init sequence, e.g. after SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;

    strange

  22. #72
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    Quote Originally Posted by manitou View Post
    Another observation: If i move the new PIT init code in startup.c to after the RTC initialization, the DemoSauce example works even with PIT_MCR = 0. I also modified startup.c in 1.8.8 with 1.47. The results were the same -- either remove PIT_MCR = 0, or move the PIT init code to after the RTC init sequence, e.g. after SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;

    strange
    I just gave it a try and works even if you move it right after setArmClock and before the SNVS code block. Maybe not so strange to set the sys clocks first then set the PIT?

  23. #73
    Senior Member
    Join Date
    Dec 2015
    Location
    LA
    Posts
    133
    Quote Originally Posted by manitou View Post
    ...
    can someone else try commenting out PIT_MCR = 0;

    Not sure why that should make a difference -- i think ROM bootloader had PIT configured as free-running 64-bit timer, but i'm only guessin.
    works for me on a Mac also.

    thanks

  24. #74
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,967
    Quote Originally Posted by mjs513 View Post
    I just gave it a try and works even if you move it right after setArmClock and before the SNVS code block. Maybe not so strange to set the sys clocks first then set the PIT?
    Having the clocks going first makes sense - @mjs513 - can you post the complete few lines to put after setArmClock()? I keep seeing ref to a line I don't see in what was posted … don't see a pull request for the code

  25. #75
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,220
    Quote Originally Posted by defragster View Post
    Having the clocks going first makes sense - @mjs513 - can you post the complete few lines to put after setArmClock()? I keep seeing ref to a line I don't see in what was posted … don't see a pull request for the code
    This is the entire function:
    Code:
    void ResetHandler(void)
    {
    	unsigned int i;
    
    #if defined(__IMXRT1062__)
    	IOMUXC_GPR_GPR17 = (uint32_t)&_flexram_bank_config;
    	IOMUXC_GPR_GPR16 = 0x00000007;
    	IOMUXC_GPR_GPR14 = 0x00AA0000;
    	__asm__ volatile("mov sp, %0" : : "r" ((uint32_t)&_estack) : );
    #endif
    	// pin 13 - if startup crashes, use this to turn on the LED early for troubleshooting
    	//IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 5;
    	//IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(7);
    	//IOMUXC_GPR_GPR27 = 0xFFFFFFFF;
    	//GPIO7_GDIR |= (1<<3);
    	//GPIO7_DR_SET = (1<<3); // digitalWrite(13, HIGH);
    
    	// Initialize memory
    	memory_copy(&_stext, &_stextload, &_etext);
    	memory_copy(&_sdata, &_sdataload, &_edata);
    	memory_clear(&_sbss, &_ebss);
    
    	// enable FPU
    	SCB_CPACR = 0x00F00000;
    
    	// set up blank interrupt & exception vector table
    	for (i=0; i < NVIC_NUM_INTERRUPTS + 16; i++) _VectorsRam[i] = &unused_interrupt_vector;
    	for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
    	SCB_VTOR = (uint32_t)_VectorsRam;
    
    	reset_PFD();
    	
    	// Configure clocks
    	// TODO: make sure all affected peripherals are turned off!
    	// PIT & GPT timers to run from 24 MHz clock (independent of CPU speed)
    	CCM_CSCMR1 = (CCM_CSCMR1 & ~CCM_CSCMR1_PERCLK_PODF(0x3F)) | CCM_CSCMR1_PERCLK_CLK_SEL;
    	// UARTs run from 24 MHz clock (works if PLL3 off or bypassed)
    	CCM_CSCDR1 = (CCM_CSCDR1 & ~CCM_CSCDR1_UART_CLK_PODF(0x3F)) | CCM_CSCDR1_UART_CLK_SEL;
    
    #if defined(__IMXRT1062__)
    	// Use fast GPIO6, GPIO7, GPIO8, GPIO9
    	IOMUXC_GPR_GPR26 = 0xFFFFFFFF;
    	IOMUXC_GPR_GPR27 = 0xFFFFFFFF;
    	IOMUXC_GPR_GPR28 = 0xFFFFFFFF;
    	IOMUXC_GPR_GPR29 = 0xFFFFFFFF;
    #endif
    
    	// must enable PRINT_DEBUG_STUFF in debug/print.h
    	printf_debug_init();
    	printf("\n***********IMXRT Startup**********\n");
    	printf("test %d %d %d\n", 1, -1234567, 3);
    
    	configure_cache();
    	configure_systick();
    	usb_pll_start();	
    	reset_PFD(); //TODO: is this really needed?
    	
    	set_arm_clock(600000000);
    	//set_arm_clock(984000000); Ludicrous Speed
    
    	// Undo PIT timer usage by ROM startup
    	CCM_CCGR1 |= CCM_CCGR1_PIT(CCM_CCGR_ON);
    	PIT_MCR = 0;
    	PIT_TCTRL0 = 0;
    	PIT_TCTRL1 = 0;
    	PIT_TCTRL2 = 0;
    	PIT_TCTRL3 = 0;
    	
    	// initialize RTC
    	if (!(SNVS_LPCR & SNVS_LPCR_SRTC_ENV)) {
    		// if SRTC isn't running, start it with default Jan 1, 2019
    		SNVS_LPSRTCLR = 1546300800u << 15;
    		SNVS_LPSRTCMR = 1546300800u >> 17;
    		SNVS_LPCR |= SNVS_LPCR_SRTC_ENV;
    	}
    	SNVS_HPCR |= SNVS_HPCR_RTC_EN | SNVS_HPCR_HP_TS;
    
    	while (millis() < 20) ; // wait at least 20ms before starting USB
    	usb_init();
    	analog_init();
    	pwm_init();
    	tempmon_init();
    
    	while (millis() < 300) ; // wait at least 300ms before calling user code
    	//printf("before C++ constructors\n");
    	__libc_init_array();
    	//printf("after C++ constructors\n");
    	//printf("before setup\n");
    	setup();
    	//printf("after setup\n");
    	while (1) {
    		//printf("loop\n");
    		loop();
    		yield();
    	}
    }

Posting Permissions

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