Comms between MAX 10 FPGA and ST uP

Committer:
jimherd
Date:
Fri Jun 26 11:02:30 2020 +0000
Revision:
23:4b391cfd4f2d
Parent:
22:c47d4177d59c
Child:
24:551a996eb5c2
"soft_bus_check" changed to use decrementing timeout counter rather than fixed delay.

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 * Author : Jim Herd
jimherd 0:9600ed6fd725 5 *
jimherd 0:9600ed6fd725 6 * Version 0.1 : initial release
jimherd 0:9600ed6fd725 7 */
jimherd 0:9600ed6fd725 8 #include "mbed.h"
jimherd 17:928b755cba80 9
jimherd 0:9600ed6fd725 10 #ifndef FPGA_bus_H
jimherd 0:9600ed6fd725 11 #define FPGA_bus_H
jimherd 0:9600ed6fd725 12
jimherd 20:aacf2ebd93ff 13 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 14 // MACROS
jimherd 20:aacf2ebd93ff 15
jimherd 20:aacf2ebd93ff 16 #define LOOP_HERE for(;;)
jimherd 20:aacf2ebd93ff 17
jimherd 20:aacf2ebd93ff 18 //////////////////////////////////////////////////////////////////////////
jimherd 0:9600ed6fd725 19 // Pin definitions
jimherd 0:9600ed6fd725 20
jimherd 0:9600ed6fd725 21 #define ASYNC_UP_RW_PIN PB_0
jimherd 0:9600ed6fd725 22 #define ASYNC_UP_HANDSHAKE_1_PIN PB_1
jimherd 0:9600ed6fd725 23 #define ASYNC_UP_HANDSHAKE_2_PIN PB_2
jimherd 0:9600ed6fd725 24 #define ASYNC_UP_START_PIN PB_3
jimherd 0:9600ed6fd725 25 #define ASYNC_UP_ACK_PIN PB_4
jimherd 0:9600ed6fd725 26 #define ASYNC_UP_RESET_PIN PB_5
jimherd 0:9600ed6fd725 27
jimherd 9:6fe95fb0c7ea 28 #define LOG_PIN PB_8
jimherd 9:6fe95fb0c7ea 29
jimherd 0:9600ed6fd725 30 //
jimherd 16:d69a36a541c5 31 //#define PWM_BASE 1
jimherd 0:9600ed6fd725 32 #define NOS_PWM_REGISTERS 4
jimherd 14:b56473e54f6f 33 #define NOS_PWM_CHANNELS 1
jimherd 0:9600ed6fd725 34
jimherd 16:d69a36a541c5 35 //#define QE_BASE ((NOS_PWM_REGISTERS * NOS_PWM_CHANNELS) + PWM_BASE)
jimherd 0:9600ed6fd725 36 #define NOS_QE_REGISTERS 7
jimherd 14:b56473e54f6f 37 #define NOS_QE_CHANNELS 1
jimherd 0:9600ed6fd725 38
jimherd 16:d69a36a541c5 39 //#define RC_BASE ((NOS_QE_REGISTERS * NOS_QE_CHANNELS) + QE_BASE)
jimherd 0:9600ed6fd725 40 #define NOS_RC_CHANNELS 8
jimherd 2:fd5c862b86db 41 #define GLOBAL_RC_ENABLE 0x80000000
jimherd 0:9600ed6fd725 42
jimherd 16:d69a36a541c5 43 #define PWM_ch0 (PWM_base + (0 * NOS_PWM_REGISTERS))
jimherd 16:d69a36a541c5 44 #define PWM_ch1 (PWM_base + (1 * NOS_PWM_REGISTERS))
jimherd 16:d69a36a541c5 45 #define PWM_ch3 (PWM_base + (3 * NOS_PWM_REGISTERS))
jimherd 0:9600ed6fd725 46
jimherd 0:9600ed6fd725 47 #define RC_0 RC_BASE
jimherd 0:9600ed6fd725 48
jimherd 9:6fe95fb0c7ea 49 //
jimherd 9:6fe95fb0c7ea 50 // System can be configured to return ONE or TWO 32-bit values from the FPGA.
jimherd 9:6fe95fb0c7ea 51 //
jimherd 9:6fe95fb0c7ea 52 // first value : 32-bit data value
jimherd 9:6fe95fb0c7ea 53 // second value : 32-bit status value
jimherd 9:6fe95fb0c7ea 54 //
jimherd 9:6fe95fb0c7ea 55 // In practice, the status word carries little or no information but consumes
jimherd 9:6fe95fb0c7ea 56 // four 8-bit transactions between the FPGA and the uP.
jimherd 9:6fe95fb0c7ea 57 //
jimherd 9:6fe95fb0c7ea 58 // Uncomment following #define to enable status word to be returned.
jimherd 9:6fe95fb0c7ea 59
jimherd 9:6fe95fb0c7ea 60 //#define INCLUDE_32_BIT_STATUS_RETURN
jimherd 9:6fe95fb0c7ea 61
jimherd 9:6fe95fb0c7ea 62 #ifdef INCLUDE_32_BIT_STATUS_RETURN
jimherd 9:6fe95fb0c7ea 63 #define NOS_RECEIVED_PACKET_WORDS 2
jimherd 9:6fe95fb0c7ea 64 #else
jimherd 9:6fe95fb0c7ea 65 #define NOS_RECEIVED_PACKET_WORDS 1
jimherd 9:6fe95fb0c7ea 66 #endif
jimherd 0:9600ed6fd725 67
jimherd 0:9600ed6fd725 68 #define SET_BUS_INPUT (GPIOC->MODER = (GPIOC->MODER & 0xFFFF0000))
jimherd 0:9600ed6fd725 69 #define SET_BUS_OUTPUT (GPIOC->MODER = ((GPIOC->MODER & 0xFFFF0000) | 0x00005555))
jimherd 0:9600ed6fd725 70 #define OUTPUT_BYTE_TO_BUS(value) (GPIOC->ODR = ((GPIOC->ODR & 0x0000FF00) | (value & 0x000000FF)))
jimherd 0:9600ed6fd725 71 #define INPUT_BYTE_FROM_BUS (GPIOC->IDR & 0x000000FF)
jimherd 0:9600ed6fd725 72 #define ENABLE_GPIO_SUBSYSTEM (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
jimherd 0:9600ed6fd725 73
jimherd 20:aacf2ebd93ff 74 //////////////////////////////////////////////////////////////////////////
jimherd 1:b819a72b3b5d 75 // FPGA constants
jimherd 1:b819a72b3b5d 76
jimherd 1:b819a72b3b5d 77 #define nS_IN_uS 1000
jimherd 20:aacf2ebd93ff 78 #define FPGA_CLOCK_PERIOD_nS 20
jimherd 21:6b2b7a0e2d9a 79 #define uS_DELAY_BEFORE_TEST_HANDSHAKE 25
jimherd 22:c47d4177d59c 80 #define HANDSHAKE_TIMEOUT_COUNT 10000
jimherd 1:b819a72b3b5d 81
jimherd 20:aacf2ebd93ff 82 //////////////////////////////////////////////////////////////////////////
jimherd 1:b819a72b3b5d 83 // error codes
jimherd 1:b819a72b3b5d 84
jimherd 21:6b2b7a0e2d9a 85 #define NO_ERROR 0
jimherd 23:4b391cfd4f2d 86 #define BUS_FAIL_1 -31 // handshake_2 initially HIGH but should be LOW
jimherd 23:4b391cfd4f2d 87 #define BUS_FAIL_2 -32 // handshake_2 not transitioned to HIGH
jimherd 23:4b391cfd4f2d 88 #define BUS_FAIL_3 -33 // handshake_2 not transitioned to HIGH
jimherd 1:b819a72b3b5d 89
jimherd 20:aacf2ebd93ff 90 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 91 // typedef structures
jimherd 0:9600ed6fd725 92
jimherd 0:9600ed6fd725 93 typedef struct {
jimherd 0:9600ed6fd725 94 uint8_t command;
jimherd 0:9600ed6fd725 95 uint8_t register_no;
jimherd 0:9600ed6fd725 96 uint32_t cmd_data;
jimherd 0:9600ed6fd725 97 uint32_t reply_data;
jimherd 0:9600ed6fd725 98 uint32_t reply_status;
jimherd 0:9600ed6fd725 99 } FPGA_packet_t;
jimherd 0:9600ed6fd725 100
jimherd 0:9600ed6fd725 101 typedef union {
jimherd 9:6fe95fb0c7ea 102 uint32_t word_data[2]; // NOS_RECEIVED_PACKET_WORDS];
jimherd 9:6fe95fb0c7ea 103 uint8_t byte_data[8]; // NOS_RECEIVED_PACKET_WORDS << 2];
jimherd 0:9600ed6fd725 104 } received_packet_t;
jimherd 0:9600ed6fd725 105
jimherd 0:9600ed6fd725 106 enum {READ_REGISTER_CMD=0, WRITE_REGISTER_CMD=1};
jimherd 0:9600ed6fd725 107 enum {READ_BUS=0, WRITE_BUS=1};
jimherd 0:9600ed6fd725 108 enum {LOW=0, HIGH=1};
jimherd 4:e5d36eee9245 109
jimherd 20:aacf2ebd93ff 110 //////////////////////////////////////////////////////////////////////////
jimherd 6:e68defb7b775 111 // SYS_data registers
jimherd 6:e68defb7b775 112
jimherd 6:e68defb7b775 113 enum {SYS_DATA_REG_ADDR=0};
jimherd 6:e68defb7b775 114
jimherd 20:aacf2ebd93ff 115 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 116 // PWM registers with relative addresses
jimherd 4:e5d36eee9245 117 //
jimherd 0:9600ed6fd725 118 enum {PWM_PERIOD=0, PWM_ON_TIME=1, PWM_CONFIG=2, PWM_STATUS=3};
jimherd 20:aacf2ebd93ff 119 //
jimherd 20:aacf2ebd93ff 120 // constants to define bits in PWM config register
jimherd 0:9600ed6fd725 121
jimherd 20:aacf2ebd93ff 122 #define PWM_CONFIG_DEFAULT 0x00
jimherd 20:aacf2ebd93ff 123 enum {PWM_OFF=0x0, PWM_ON=0x1};
jimherd 20:aacf2ebd93ff 124 enum {INT_H_BRIDGE_OFF=0x0, INT_H_BRIDGE_ON=0x10000};
jimherd 20:aacf2ebd93ff 125 enum {EXT_H_BRIDGE_OFF=0x0, EXT_H_BRIDGE_ON=0x20000};
jimherd 20:aacf2ebd93ff 126 enum {MODE_PWM_CONTROL=0x0, MODE_DIR_CONTROL=0x40000};
jimherd 20:aacf2ebd93ff 127 enum {MOTOR_COAST=0x0, MOTOR_FORWARD=0x100000, MOTOR_BACKWARD=0x300000, MOTOR_BRAKE=0xC00000};
jimherd 20:aacf2ebd93ff 128 enum {NO_SWAP=0x0, YES_SWAP=0x1000000};
jimherd 20:aacf2ebd93ff 129 enum {PWM_BRAKE_DWELL=0x0, PWM_COAST_DWELL=0x2000000};
jimherd 20:aacf2ebd93ff 130 enum {NO_INVERT = 0x0, H_BRIDGE_1_INVERT=0x4000000, H_BRIDGE_2_INVERT=0x8000000, ALL_INVERT=0xC000000};
jimherd 20:aacf2ebd93ff 131 enum {BACKWARD, FORWARD};
jimherd 20:aacf2ebd93ff 132
jimherd 20:aacf2ebd93ff 133 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 134 // QE registers with relative addresses
jimherd 4:e5d36eee9245 135 //
jimherd 4:e5d36eee9245 136 enum {QE_COUNT_BUFFER=0, QE_TURN_BUFFER=1, QE_SPEED_BUFFER=2, QE_SIM_PHASE_TIME=3,
jimherd 4:e5d36eee9245 137 QE_COUNTS_PER_REV=4, QE_CONFIG=5, QE_STATUS=6};
jimherd 8:65d1b1a7bfcc 138 //
jimherd 8:65d1b1a7bfcc 139 // constants to define bits in QE config register
jimherd 4:e5d36eee9245 140
jimherd 9:6fe95fb0c7ea 141 #define QE_CONFIG_DEFAULT 0x00
jimherd 8:65d1b1a7bfcc 142 enum {QE_SIG_EXT=0x00, QE_SIG_INT_SIM=0x02};
jimherd 8:65d1b1a7bfcc 143 enum {QE_INT_SIM_DISABLE=0x0, QE_INT_SIM_ENABLE=0x04};
jimherd 8:65d1b1a7bfcc 144 enum {QE_SIM_DIR_FORWARD=0x0, QE_SIM_DIR_BACKWARD=0x08};
jimherd 8:65d1b1a7bfcc 145 enum {QE_NO_SWAP_AB=0x00, QE_SWAP_AB=0x10};
jimherd 8:65d1b1a7bfcc 146 enum {QE_SPEED_CALC_DISABLE=0x00, QE_SPEED_CALC_ENABLE=0x10000};
jimherd 8:65d1b1a7bfcc 147 enum {QE_SPEED_CALC_FILTER_DISABLE=0x00, QE_SPEED_CALC_FILTER_ENABLE=0x20000};
jimherd 10:56a045a02047 148 enum {QE_FILTER_SAMPLE_2=0x00, QE_FILTER_SAMPLE_4=0x100000, QE_FILTER_SAMPLE_8=0x200000,
jimherd 10:56a045a02047 149 QE_FILTER_SAMPLE_16=0x300000, QE_FILTER_SAMPLE_32=0x400000};
jimherd 20:aacf2ebd93ff 150
jimherd 20:aacf2ebd93ff 151 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 152 // RC servo registers with relative addresses
jimherd 4:e5d36eee9245 153 //
jimherd 0:9600ed6fd725 154 enum {RC_SERVO_PERIOD=0, RC_SERVO_CONFIG=1, RC_SERVO_STATUS=2, RC_SERVO_ON_TIME=3};
jimherd 0:9600ed6fd725 155
jimherd 20:aacf2ebd93ff 156 //////////////////////////////////////////////////////////////////////////
jimherd 20:aacf2ebd93ff 157 // FPGA_bus class
jimherd 20:aacf2ebd93ff 158 // ==============
jimherd 9:6fe95fb0c7ea 159
jimherd 0:9600ed6fd725 160 class FPGA_bus {
jimherd 0:9600ed6fd725 161 public:
jimherd 7:c0bef9c1f5d5 162 FPGA_bus(int nos_PWM = NOS_PWM_CHANNELS ,
jimherd 7:c0bef9c1f5d5 163 int nos_QE = NOS_QE_CHANNELS ,
jimherd 14:b56473e54f6f 164 int nos_servo = NOS_RC_CHANNELS ); // constructor
jimherd 20:aacf2ebd93ff 165 //
jimherd 20:aacf2ebd93ff 166 // functions
jimherd 20:aacf2ebd93ff 167 //
jimherd 20:aacf2ebd93ff 168 int32_t initialise(void);
jimherd 20:aacf2ebd93ff 169 void do_transaction(uint32_t command,
jimherd 20:aacf2ebd93ff 170 uint32_t register_address,
jimherd 20:aacf2ebd93ff 171 uint32_t register_data,
jimherd 20:aacf2ebd93ff 172 uint32_t *data,
jimherd 20:aacf2ebd93ff 173 uint32_t *status);
jimherd 20:aacf2ebd93ff 174 void write_register(uint32_t register_addr, uint32_t value);
jimherd 20:aacf2ebd93ff 175 void set_PWM_period(uint32_t channel, float frequency);
jimherd 20:aacf2ebd93ff 176 void set_PWM_duty(uint32_t channel, float percentage);
jimherd 20:aacf2ebd93ff 177 void PWM_enable(uint32_t channel);
jimherd 20:aacf2ebd93ff 178 void PWM_config(uint32_t channel, uint32_t config_value);
jimherd 20:aacf2ebd93ff 179 void set_RC_period(void);
jimherd 20:aacf2ebd93ff 180 void set_RC_period(uint32_t duty_uS);
jimherd 20:aacf2ebd93ff 181 void set_RC_pulse(uint32_t channel, uint32_t pulse_uS);
jimherd 20:aacf2ebd93ff 182 void enable_RC_channel(uint32_t channel);
jimherd 20:aacf2ebd93ff 183 void disable_RC_channel(uint32_t channel);
jimherd 20:aacf2ebd93ff 184 void QE_config(uint32_t channel, uint32_t config_value);
jimherd 20:aacf2ebd93ff 185 void enable_speed_measure(uint32_t channel, uint32_t config_value, uint32_t phase_time);
jimherd 5:64c677e9995c 186 uint32_t read_speed_measure(uint32_t channel);
jimherd 10:56a045a02047 187 uint32_t read_count_measure(uint32_t channel);
jimherd 6:e68defb7b775 188 uint32_t get_SYS_data(void);
jimherd 22:c47d4177d59c 189 int32_t soft_check_bus(void);
jimherd 20:aacf2ebd93ff 190 //
jimherd 20:aacf2ebd93ff 191 // data
jimherd 20:aacf2ebd93ff 192 //
jimherd 1:b819a72b3b5d 193 int32_t global_FPGA_unit_error_flag;
jimherd 20:aacf2ebd93ff 194 //
jimherd 20:aacf2ebd93ff 195 // persistant system data
jimherd 20:aacf2ebd93ff 196 //
jimherd 20:aacf2ebd93ff 197 struct SYS_data {
jimherd 20:aacf2ebd93ff 198 uint8_t major_version;
jimherd 20:aacf2ebd93ff 199 uint8_t minor_version;
jimherd 20:aacf2ebd93ff 200 uint8_t number_of_PWM_channels;
jimherd 20:aacf2ebd93ff 201 uint8_t number_of_QE_channels;
jimherd 20:aacf2ebd93ff 202 uint8_t number_of_RC_channels;
jimherd 20:aacf2ebd93ff 203 uint32_t PWM_period_value[NOS_PWM_CHANNELS];
jimherd 20:aacf2ebd93ff 204 uint32_t PWM_duty_value[NOS_PWM_CHANNELS];
jimherd 20:aacf2ebd93ff 205 } sys_data;
jimherd 0:9600ed6fd725 206
jimherd 15:6420b52d30cc 207 private:
jimherd 20:aacf2ebd93ff 208 //
jimherd 20:aacf2ebd93ff 209 // data
jimherd 20:aacf2ebd93ff 210 //
jimherd 0:9600ed6fd725 211 uint32_t _nos_PWM_units;
jimherd 0:9600ed6fd725 212 uint32_t _nos_QE_units;
jimherd 0:9600ed6fd725 213 uint32_t _nos_servo_units;
jimherd 0:9600ed6fd725 214
jimherd 15:6420b52d30cc 215 uint32_t PWM_base, QE_base, RC_base;
jimherd 15:6420b52d30cc 216
jimherd 0:9600ed6fd725 217 uint32_t data, status, tmp_config;
jimherd 0:9600ed6fd725 218 received_packet_t in_pkt;
jimherd 20:aacf2ebd93ff 219 //
jimherd 20:aacf2ebd93ff 220 // functions
jimherd 20:aacf2ebd93ff 221 //
jimherd 20:aacf2ebd93ff 222 void do_start(void);
jimherd 20:aacf2ebd93ff 223 void do_end(void);
jimherd 20:aacf2ebd93ff 224 void write_byte(uint32_t byte_value);
jimherd 0:9600ed6fd725 225 uint32_t read_byte(void);
jimherd 20:aacf2ebd93ff 226 void do_write( uint32_t command,
jimherd 20:aacf2ebd93ff 227 uint32_t register_address,
jimherd 20:aacf2ebd93ff 228 uint32_t register_data);
jimherd 20:aacf2ebd93ff 229 void do_read(received_packet_t *buffer);
jimherd 20:aacf2ebd93ff 230 void do_reset(void);
jimherd 22:c47d4177d59c 231 int32_t hard_check_bus(void);
jimherd 20:aacf2ebd93ff 232 void update_FPGA_register_pointers(void);
jimherd 20:aacf2ebd93ff 233 //
jimherd 20:aacf2ebd93ff 234 // Hardware digital I/O lines
jimherd 20:aacf2ebd93ff 235 //
jimherd 0:9600ed6fd725 236 DigitalOut async_uP_start;
jimherd 0:9600ed6fd725 237 DigitalOut async_uP_handshake_1;
jimherd 0:9600ed6fd725 238 DigitalOut async_uP_RW;
jimherd 0:9600ed6fd725 239 DigitalOut async_uP_reset;
jimherd 0:9600ed6fd725 240 DigitalIn uP_ack;
jimherd 0:9600ed6fd725 241 DigitalIn uP_handshake_2;
jimherd 0:9600ed6fd725 242
jimherd 9:6fe95fb0c7ea 243 DigitalOut log_pin;
jimherd 9:6fe95fb0c7ea 244
jimherd 0:9600ed6fd725 245 };
jimherd 0:9600ed6fd725 246
jimherd 0:9600ed6fd725 247 #endif
jimherd 0:9600ed6fd725 248