I’m learning the pynq-z2 dev board and building some systems with it. The image I’m using is version 2.7. When I realized the iic and peripheral device control, the program crashed. The RPI iic will stop for about one minute in normal communication, but the ARDUINO iic in the same process can read and write normally. The overlay I use is base.bit, and the code related to RPI is as follows.
base.select_rpi()
%%microblaze base.RPI
#include “xio_switch.h”
#include “circular_buffer.h”
#include “i2c.h”
#include “timer.h”
#include <yield.h>
#define PCA9685 0x40//Device add
#define MODE 0x00 //End time of PWM signal
#define MODE_EConfig 0x00 //Enable auto-increment register address
#define MODE_RESET 0x80 //PCA reset
#define MODE_DConfig 0x10 //Disable auto-increment register address
#define PRE_SCALE 0xFE //PWM wave frequency setting 0 to 4095
#define HZ_CONFIG 0x7F //PWM wave frequency setting 0 to 4095
//For channel 14:
#define LED0_ON_L 0x3E //Start time of PWM signal 0 to 4095
#define LED0_ON_H 0x3F //Start time of PWM signal 0 to 4095
#define LED0_OFF_L 0x40 //End time of PWM signal 0 to 4095
#define LED0_OFF_H 0x41 //End time of PWM signal 0 to 4095
//For channel 15:
#define LED1_ON_L 0x42 //Start time of PWM signal 0 to 4095
#define LED1_ON_H 0x43 //Start time of PWM signal 0 to 4095
#define LED1_OFF_L 0x44 //End time of PWM signal 0 to 4095
#define LED1_OFF_H 0x45 //End time of PWM signal 0 to 4095
i2c Rdevice = i2c_open_device(1);
unsigned char address[3] = {0x00, 0x00, 0x00};
unsigned char data[1] = {0xAA};
void PAC_reg_wirte16(unsigned char Reg_adrs,unsigned char Hdata, unsigned char Ldata){
address[0] = Reg_adrs;
address[1] = Hdata;
address[2] = Ldata;
i2c_write(Rdevice, PCA9685, address, 3);
}
void PAC_reg_wirte8(unsigned char Reg_adrs,unsigned char Sdata){
address[0] = Reg_adrs;
address[1] = Sdata;
i2c_write(Rdevice, PCA9685, address, 2);
}
void PAC_reg_read(unsigned char Reg_adrs){
address[0] = Reg_adrs;
i2c_write(Rdevice, PCA9685, address, 1);
i2c_read(Rdevice, PCA9685, data, 1);
}
void PAC_init(){
set_pin(2, SDA1);
set_pin(3, SCL1);
PAC_reg_wirte8(MODE, MODE_EConfig);
PAC_reg_wirte8(MODE, MODE_DConfig);
PAC_reg_wirte16(PRE_SCALE, 0x00, HZ_CONFIG);
PAC_reg_wirte8(MODE, MODE_EConfig);
}
//down motor
void set_pwm1(int duty){
unsigned char pwm;
if(duty > 504)
{
PAC_reg_wirte8(LED1_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED1_ON_H, 0x00);
PAC_reg_wirte8(LED1_OFF_L, 0xF8); // End time: 0
PAC_reg_wirte8(LED1_OFF_H, 0x01);
}
else if(duty < 103)
{
PAC_reg_wirte8(LED1_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED1_ON_H, 0x00);
PAC_reg_wirte8(LED1_OFF_L, 0x67); // End time: 0
PAC_reg_wirte8(LED1_OFF_H, 0x00);
}
else
{
PAC_reg_wirte8(LED1_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED1_ON_H, 0x00);
pwm = duty & 0xFF;
PAC_reg_wirte8(LED1_OFF_L, pwm); // End time: 0
pwm = (duty >> 8)& 0xFF;
PAC_reg_wirte8(LED1_OFF_H, pwm);
}
}
//up motor
void set_pwm0(int duty){
unsigned char pwm;
if(duty > 483)
{
PAC_reg_wirte8(LED0_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED0_ON_H, 0x00);
PAC_reg_wirte8(LED0_OFF_L, 0xE3); // End time: 0
PAC_reg_wirte8(LED0_OFF_H, 0x01);
}
else if(duty < 270)
{
PAC_reg_wirte8(LED0_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED0_ON_H, 0x00);
PAC_reg_wirte8(LED0_OFF_L, 270); // End time: 0
PAC_reg_wirte8(LED0_OFF_H, 0x00);
}
else
{
PAC_reg_wirte8(LED0_ON_L, 0x00); // Start time: 0
PAC_reg_wirte8(LED0_ON_H, 0x00);
pwm = duty & 0xFF;
PAC_reg_wirte8(LED0_OFF_L, pwm); // End time: 0
pwm = (duty >> 8)& 0xFF;
PAC_reg_wirte8(LED0_OFF_H, pwm);
}
}
int pwm1 = 303;
int pwm0 = 404;
void PWM_set(){
while(1){
set_pwm1(pwm1);
set_pwm0(pwm0);
delay_ms(50);
yield();
}
}
void PWM_get(int motor0, int motor1){
pwm0 = motor0;
pwm1 = motor1;
}
def task2():
PAC_init()
PWM_set()
time.sleep(1)
while not base.buttons[0].read():
with pitch.get_lock(), roll.get_lock(), motor0.get_lock(), motor1.get_lock():
motor_buffer[0] = int(motor0.value)
motor_buffer[1] = int(motor1.value)
PWM_get(motor_buffer[0], motor_buffer[1])
The values of motor0 and motor1 are obtained well.
The main function is as follows:
if name == “main”:
process1 = Process(target=task1)
process2 = Process(target=task2)
process1.start()
process2.start()
process1.join()
process2.join()