Comms between MAX 10 FPGA and ST uP

Committer:
jimherd
Date:
Wed Feb 20 16:42:55 2019 +0000
Revision:
0:9600ed6fd725
Child:
1:b819a72b3b5d
Added PWM config function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jimherd 0:9600ed6fd725 1 /*
jimherd 0:9600ed6fd725 2 * FPGA_bus : 8-bit bi-directional bus between uP and FPGA
jimherd 0:9600ed6fd725 3 */
jimherd 0:9600ed6fd725 4 #include "mbed.h"
jimherd 0:9600ed6fd725 5 #include "FPGA_bus.h"
jimherd 0:9600ed6fd725 6
jimherd 0:9600ed6fd725 7 /** create a FPGA_bus object connecting uP to FPGA
jimherd 0:9600ed6fd725 8 *
jimherd 0:9600ed6fd725 9 * @param nos_PWM Number of PWM channels (default = 4)
jimherd 0:9600ed6fd725 10 * @param nos_QE Number of Quadrature Encoder channels (default = 4)
jimherd 0:9600ed6fd725 11 * @param nos_servo Number of RC servo channels (default = 8)
jimherd 0:9600ed6fd725 12 *
jimherd 0:9600ed6fd725 13 * Notes
jimherd 0:9600ed6fd725 14 * You can only change the defaults by recompiling the SystemVerilog code
jimherd 0:9600ed6fd725 15 * on the FPGA.
jimherd 0:9600ed6fd725 16 */
jimherd 0:9600ed6fd725 17 FPGA_bus::FPGA_bus(int nos_PWM = NOS_PWM_CHANNELS,
jimherd 0:9600ed6fd725 18 int nos_QE = NOS_QE_CHANNELS,
jimherd 0:9600ed6fd725 19 int nos_servo = NOS_RC_CHANNELS)
jimherd 0:9600ed6fd725 20
jimherd 0:9600ed6fd725 21 : async_uP_start(ASYNC_UP_START_PIN),
jimherd 0:9600ed6fd725 22 async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN),
jimherd 0:9600ed6fd725 23 async_uP_RW(ASYNC_UP_RW_PIN),
jimherd 0:9600ed6fd725 24 async_uP_reset(ASYNC_UP_RESET_PIN),
jimherd 0:9600ed6fd725 25 uP_ack(ASYNC_UP_ACK_PIN),
jimherd 0:9600ed6fd725 26 uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN)
jimherd 0:9600ed6fd725 27 {
jimherd 0:9600ed6fd725 28 _nos_PWM_units = nos_PWM;
jimherd 0:9600ed6fd725 29 _nos_QE_units = nos_QE;
jimherd 0:9600ed6fd725 30 _nos_servo_units = nos_servo;
jimherd 0:9600ed6fd725 31
jimherd 0:9600ed6fd725 32 async_uP_start = LOW;
jimherd 0:9600ed6fd725 33 }
jimherd 0:9600ed6fd725 34
jimherd 0:9600ed6fd725 35 FPGA_bus::FPGA_bus(void)
jimherd 0:9600ed6fd725 36 : async_uP_start(ASYNC_UP_START_PIN),
jimherd 0:9600ed6fd725 37 async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN),
jimherd 0:9600ed6fd725 38 async_uP_RW(ASYNC_UP_RW_PIN),
jimherd 0:9600ed6fd725 39 async_uP_reset(ASYNC_UP_RESET_PIN),
jimherd 0:9600ed6fd725 40 uP_ack(ASYNC_UP_ACK_PIN),
jimherd 0:9600ed6fd725 41 uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN)
jimherd 0:9600ed6fd725 42 {
jimherd 0:9600ed6fd725 43 _nos_PWM_units = NOS_PWM_CHANNELS;
jimherd 0:9600ed6fd725 44 _nos_QE_units = NOS_QE_CHANNELS;
jimherd 0:9600ed6fd725 45 _nos_servo_units = NOS_RC_CHANNELS;
jimherd 0:9600ed6fd725 46
jimherd 0:9600ed6fd725 47 async_uP_start = LOW;
jimherd 0:9600ed6fd725 48 }
jimherd 0:9600ed6fd725 49
jimherd 0:9600ed6fd725 50
jimherd 0:9600ed6fd725 51
jimherd 0:9600ed6fd725 52 void FPGA_bus::initialise(void)
jimherd 0:9600ed6fd725 53 {
jimherd 0:9600ed6fd725 54 // GPIOC Periph clock enable
jimherd 0:9600ed6fd725 55
jimherd 0:9600ed6fd725 56 ENABLE_GPIO_SUBSYSTEM;
jimherd 0:9600ed6fd725 57 wait_us(2);
jimherd 0:9600ed6fd725 58
jimherd 0:9600ed6fd725 59 async_uP_start = LOW;
jimherd 0:9600ed6fd725 60 async_uP_reset = HIGH;
jimherd 0:9600ed6fd725 61 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 62 async_uP_RW = LOW;
jimherd 0:9600ed6fd725 63
jimherd 0:9600ed6fd725 64 async_uP_reset = LOW; // generate low reset pulse
jimherd 0:9600ed6fd725 65 wait_us(20);
jimherd 0:9600ed6fd725 66 async_uP_reset = HIGH;
jimherd 0:9600ed6fd725 67 wait_us(20);
jimherd 0:9600ed6fd725 68 }
jimherd 0:9600ed6fd725 69
jimherd 0:9600ed6fd725 70 void FPGA_bus::do_start(void)
jimherd 0:9600ed6fd725 71 {
jimherd 0:9600ed6fd725 72 async_uP_start = HIGH;
jimherd 0:9600ed6fd725 73 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 74 async_uP_start = LOW;
jimherd 0:9600ed6fd725 75 }
jimherd 0:9600ed6fd725 76
jimherd 0:9600ed6fd725 77 void FPGA_bus::do_end(void)
jimherd 0:9600ed6fd725 78 {
jimherd 0:9600ed6fd725 79 while (uP_ack == HIGH)
jimherd 0:9600ed6fd725 80 ;
jimherd 0:9600ed6fd725 81 async_uP_start = LOW;
jimherd 0:9600ed6fd725 82 }
jimherd 0:9600ed6fd725 83
jimherd 0:9600ed6fd725 84 void FPGA_bus::write_byte(uint32_t byte_value)
jimherd 0:9600ed6fd725 85 {
jimherd 0:9600ed6fd725 86 SET_BUS_OUTPUT;
jimherd 0:9600ed6fd725 87 OUTPUT_BYTE_TO_BUS(byte_value);
jimherd 0:9600ed6fd725 88 async_uP_RW = WRITE_BUS;
jimherd 0:9600ed6fd725 89 async_uP_handshake_1 = HIGH;
jimherd 0:9600ed6fd725 90 while (uP_handshake_2 == LOW)
jimherd 0:9600ed6fd725 91 ;
jimherd 0:9600ed6fd725 92 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 93 while (uP_handshake_2 == HIGH)
jimherd 0:9600ed6fd725 94 ;
jimherd 0:9600ed6fd725 95 }
jimherd 0:9600ed6fd725 96
jimherd 0:9600ed6fd725 97 uint32_t FPGA_bus::read_byte(void)
jimherd 0:9600ed6fd725 98 {
jimherd 0:9600ed6fd725 99 SET_BUS_INPUT;
jimherd 0:9600ed6fd725 100 async_uP_RW = READ_BUS;
jimherd 0:9600ed6fd725 101 while (uP_handshake_2 == LOW)
jimherd 0:9600ed6fd725 102 ;
jimherd 0:9600ed6fd725 103 data = INPUT_BYTE_FROM_BUS;
jimherd 0:9600ed6fd725 104 async_uP_handshake_1 = HIGH;
jimherd 0:9600ed6fd725 105 while (uP_handshake_2 == HIGH)
jimherd 0:9600ed6fd725 106 ;
jimherd 0:9600ed6fd725 107 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 108 return data;
jimherd 0:9600ed6fd725 109 }
jimherd 0:9600ed6fd725 110
jimherd 0:9600ed6fd725 111 void FPGA_bus::do_write(uint32_t command,
jimherd 0:9600ed6fd725 112 uint32_t register_address,
jimherd 0:9600ed6fd725 113 uint32_t register_data)
jimherd 0:9600ed6fd725 114 {
jimherd 0:9600ed6fd725 115 write_byte(command);
jimherd 0:9600ed6fd725 116 write_byte(register_address);
jimherd 0:9600ed6fd725 117 write_byte(register_data);
jimherd 0:9600ed6fd725 118 write_byte(register_data>>8);
jimherd 0:9600ed6fd725 119 write_byte(register_data>>16);
jimherd 0:9600ed6fd725 120 write_byte(register_data>>24);
jimherd 0:9600ed6fd725 121 }
jimherd 0:9600ed6fd725 122
jimherd 0:9600ed6fd725 123 void FPGA_bus::do_read(received_packet_t *buffer)
jimherd 0:9600ed6fd725 124 {
jimherd 0:9600ed6fd725 125 for (int i=0; i < (NOS_RECEIVED_PACKET_WORDS<<2) ; i++) {
jimherd 0:9600ed6fd725 126 buffer->byte_data[i] = (uint8_t)read_byte();
jimherd 0:9600ed6fd725 127 }
jimherd 0:9600ed6fd725 128 }
jimherd 0:9600ed6fd725 129
jimherd 0:9600ed6fd725 130 void FPGA_bus::do_transaction(uint32_t command,
jimherd 0:9600ed6fd725 131 uint32_t register_address,
jimherd 0:9600ed6fd725 132 uint32_t register_data,
jimherd 0:9600ed6fd725 133 uint32_t *data,
jimherd 0:9600ed6fd725 134 uint32_t *status)
jimherd 0:9600ed6fd725 135 {
jimherd 0:9600ed6fd725 136 do_start();
jimherd 0:9600ed6fd725 137 // pc.printf("\n1");
jimherd 0:9600ed6fd725 138 do_write(command, register_address, register_data);
jimherd 0:9600ed6fd725 139 // pc.printf(" 2");
jimherd 0:9600ed6fd725 140 do_read(&in_pkt);
jimherd 0:9600ed6fd725 141 // pc.printf(" 3");
jimherd 0:9600ed6fd725 142 do_end();
jimherd 0:9600ed6fd725 143 // pc.printf(" 4\n");
jimherd 0:9600ed6fd725 144 *data = in_pkt.word_data[0];
jimherd 0:9600ed6fd725 145 *status = in_pkt.word_data[1];
jimherd 0:9600ed6fd725 146 // pc.printf("data = %#08X :: status = %#08X\n", in_pkt.word_data[0], in_pkt.word_data[1]);
jimherd 0:9600ed6fd725 147 }
jimherd 0:9600ed6fd725 148
jimherd 0:9600ed6fd725 149 uint32_t FPGA_bus::do_command(FPGA_packet_t cmd_packet)
jimherd 0:9600ed6fd725 150 {
jimherd 0:9600ed6fd725 151 async_uP_start = LOW;
jimherd 0:9600ed6fd725 152 return 0;
jimherd 0:9600ed6fd725 153 }
jimherd 0:9600ed6fd725 154
jimherd 0:9600ed6fd725 155 uint32_t FPGA_bus::set_PWM_period(uint32_t channel, float frequency)
jimherd 0:9600ed6fd725 156 {
jimherd 0:9600ed6fd725 157 uint32_t period_value = (uint32_t)(1000000/(20 * frequency));
jimherd 0:9600ed6fd725 158 do_transaction(WRITE_REGISTER_CMD, (channel + PWM_PERIOD) , period_value, &data, &status);
jimherd 0:9600ed6fd725 159 sys_data.PWM_period_value[channel] = period_value;
jimherd 0:9600ed6fd725 160 return status;
jimherd 0:9600ed6fd725 161 }
jimherd 0:9600ed6fd725 162
jimherd 0:9600ed6fd725 163 uint32_t FPGA_bus::set_PWM_duty(uint32_t channel, float percentage)
jimherd 0:9600ed6fd725 164 {
jimherd 0:9600ed6fd725 165 uint32_t duty_value = (uint32_t)((sys_data.PWM_period_value[channel] * percentage) / 100);
jimherd 0:9600ed6fd725 166 do_transaction(WRITE_REGISTER_CMD, (channel + PWM_ON_TIME) , duty_value, &data, &status);
jimherd 0:9600ed6fd725 167 sys_data.PWM_duty_value[channel] = duty_value;
jimherd 0:9600ed6fd725 168 return status;
jimherd 0:9600ed6fd725 169 }
jimherd 0:9600ed6fd725 170
jimherd 0:9600ed6fd725 171 uint32_t FPGA_bus::PWM_enable(uint32_t channel)
jimherd 0:9600ed6fd725 172 {
jimherd 0:9600ed6fd725 173 do_transaction(WRITE_REGISTER_CMD, (channel + PWM_CONFIG) , 1, &data, &status);
jimherd 0:9600ed6fd725 174 // sys_data.PWM_duty_value[channel] = duty_value;
jimherd 0:9600ed6fd725 175 return status;
jimherd 0:9600ed6fd725 176 }
jimherd 0:9600ed6fd725 177
jimherd 0:9600ed6fd725 178 uint32_t FPGA_bus::PWM_config(uint32_t channel, uint32_t config_value)
jimherd 0:9600ed6fd725 179 {
jimherd 0:9600ed6fd725 180 do_transaction(WRITE_REGISTER_CMD, (channel + PWM_CONFIG) , config_value, &data, &status);
jimherd 0:9600ed6fd725 181 sys_data.PWM_duty_value[channel] = config_value;
jimherd 0:9600ed6fd725 182 return status;
jimherd 0:9600ed6fd725 183 }