Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: FPGA_bus.cpp
- Revision:
- 0:9600ed6fd725
- Child:
- 1:b819a72b3b5d
diff -r 000000000000 -r 9600ed6fd725 FPGA_bus.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FPGA_bus.cpp Wed Feb 20 16:42:55 2019 +0000 @@ -0,0 +1,183 @@ +/* + * FPGA_bus : 8-bit bi-directional bus between uP and FPGA + */ +#include "mbed.h" +#include "FPGA_bus.h" + +/** create a FPGA_bus object connecting uP to FPGA + * + * @param nos_PWM Number of PWM channels (default = 4) + * @param nos_QE Number of Quadrature Encoder channels (default = 4) + * @param nos_servo Number of RC servo channels (default = 8) + * + * Notes + * You can only change the defaults by recompiling the SystemVerilog code + * on the FPGA. + */ +FPGA_bus::FPGA_bus(int nos_PWM = NOS_PWM_CHANNELS, + int nos_QE = NOS_QE_CHANNELS, + int nos_servo = NOS_RC_CHANNELS) + + : async_uP_start(ASYNC_UP_START_PIN), + async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN), + async_uP_RW(ASYNC_UP_RW_PIN), + async_uP_reset(ASYNC_UP_RESET_PIN), + uP_ack(ASYNC_UP_ACK_PIN), + uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN) +{ + _nos_PWM_units = nos_PWM; + _nos_QE_units = nos_QE; + _nos_servo_units = nos_servo; + + async_uP_start = LOW; +} + +FPGA_bus::FPGA_bus(void) + : async_uP_start(ASYNC_UP_START_PIN), + async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN), + async_uP_RW(ASYNC_UP_RW_PIN), + async_uP_reset(ASYNC_UP_RESET_PIN), + uP_ack(ASYNC_UP_ACK_PIN), + uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN) +{ + _nos_PWM_units = NOS_PWM_CHANNELS; + _nos_QE_units = NOS_QE_CHANNELS; + _nos_servo_units = NOS_RC_CHANNELS; + + async_uP_start = LOW; +} + + + +void FPGA_bus::initialise(void) +{ + // GPIOC Periph clock enable + + ENABLE_GPIO_SUBSYSTEM; + wait_us(2); + + async_uP_start = LOW; + async_uP_reset = HIGH; + async_uP_handshake_1 = LOW; + async_uP_RW = LOW; + + async_uP_reset = LOW; // generate low reset pulse + wait_us(20); + async_uP_reset = HIGH; + wait_us(20); +} + +void FPGA_bus::do_start(void) +{ + async_uP_start = HIGH; + async_uP_handshake_1 = LOW; + async_uP_start = LOW; +} + +void FPGA_bus::do_end(void) +{ + while (uP_ack == HIGH) + ; + async_uP_start = LOW; +} + +void FPGA_bus::write_byte(uint32_t byte_value) +{ + SET_BUS_OUTPUT; + OUTPUT_BYTE_TO_BUS(byte_value); + async_uP_RW = WRITE_BUS; + async_uP_handshake_1 = HIGH; + while (uP_handshake_2 == LOW) + ; + async_uP_handshake_1 = LOW; + while (uP_handshake_2 == HIGH) + ; +} + +uint32_t FPGA_bus::read_byte(void) +{ + SET_BUS_INPUT; + async_uP_RW = READ_BUS; + while (uP_handshake_2 == LOW) + ; + data = INPUT_BYTE_FROM_BUS; + async_uP_handshake_1 = HIGH; + while (uP_handshake_2 == HIGH) + ; + async_uP_handshake_1 = LOW; + return data; +} + +void FPGA_bus::do_write(uint32_t command, + uint32_t register_address, + uint32_t register_data) +{ + write_byte(command); + write_byte(register_address); + write_byte(register_data); + write_byte(register_data>>8); + write_byte(register_data>>16); + write_byte(register_data>>24); +} + +void FPGA_bus::do_read(received_packet_t *buffer) +{ + for (int i=0; i < (NOS_RECEIVED_PACKET_WORDS<<2) ; i++) { + buffer->byte_data[i] = (uint8_t)read_byte(); + } +} + +void FPGA_bus::do_transaction(uint32_t command, + uint32_t register_address, + uint32_t register_data, + uint32_t *data, + uint32_t *status) +{ + do_start(); + // pc.printf("\n1"); + do_write(command, register_address, register_data); + // pc.printf(" 2"); + do_read(&in_pkt); + // pc.printf(" 3"); + do_end(); + // pc.printf(" 4\n"); + *data = in_pkt.word_data[0]; + *status = in_pkt.word_data[1]; + // pc.printf("data = %#08X :: status = %#08X\n", in_pkt.word_data[0], in_pkt.word_data[1]); +} + +uint32_t FPGA_bus::do_command(FPGA_packet_t cmd_packet) +{ + async_uP_start = LOW; + return 0; +} + +uint32_t FPGA_bus::set_PWM_period(uint32_t channel, float frequency) +{ + uint32_t period_value = (uint32_t)(1000000/(20 * frequency)); + do_transaction(WRITE_REGISTER_CMD, (channel + PWM_PERIOD) , period_value, &data, &status); + sys_data.PWM_period_value[channel] = period_value; + return status; +} + +uint32_t FPGA_bus::set_PWM_duty(uint32_t channel, float percentage) +{ + uint32_t duty_value = (uint32_t)((sys_data.PWM_period_value[channel] * percentage) / 100); + do_transaction(WRITE_REGISTER_CMD, (channel + PWM_ON_TIME) , duty_value, &data, &status); + sys_data.PWM_duty_value[channel] = duty_value; + return status; +} + +uint32_t FPGA_bus::PWM_enable(uint32_t channel) +{ + do_transaction(WRITE_REGISTER_CMD, (channel + PWM_CONFIG) , 1, &data, &status); + // sys_data.PWM_duty_value[channel] = duty_value; + return status; +} + +uint32_t FPGA_bus::PWM_config(uint32_t channel, uint32_t config_value) +{ + do_transaction(WRITE_REGISTER_CMD, (channel + PWM_CONFIG) , config_value, &data, &status); + sys_data.PWM_duty_value[channel] = config_value; + return status; +} \ No newline at end of file