Comms between MAX 10 FPGA and ST uP
FPGA_bus.h@7:c0bef9c1f5d5, 2020-04-13 (annotated)
- Committer:
- jimherd
- Date:
- Mon Apr 13 16:10:23 2020 +0000
- Revision:
- 7:c0bef9c1f5d5
- Parent:
- 6:e68defb7b775
- Child:
- 12:b9b4ff729fef
Change to remove default constructor error with Arm V6 compiler.
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:9600ed6fd725 | 9 | |
jimherd | 0:9600ed6fd725 | 10 | #ifndef FPGA_bus_H |
jimherd | 0:9600ed6fd725 | 11 | #define FPGA_bus_H |
jimherd | 0:9600ed6fd725 | 12 | |
jimherd | 0:9600ed6fd725 | 13 | // |
jimherd | 0:9600ed6fd725 | 14 | // Pin definitions |
jimherd | 0:9600ed6fd725 | 15 | |
jimherd | 0:9600ed6fd725 | 16 | #define ASYNC_UP_RW_PIN PB_0 |
jimherd | 0:9600ed6fd725 | 17 | #define ASYNC_UP_HANDSHAKE_1_PIN PB_1 |
jimherd | 0:9600ed6fd725 | 18 | #define ASYNC_UP_HANDSHAKE_2_PIN PB_2 |
jimherd | 0:9600ed6fd725 | 19 | #define ASYNC_UP_START_PIN PB_3 |
jimherd | 0:9600ed6fd725 | 20 | #define ASYNC_UP_ACK_PIN PB_4 |
jimherd | 0:9600ed6fd725 | 21 | #define ASYNC_UP_RESET_PIN PB_5 |
jimherd | 0:9600ed6fd725 | 22 | |
jimherd | 0:9600ed6fd725 | 23 | // |
jimherd | 0:9600ed6fd725 | 24 | // |
jimherd | 0:9600ed6fd725 | 25 | #define PWM_BASE 1 |
jimherd | 0:9600ed6fd725 | 26 | #define NOS_PWM_REGISTERS 4 |
jimherd | 0:9600ed6fd725 | 27 | #define NOS_PWM_CHANNELS 4 |
jimherd | 0:9600ed6fd725 | 28 | |
jimherd | 0:9600ed6fd725 | 29 | #define QE_BASE ((NOS_PWM_REGISTERS * NOS_PWM_CHANNELS) + PWM_BASE) |
jimherd | 0:9600ed6fd725 | 30 | #define NOS_QE_REGISTERS 7 |
jimherd | 0:9600ed6fd725 | 31 | #define NOS_QE_CHANNELS 4 |
jimherd | 0:9600ed6fd725 | 32 | |
jimherd | 4:e5d36eee9245 | 33 | #define QE_SPEED_CALC_ENABLE 0x00010000 |
jimherd | 4:e5d36eee9245 | 34 | #define QE_SPEED_CALC_DISABLE 0x00000000 |
jimherd | 4:e5d36eee9245 | 35 | |
jimherd | 0:9600ed6fd725 | 36 | #define RC_BASE ((NOS_QE_REGISTERS * NOS_QE_CHANNELS) + QE_BASE) |
jimherd | 0:9600ed6fd725 | 37 | #define NOS_RC_CHANNELS 8 |
jimherd | 2:fd5c862b86db | 38 | #define GLOBAL_RC_ENABLE 0x80000000 |
jimherd | 0:9600ed6fd725 | 39 | |
jimherd | 0:9600ed6fd725 | 40 | #define PWM_ch0 (PWM_BASE + (0 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 41 | #define PWM_ch1 (PWM_BASE + (1 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 42 | #define PWM_ch3 (PWM_BASE + (3 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 43 | |
jimherd | 0:9600ed6fd725 | 44 | #define RC_0 RC_BASE |
jimherd | 0:9600ed6fd725 | 45 | |
jimherd | 0:9600ed6fd725 | 46 | #define NOS_RECEIVED_PACKET_WORDS 2 |
jimherd | 0:9600ed6fd725 | 47 | |
jimherd | 0:9600ed6fd725 | 48 | #define SET_BUS_INPUT (GPIOC->MODER = (GPIOC->MODER & 0xFFFF0000)) |
jimherd | 0:9600ed6fd725 | 49 | #define SET_BUS_OUTPUT (GPIOC->MODER = ((GPIOC->MODER & 0xFFFF0000) | 0x00005555)) |
jimherd | 0:9600ed6fd725 | 50 | #define OUTPUT_BYTE_TO_BUS(value) (GPIOC->ODR = ((GPIOC->ODR & 0x0000FF00) | (value & 0x000000FF))) |
jimherd | 0:9600ed6fd725 | 51 | #define INPUT_BYTE_FROM_BUS (GPIOC->IDR & 0x000000FF) |
jimherd | 0:9600ed6fd725 | 52 | #define ENABLE_GPIO_SUBSYSTEM (RCC->AHBENR |= RCC_AHBENR_GPIOCEN) |
jimherd | 0:9600ed6fd725 | 53 | |
jimherd | 1:b819a72b3b5d | 54 | // |
jimherd | 1:b819a72b3b5d | 55 | // FPGA constants |
jimherd | 1:b819a72b3b5d | 56 | |
jimherd | 1:b819a72b3b5d | 57 | #define nS_IN_uS 1000 |
jimherd | 1:b819a72b3b5d | 58 | #define FPGA_CLOCK_PERIOD_nS 20 |
jimherd | 1:b819a72b3b5d | 59 | |
jimherd | 1:b819a72b3b5d | 60 | // |
jimherd | 1:b819a72b3b5d | 61 | // error codes |
jimherd | 1:b819a72b3b5d | 62 | |
jimherd | 1:b819a72b3b5d | 63 | #define NO_ERROR 0 |
jimherd | 1:b819a72b3b5d | 64 | |
jimherd | 0:9600ed6fd725 | 65 | #define LOOP_HERE for(;;) |
jimherd | 0:9600ed6fd725 | 66 | |
jimherd | 0:9600ed6fd725 | 67 | typedef struct { |
jimherd | 0:9600ed6fd725 | 68 | uint8_t command; |
jimherd | 0:9600ed6fd725 | 69 | uint8_t register_no; |
jimherd | 0:9600ed6fd725 | 70 | uint32_t cmd_data; |
jimherd | 0:9600ed6fd725 | 71 | uint32_t reply_data; |
jimherd | 0:9600ed6fd725 | 72 | uint32_t reply_status; |
jimherd | 0:9600ed6fd725 | 73 | } FPGA_packet_t; |
jimherd | 0:9600ed6fd725 | 74 | |
jimherd | 0:9600ed6fd725 | 75 | typedef union { |
jimherd | 0:9600ed6fd725 | 76 | uint32_t word_data[NOS_RECEIVED_PACKET_WORDS]; |
jimherd | 0:9600ed6fd725 | 77 | uint8_t byte_data[NOS_RECEIVED_PACKET_WORDS << 2]; |
jimherd | 0:9600ed6fd725 | 78 | } received_packet_t; |
jimherd | 0:9600ed6fd725 | 79 | |
jimherd | 0:9600ed6fd725 | 80 | enum {READ_REGISTER_CMD=0, WRITE_REGISTER_CMD=1}; |
jimherd | 0:9600ed6fd725 | 81 | enum {READ_BUS=0, WRITE_BUS=1}; |
jimherd | 0:9600ed6fd725 | 82 | enum {LOW=0, HIGH=1}; |
jimherd | 4:e5d36eee9245 | 83 | |
jimherd | 6:e68defb7b775 | 84 | // |
jimherd | 6:e68defb7b775 | 85 | // SYS_data registers |
jimherd | 6:e68defb7b775 | 86 | |
jimherd | 6:e68defb7b775 | 87 | enum {SYS_DATA_REG_ADDR=0}; |
jimherd | 6:e68defb7b775 | 88 | |
jimherd | 4:e5d36eee9245 | 89 | // PWM registers |
jimherd | 4:e5d36eee9245 | 90 | // |
jimherd | 0:9600ed6fd725 | 91 | enum {PWM_PERIOD=0, PWM_ON_TIME=1, PWM_CONFIG=2, PWM_STATUS=3}; |
jimherd | 0:9600ed6fd725 | 92 | |
jimherd | 4:e5d36eee9245 | 93 | // QE registers |
jimherd | 4:e5d36eee9245 | 94 | // |
jimherd | 4:e5d36eee9245 | 95 | enum {QE_COUNT_BUFFER=0, QE_TURN_BUFFER=1, QE_SPEED_BUFFER=2, QE_SIM_PHASE_TIME=3, |
jimherd | 4:e5d36eee9245 | 96 | QE_COUNTS_PER_REV=4, QE_CONFIG=5, QE_STATUS=6}; |
jimherd | 4:e5d36eee9245 | 97 | |
jimherd | 4:e5d36eee9245 | 98 | // RC servo registers |
jimherd | 4:e5d36eee9245 | 99 | // |
jimherd | 0:9600ed6fd725 | 100 | enum {RC_SERVO_PERIOD=0, RC_SERVO_CONFIG=1, RC_SERVO_STATUS=2, RC_SERVO_ON_TIME=3}; |
jimherd | 0:9600ed6fd725 | 101 | |
jimherd | 0:9600ed6fd725 | 102 | enum {PWM_OFF=0x0, PWM_ON=0x1}; |
jimherd | 0:9600ed6fd725 | 103 | enum {INT_H_BRIDGE_OFF=0x0, INT_H_BRIDGE_ON=0x10000}; |
jimherd | 0:9600ed6fd725 | 104 | enum {EXT_H_BRIDGE_OFF=0x0, EXT_H_BRIDGE_ON=0x20000}; |
jimherd | 0:9600ed6fd725 | 105 | enum {MOTOR_COAST=0x0, MOTOR_FORWARD=0x40000, MOTOR_BACKWARD=0x80000, MOTOR_BRAKE=0xC0000}; |
jimherd | 0:9600ed6fd725 | 106 | enum {MODE_PWM_CONTROL=0x0, MODE_DIR_CONTROL=0x200000}; |
jimherd | 0:9600ed6fd725 | 107 | enum {NO_SWAP=0x0, YES_SWAP=0x800000}; |
jimherd | 0:9600ed6fd725 | 108 | enum {PWM_BRAKE_DWELL=0x0, PWM_COAST_DWELL=0x1000000}; |
jimherd | 0:9600ed6fd725 | 109 | enum {NO_INVERT = 0x0, H_BRIDGE_1_INVERT=0x2000000, H_BRIDGE_2_INVERT=0x4000000, ALL_INVERT=0x6000000}; |
jimherd | 0:9600ed6fd725 | 110 | enum {BACKWARD, FORWARD}; |
jimherd | 0:9600ed6fd725 | 111 | |
jimherd | 0:9600ed6fd725 | 112 | //DigitalOut async_uP_start(ASYNC_UP_START_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 113 | //DigitalOut async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 114 | //DigitalOut async_uP_RW(ASYNC_UP_RW_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 115 | //DigitalOut async_uP_reset(ASYNC_UP_RESET_PIN, HIGH); |
jimherd | 0:9600ed6fd725 | 116 | //DigitalIn uP_ack(ASYNC_UP_ACK_PIN, PullDown); |
jimherd | 0:9600ed6fd725 | 117 | //DigitalIn uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN); |
jimherd | 0:9600ed6fd725 | 118 | |
jimherd | 0:9600ed6fd725 | 119 | class FPGA_bus { |
jimherd | 0:9600ed6fd725 | 120 | public: |
jimherd | 7:c0bef9c1f5d5 | 121 | // FPGA_bus(void); // constructor |
jimherd | 7:c0bef9c1f5d5 | 122 | FPGA_bus(int nos_PWM = NOS_PWM_CHANNELS , |
jimherd | 7:c0bef9c1f5d5 | 123 | int nos_QE = NOS_QE_CHANNELS , |
jimherd | 7:c0bef9c1f5d5 | 124 | int nos_servo = NOS_RC_CHANNELS ); // constructor |
jimherd | 7:c0bef9c1f5d5 | 125 | |
jimherd | 0:9600ed6fd725 | 126 | |
jimherd | 0:9600ed6fd725 | 127 | void initialise(void); |
jimherd | 0:9600ed6fd725 | 128 | uint32_t do_command(FPGA_packet_t cmd_packet); |
jimherd | 1:b819a72b3b5d | 129 | void set_PWM_period(uint32_t channel, float frequency); |
jimherd | 1:b819a72b3b5d | 130 | void set_PWM_duty(uint32_t channel, float percentage); |
jimherd | 1:b819a72b3b5d | 131 | void PWM_enable(uint32_t channel); |
jimherd | 1:b819a72b3b5d | 132 | void PWM_config(uint32_t channel, uint32_t config_value); |
jimherd | 4:e5d36eee9245 | 133 | void set_RC_period(void); |
jimherd | 4:e5d36eee9245 | 134 | void set_RC_period(uint32_t duty_uS); |
jimherd | 1:b819a72b3b5d | 135 | void set_RC_pulse(uint32_t channel, uint32_t pulse_uS); |
jimherd | 1:b819a72b3b5d | 136 | void enable_RC_channel(uint32_t channel); |
jimherd | 2:fd5c862b86db | 137 | void disable_RC_channel(uint32_t channel); |
jimherd | 4:e5d36eee9245 | 138 | void enable_speed_measure(uint32_t channel); |
jimherd | 5:64c677e9995c | 139 | uint32_t read_speed_measure(uint32_t channel); |
jimherd | 1:b819a72b3b5d | 140 | |
jimherd | 6:e68defb7b775 | 141 | uint32_t get_SYS_data(void); |
jimherd | 6:e68defb7b775 | 142 | |
jimherd | 1:b819a72b3b5d | 143 | int32_t global_FPGA_unit_error_flag; |
jimherd | 0:9600ed6fd725 | 144 | |
jimherd | 0:9600ed6fd725 | 145 | protected: |
jimherd | 0:9600ed6fd725 | 146 | uint32_t _nos_PWM_units; |
jimherd | 0:9600ed6fd725 | 147 | uint32_t _nos_QE_units; |
jimherd | 0:9600ed6fd725 | 148 | uint32_t _nos_servo_units; |
jimherd | 0:9600ed6fd725 | 149 | |
jimherd | 0:9600ed6fd725 | 150 | private: |
jimherd | 0:9600ed6fd725 | 151 | uint32_t data, status, tmp_config; |
jimherd | 0:9600ed6fd725 | 152 | received_packet_t in_pkt; |
jimherd | 0:9600ed6fd725 | 153 | |
jimherd | 0:9600ed6fd725 | 154 | void do_start(void); |
jimherd | 0:9600ed6fd725 | 155 | void do_end(void); |
jimherd | 0:9600ed6fd725 | 156 | void write_byte(uint32_t byte_value); |
jimherd | 0:9600ed6fd725 | 157 | uint32_t read_byte(void); |
jimherd | 0:9600ed6fd725 | 158 | void do_write( uint32_t command, |
jimherd | 0:9600ed6fd725 | 159 | uint32_t register_address, |
jimherd | 0:9600ed6fd725 | 160 | uint32_t register_data); |
jimherd | 0:9600ed6fd725 | 161 | void do_read(received_packet_t *buffer); |
jimherd | 0:9600ed6fd725 | 162 | void do_transaction(uint32_t command, |
jimherd | 0:9600ed6fd725 | 163 | uint32_t register_address, |
jimherd | 0:9600ed6fd725 | 164 | uint32_t register_data, |
jimherd | 0:9600ed6fd725 | 165 | uint32_t *data, |
jimherd | 0:9600ed6fd725 | 166 | uint32_t *status); |
jimherd | 0:9600ed6fd725 | 167 | |
jimherd | 0:9600ed6fd725 | 168 | DigitalOut async_uP_start; |
jimherd | 0:9600ed6fd725 | 169 | DigitalOut async_uP_handshake_1; |
jimherd | 0:9600ed6fd725 | 170 | DigitalOut async_uP_RW; |
jimherd | 0:9600ed6fd725 | 171 | DigitalOut async_uP_reset; |
jimherd | 0:9600ed6fd725 | 172 | DigitalIn uP_ack; |
jimherd | 0:9600ed6fd725 | 173 | DigitalIn uP_handshake_2; |
jimherd | 0:9600ed6fd725 | 174 | |
jimherd | 0:9600ed6fd725 | 175 | struct SYS_data { |
jimherd | 6:e68defb7b775 | 176 | uint8_t major_version; |
jimherd | 6:e68defb7b775 | 177 | uint8_t minor_version; |
jimherd | 6:e68defb7b775 | 178 | uint8_t number_of_PWM_channels; |
jimherd | 6:e68defb7b775 | 179 | uint8_t number_of_QE_channels; |
jimherd | 6:e68defb7b775 | 180 | uint8_t number_of_RC_channels; |
jimherd | 6:e68defb7b775 | 181 | uint8_t PWM_period_value[NOS_PWM_CHANNELS]; |
jimherd | 6:e68defb7b775 | 182 | uint8_t PWM_duty_value[NOS_PWM_CHANNELS]; |
jimherd | 6:e68defb7b775 | 183 | uint8_t pad1; |
jimherd | 0:9600ed6fd725 | 184 | } sys_data; |
jimherd | 0:9600ed6fd725 | 185 | }; |
jimherd | 0:9600ed6fd725 | 186 | |
jimherd | 0:9600ed6fd725 | 187 | #endif |
jimherd | 0:9600ed6fd725 | 188 |