jim herd / FPGA_bus
Committer:
jimherd
Date:
Mon Apr 13 16:10:23 2020 +0000
Revision:
7:c0bef9c1f5d5
Parent:
6:e68defb7b775
Child:
12:b9b4ff729fef
Child:
13:67382358d024
Change to remove default constructor error with Arm V6 compiler.

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 7:c0bef9c1f5d5 16 */
jimherd 7:c0bef9c1f5d5 17
jimherd 7:c0bef9c1f5d5 18 /*
jimherd 0:9600ed6fd725 19 FPGA_bus::FPGA_bus(void)
jimherd 0:9600ed6fd725 20 : async_uP_start(ASYNC_UP_START_PIN),
jimherd 0:9600ed6fd725 21 async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN),
jimherd 0:9600ed6fd725 22 async_uP_RW(ASYNC_UP_RW_PIN),
jimherd 0:9600ed6fd725 23 async_uP_reset(ASYNC_UP_RESET_PIN),
jimherd 0:9600ed6fd725 24 uP_ack(ASYNC_UP_ACK_PIN),
jimherd 0:9600ed6fd725 25 uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN)
jimherd 0:9600ed6fd725 26 {
jimherd 0:9600ed6fd725 27 _nos_PWM_units = NOS_PWM_CHANNELS;
jimherd 0:9600ed6fd725 28 _nos_QE_units = NOS_QE_CHANNELS;
jimherd 0:9600ed6fd725 29 _nos_servo_units = NOS_RC_CHANNELS;
jimherd 0:9600ed6fd725 30
jimherd 0:9600ed6fd725 31 async_uP_start = LOW;
jimherd 0:9600ed6fd725 32 }
jimherd 7:c0bef9c1f5d5 33 */
jimherd 7:c0bef9c1f5d5 34 FPGA_bus::FPGA_bus(int nos_PWM /* = NOS_PWM_CHANNELS */,
jimherd 7:c0bef9c1f5d5 35 int nos_QE /* = NOS_QE_CHANNELS */,
jimherd 7:c0bef9c1f5d5 36 int nos_servo /* = NOS_RC_CHANNELS */ )
jimherd 7:c0bef9c1f5d5 37
jimherd 7:c0bef9c1f5d5 38 : async_uP_start(ASYNC_UP_START_PIN),
jimherd 7:c0bef9c1f5d5 39 async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN),
jimherd 7:c0bef9c1f5d5 40 async_uP_RW(ASYNC_UP_RW_PIN),
jimherd 7:c0bef9c1f5d5 41 async_uP_reset(ASYNC_UP_RESET_PIN),
jimherd 7:c0bef9c1f5d5 42 uP_ack(ASYNC_UP_ACK_PIN),
jimherd 7:c0bef9c1f5d5 43 uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN),
jimherd 7:c0bef9c1f5d5 44
jimherd 7:c0bef9c1f5d5 45 _nos_PWM_units(nos_PWM),
jimherd 7:c0bef9c1f5d5 46 _nos_QE_units(nos_QE),
jimherd 7:c0bef9c1f5d5 47 _nos_servo_units(nos_servo)
jimherd 7:c0bef9c1f5d5 48 {
jimherd 7:c0bef9c1f5d5 49 /* _nos_PWM_units = nos_PWM;
jimherd 7:c0bef9c1f5d5 50 _nos_QE_units = nos_QE;
jimherd 7:c0bef9c1f5d5 51 _nos_servo_units = nos_servo; */
jimherd 7:c0bef9c1f5d5 52
jimherd 7:c0bef9c1f5d5 53 async_uP_start = LOW;
jimherd 7:c0bef9c1f5d5 54 }
jimherd 0:9600ed6fd725 55
jimherd 0:9600ed6fd725 56
jimherd 0:9600ed6fd725 57 void FPGA_bus::initialise(void)
jimherd 0:9600ed6fd725 58 {
jimherd 0:9600ed6fd725 59 // GPIOC Periph clock enable
jimherd 0:9600ed6fd725 60
jimherd 0:9600ed6fd725 61 ENABLE_GPIO_SUBSYSTEM;
jimherd 0:9600ed6fd725 62 wait_us(2);
jimherd 0:9600ed6fd725 63
jimherd 0:9600ed6fd725 64 async_uP_start = LOW;
jimherd 0:9600ed6fd725 65 async_uP_reset = HIGH;
jimherd 0:9600ed6fd725 66 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 67 async_uP_RW = LOW;
jimherd 0:9600ed6fd725 68
jimherd 0:9600ed6fd725 69 async_uP_reset = LOW; // generate low reset pulse
jimherd 0:9600ed6fd725 70 wait_us(20);
jimherd 0:9600ed6fd725 71 async_uP_reset = HIGH;
jimherd 0:9600ed6fd725 72 wait_us(20);
jimherd 1:b819a72b3b5d 73
jimherd 1:b819a72b3b5d 74 global_FPGA_unit_error_flag = NO_ERROR;
jimherd 0:9600ed6fd725 75 }
jimherd 0:9600ed6fd725 76
jimherd 0:9600ed6fd725 77 void FPGA_bus::do_start(void)
jimherd 0:9600ed6fd725 78 {
jimherd 0:9600ed6fd725 79 async_uP_start = HIGH;
jimherd 0:9600ed6fd725 80 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 81 async_uP_start = LOW;
jimherd 0:9600ed6fd725 82 }
jimherd 0:9600ed6fd725 83
jimherd 0:9600ed6fd725 84 void FPGA_bus::do_end(void)
jimherd 0:9600ed6fd725 85 {
jimherd 0:9600ed6fd725 86 while (uP_ack == HIGH)
jimherd 0:9600ed6fd725 87 ;
jimherd 0:9600ed6fd725 88 async_uP_start = LOW;
jimherd 0:9600ed6fd725 89 }
jimherd 0:9600ed6fd725 90
jimherd 0:9600ed6fd725 91 void FPGA_bus::write_byte(uint32_t byte_value)
jimherd 0:9600ed6fd725 92 {
jimherd 0:9600ed6fd725 93 SET_BUS_OUTPUT;
jimherd 0:9600ed6fd725 94 OUTPUT_BYTE_TO_BUS(byte_value);
jimherd 0:9600ed6fd725 95 async_uP_RW = WRITE_BUS;
jimherd 0:9600ed6fd725 96 async_uP_handshake_1 = HIGH;
jimherd 0:9600ed6fd725 97 while (uP_handshake_2 == LOW)
jimherd 0:9600ed6fd725 98 ;
jimherd 0:9600ed6fd725 99 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 100 while (uP_handshake_2 == HIGH)
jimherd 0:9600ed6fd725 101 ;
jimherd 0:9600ed6fd725 102 }
jimherd 0:9600ed6fd725 103
jimherd 0:9600ed6fd725 104 uint32_t FPGA_bus::read_byte(void)
jimherd 0:9600ed6fd725 105 {
jimherd 0:9600ed6fd725 106 SET_BUS_INPUT;
jimherd 0:9600ed6fd725 107 async_uP_RW = READ_BUS;
jimherd 0:9600ed6fd725 108 while (uP_handshake_2 == LOW)
jimherd 0:9600ed6fd725 109 ;
jimherd 0:9600ed6fd725 110 data = INPUT_BYTE_FROM_BUS;
jimherd 0:9600ed6fd725 111 async_uP_handshake_1 = HIGH;
jimherd 0:9600ed6fd725 112 while (uP_handshake_2 == HIGH)
jimherd 0:9600ed6fd725 113 ;
jimherd 0:9600ed6fd725 114 async_uP_handshake_1 = LOW;
jimherd 0:9600ed6fd725 115 return data;
jimherd 0:9600ed6fd725 116 }
jimherd 0:9600ed6fd725 117
jimherd 0:9600ed6fd725 118 void FPGA_bus::do_write(uint32_t command,
jimherd 0:9600ed6fd725 119 uint32_t register_address,
jimherd 0:9600ed6fd725 120 uint32_t register_data)
jimherd 0:9600ed6fd725 121 {
jimherd 0:9600ed6fd725 122 write_byte(command);
jimherd 0:9600ed6fd725 123 write_byte(register_address);
jimherd 0:9600ed6fd725 124 write_byte(register_data);
jimherd 0:9600ed6fd725 125 write_byte(register_data>>8);
jimherd 0:9600ed6fd725 126 write_byte(register_data>>16);
jimherd 0:9600ed6fd725 127 write_byte(register_data>>24);
jimherd 0:9600ed6fd725 128 }
jimherd 0:9600ed6fd725 129
jimherd 0:9600ed6fd725 130 void FPGA_bus::do_read(received_packet_t *buffer)
jimherd 0:9600ed6fd725 131 {
jimherd 0:9600ed6fd725 132 for (int i=0; i < (NOS_RECEIVED_PACKET_WORDS<<2) ; i++) {
jimherd 0:9600ed6fd725 133 buffer->byte_data[i] = (uint8_t)read_byte();
jimherd 0:9600ed6fd725 134 }
jimherd 0:9600ed6fd725 135 }
jimherd 0:9600ed6fd725 136
jimherd 0:9600ed6fd725 137 void FPGA_bus::do_transaction(uint32_t command,
jimherd 0:9600ed6fd725 138 uint32_t register_address,
jimherd 0:9600ed6fd725 139 uint32_t register_data,
jimherd 0:9600ed6fd725 140 uint32_t *data,
jimherd 0:9600ed6fd725 141 uint32_t *status)
jimherd 0:9600ed6fd725 142 {
jimherd 0:9600ed6fd725 143 do_start();
jimherd 0:9600ed6fd725 144 // pc.printf("\n1");
jimherd 0:9600ed6fd725 145 do_write(command, register_address, register_data);
jimherd 0:9600ed6fd725 146 // pc.printf(" 2");
jimherd 0:9600ed6fd725 147 do_read(&in_pkt);
jimherd 0:9600ed6fd725 148 // pc.printf(" 3");
jimherd 0:9600ed6fd725 149 do_end();
jimherd 0:9600ed6fd725 150 // pc.printf(" 4\n");
jimherd 0:9600ed6fd725 151 *data = in_pkt.word_data[0];
jimherd 0:9600ed6fd725 152 *status = in_pkt.word_data[1];
jimherd 0:9600ed6fd725 153 // pc.printf("data = %#08X :: status = %#08X\n", in_pkt.word_data[0], in_pkt.word_data[1]);
jimherd 0:9600ed6fd725 154 }
jimherd 0:9600ed6fd725 155
jimherd 0:9600ed6fd725 156 uint32_t FPGA_bus::do_command(FPGA_packet_t cmd_packet)
jimherd 0:9600ed6fd725 157 {
jimherd 0:9600ed6fd725 158 async_uP_start = LOW;
jimherd 0:9600ed6fd725 159 return 0;
jimherd 0:9600ed6fd725 160 }
jimherd 0:9600ed6fd725 161
jimherd 1:b819a72b3b5d 162 void FPGA_bus::set_PWM_period(uint32_t channel, float frequency)
jimherd 0:9600ed6fd725 163 {
jimherd 4:e5d36eee9245 164 uint32_t register_address = ((PWM_BASE + (channel * NOS_PWM_REGISTERS)) + PWM_PERIOD);
jimherd 0:9600ed6fd725 165 uint32_t period_value = (uint32_t)(1000000/(20 * frequency));
jimherd 4:e5d36eee9245 166 do_transaction(WRITE_REGISTER_CMD, register_address, period_value, &data, &status);
jimherd 0:9600ed6fd725 167 sys_data.PWM_period_value[channel] = period_value;
jimherd 1:b819a72b3b5d 168 global_FPGA_unit_error_flag = status;
jimherd 0:9600ed6fd725 169 }
jimherd 0:9600ed6fd725 170
jimherd 1:b819a72b3b5d 171 void FPGA_bus::set_PWM_duty(uint32_t channel, float percentage)
jimherd 0:9600ed6fd725 172 {
jimherd 4:e5d36eee9245 173 uint32_t register_address = ((PWM_BASE + (channel * NOS_PWM_REGISTERS)) + PWM_ON_TIME);
jimherd 0:9600ed6fd725 174 uint32_t duty_value = (uint32_t)((sys_data.PWM_period_value[channel] * percentage) / 100);
jimherd 4:e5d36eee9245 175 do_transaction(WRITE_REGISTER_CMD, register_address , duty_value, &data, &status);
jimherd 0:9600ed6fd725 176 sys_data.PWM_duty_value[channel] = duty_value;
jimherd 1:b819a72b3b5d 177 global_FPGA_unit_error_flag = status;;
jimherd 0:9600ed6fd725 178 }
jimherd 0:9600ed6fd725 179
jimherd 1:b819a72b3b5d 180 void FPGA_bus::PWM_enable(uint32_t channel)
jimherd 0:9600ed6fd725 181 {
jimherd 4:e5d36eee9245 182 uint32_t register_address = ((PWM_BASE + (channel * NOS_PWM_REGISTERS)) + PWM_CONFIG);
jimherd 4:e5d36eee9245 183 do_transaction(WRITE_REGISTER_CMD, register_address , 1, &data, &status);
jimherd 0:9600ed6fd725 184 // sys_data.PWM_duty_value[channel] = duty_value;
jimherd 1:b819a72b3b5d 185 global_FPGA_unit_error_flag = status;;
jimherd 0:9600ed6fd725 186 }
jimherd 0:9600ed6fd725 187
jimherd 1:b819a72b3b5d 188 void FPGA_bus::PWM_config(uint32_t channel, uint32_t config_value)
jimherd 0:9600ed6fd725 189 {
jimherd 4:e5d36eee9245 190 uint32_t register_address = ((PWM_BASE + (channel * NOS_PWM_REGISTERS)) + PWM_CONFIG);
jimherd 4:e5d36eee9245 191 do_transaction(WRITE_REGISTER_CMD, register_address , config_value, &data, &status);
jimherd 0:9600ed6fd725 192 sys_data.PWM_duty_value[channel] = config_value;
jimherd 1:b819a72b3b5d 193 global_FPGA_unit_error_flag = status;;
jimherd 1:b819a72b3b5d 194 }
jimherd 1:b819a72b3b5d 195
jimherd 4:e5d36eee9245 196 void FPGA_bus::set_RC_period(void)
jimherd 1:b819a72b3b5d 197 {
jimherd 4:e5d36eee9245 198 do_transaction(WRITE_REGISTER_CMD, (RC_BASE + RC_SERVO_PERIOD), 1000000, &data, &status);
jimherd 6:e68defb7b775 199 global_FPGA_unit_error_flag = status;
jimherd 1:b819a72b3b5d 200 }
jimherd 1:b819a72b3b5d 201
jimherd 4:e5d36eee9245 202 void FPGA_bus::set_RC_period(uint32_t duty_uS)
jimherd 1:b819a72b3b5d 203 {
jimherd 1:b819a72b3b5d 204 uint32_t nos_20nS_ticks = ((duty_uS * nS_IN_uS)/FPGA_CLOCK_PERIOD_nS);
jimherd 4:e5d36eee9245 205 do_transaction(WRITE_REGISTER_CMD, (RC_BASE + RC_SERVO_PERIOD), nos_20nS_ticks, &data, &status);
jimherd 6:e68defb7b775 206 global_FPGA_unit_error_flag = status;
jimherd 1:b819a72b3b5d 207 }
jimherd 1:b819a72b3b5d 208
jimherd 1:b819a72b3b5d 209 void FPGA_bus :: set_RC_pulse(uint32_t channel, uint32_t pulse_uS)
jimherd 1:b819a72b3b5d 210 {
jimherd 1:b819a72b3b5d 211 uint32_t nos_20nS_ticks = ((pulse_uS * nS_IN_uS)/FPGA_CLOCK_PERIOD_nS);
jimherd 4:e5d36eee9245 212 do_transaction(WRITE_REGISTER_CMD, (RC_BASE + RC_SERVO_ON_TIME + channel), nos_20nS_ticks, &data, &status);
jimherd 1:b819a72b3b5d 213 global_FPGA_unit_error_flag = status;;
jimherd 1:b819a72b3b5d 214 }
jimherd 1:b819a72b3b5d 215
jimherd 4:e5d36eee9245 216 void FPGA_bus::enable_RC_channel(uint32_t channel)
jimherd 1:b819a72b3b5d 217 {
jimherd 4:e5d36eee9245 218 do_transaction(READ_REGISTER_CMD, (RC_BASE + RC_SERVO_CONFIG), NULL, &data, &status);
jimherd 2:fd5c862b86db 219 int32_t config = (data || (0x01 << channel)) + GLOBAL_RC_ENABLE;
jimherd 4:e5d36eee9245 220 do_transaction(WRITE_REGISTER_CMD, (RC_BASE + RC_SERVO_CONFIG), config, &data, &status);
jimherd 3:cf36c2d4208f 221 global_FPGA_unit_error_flag = status;
jimherd 2:fd5c862b86db 222 }
jimherd 2:fd5c862b86db 223
jimherd 4:e5d36eee9245 224 void FPGA_bus::disable_RC_channel(uint32_t channel)
jimherd 2:fd5c862b86db 225 {
jimherd 4:e5d36eee9245 226 do_transaction(READ_REGISTER_CMD, (RC_BASE + RC_SERVO_CONFIG), NULL, &data, &status);
jimherd 4:e5d36eee9245 227 uint32_t config = data && ~(0x01 << channel);
jimherd 4:e5d36eee9245 228 do_transaction(WRITE_REGISTER_CMD, (RC_BASE + RC_SERVO_CONFIG), config, &data, &status);
jimherd 1:b819a72b3b5d 229 global_FPGA_unit_error_flag = status;
jimherd 4:e5d36eee9245 230 }
jimherd 4:e5d36eee9245 231
jimherd 4:e5d36eee9245 232 void FPGA_bus::enable_speed_measure(uint32_t channel)
jimherd 4:e5d36eee9245 233 {
jimherd 4:e5d36eee9245 234 uint32_t register_address = ((QE_BASE + (channel * NOS_QE_REGISTERS)) + QE_CONFIG);
jimherd 4:e5d36eee9245 235 uint32_t register_data = QE_SPEED_CALC_ENABLE;
jimherd 4:e5d36eee9245 236 do_transaction(WRITE_REGISTER_CMD, register_address, register_data, &data, &status);
jimherd 5:64c677e9995c 237 global_FPGA_unit_error_flag = status;
jimherd 5:64c677e9995c 238 }
jimherd 5:64c677e9995c 239
jimherd 5:64c677e9995c 240 uint32_t FPGA_bus::read_speed_measure(uint32_t channel)
jimherd 5:64c677e9995c 241 {
jimherd 5:64c677e9995c 242 uint32_t register_address = ((QE_BASE + (channel * NOS_QE_REGISTERS)) + QE_CONFIG);
jimherd 5:64c677e9995c 243 do_transaction(READ_REGISTER_CMD, register_address, NULL, &data, &status);
jimherd 5:64c677e9995c 244 global_FPGA_unit_error_flag = status;
jimherd 5:64c677e9995c 245 return data;
jimherd 6:e68defb7b775 246 }
jimherd 6:e68defb7b775 247
jimherd 6:e68defb7b775 248 uint32_t FPGA_bus::get_SYS_data(void)
jimherd 6:e68defb7b775 249 {
jimherd 6:e68defb7b775 250 do_transaction(READ_REGISTER_CMD, SYS_DATA_REG_ADDR, NULL, &data, &status);
jimherd 6:e68defb7b775 251 sys_data.major_version = (data & 0x0000000F);
jimherd 6:e68defb7b775 252 sys_data.minor_version = (data >> 4) & 0x0000000F;
jimherd 6:e68defb7b775 253 sys_data.number_of_PWM_channels = (data >> 8) & 0x0000000F;
jimherd 6:e68defb7b775 254 sys_data.number_of_QE_channels = (data >> 8) & 0x0000000F;
jimherd 6:e68defb7b775 255 sys_data.number_of_RC_channels = (data >> 8) & 0x0000000F;
jimherd 6:e68defb7b775 256
jimherd 6:e68defb7b775 257 global_FPGA_unit_error_flag = status;
jimherd 6:e68defb7b775 258 return data;
jimherd 0:9600ed6fd725 259 }