Open Zaltora opened 6 years ago
I use uart_getc_nowait(bus)
.
I try to checkout old commit 3 month ago, but i got same problem. The good program was made 19 feb 2018.
I don't no what happens.
Okay, i was wrong. Is not uart problem, it is the filesystem spiffs/ libc API when a save or close file. Each time a file is saved, the pwm is disturbed. Maybe the FLASH acces.
Interrupts are disabled while accessing the flash, for reading or writing. This is necessary because code can not be run from the flash while accessing it. Writing might be especially slow and could this cause the pwm problems? The extras/pwm implementation appears to use an interrupt that would be disabled.
It might be possible to run the pwm from a NMI. All the code in the interrupt handler would need to be in the IRAM. Never tried this, but perhaps sdk_wDev_MacTimSetFunc
and sdk_wDev_MacTimArm
or sdk_wDev_MacTim1SetFunc
and sdk_wDev_MacTim1Arm
could be used for the pwm timer?? These appears to generate NMIs. The sdk_wDev_MacTim1Arm
appears to be used for a soft wdt, so perhaps try the other.
Also saw some discussion that the esp8266 might have a hardware pwm, and perhaps support could be added for that. For example, see https://github.com/esp8266/Arduino/issues/1654 Does anyone know or a hardware pwm implementation?
Fwiw the hardware pwm seems to work, and the registers appear to be already defined. Where this were adequate it might be smoother than a software pwm and less burden on the system. The example below could dim the blue led on a nodemcu. If someone could confirm the frequency and duty calculations then we could add a description to gpio_regs.h and perhaps even some supporting functions and an example.
uint8_t gpio_num = 2; // Blue led
gpio_enable(gpio_num, GPIO_OUTPUT);
GPIO.CONF[gpio_num] |= GPIO_CONF_SOURCE_PWM;
// Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128)
// Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256)
uint8_t prescale = 0xff;
uint8_t duty = 32;
GPIO.PWM = GPIO_PWM_ENABLE | (prescale << 16) | duty;
o yeah, That will be nice to get this HW pwm !! I will try this. I a mreally surprise to learn today that exist this HW pwm.
Before, i was trying to work with overlap SPI without succes to connect the flash SPI wire with my screen. I am no sure if it is possible to put esp8266 in SPI slave mode too.
Edit: the resolution is 256 ? or it can be greater ?
Wow @ourairquality, where did you learn about this HW PWM capability? I thought there wasn't one. So is this really different from the HW delta-sigma modulator that has been known to exists? Do you know if it supports multiple channels?
@flannelhead The definitions were already in the include files, and it is described there as a PWM. I think this is the sigma-delta modulator. It seems to support only one channel, but it seems possible to route that one channel to all of gpio 0 to 15. It does appear to be limited to a resolution of 256. So it is limited, but still it might suit some uses and be smoother and less burden than the software solutions. If the name 'PWM' is misleading then perhaps we should rename the definitions in the include file, and we need to confirm and documentation the frequency and duty cycle.
@Zaltora Can this PWM address your use case? If not then have you tried using the NMI timer? I could try to write an example if needed?
I'm not 100% positive what you are referring to, but I believe this is Espressif's implementation of their software PWM. The most noticable issue is that it does not work well on 100% duty. Hardware PWM is available in ESP32 though.
i had begin to write a HW PWM driver with same API that SOFT PWM driver.
If 100% duty don't work well, it is doesn't matter. like soft pwm, the pin will be set as output at level high.
After looking register definition, i found that the correct setting for PWM is :
GPIO.PWM = GPIO_PWM_ENABLE | (prescale << 8) | duty;
I can't confirm this:
// Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128)
// Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256)
I don't no how set the variable "target". We got just a prescale in register definition. After test, i can change duty from 0(0%) to 127(100%) for my motor. I think the problem is the frequency. It is too high. With a prescale of 0, my motor can just be on or off.
@ourairquality : I can't use this HW PWM for my app. I need more precision on duty. I didn't test NMI yet, i don't no what i need to change. My first thought was to use sdk_wDev_MacTimSetFunc
and call the interupt handler. i don't no if i need to disable thing related to Timer1 or it is just a way to tell the system that this function will be masked ?
Hi i got a recent bug, It is feel that receive UART interrupt > Timer1 interrupt. The motor is disrupting when i wrote on keyboard some text. Before, this problem was not present. I try to found what PR or sub-module does this bug. recent "lock" change maybe ? It is not a HW bug, and i didn't change the uart part of my app.