From the schematic, it looks like pins IO3, IO[7:6], snf IO[11:9] can be used as PWM. I would suspect that the developers of the Intel Arduino stack have it set up such that if you use the analogWrite() function, it'll set the muxes up behind the scenes and program the PWM. Keep in mind, though, that PWM in general is about changing the duty-cycle of the square wave to vary how much power is being delivered to the load. The frequency stays constant. In Arduino, I don't believe you have the ability to specify what the actual PWM frequency is, just the duty cycle. On an AVR, the underlying hardware can be programmed such that you can approximate various frequencies (and also specify the duty cycle). But that is, of course, specific to that architecture.
The Galileo boards provide GPIO via a Cypress 40-bit I/O expander (CY8C9540A, datasheet at http://www.cypress.com/?docID=31413). The Galileo Board User's Guide says it's on the I2C bus at address 0x21 with its EEPROM at 0x51. If you pulled J2 on the board, the addresses change to 0x20 and 0x50. Pages 12 and 13 in the Cypress datasheet has the registers that you're going to want to be writing via I2C. Use the Arduino 'Wire' library to send the commands to the Cypress part to program PWM directly.
Is there any reason why you cannot use one of the PWM pins? That would give you a square wave with very precise control over frequency and duty cycle.
Using a loop inside a sketch is going to give you significant jitter and non-deterministic timing at best.
Additionally, you can program the PWM fully from within arduino by sending commands to the file system.
Have you tried the steps described in the Sergey’s Blog for the PWM enabling and setting parameters?
In the section Pulse-Width Modulation you can find a description about how to set up period and duty cycle, but as stated above, only on PWM pins
To setup a 100,000 nS Period with 50000 nS duty cycle on pin 9 from within a sketch it would look something like this : (typed in the blind)
system("echo -n \"1\" >/sys/class/pwm/pwmchip0/export");
system("echo -n \"100000\" >/sys/class/pwm/pwmchip0/pwm1/period");
system("echo -n \"50000\" >/sys/class/pwm/pwmchip0/pwm1/duty_cycle");
system("echo -n \"1\" >/sys/class/pwm/pwmchip0/pwm1/enable");
What are those sys nodes pointing at? If it's the CY8C9540A on the board, I don't think that'll work. According to the datasheet, the shortest period you can program the PWM output to is ~42nS (by setting the PWM clock source to 24mHz). Next shortest is 667nS (PWM clock @ 1.5mHz). Past that, you have a little bit of granularity by dividing down the 93.75kHz clock with an 8-bit value (t_min = ~10uS, t_max = 2.72ms). The period register (2ah) isn't setting the period of the PWM output, at least not directly. If I'm reading it correctly, it's the period of the PWM counter. Each tick of your PWM input clock (or divided down 93.75kHz clock), it increments with the PWM output period being the value in the register scaled by the period of your input clock.
All the registers in the CY8C9540A are 8-bit, so I'm assuming the sys interface is doing the required math try to convert the period/duty cycle values. However, the datasheet doesn't look like it supports the fine-grained frequency and duty cycle selection from your example. Really, a PWM isn't going to be as flexible as he likely wants for generating arbitrary square waves. Although looking up at his original question, it looks like he was driving a stepper motor. Given that, I'm guessing that specific frequency isn't as critical as long as it's in the range the motor can accept.
Oren, what model of motor are you trying to drive with the PWM pin?
Hi, thanks for all the answers, but for now none of them are working.
I am trying to drive a step motor using an RMS R208 microstep driver - http://www.rmsmotion.com/ecart/part_detail.aspx?catID=1&partID=13 .
From testing the driver with a function generator, we see that it responds best to square waves waves of frequencies between about 600-900 [HZ], and would like to output these frequencies with the Galileo board. We have been trying to program specific frequencies to the PWM pins, but have not been able to so far. If we were using a different Arduino chip that supported all the available libraries, it wouldn't be a problem as there are several libraries that can help do that (the Tone library, for instance). However, the Arduino library support on Galileo is very limited.
Take a look at this message https://communities.intel.com/message/207904#207904 , why don’t you try with this small sketches , for example the one under example 3 seems that might work for you and you can slow down the pulse by adding a delay in the last line of the while(1) and check the frequency with an oscilloscope. I know this is not the best way to do this, but we do know this work. I think you should make sure you are getting the right signal before connecting it to the driver.
You can hit ~901Hz by programming the CY8C9540A directly via I2C. You can do ~901Hz @ 50% duty cycle with a divisor of 52, a period modifier of 2, and a pulse width of 1.
The registers you need to program would be:
Reg. = Value
0x29 = 0x04
0x2A = 0x02
0x2B = 0x01
0x2C = 0x34
You will also need to program the correct PWM select register (0x28) for the PWM you want to program and enable the particular pin to be driven by PWM. See the datasheet for the particulars. I haven't tested this out but I can try this weekend if I get some time.
In your original question you said that you wanted to get a square wave at 500Hz. You can use this lines in the void loop of your sketch.
system("echo 3 >/sys/class/pwm/pwmchip0/export");
system("echo 1750000 >/sys/class/pwm/pwmchip0/pwm3/period");
system("echo 8800000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle");
system("echo 1 >/sys/class/pwm/pwmchip0/pwm3/enable");
If you are still not moving the step motors, I don’t think the problem would be the square wave. I recommend you to check the signal with an oscilloscope to be sure it’s working correctly and then double check with the Galileo connected to the driver and see if the signal is getting distorted, or if it stops working when you connect it.