mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Check in files for the FPGA CI Test Shield
Bring all the FPGA CI Test Shield C and C++ driver files into mbed-os as the component FPGA_CI_TEST_SHIELD. When this component is enabled all the files that are needed to communicate with, update firmware on and run testing with the FPGA are built.pull/10540/head
							parent
							
								
									42a9a7a573
								
							
						
					
					
						commit
						b3332129b2
					
				| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "DynamicPinList.h"
 | 
			
		||||
 | 
			
		||||
DynamicPinList::DynamicPinList()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DynamicPinList::DynamicPinList(const PinList *pin_list)
 | 
			
		||||
{
 | 
			
		||||
    for (uint32_t i = 0; i < pin_list->count; i++) {
 | 
			
		||||
        _pins.push_back(pin_list->pins[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DynamicPinList::DynamicPinList(const DynamicPinList &other)
 | 
			
		||||
{
 | 
			
		||||
    _pins = other._pins;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicPinList::add(PinName pin)
 | 
			
		||||
{
 | 
			
		||||
    _pins.push_back(pin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DynamicPinList::has_pin(PinName pin) const
 | 
			
		||||
{
 | 
			
		||||
    for (uint32_t i = 0; i < _pins.size(); i++) {
 | 
			
		||||
        if (pin == _pins[i]) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DynamicPinList::clear()
 | 
			
		||||
{
 | 
			
		||||
    _pins.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t DynamicPinList::count() const
 | 
			
		||||
{
 | 
			
		||||
    return _pins.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PinName DynamicPinList::get(uint32_t index) const
 | 
			
		||||
{
 | 
			
		||||
    return index < _pins.size() ? _pins[index] : NC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DynamicPinList::index(PinName pin) const
 | 
			
		||||
{
 | 
			
		||||
    for (uint32_t i = 0; i < _pins.size(); i++) {
 | 
			
		||||
        if (pin == _pins[i]) {
 | 
			
		||||
            return i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef DYNAMIC_PIN_LIST_H
 | 
			
		||||
#define DYNAMIC_PIN_LIST_H
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "pinmap.h"
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
class DynamicPinList {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an empty pin list
 | 
			
		||||
     */
 | 
			
		||||
    DynamicPinList();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a pin list with the given contents
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin_list List of pins to create this list from
 | 
			
		||||
     */
 | 
			
		||||
    DynamicPinList(const PinList *pin_list);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a copy of another list
 | 
			
		||||
     *
 | 
			
		||||
     * @param other Other object to copy contruct this from
 | 
			
		||||
     */
 | 
			
		||||
    DynamicPinList(const DynamicPinList &other);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a pin to the pin list
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to add to this pin list
 | 
			
		||||
     */
 | 
			
		||||
    void add(PinName pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the given pin is in this list
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to check for in the list
 | 
			
		||||
     * @return true if the pin is in the list, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool has_pin(PinName pin) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Empty this pin list
 | 
			
		||||
     */
 | 
			
		||||
    void clear();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return the number of pins in this list
 | 
			
		||||
     *
 | 
			
		||||
     * @return Elements in this list
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t count() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the pin at the given index
 | 
			
		||||
     *
 | 
			
		||||
     * @return Pin at this position
 | 
			
		||||
     */
 | 
			
		||||
    PinName get(uint32_t index) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the location of the given pin
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to get the index of
 | 
			
		||||
     * @return pin index or -1 if pin is not in the list
 | 
			
		||||
     */
 | 
			
		||||
    int index(PinName pin) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    vector<PinName> _pins;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,144 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "I2CTester.h"
 | 
			
		||||
#include "fpga_config.h"
 | 
			
		||||
 | 
			
		||||
uint8_t I2CTester::num_starts()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t num_starts = 0;
 | 
			
		||||
    read(TESTER_I2C_STARTS, &num_starts, sizeof(num_starts));
 | 
			
		||||
    return num_starts;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2CTester::num_stops()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t num_stops = 0;
 | 
			
		||||
    read(TESTER_I2C_STOPS, &num_stops, sizeof(num_stops));
 | 
			
		||||
    return num_stops;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t I2CTester::num_acks()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t num_acks = 0;
 | 
			
		||||
    read(TESTER_I2C_ACKS, (uint8_t*)&num_acks, sizeof(num_acks));
 | 
			
		||||
    return num_acks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t I2CTester::num_nacks()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t num_nacks = 0;
 | 
			
		||||
    read(TESTER_I2C_NACKS, (uint8_t*)&num_nacks, sizeof(num_nacks));
 | 
			
		||||
    return num_nacks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t I2CTester::transfer_count()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t transfers = 0;
 | 
			
		||||
    MBED_ASSERT(sizeof(transfers) == TESTER_I2C_TRANSFERS_SIZE);
 | 
			
		||||
    read(TESTER_I2C_TRANSFERS, (uint8_t*)&transfers, sizeof(transfers));
 | 
			
		||||
    return transfers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t I2CTester::get_receive_checksum()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t to_slave_checksum = 0;
 | 
			
		||||
    MBED_ASSERT(sizeof(to_slave_checksum) == TESTER_I2C_TO_SLAVE_CHECKSUM_SIZE);
 | 
			
		||||
    read(TESTER_I2C_TO_SLAVE_CHECKSUM, (uint8_t*)&to_slave_checksum, sizeof(to_slave_checksum));
 | 
			
		||||
    return to_slave_checksum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2CTester::state_num()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t state_num = 0;
 | 
			
		||||
    read(TESTER_I2C_STATE_NUM, &state_num, sizeof(state_num));
 | 
			
		||||
    return state_num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2CTester::num_dev_addr_matches()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t num_correct = 0;
 | 
			
		||||
    read(TESTER_I2C_NUMBER_DEV_ADDR_MATCHES, &num_correct, sizeof(num_correct));
 | 
			
		||||
    return num_correct;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void I2CTester::set_device_address(uint16_t addr)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t data = addr;
 | 
			
		||||
    write(TESTER_I2C_DEVICE_ADDRESS, (uint8_t*)&data, sizeof(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t I2CTester::get_device_address()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t addr = 0;
 | 
			
		||||
    read(TESTER_I2C_DEVICE_ADDRESS, (uint8_t*)&addr, sizeof(addr));
 | 
			
		||||
    return addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void I2CTester::set_sda(uint8_t value)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val = value;
 | 
			
		||||
    write(TESTER_I2C_SET_SDA, &val, sizeof(val));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t I2CTester::get_prev_to_slave_4()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t prev_to_slave_4 = 0;
 | 
			
		||||
    read(TESTER_I2C_PREV_TO_SLAVE_4, &prev_to_slave_4, sizeof(prev_to_slave_4));
 | 
			
		||||
    return prev_to_slave_4;
 | 
			
		||||
}
 | 
			
		||||
uint8_t I2CTester::get_prev_to_slave_3()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t prev_to_slave_3 = 0;
 | 
			
		||||
    read(TESTER_I2C_PREV_TO_SLAVE_3, &prev_to_slave_3, sizeof(prev_to_slave_3));
 | 
			
		||||
    return prev_to_slave_3;
 | 
			
		||||
}
 | 
			
		||||
uint8_t I2CTester::get_prev_to_slave_2()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t prev_to_slave_2 = 0;
 | 
			
		||||
    read(TESTER_I2C_PREV_TO_SLAVE_2, &prev_to_slave_2, sizeof(prev_to_slave_2));
 | 
			
		||||
    return prev_to_slave_2;
 | 
			
		||||
}
 | 
			
		||||
uint8_t I2CTester::get_prev_to_slave_1()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t prev_to_slave_1 = 0;
 | 
			
		||||
    read(TESTER_I2C_PREV_TO_SLAVE_1, &prev_to_slave_1, sizeof(prev_to_slave_1));
 | 
			
		||||
    return prev_to_slave_1;
 | 
			
		||||
}
 | 
			
		||||
void I2CTester::set_next_from_slave(uint8_t value)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val = value;
 | 
			
		||||
    write(TESTER_I2C_NEXT_FROM_SLAVE, &val, sizeof(val));
 | 
			
		||||
}
 | 
			
		||||
uint8_t I2CTester::get_next_from_slave()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t next_from_slave = 0;
 | 
			
		||||
    read(TESTER_I2C_NEXT_FROM_SLAVE, &next_from_slave, sizeof(next_from_slave));
 | 
			
		||||
    return next_from_slave;
 | 
			
		||||
}
 | 
			
		||||
uint16_t I2CTester::num_writes()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t num_writes = 0;
 | 
			
		||||
    read(TESTER_I2C_NUM_WRITES, (uint8_t*)&num_writes, sizeof(num_writes));
 | 
			
		||||
    return num_writes;
 | 
			
		||||
}
 | 
			
		||||
uint16_t I2CTester::num_reads()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t num_reads = 0;
 | 
			
		||||
    read(TESTER_I2C_NUM_READS, (uint8_t*)&num_reads, sizeof(num_reads));
 | 
			
		||||
    return num_reads;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,173 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef I2C_TESTER_H
 | 
			
		||||
#define I2C_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "MbedTester.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class I2CTester: public MbedTester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    I2CTester(const PinList *form_factor, const PinList *exclude_pins)
 | 
			
		||||
        : MbedTester(form_factor, exclude_pins)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* **I2C peripheral functions** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of start conditions since last I2C reset
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of start conditions
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t num_starts();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of stop conditions since last I2C reset
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of stop conditions
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t num_stops();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of ACKs since last I2C reset
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of ACKs
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t num_acks();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of NACKs since last I2C reset
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of NACKs
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t num_nacks();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the number of transfers which have occurred, not including the device address byte
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of I2C transfers that have completed since
 | 
			
		||||
     *         i2c was reset, not including the device address byte
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t transfer_count();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a checksum of data send to the tester
 | 
			
		||||
     *
 | 
			
		||||
     * @return The sum of all bytes sent to the tester since reset
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_receive_checksum();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the I2C slave state number
 | 
			
		||||
     *
 | 
			
		||||
     * @return The state number
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t state_num();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of times the device address has been sent correctly
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of times the device address has been sent correctly
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t num_dev_addr_matches();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the I2C slave device address
 | 
			
		||||
     *
 | 
			
		||||
     * @param addr New address for slave device
 | 
			
		||||
     */
 | 
			
		||||
    void set_device_address(uint16_t addr);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the I2C slave device address
 | 
			
		||||
     *
 | 
			
		||||
     * @return The slave device address
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_device_address();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set SDA (test mode)
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Test value for SDA
 | 
			
		||||
     */
 | 
			
		||||
    void set_sda(uint8_t value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value written to slave in the fourth to last transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @return value written to slave in the fourth to last transaction
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_prev_to_slave_4();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value written to slave in the third to last transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @return value written to slave in the third to last transaction
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_prev_to_slave_3();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value written to slave in the second to last transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @return value written to slave in the second to last transaction
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_prev_to_slave_2();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value written to slave in the last transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @return value written to slave in the last transaction
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_prev_to_slave_1();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the value to be read from slave in next read transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Value to be read from slave in next read transaction
 | 
			
		||||
     */
 | 
			
		||||
    void set_next_from_slave(uint8_t value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value to be read from slave in next read transaction
 | 
			
		||||
     *
 | 
			
		||||
     * @return Value to be read from slave in next read transaction
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_next_from_slave();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the number of writes which have occurred, not including the device address byte
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of I2C writes that have completed since
 | 
			
		||||
     *         i2c was reset, not including the device address byte
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t num_writes();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the number of reads which have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of I2C reads that have completed since
 | 
			
		||||
     *         i2c was reset
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t num_reads();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,878 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_TESTER_H
 | 
			
		||||
#define MBED_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "DynamicPinList.h"
 | 
			
		||||
 | 
			
		||||
class MbedTester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * This type represents the index of a physical pin on the FPGA.
 | 
			
		||||
     * This can be any value from 0 to 127. A form factor is used to
 | 
			
		||||
     * map a PinName to a physical pin index.
 | 
			
		||||
     */
 | 
			
		||||
    typedef uint8_t PhysicalIndex;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * There are 8 logical pins connected to the peripherals inside the FPGA.
 | 
			
		||||
     * These are logical pins 0 through 7. All peripherals can read from these
 | 
			
		||||
     * pins and the currently active peripheral can output on these pins.
 | 
			
		||||
     *
 | 
			
		||||
     * Each logical pin has a fixed function for a given peripheral which is
 | 
			
		||||
     * why the same value is defined multiple times. For example logical pin
 | 
			
		||||
     * 2 is SPI clock (SPISclk) when SPI is the active peripheral and
 | 
			
		||||
     * UART clear to send (UARTCts) when UART is the active peripheral.
 | 
			
		||||
     *
 | 
			
		||||
     * A logic pin can be mapped to any physical pin (PinName type) by calling
 | 
			
		||||
     * the function MbedTester::pin_map_set.
 | 
			
		||||
     */
 | 
			
		||||
    enum LogicalPin {
 | 
			
		||||
 | 
			
		||||
        LogicalPinGPIO0 = 0,
 | 
			
		||||
        LogicalPinGPIO1 = 1,
 | 
			
		||||
        LogicalPinGPIO2 = 2,
 | 
			
		||||
        LogicalPinGPIO3 = 3,
 | 
			
		||||
        LogicalPinGPIO4 = 4,
 | 
			
		||||
        LogicalPinGPIO5 = 5,
 | 
			
		||||
        LogicalPinGPIO6 = 6,
 | 
			
		||||
        LogicalPinGPIO7 = 7,
 | 
			
		||||
 | 
			
		||||
        LogicalPinSPIMosi = 0,
 | 
			
		||||
        LogicalPinSPIMiso = 1,
 | 
			
		||||
        LogicalPinSPISclk = 2,
 | 
			
		||||
        LogicalPinSPISsel = 3,
 | 
			
		||||
 | 
			
		||||
        LogicalPinIOMetrics0 = 0,
 | 
			
		||||
        LogicalPinIOMetrics1 = 1,
 | 
			
		||||
        LogicalPinIOMetrics2 = 2,
 | 
			
		||||
        LogicalPinIOMetrics3 = 3,
 | 
			
		||||
        LogicalPinIOMetrics4 = 4,
 | 
			
		||||
        LogicalPinIOMetrics5 = 5,
 | 
			
		||||
        LogicalPinIOMetrics6 = 6,
 | 
			
		||||
        LogicalPinIOMetrics7 = 7,
 | 
			
		||||
 | 
			
		||||
        LogicalPinUARTTx = 0,
 | 
			
		||||
        LogicalPinUARTRx = 1,
 | 
			
		||||
        LogicalPinUARTCts = 2,
 | 
			
		||||
        LogicalPinUARTRts = 3,
 | 
			
		||||
 | 
			
		||||
        LogicalPinI2CSda = 0,
 | 
			
		||||
        LogicalPinI2CScl = 1,
 | 
			
		||||
 | 
			
		||||
        LogicalPinCount = 8,
 | 
			
		||||
        LogicalPinBanks = 2,
 | 
			
		||||
        LogicalPinTotal = LogicalPinCount * LogicalPinBanks
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * These are the peripherals internal to the FPGA. A peripheral can be
 | 
			
		||||
     * selected by calling MbedTester::select_peripheral.
 | 
			
		||||
     */
 | 
			
		||||
    enum Peripheral {
 | 
			
		||||
        PeripheralGPIO = 1,
 | 
			
		||||
        PeripheralSPI = 2,
 | 
			
		||||
        PeripheralUART = 4,
 | 
			
		||||
        PeripheralI2C = 5,
 | 
			
		||||
        PeripheralSPISlave = 6
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a new MbedTester object
 | 
			
		||||
     *
 | 
			
		||||
     * The form factor pins passed into this class must match the
 | 
			
		||||
     * physical MbedTester shield connected to this board or testing
 | 
			
		||||
     * will not work correctly. The order of pins in this list must
 | 
			
		||||
     * match the order of the shield.
 | 
			
		||||
     *
 | 
			
		||||
     * The exclude pins list should be used to exclude pins which you either
 | 
			
		||||
     * don't want to be tested or are not suitable for use as a control
 | 
			
		||||
     * channel. This list is allowed to contain pins that are not in the
 | 
			
		||||
     * form factor.
 | 
			
		||||
     *
 | 
			
		||||
     * @param form_factor The pins that are available on this form factor
 | 
			
		||||
     * @param exclude_pins The pins that must not be used
 | 
			
		||||
     */
 | 
			
		||||
    MbedTester(const PinList *form_factor, const PinList *exclude_pins);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Destroy and cleanup resources associated with this object
 | 
			
		||||
     */
 | 
			
		||||
    ~MbedTester();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable automatic selection and update of control pins
 | 
			
		||||
     *
 | 
			
		||||
     * Calling this function configures MbedTester to automatically select
 | 
			
		||||
     * and update the control pins. The control pins are moved if the
 | 
			
		||||
     * function MbedTester::pin_map_set is called and maps a pin that is being used
 | 
			
		||||
     * for control.
 | 
			
		||||
     *
 | 
			
		||||
     * @note Automatic selection and update of control pins is the default.
 | 
			
		||||
     * Unless MbedTester::set_control_pins_manual has been called to manually
 | 
			
		||||
     * set the control pins this function has no effect.
 | 
			
		||||
     */
 | 
			
		||||
    void set_control_pins_auto();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the control pins to use for communication
 | 
			
		||||
     *
 | 
			
		||||
     * Manually set the control pins. Calling this function
 | 
			
		||||
     * disables automatic control pin selection and updates.
 | 
			
		||||
     * The function MbedTester::pin_map_set must not be used to map over
 | 
			
		||||
     * control pins when in this mode.
 | 
			
		||||
     *
 | 
			
		||||
     * @param clk Clock pin to use as the control channel
 | 
			
		||||
     * @param mosi Mosi pin to use as the control channel
 | 
			
		||||
     * @param miso Miso pin to use as the control channel
 | 
			
		||||
     * @param aux Auxillary pin to use as the control cannel
 | 
			
		||||
     */
 | 
			
		||||
    void set_control_pins_manual(PinName clk, PinName mosi, PinName miso, PinName aux);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read FPGA CI Test Shield firmware
 | 
			
		||||
     *
 | 
			
		||||
     * Read the firmware on the FPGA CI Test Shield. An optional progress callback
 | 
			
		||||
     * can be supplied to display progress while the firmware is being read.
 | 
			
		||||
     *
 | 
			
		||||
     * @param dest File to write the firmware to. This file must have been opened as writeable
 | 
			
		||||
     * @param progress Optional progress callback called when the percent complete changes
 | 
			
		||||
     * @return true if firmware was successfully read, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool firmware_dump(FileHandle *dest, Callback<void(uint8_t)> progress = Callback<void(uint8_t)>());
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read FPGA CI Test Shield flash
 | 
			
		||||
     *
 | 
			
		||||
     * Read the entire flash contents of the FPGA CI Test Shield. An optional progress callback
 | 
			
		||||
     * can be supplied to display progress while the firmware is being read.
 | 
			
		||||
     *
 | 
			
		||||
     * @param dest File to write the firmware to. This file must have been opened as writeable
 | 
			
		||||
     * @param progress Optional progress callback called when the percent complete changes
 | 
			
		||||
     * @return true if firmware was successfully read, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool firmware_dump_all(FileHandle *dest, Callback<void(uint8_t)> progress = Callback<void(uint8_t)>());
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Program new FPGA CI Test Shield firmware
 | 
			
		||||
     *
 | 
			
		||||
     * Program firmware from the file given. The binary bitstream must be in the correct format
 | 
			
		||||
     * and contain a correct CRC or the update will fail. To correctly format a bitstream binary
 | 
			
		||||
     * the post_process_bitstream.py script in the fpga-ci-test-shield repository should be used.
 | 
			
		||||
     *
 | 
			
		||||
     * Note - release binaries for the FPGA CI Test Shield have already been formatted and
 | 
			
		||||
     *        can be loaded directly with this function
 | 
			
		||||
     *
 | 
			
		||||
     * @param src File containing the new firmware to program
 | 
			
		||||
     * @param progress Optional progress callback called when the percent complete changes
 | 
			
		||||
     * @return true if firmware was successfully applied, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool firmware_update(FileHandle *src, Callback<void(uint8_t)> progress = Callback<void(uint8_t)>());
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Map a physical pin to the given logical pin
 | 
			
		||||
     *
 | 
			
		||||
     * This function will automatically move the control channel
 | 
			
		||||
     * pins to avoid interfering with the mapped pin.
 | 
			
		||||
     *
 | 
			
		||||
     * @param physical Physical pin on the board
 | 
			
		||||
     * @param logical Logical pin to map to
 | 
			
		||||
     */
 | 
			
		||||
    void pin_map_set(PinName physical, LogicalPin logical);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset all pin mappings
 | 
			
		||||
     *
 | 
			
		||||
     * After this call all pins will be unmapped
 | 
			
		||||
     */
 | 
			
		||||
    void pin_map_reset();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset all peripherals
 | 
			
		||||
     *
 | 
			
		||||
     * This does not reset the pin mappings
 | 
			
		||||
     */
 | 
			
		||||
    void peripherals_reset();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset everything
 | 
			
		||||
     *
 | 
			
		||||
     * This function resets the state of both the FPGA CI Test Shield
 | 
			
		||||
     * and the MbedTester object itself.
 | 
			
		||||
     *
 | 
			
		||||
     * Reset effects on the FPGA CI Test Shield include:
 | 
			
		||||
     * - All pins are tristated
 | 
			
		||||
     * - All pin mappings are reset
 | 
			
		||||
     * - All pullup/pulldown settings are reset
 | 
			
		||||
     * - All peripherals are reset
 | 
			
		||||
     *
 | 
			
		||||
     * Reset effects on the MbedTester object include
 | 
			
		||||
     * - Control channels tristated and freed
 | 
			
		||||
     * - Control channel selection set to automatic
 | 
			
		||||
     * - Most internal state reinitialized
 | 
			
		||||
     */
 | 
			
		||||
    void reset();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reprogram the FPGA
 | 
			
		||||
     *
 | 
			
		||||
     * This function causes the FPGA to reboot and reload RAM contents.
 | 
			
		||||
     * This should be used after MbedTester::firmware_update to load the
 | 
			
		||||
     * new image.
 | 
			
		||||
     */
 | 
			
		||||
    void reprogram();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the running FPGA firmware version
 | 
			
		||||
     *
 | 
			
		||||
     * @return The version of firmware running on the FPGA.
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t version();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Select the currently active peripheral
 | 
			
		||||
     *
 | 
			
		||||
     * @param peripheral Active peripheral
 | 
			
		||||
     */
 | 
			
		||||
    void select_peripheral(Peripheral peripheral);
 | 
			
		||||
 | 
			
		||||
    /* **GPIO peripheral functions** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a gpio pin
 | 
			
		||||
     *
 | 
			
		||||
     * @param gpio Logical pin to read from
 | 
			
		||||
     * @return 1 if the pin is high 0 if the pin is low
 | 
			
		||||
     */
 | 
			
		||||
    int gpio_read(LogicalPin gpio);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set value and drive of a gpio pin
 | 
			
		||||
     *
 | 
			
		||||
     * @param gpio Logical pin to write to
 | 
			
		||||
     * @param value 0 to set the pin low or non-zero to set it high
 | 
			
		||||
     * @param driver 0 to set the pin to Hi-Z or non-zero to drive the pin
 | 
			
		||||
     */
 | 
			
		||||
    void gpio_write(LogicalPin gpio, int value, bool drive);
 | 
			
		||||
 | 
			
		||||
    /* **IO Metrics functions** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start recording metrics on all logical pins
 | 
			
		||||
     *
 | 
			
		||||
     * This function resets all past metrics to 0. To
 | 
			
		||||
     * preserve these call io_metrics_continue instead.
 | 
			
		||||
     */
 | 
			
		||||
    void io_metrics_start();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop recording metrics on all logical pins
 | 
			
		||||
     *
 | 
			
		||||
     * This function should be called before any metrics
 | 
			
		||||
     * are read to ensure the value does not change while
 | 
			
		||||
     * they are being read.
 | 
			
		||||
     */
 | 
			
		||||
    void io_metrics_stop();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Continue recording metrics on all logical pins
 | 
			
		||||
     *
 | 
			
		||||
     * Resume recording metrics.
 | 
			
		||||
     */
 | 
			
		||||
    void io_metrics_continue();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the shortest low pulse recorded
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The shortest number of 100MHz clock cycles the pin was low
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_min_pulse_low(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the shortest high pulse recorded
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The shortest number of 100MHz clock cycles the pin was high
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_min_pulse_high(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the longest low pulse recorded
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The longest number of 100MHz clock cycles the pin was low
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_max_pulse_low(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the longest high pulse recorded
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The longest number of 100MHz clock cycles the pin was high
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_max_pulse_high(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of rising edges
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The number of rising edges
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_rising_edges(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of falling edges
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Pin to read the metrics for
 | 
			
		||||
     * @return The number of falling edges
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t io_metrics_falling_edges(LogicalPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reset the IO expander modules
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    void pin_pull_reset_all();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FPGA Pullup mode
 | 
			
		||||
     */
 | 
			
		||||
    enum PullMode {
 | 
			
		||||
        PullUp,
 | 
			
		||||
        PullDown,
 | 
			
		||||
        PullNone
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via PinName
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Mbed pin whose mode is being set
 | 
			
		||||
     * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
 | 
			
		||||
     * @return 0 on success, nonzero on failure
 | 
			
		||||
     */
 | 
			
		||||
    int pin_set_pull(PinName pin, PullMode mode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode via pin index
 | 
			
		||||
     *
 | 
			
		||||
     * @param index Mbed pin index whose mode is being set
 | 
			
		||||
     * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
 | 
			
		||||
     * @return 0 on success, nonzero on failure
 | 
			
		||||
     */
 | 
			
		||||
    int pin_set_pull_index(int index, PullMode mode);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Register of the IO expander
 | 
			
		||||
     */
 | 
			
		||||
    enum IOExpanderReg {
 | 
			
		||||
        RegInput,
 | 
			
		||||
        RegOutput,
 | 
			
		||||
        RegConfig
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander via PinName
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Mbed pin whose register bit is being read
 | 
			
		||||
     * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
 | 
			
		||||
     * @return The value of the bit read
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t io_expander_read(PinName pin, IOExpanderReg reg_type);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander via pin index
 | 
			
		||||
     *
 | 
			
		||||
     * @param index Mbed pin index whose register bit is being read
 | 
			
		||||
     * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
 | 
			
		||||
     * @return The value of the bit read
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t io_expander_read_index(int index, IOExpanderReg reg_type);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Configure an Mbed pin for a pulldown resistor, pullup resistor, or tristate mode
 | 
			
		||||
     * (this version of the function uses io_expander_i2c_read_bb and io_expander_i2c_write_bb)
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Mbed pin whose mode is being set
 | 
			
		||||
     * @param mode (MbedTester::PullUp, MbedTester::PullDown, or MbedTester::PullNone)
 | 
			
		||||
     * @return 0 on success, nonzero on failure
 | 
			
		||||
     */
 | 
			
		||||
    int pin_set_pull_bb(PinName pin, PullMode mode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a bit for a specific Mbed pin that is set in the input, output, or configuration registers inside of the IO expander
 | 
			
		||||
     * (this version of the function uses io_expander_i2c_read_bb)
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin Mbed pin whose register bit is being read
 | 
			
		||||
     * @param reg_type Pin register to access, options are: MbedTester::RegInput, MbedTester::RegOutput, or MbedTester::RegConfig
 | 
			
		||||
     * @return The value of the bit read
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t io_expander_read_bb(PinName pin, IOExpanderReg reg_type);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create an analog voltage via the FPGA sys pwm in order to test Mbed AnalogIn
 | 
			
		||||
     *
 | 
			
		||||
     * @param enable Enable the FPGA system PWM (false: of, true: on)
 | 
			
		||||
     * @param voltage The analog voltage that will be created by the FPGA CI test shield (float: 0.0 to 1.0)
 | 
			
		||||
     */
 | 
			
		||||
    void set_analog_out(bool enable, float voltage);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn the FPGA ADC on and off (power management data will be collected while the ADC is on)
 | 
			
		||||
     *
 | 
			
		||||
     * @param val FPGA ADC enable bit (false: off, true: on)
 | 
			
		||||
     */
 | 
			
		||||
    void set_sample_adc(bool val);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the result of the analog to digital conversion computed on the FPGA in the form of a voltage reading. The FPGA ADC operates on 0V-1V, which means this function will only ever return a float ranging from 0.0-1.0.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The conversion result in the form of a voltage measurement for AnalogMuxIn, Eg. a return value of 0.7 means the ADC on the FPGA read 0.7 volts on its analog input
 | 
			
		||||
     */
 | 
			
		||||
    float get_analog_in();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Similar to 'get_analog_in' but returns a voltage reading from ANIN0-3
 | 
			
		||||
     *
 | 
			
		||||
     * @param index ANIN pin to read (0-3)
 | 
			
		||||
     * @return The conversion result in the form of a voltage measurement for ANIN0-3
 | 
			
		||||
     */
 | 
			
		||||
    float get_anin_voltage(int index);
 | 
			
		||||
 | 
			
		||||
    /* **Mid level system access** */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * These are the pins on the FPGA that are not connected to the Mbed board.
 | 
			
		||||
     * These can be controlled by using MbedTester::sys_pin_read and MbedTester::sys_pin_write.
 | 
			
		||||
     * These should not be used directly when using the FPGA CI Test Shield. The higher layer
 | 
			
		||||
     * APIs should be used instead.
 | 
			
		||||
     */
 | 
			
		||||
    enum SystemPin {
 | 
			
		||||
        Reset,
 | 
			
		||||
        Reprogram,
 | 
			
		||||
 | 
			
		||||
        DigitalID0,
 | 
			
		||||
        DigitalID1,
 | 
			
		||||
        DigitalID2,
 | 
			
		||||
 | 
			
		||||
        Led0,
 | 
			
		||||
        Led1,
 | 
			
		||||
        Led2,
 | 
			
		||||
        Led3,
 | 
			
		||||
 | 
			
		||||
        SPIIO0,
 | 
			
		||||
        SPIIO1,
 | 
			
		||||
        SPIIO2,
 | 
			
		||||
        SPIIO3,
 | 
			
		||||
        SPIClk,
 | 
			
		||||
        SPICS,
 | 
			
		||||
 | 
			
		||||
        I2CReset,
 | 
			
		||||
        I2CSda0,
 | 
			
		||||
        I2CSda1,
 | 
			
		||||
        I2CSda2,
 | 
			
		||||
        I2CScl0,
 | 
			
		||||
        I2CScl1,
 | 
			
		||||
        I2CScl2,
 | 
			
		||||
 | 
			
		||||
        AnalogMuxEnable,
 | 
			
		||||
        AnalogMuxPwmOut,
 | 
			
		||||
        AnalogMuxIn,
 | 
			
		||||
        AnalogMuxAddr0,
 | 
			
		||||
        AnalogMuxAddr1,
 | 
			
		||||
        AnalogMuxAddr2,
 | 
			
		||||
        AnalogMuxAddr3,
 | 
			
		||||
        AnalogMuxAddr4,
 | 
			
		||||
        AnalogMuxAddr5,
 | 
			
		||||
        AnalogMuxAddr6,
 | 
			
		||||
        AnalogMuxAddr7,
 | 
			
		||||
 | 
			
		||||
        AnalogInP0,
 | 
			
		||||
        AnalogInP1,
 | 
			
		||||
        AnalogInP2,
 | 
			
		||||
        AnalogInP3,
 | 
			
		||||
        AnalogInN0,
 | 
			
		||||
        AnalogInN1,
 | 
			
		||||
        AnalogInN2,
 | 
			
		||||
        AnalogInN3,
 | 
			
		||||
 | 
			
		||||
        SystemPinCount
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read from the given system pin
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin The pin to read from
 | 
			
		||||
     * @return true if 1 was read, false if 0
 | 
			
		||||
     */
 | 
			
		||||
    bool sys_pin_read(SystemPin pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write to the given system pin
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin The pin to write to
 | 
			
		||||
     * @param value The value to output on the pin when driven
 | 
			
		||||
     * @param true to drive the output, false to set the output high-z
 | 
			
		||||
     * @return true if 1 was read, false if 0
 | 
			
		||||
     */
 | 
			
		||||
    void sys_pin_write(SystemPin pin, int value, bool drive);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * I2C read on I2C system channels 0, 1, or 2
 | 
			
		||||
     *
 | 
			
		||||
     * @param i2c_index The number corresponding to the system i2c bus being used (0, 1, or 2)
 | 
			
		||||
     * @param dev_addr The I2C address of the device being read from
 | 
			
		||||
     * @param start_reg The internal device address where the read will start
 | 
			
		||||
     * @param data Data buffer for data to be read into
 | 
			
		||||
     * @param length The number of bytes to read
 | 
			
		||||
     * @return 0 on success (ACK), nonzero on failure (NACK)
 | 
			
		||||
     */
 | 
			
		||||
    int io_expander_i2c_read(uint8_t i2c_index, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * I2C write on I2C system channels 0, 1, or 2
 | 
			
		||||
     *
 | 
			
		||||
     * @param i2c_index The number corresponding to the system i2c bus being used (0, 1, or 2)
 | 
			
		||||
     * @param dev_addr The I2C address of the device being written to
 | 
			
		||||
     * @param data The data to be written
 | 
			
		||||
     * @param length The number of bytes to be written
 | 
			
		||||
     * @return 0 on success (ACK), nonzero on failure (NACK)
 | 
			
		||||
     */
 | 
			
		||||
    int io_expander_i2c_write(uint8_t i2c_index, uint8_t dev_addr, uint8_t *data, int length);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * I2C read on I2C system channels 0, 1, or 2
 | 
			
		||||
     * (bit banged version of function, bit banged over control channel)
 | 
			
		||||
     *
 | 
			
		||||
     * @param sda System pin used for sda
 | 
			
		||||
     * @param scl System pin used for scl
 | 
			
		||||
     * @param dev_addr The I2C address of the device being read from
 | 
			
		||||
     * @param start_reg The internal device address where the read will start
 | 
			
		||||
     * @param data Data buffer for data to be read into
 | 
			
		||||
     * @param length The number of bytes to read
 | 
			
		||||
     * @return 0 on success (ACK), nonzero on failure (NACK)
 | 
			
		||||
     */
 | 
			
		||||
    int io_expander_i2c_read_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t start_reg, uint8_t *data, int length);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * I2C write on I2C system channels 0, 1, or 2
 | 
			
		||||
     * (bit banged version of function, bit banged over control channel)
 | 
			
		||||
     *
 | 
			
		||||
     * @param sda System pin used for sda
 | 
			
		||||
     * @param scl System pin used for scl
 | 
			
		||||
     * @param dev_addr The I2C address of the device being written to
 | 
			
		||||
     * @param data The data to be written
 | 
			
		||||
     * @param length The number of bytes to be written
 | 
			
		||||
     * @return 0 on success (ACK), nonzero on failure (NACK)
 | 
			
		||||
     */
 | 
			
		||||
    int io_expander_i2c_write_bb(SystemPin sda, SystemPin scl, uint8_t dev_addr, uint8_t *data, int length);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the AnalogMuxAddr pins on the FPGA via PinName
 | 
			
		||||
     *
 | 
			
		||||
     * @param pin The Mbed pin that the analog signal will be routed to
 | 
			
		||||
     * @return 0 on success, nonzero on failure
 | 
			
		||||
     */
 | 
			
		||||
    int set_mux_addr(PinName pin);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the AnalogMuxAddr pins on the FPGA via pin index
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The Mbed pin index that the analog signal will be routed to
 | 
			
		||||
     * @return 0 on success, nonzero on failure
 | 
			
		||||
     */
 | 
			
		||||
    int set_mux_addr_index(int index);
 | 
			
		||||
 | 
			
		||||
    /* **AnalogIn peripheral functions** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn on/off the analog muxes
 | 
			
		||||
     *
 | 
			
		||||
     * @param val false: off, true: on
 | 
			
		||||
     */
 | 
			
		||||
    void set_mux_enable(bool val);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn on/off pwm output on FPGA to test Mbed AnalogIn
 | 
			
		||||
     *
 | 
			
		||||
     * @param val false: off, true: on
 | 
			
		||||
     */
 | 
			
		||||
    void set_pwm_enable(bool val);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if FPGA pwm out is on or off
 | 
			
		||||
     *
 | 
			
		||||
     * @return FPGA enable bit (false: off, true: on)
 | 
			
		||||
     */
 | 
			
		||||
    bool get_pwm_enable();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the pwm output period and number of cycles high (duty cycle) on the FPGA
 | 
			
		||||
     *
 | 
			
		||||
     * @param period In units of clk cycles
 | 
			
		||||
     * @param cycles_high In units of clk cycles
 | 
			
		||||
     */
 | 
			
		||||
    void set_pwm_period_and_cycles_high(uint32_t period, uint32_t cycles_high);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the pwm output period of the FPGA
 | 
			
		||||
     *
 | 
			
		||||
     * @return FPGA pwm output period in units of clk cycles
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_pwm_period();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of cycles that are high (duty cycle) from FPGA pwm
 | 
			
		||||
     *
 | 
			
		||||
     * @return FPGA pwm output cycles high
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t get_pwm_cycles_high();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the 12-bit analog to digital conversion result from the FPGA
 | 
			
		||||
     *
 | 
			
		||||
     * @return 12-bit FPGA ADC result for AnalogMuxIn
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_analogmuxin_measurement();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Similar to 'get_analogmuxin_measurement' but returns the current XADC measurement for ANIN0-3
 | 
			
		||||
     *
 | 
			
		||||
     * @param index ANIN pin to read (0-3)
 | 
			
		||||
     * @return 12-bit FPGA ADC result for ANIN0-3
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_anin_measurement(int index);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets (by reference) the sum of all ANIN ADC results for any of the 4 ANIN pins specified by the index,
 | 
			
		||||
     * number of ADC sample sequences that have completed since the XADC was turned on, and the number of FPGA clk cycles
 | 
			
		||||
     * that have taken place since the ADC was turned on.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index ANIN pin of which to get sum of results (0-3)
 | 
			
		||||
     * @param sum The sum of all specified ANIN pin's ADC results
 | 
			
		||||
     * @param samples The number of ADC sample sequences that have completed since the XADC was turned on
 | 
			
		||||
     * @param cycles The number of FPGA clk cycles that have taken place since the ADC was turned on
 | 
			
		||||
     */
 | 
			
		||||
    void get_anin_sum_samples_cycles(int index, uint64_t *sum, uint32_t *samples, uint64_t *cycles);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allows safe reading of FPGA ADC related values while the FPGA ADC is on
 | 
			
		||||
     * If snapshot is set then the ADC values will be safely latched in the FPGA and safe to read.
 | 
			
		||||
     * The RTL will set snapshot to 0 after 1 clk cycle.
 | 
			
		||||
     */
 | 
			
		||||
    void set_snapshot();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the current system pin mode to disabled
 | 
			
		||||
     *
 | 
			
		||||
     * This releases any pin mappings that were set by the previous pin mode.
 | 
			
		||||
     */
 | 
			
		||||
    void sys_pin_mode_disabled();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the current system pin mode to serial flash
 | 
			
		||||
     *
 | 
			
		||||
     * Remap physical pins to the serial flash the FPGA boots from.
 | 
			
		||||
     * This is used for firmware updates.
 | 
			
		||||
     *
 | 
			
		||||
     * @param mosi The physical pin index to connect to serial flash mosi
 | 
			
		||||
     * @param miso The physical pin index to connect to serial flash miso
 | 
			
		||||
     * @param clk The physical pin index to connect to serial flash clk
 | 
			
		||||
     * @param ssel The physical pin index to connect to serial flash cs
 | 
			
		||||
     */
 | 
			
		||||
    void sys_pin_mode_spi_serial_flash(PhysicalIndex mosi, PhysicalIndex miso, PhysicalIndex clk, PhysicalIndex ssel);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the current system pin mode to io expander I2C bus
 | 
			
		||||
     *
 | 
			
		||||
     * Remap physical pins to the io expander I2C bus. The IO expanders
 | 
			
		||||
     * are used for setting pullups and pulldowns.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index The index of the I2C bus to connect to
 | 
			
		||||
     * @param sda_in Physical pin index for the FPGA to output the state of SDA on
 | 
			
		||||
     * @param sda_val Physical pin index for the FPGA to read SDA from. When in this mode the Mbed board
 | 
			
		||||
     *                must always drive this pin. Driving a 0 causes the FPGA to pull the SDA on the I2C bus low. Setting
 | 
			
		||||
     *                a 1 causes the FPGA to let SDA on the I2C bus float (and get pulled to 1).
 | 
			
		||||
     * @param scl_in Physical pin index for the FPGA to output the state of SCL on
 | 
			
		||||
     * @param scl_val Physical pin index for the FPGA to read SCL from. When in this mode the Mbed board
 | 
			
		||||
     *                must always drive this pin. Driving a 0 causes the FPGA to pull the SCL on the I2C bus low. Setting
 | 
			
		||||
     *                a 1 causes the FPGA to let SDA on the SCL bus float (and get pulled to 1).
 | 
			
		||||
     */
 | 
			
		||||
    void sys_pin_mode_i2c_io_expander(int index, PhysicalIndex sda_in, PhysicalIndex sda_val, PhysicalIndex scl_in, PhysicalIndex scl_val);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Map a physical pin index to the given logical pin
 | 
			
		||||
     *
 | 
			
		||||
     * This function will automatically move the control channel
 | 
			
		||||
     * pins to avoid interfering with the mapped pin. The physical
 | 
			
		||||
     * pin index does not need to be part of the form factor.
 | 
			
		||||
     *
 | 
			
		||||
     * @param physical_index Index of the physical pin on the board
 | 
			
		||||
     * @param logical Logical pin to map to
 | 
			
		||||
     */
 | 
			
		||||
    void pin_map_index(PhysicalIndex physical_index, LogicalPin logical);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* **Low level memory access** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write to tester memory
 | 
			
		||||
     *
 | 
			
		||||
     * @addr addr Address to write to
 | 
			
		||||
     * @param data Data to write
 | 
			
		||||
     * @param size Number of bytes to write
 | 
			
		||||
     */
 | 
			
		||||
    void write(uint32_t addr, const uint8_t *data, uint32_t size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read from tester memory
 | 
			
		||||
     *
 | 
			
		||||
     * @addr addr Address to read from
 | 
			
		||||
     * @param data Buffer to fill with data
 | 
			
		||||
     * @param size Number of bytes to read
 | 
			
		||||
     */
 | 
			
		||||
    void read(uint32_t addr, uint8_t *data, uint32_t size);
 | 
			
		||||
 | 
			
		||||
    /* **Self tests** */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Run all self tests
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if all self tests pass, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool self_test_all();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Test that all allowed control channels can be used
 | 
			
		||||
     *
 | 
			
		||||
     * Check that all pairs of clk and mosi which aren't in
 | 
			
		||||
     * the restricted list can be used.
 | 
			
		||||
     *
 | 
			
		||||
     * @note CLK and MOSI lines are paired, where CLK is always
 | 
			
		||||
     * on an even index and MOSI is always on an oddd index:
 | 
			
		||||
     * clk_index_N = N * 2
 | 
			
		||||
     * mosi_index_N = N * 2 + 1
 | 
			
		||||
     *
 | 
			
		||||
     * @note This functions sets the control pin management mode
 | 
			
		||||
     * to automatic when it completes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if all control channel pairs (clk and mosi) of this
 | 
			
		||||
     *         configuration can be used, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool self_test_control_channels();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Test that all allowed control miso lines can be used
 | 
			
		||||
     *
 | 
			
		||||
     * Check that every pin of this form factor aside from the
 | 
			
		||||
     * pins in the restricted list can be used as miso.
 | 
			
		||||
     *
 | 
			
		||||
     * @note This functions sets the control pin management mode
 | 
			
		||||
     * to automatic when it completes.
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if all control channel miso lines of this
 | 
			
		||||
     *         configuration can be used, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool self_test_control_miso();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Test that the current control channel works
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if communication is successful, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool self_test_control_current();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Find suitable control pins
 | 
			
		||||
     *
 | 
			
		||||
     * This function finds the appropriate set of pins and test to ensure that communication with
 | 
			
		||||
     * the FPGA can be performed over them. Before calling this function MbedTester pins must be
 | 
			
		||||
     * freed by calling MbedTester::_free_control_pins.
 | 
			
		||||
     *
 | 
			
		||||
     * @param clk_out Clock pin to find and set
 | 
			
		||||
     * @param mosi_out Mosi pin to find and set
 | 
			
		||||
     * @param miso_out Miso pin to find and set
 | 
			
		||||
     * @param aux_out Aux pin to find and set
 | 
			
		||||
     * @return true if all pins were found, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool _find_control_indexes(PhysicalIndex &clk_out, PhysicalIndex &mosi_out, PhysicalIndex &miso_out, PhysicalIndex &aux_out);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Allocate control pins
 | 
			
		||||
     *
 | 
			
		||||
     * The pin indexes must already have been found
 | 
			
		||||
     */
 | 
			
		||||
    void _setup_control_pins();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Free control pins
 | 
			
		||||
     *
 | 
			
		||||
     * This function is safe to call even if the pins have been freed
 | 
			
		||||
     */
 | 
			
		||||
    void _free_control_pins();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Update the control channel if needed
 | 
			
		||||
     *
 | 
			
		||||
     * Open a control channel using allowed pins:
 | 
			
		||||
     * - Pin must be in the form factor
 | 
			
		||||
     * - Pin must not be in the exclude list
 | 
			
		||||
     * - Pin must not be mapped already
 | 
			
		||||
     */
 | 
			
		||||
    void _update_control_pins();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Check if this control channel needs to be updated
 | 
			
		||||
     *
 | 
			
		||||
     * @return true if the control channel needs to be updated, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    bool _update_needed();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Reset the state of the MbedTester class
 | 
			
		||||
     *
 | 
			
		||||
     * This does not effect the state of the FPGA in any way.
 | 
			
		||||
     */
 | 
			
		||||
    void _reset();
 | 
			
		||||
 | 
			
		||||
    PhysicalIndex _mapping[LogicalPinCount * (LogicalPinBanks + 1)];
 | 
			
		||||
    DynamicPinList _form_factor;
 | 
			
		||||
    DynamicPinList _exclude_pins;
 | 
			
		||||
    bool _control_auto;
 | 
			
		||||
    bool _control_valid;
 | 
			
		||||
    PhysicalIndex _clk_index;
 | 
			
		||||
    PhysicalIndex _mosi_index;
 | 
			
		||||
    PhysicalIndex _miso_index;
 | 
			
		||||
    PhysicalIndex _aux_index;
 | 
			
		||||
    DigitalInOut *_clk;
 | 
			
		||||
    DigitalInOut *_mosi;
 | 
			
		||||
    DigitalInOut *_miso;
 | 
			
		||||
    DigitalInOut *_aux;
 | 
			
		||||
    /*
 | 
			
		||||
     * Used to reset IO expander chips only once the first time
 | 
			
		||||
     * any IO expander is accessed as well as during an io_exp_test
 | 
			
		||||
     */
 | 
			
		||||
    int _init_io_exp_rst_flag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "SPIMasterTester.h"
 | 
			
		||||
#include "fpga_config.h"
 | 
			
		||||
 | 
			
		||||
uint16_t SPIMasterTester::get_transfer_count()
 | 
			
		||||
{
 | 
			
		||||
    return SPITester::get_transfer_count(TESTER_SPI_MASTER_TRANSFERS, TESTER_SPI_MASTER_TRANSFERS_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SPIMasterTester::get_receive_checksum()
 | 
			
		||||
{
 | 
			
		||||
    return SPITester::get_receive_checksum(TESTER_SPI_MASTER_TO_SLAVE_CHECKSUM, TESTER_SPI_MASTER_TO_SLAVE_CHECKSUM_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPIMasterTester::set_mode(SPITester::SpiMode mode)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_mode(mode, TESTER_SPI_MASTER_CTRL, TESTER_SPI_MASTER_CTRL_SIZE, TESTER_SPI_MASTER_CLK_MODE_OFFSET, TESTER_SPI_MASTER_CLK_MODE_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPIMasterTester::set_bit_order(SPITester::SpiBitOrder bit_order)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_bit_order(bit_order, TESTER_SPI_MASTER_CTRL, TESTER_SPI_MASTER_CTRL_SIZE, TESTER_SPI_MASTER_BIT_ORDER_OFFSET, TESTER_SPI_MASTER_BIT_ORDER_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPIMasterTester::set_sym_size(uint32_t sym_size)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_sym_size(sym_size, TESTER_SPI_MASTER_CTRL, TESTER_SPI_MASTER_CTRL_SIZE, TESTER_SPI_MASTER_SYM_SIZE_OFFSET, TESTER_SPI_MASTER_SYM_SIZE_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPIMasterTester::set_duplex_mode(SPITester::SpiDuplex duplex)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_duplex_mode(duplex, TESTER_SPI_MASTER_CTRL, TESTER_SPI_MASTER_CTRL_SIZE, TESTER_SPI_MASTER_DUPLEX_OFFSET, TESTER_SPI_MASTER_DUPLEX_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPIMasterTester::set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_hd_tx_rx_cnt(tx_cnt, rx_cnt, TESTER_SPI_MASTER_HD_RX_CNT, TESTER_SPI_MASTER_HD_RX_CNT_SIZE, TESTER_SPI_MASTER_HD_TX_CNT, TESTER_SPI_MASTER_HD_TX_CNT_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SPIMasterTester::get_cs_to_first_clk_edge_ns()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t delay_ns;
 | 
			
		||||
    read(TESTER_SPI_MASTER_CS_TO_FIRST_SCLK_CNT, (uint8_t*)&delay_ns, TESTER_SPI_MASTER_CS_TO_FIRST_SCLK_CNT_SIZE);
 | 
			
		||||
 | 
			
		||||
    return (delay_ns * 10);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SPIMasterTester::get_last_clk_edge_to_cs_ns()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t delay_ns;
 | 
			
		||||
    read(TESTER_SPI_MASTER_LAST_SCLK_TO_CS_CNT, (uint8_t*)&delay_ns, TESTER_SPI_MASTER_LAST_SCLK_TO_CS_CNT_SIZE);
 | 
			
		||||
 | 
			
		||||
    return (delay_ns * 10);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SPI_MASTER_TESTER_H
 | 
			
		||||
#define SPI_MASTER_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "SPITester.h"
 | 
			
		||||
 | 
			
		||||
class SPIMasterTester: public SPITester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    SPIMasterTester(const PinList *form_factor, const PinList *exclude_pins)
 | 
			
		||||
        : SPITester(form_factor, exclude_pins)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the number of transfers which have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of SPI transfers that have completed since
 | 
			
		||||
     *         spi was reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_transfer_count();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a checksum of data send to the tester
 | 
			
		||||
     *
 | 
			
		||||
     * @return The sum of all bytes sent to the tester since reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_receive_checksum();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the clock mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_mode(SpiMode mode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set bit order durring transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_bit_order(SpiBitOrder bit_order);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set symbol size used durring transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_sym_size(uint32_t sym_size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set full-duplex/half-duplex transmission mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param duplex duplex mode used for the transmission
 | 
			
		||||
     */
 | 
			
		||||
    void set_duplex_mode(SpiDuplex duplex);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set tx/rx symbol count.
 | 
			
		||||
     *
 | 
			
		||||
     *  @tx_cnt TX symbol count
 | 
			
		||||
     *  @rx_cnt RX symbol count
 | 
			
		||||
     *
 | 
			
		||||
     *  @note Required only in Half-Duplex mode.
 | 
			
		||||
     */
 | 
			
		||||
    void set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get nano seconds between chip select assertion and the first spi clock edge.
 | 
			
		||||
     *
 | 
			
		||||
     *  @return nano seconds between chip select assertion and the first spi clock edge.
 | 
			
		||||
     *
 | 
			
		||||
     *  @note Number of nano seconds is calculated based of number of counted clk changes and
 | 
			
		||||
     *        clk frequency (100 MHz => 1 clk tick corresponds to 10 ns).
 | 
			
		||||
     *        Accuracy of the returned value is +/- 10 ns.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_cs_to_first_clk_edge_ns();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get nano seconds between last spi clock edge and chip select de-assertion.
 | 
			
		||||
     *
 | 
			
		||||
     *  @return nano seconds between last spi clock edge and chip select de-assertion.
 | 
			
		||||
     *
 | 
			
		||||
     *  @note Number of nano seconds is calculated based of number of counted clk changes and
 | 
			
		||||
     *        clk frequency (100 MHz => 1 clk tick corresponds to 10 ns).
 | 
			
		||||
     *        Accuracy of the returned value is +/- 10 ns.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_last_clk_edge_to_cs_ns();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "SPISlaveTester.h"
 | 
			
		||||
#include "fpga_config.h"
 | 
			
		||||
 | 
			
		||||
uint16_t SPISlaveTester::get_transfer_count()
 | 
			
		||||
{
 | 
			
		||||
    return SPITester::get_transfer_count(TESTER_SPI_SLAVE_TRANSFERS, TESTER_SPI_SLAVE_TRANSFERS_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SPISlaveTester::get_receive_checksum()
 | 
			
		||||
{
 | 
			
		||||
    return SPITester::get_receive_checksum(TESTER_SPI_SLAVE_TO_MASTER_CHECKSUM, TESTER_SPI_SLAVE_TO_MASTER_CHECKSUM_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_mode(SPITester::SpiMode mode)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_mode(mode, TESTER_SPI_SLAVE_CTRL, TESTER_SPI_SLAVE_CTRL_SIZE, TESTER_SPI_SLAVE_CLK_MODE_OFFSET, TESTER_SPI_SLAVE_CLK_MODE_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_bit_order(SPITester::SpiBitOrder bit_order)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_bit_order(bit_order, TESTER_SPI_SLAVE_CTRL, TESTER_SPI_SLAVE_CTRL_SIZE, TESTER_SPI_SLAVE_BIT_ORDER_OFFSET, TESTER_SPI_SLAVE_BIT_ORDER_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_sym_size(uint32_t sym_size)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_sym_size(sym_size, TESTER_SPI_SLAVE_CTRL, TESTER_SPI_SLAVE_CTRL_SIZE, TESTER_SPI_SLAVE_SYM_SIZE_OFFSET, TESTER_SPI_SLAVE_SYM_SIZE_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_duplex_mode(SPITester::SpiDuplex duplex)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_duplex_mode(duplex, TESTER_SPI_SLAVE_CTRL, TESTER_SPI_SLAVE_CTRL_SIZE, TESTER_SPI_SLAVE_DUPLEX_OFFSET, TESTER_SPI_SLAVE_DUPLEX_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt)
 | 
			
		||||
{
 | 
			
		||||
    SPITester::set_hd_tx_rx_cnt(tx_cnt, rx_cnt, TESTER_SPI_SLAVE_HD_RX_CNT, TESTER_SPI_SLAVE_HD_RX_CNT_SIZE, TESTER_SPI_SLAVE_HD_TX_CNT, TESTER_SPI_SLAVE_HD_TX_CNT_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_spi_master_freq(uint16_t clk_div)
 | 
			
		||||
{
 | 
			
		||||
    write(TESTER_SPI_SLAVE_CLK_DIV, (uint8_t*)&clk_div, TESTER_SPI_SLAVE_CLK_DIV_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_num_of_symbols(uint16_t num_of_sym)
 | 
			
		||||
{
 | 
			
		||||
    write(TESTER_SPI_SLAVE_NUM_OF_SYMBOLS, (uint8_t*)&num_of_sym, TESTER_SPI_SLAVE_NUM_OF_SYMBOLS_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_start_delay_us(uint8_t start_delay_us)
 | 
			
		||||
{
 | 
			
		||||
    write(TESTER_SPI_SLAVE_START_DELAY_US, (uint8_t*)&start_delay_us, TESTER_SPI_SLAVE_START_DELAY_US_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::set_sym_delay_ns(uint16_t sym_delay_ns)
 | 
			
		||||
{
 | 
			
		||||
    const uint16_t sym_delay_ticks = (sym_delay_ns + 9) / 10; // round up
 | 
			
		||||
    write(TESTER_SPI_SLAVE_SYM_DELAY_TICKS, (uint8_t*)&sym_delay_ticks, TESTER_SPI_SLAVE_SYM_DELAY_TICKS_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPISlaveTester::start_transfer()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t spi_ctrl = 0;
 | 
			
		||||
    read(TESTER_SPI_SLAVE_CTRL, (uint8_t*)&spi_ctrl, TESTER_SPI_SLAVE_CTRL_SIZE);
 | 
			
		||||
    spi_ctrl &= ~(((1  <<  TESTER_SPI_SLAVE_START_REQUEST_SIZE) - 1) << TESTER_SPI_SLAVE_START_REQUEST_OFFSET);
 | 
			
		||||
    spi_ctrl |= (1  <<  TESTER_SPI_SLAVE_START_REQUEST_OFFSET);
 | 
			
		||||
    write(TESTER_SPI_SLAVE_CTRL, (uint8_t*)&spi_ctrl, TESTER_SPI_SLAVE_CTRL_SIZE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SPI_SLAVE_TESTER_H
 | 
			
		||||
#define SPI_SLAVE_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "SPITester.h"
 | 
			
		||||
 | 
			
		||||
class SPISlaveTester: public SPITester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    SPISlaveTester(const PinList *form_factor, const PinList *exclude_pins)
 | 
			
		||||
        : SPITester(form_factor, exclude_pins)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the number of transfers which have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return The number of SPI transfers that have completed since
 | 
			
		||||
     *         spi was reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_transfer_count();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read a checksum of data sent to the tester
 | 
			
		||||
     *
 | 
			
		||||
     * @return The sum of all bytes sent to the tester since reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_receive_checksum();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the clock mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_mode(SpiMode mode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set bit order during transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_bit_order(SpiBitOrder bit_order);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set symbol size used during transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param mode Spi clock mode
 | 
			
		||||
     */
 | 
			
		||||
    void set_sym_size(uint32_t sym_size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set full-duplex/half-duplex transmission mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param duplex duplex mode used for the transmission
 | 
			
		||||
     */
 | 
			
		||||
    void set_duplex_mode(SpiDuplex duplex);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set tx/rx symbol count.
 | 
			
		||||
     *
 | 
			
		||||
     *  @tx_cnt TX symbol count
 | 
			
		||||
     *  @rx_cnt RX symbol count
 | 
			
		||||
     *
 | 
			
		||||
     *  @note Required only in Half-Duplex mode.
 | 
			
		||||
     */
 | 
			
		||||
    void set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set divisor to generate spi clock from FPGA base clock (100 MHz).
 | 
			
		||||
     *
 | 
			
		||||
     *  @clk_div clock divisor.
 | 
			
		||||
     */
 | 
			
		||||
    void set_spi_master_freq(uint16_t clk_div);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set number of symbols to be transmitted by spi master.
 | 
			
		||||
     *
 | 
			
		||||
     *  @num_of_sym Number of symbols to be transmitted by spi master.
 | 
			
		||||
     */
 | 
			
		||||
    void set_num_of_symbols(uint16_t num_of_sym);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set delay in us between start request and start of transmission.
 | 
			
		||||
     *
 | 
			
		||||
     *  @start_delay_us Delay in us between start request and start of transmission.
 | 
			
		||||
     */
 | 
			
		||||
    void set_start_delay_us(uint8_t start_delay_us);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set delay in ns between transmission of successive symbols.
 | 
			
		||||
     *
 | 
			
		||||
     *  @sym_delay_ns Delay in ns between transmission of successive symbols.
 | 
			
		||||
     */
 | 
			
		||||
    void set_sym_delay_ns(uint16_t sym_delay_ns);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Request transmission start from FPGA master.
 | 
			
		||||
     *
 | 
			
		||||
     *  @note Transmission will be started after the specified delay.
 | 
			
		||||
     */
 | 
			
		||||
    void start_transfer();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "SPITester.h"
 | 
			
		||||
#include "fpga_config.h"
 | 
			
		||||
 | 
			
		||||
uint16_t SPITester::get_transfer_count(uint32_t addr_transfers, uint32_t size_transfers)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t transfers = 0;
 | 
			
		||||
    MBED_ASSERT(sizeof(transfers) == size_transfers);
 | 
			
		||||
    read(addr_transfers, (uint8_t *)&transfers, sizeof(transfers));
 | 
			
		||||
    return transfers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SPITester::get_receive_checksum(uint32_t addr_checksum, uint32_t size_checksum)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t checksum = 0;
 | 
			
		||||
    MBED_ASSERT(sizeof(checksum) == size_checksum);
 | 
			
		||||
    read(addr_checksum, (uint8_t *)&checksum, sizeof(checksum));
 | 
			
		||||
    return checksum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPITester::set_mode(SPITester::SpiMode mode, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_clk_mode, uint32_t size_clk_mode)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t spi_ctrl = 0;
 | 
			
		||||
    read(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
    spi_ctrl &= ~(((1  <<  size_clk_mode) - 1) << offset_clk_mode);
 | 
			
		||||
    spi_ctrl |= (mode  <<  offset_clk_mode);
 | 
			
		||||
    write(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPITester::set_bit_order(SPITester::SpiBitOrder bit_order, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_bit_order, uint32_t size_bit_order)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t spi_ctrl = 0;
 | 
			
		||||
    read(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
    spi_ctrl &= ~(((1  <<  size_bit_order) - 1) << offset_bit_order);
 | 
			
		||||
    spi_ctrl |= (bit_order  <<  offset_bit_order);
 | 
			
		||||
    write(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPITester::set_sym_size(uint32_t sym_size, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_sym_size, uint32_t size_sym_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t spi_ctrl = 0;
 | 
			
		||||
    read(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
    spi_ctrl &= ~(((1  <<  size_sym_size) - 1) << offset_sym_size) ;
 | 
			
		||||
    spi_ctrl |= (sym_size  <<  offset_sym_size);
 | 
			
		||||
    write(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPITester::set_duplex_mode(SPITester::SpiDuplex duplex, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_duplex, uint32_t size_duplex)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t spi_ctrl = 0;
 | 
			
		||||
    read(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
    spi_ctrl &= ~(((1  <<  size_duplex) - 1) << offset_duplex);
 | 
			
		||||
    spi_ctrl |= (duplex  <<  offset_duplex);
 | 
			
		||||
    write(addr_spi_ctrl, (uint8_t*)&spi_ctrl, size_spi_ctrl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SPITester::set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt, uint32_t addr_hd_rx_cnt, uint32_t size_hd_rx_cnt, uint32_t addr_hd_tx_cnt, uint32_t size_hd_tx_cnt)
 | 
			
		||||
{
 | 
			
		||||
    write(addr_hd_rx_cnt, (uint8_t*)&rx_cnt, size_hd_rx_cnt);
 | 
			
		||||
    write(addr_hd_tx_cnt, (uint8_t*)&tx_cnt, size_hd_tx_cnt);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SPI_TESTER_H
 | 
			
		||||
#define SPI_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "MbedTester.h"
 | 
			
		||||
 | 
			
		||||
class SPITester: public MbedTester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    enum SpiMode {
 | 
			
		||||
        Mode0 = 0,
 | 
			
		||||
        Mode1 = 1,
 | 
			
		||||
        Mode2 = 2,
 | 
			
		||||
        Mode3 = 3
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum SpiBitOrder {
 | 
			
		||||
        MSBFirst = 0,
 | 
			
		||||
        LSBFirst = 1
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum SpiDuplex {
 | 
			
		||||
        FullDuplex = 0,
 | 
			
		||||
        HalfDuplex = 1
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    SPITester(const PinList *form_factor, const PinList *exclude_pins)
 | 
			
		||||
        : MbedTester(form_factor, exclude_pins)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /*
 | 
			
		||||
     * Read the number of transfers which have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * return The number of SPI transfers that have completed since
 | 
			
		||||
     *         spi was reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t get_transfer_count(uint32_t addr_transfers, uint32_t size_transfers);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Read a checksum of data send to the tester
 | 
			
		||||
     *
 | 
			
		||||
     * param addr_checksum Address of the FPGA checksum reg.
 | 
			
		||||
     * param size_checksum Size of the FPGA checksum reg.
 | 
			
		||||
     *
 | 
			
		||||
     * return The sum of all bytes sent to the tester since reset.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t get_receive_checksum(uint32_t addr_checksum, uint32_t size_checksum);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set the clock mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     * param mode Spi clock mode
 | 
			
		||||
     * param addr_spi_ctrl Address of the FPGA spi control reg.
 | 
			
		||||
     * param size_spi_ctrl Size of the FPGA FPGA spi control reg.
 | 
			
		||||
     * param offset_clk_mode Clock mode offset.
 | 
			
		||||
     * param size_clk_mode Clock mode size.
 | 
			
		||||
     */
 | 
			
		||||
    void set_mode(SpiMode mode, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_clk_mode, uint32_t size_clk_mode);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set bit order durring transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     * param bit_order Spi clock mode
 | 
			
		||||
     * param addr_spi_ctrl Address of the FPGA spi control reg.
 | 
			
		||||
     * param size_spi_ctrl Size of the FPGA FPGA spi control reg.
 | 
			
		||||
     * param offset_bit_order Bit order offset.
 | 
			
		||||
     * param size_bit_order Bit order size.
 | 
			
		||||
     */
 | 
			
		||||
    void set_bit_order(SpiBitOrder bit_order, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_bit_order, uint32_t size_bit_order);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set symbol size used durring transmission of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     * param sym_size Spi symbol size
 | 
			
		||||
     * param addr_spi_ctrl Address of the FPGA spi control reg.
 | 
			
		||||
     * param size_spi_ctrl Size of the FPGA FPGA spi control reg.
 | 
			
		||||
     * param offset_sym_size Symbol size offset.
 | 
			
		||||
     * param size_sym_size Symbol size size.
 | 
			
		||||
     */
 | 
			
		||||
    void set_sym_size(uint32_t sym_size, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_sym_size, uint32_t size_sym_size);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set full-duplex/half-duplex transmission mode of the spi_slave module.
 | 
			
		||||
     *
 | 
			
		||||
     * param duplex Duplex mode used for the transmission
 | 
			
		||||
     * param addr_spi_ctrl Address of the FPGA spi control reg.
 | 
			
		||||
     * param size_spi_ctrl Size of the FPGA FPGA spi control reg.
 | 
			
		||||
     * param offset_duplex Duplex mode offset.
 | 
			
		||||
     * param size_duplex Duplex mode size.
 | 
			
		||||
     */
 | 
			
		||||
    void set_duplex_mode(SpiDuplex duplex, uint32_t addr_spi_ctrl, uint32_t size_spi_ctrl, uint32_t offset_duplex, uint32_t size_duplex);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Set tx/rx symbol count.
 | 
			
		||||
     *
 | 
			
		||||
     * tx_cnt TX symbol count
 | 
			
		||||
     * rx_cnt RX symbol count
 | 
			
		||||
     * param addr_hd_rx_cnt Address of the FPGA half duplex RX count reg.
 | 
			
		||||
     * param size_hd_rx_cnt Size of the FPGA half duplex RX count reg.
 | 
			
		||||
     * param addr_hd_tx_cnt Address of the FPGA half duplex TX count reg.
 | 
			
		||||
     * param size_hd_tx_cnt Size of the FPGA half duplex TX count reg.
 | 
			
		||||
     *
 | 
			
		||||
     *  note Required only in Half-Duplex mode.
 | 
			
		||||
     */
 | 
			
		||||
    void set_hd_tx_rx_cnt(uint16_t tx_cnt, uint16_t rx_cnt, uint32_t addr_hd_rx_cnt, uint32_t size_hd_rx_cnt, uint32_t addr_hd_tx_cnt, uint32_t size_hd_tx_cnt);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,131 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "UARTTester.h"
 | 
			
		||||
#include "fpga_config.h"
 | 
			
		||||
 | 
			
		||||
void UARTTester::set_baud(uint32_t baudrate)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t divisor = TESTER_CLOCK_FREQUENCY_HZ / baudrate;
 | 
			
		||||
    // Baud divisor is only 16 bits
 | 
			
		||||
    MBED_ASSERT((divisor & 0xFFFF0000) == 0);
 | 
			
		||||
    write(TESTER_UART_BAUD_DIVISOR, (uint8_t *)&divisor, TESTER_UART_BAUD_DIVISOR_SIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::set_bits(uint8_t data_bits)
 | 
			
		||||
{
 | 
			
		||||
    // Check for supported range
 | 
			
		||||
    MBED_ASSERT((data_bits >= 1) && (data_bits <= 16));
 | 
			
		||||
    write(TESTER_UART_BIT_COUNT, &data_bits, sizeof(data_bits));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::set_stops(uint8_t stop_bits)
 | 
			
		||||
{
 | 
			
		||||
    // Check for supported range
 | 
			
		||||
    MBED_ASSERT((stop_bits >= 1) && (stop_bits <= 16));
 | 
			
		||||
    write(TESTER_UART_STOP_COUNT, &stop_bits, sizeof(stop_bits));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::set_parity(bool enable, bool odd_n_even)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t parity = (enable ? TESTER_UART_PARITY_ENABLE : 0) |
 | 
			
		||||
            (odd_n_even ? TESTER_UART_PARITY_ODD_N_EVEN : 0);
 | 
			
		||||
    write(TESTER_UART_PARITY, &parity, sizeof(parity));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::rx_start()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = TESTER_UART_RX_CONTROL_ENABLE;
 | 
			
		||||
    write(TESTER_UART_RX_CONTROL, &data, sizeof(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::rx_stop()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data = 0;
 | 
			
		||||
    write(TESTER_UART_RX_CONTROL, &data, sizeof(data));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t UARTTester::rx_get_checksum()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t checksum = 0;
 | 
			
		||||
    read(TESTER_UART_RX_CHECKSUM, (uint8_t *)&checksum, sizeof(checksum));
 | 
			
		||||
    return checksum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t UARTTester::rx_get_count()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t count = 0;
 | 
			
		||||
    read(TESTER_UART_RX_COUNT, (uint8_t *)&count, sizeof(count));
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t UARTTester::rx_get_data(int prev)
 | 
			
		||||
{
 | 
			
		||||
    MBED_ASSERT((prev >= 1) && (prev <= 4));
 | 
			
		||||
    uint16_t data = 0;
 | 
			
		||||
    read(TESTER_UART_RX_PREV_1 - (prev - 1) * 2, (uint8_t *)&data, sizeof(data));
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t UARTTester::rx_get_parity_errors()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t errors = 0;
 | 
			
		||||
    read(TESTER_UART_RX_PARITY_ERRORS, (uint8_t *)&errors, sizeof(errors));
 | 
			
		||||
    return errors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t UARTTester::rx_get_stop_errors()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t errors = 0;
 | 
			
		||||
    read(TESTER_UART_RX_STOP_ERRORS, (uint8_t *)&errors, sizeof(errors));
 | 
			
		||||
    return errors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t UARTTester::rx_get_framing_errors()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t errors = 0;
 | 
			
		||||
    read(TESTER_UART_RX_FRAMING_ERRORS, (uint8_t *)&errors, sizeof(errors));
 | 
			
		||||
    return errors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::tx_start(bool cts_enabled)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t control = TESTER_UART_TX_CONTROL_ENABLE | (cts_enabled ? TESTER_UART_TX_CONTROL_ENABLE_CTS : 0);
 | 
			
		||||
    write(TESTER_UART_TX_CONTROL, (uint8_t *)&control, sizeof(control));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::tx_stop()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t control = 0;
 | 
			
		||||
    write(TESTER_UART_TX_CONTROL, (uint8_t *)&control, sizeof(control));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::tx_set_count(uint32_t count)
 | 
			
		||||
{
 | 
			
		||||
    write(TESTER_UART_TX_COUNT, (uint8_t *)&count, sizeof(count));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::tx_set_next(uint16_t value)
 | 
			
		||||
{
 | 
			
		||||
    write(TESTER_UART_TX_NEXT, (uint8_t *)&value, sizeof(value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTTester::cts_deassert_delay(uint32_t delay_ns)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t delay_clks = delay_ns / TESTER_CLOCK_PERIOD_NS;
 | 
			
		||||
    write(TESTER_UART_CTS_DEACTIVATE_DELAY, (uint8_t *)&delay_clks, sizeof(delay_clks));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,158 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UART_TESTER_H
 | 
			
		||||
#define UART_TESTER_H
 | 
			
		||||
 | 
			
		||||
#include "MbedTester.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UARTTester: public MbedTester {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    UARTTester(const PinList *form_factor, const PinList *exclude_pins)
 | 
			
		||||
        : MbedTester(form_factor, exclude_pins)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the baudrate for uart TX and RX
 | 
			
		||||
     *
 | 
			
		||||
     * @param baudrate Target baudrate in HZ
 | 
			
		||||
     */
 | 
			
		||||
    void set_baud(uint32_t baudrate);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the number of data bits
 | 
			
		||||
     *
 | 
			
		||||
     * Supported values for data bits is 1 to 16
 | 
			
		||||
     *
 | 
			
		||||
     * @param data_bits The number of data bits in this transfer
 | 
			
		||||
     */
 | 
			
		||||
    void set_bits(uint8_t data_bits);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the number of stop bits
 | 
			
		||||
     *
 | 
			
		||||
     * Supported values for stop bits is 1 to 16
 | 
			
		||||
     *
 | 
			
		||||
     * @param stop_bits The number of stop bits to end the transfer with
 | 
			
		||||
     */
 | 
			
		||||
    void set_stops(uint8_t stop_bits);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable or disable parity checking
 | 
			
		||||
     *
 | 
			
		||||
     * @param enable true to enable parity checking, false to disable it
 | 
			
		||||
     * @param odd_n_even true of odd parity, false for even
 | 
			
		||||
     */
 | 
			
		||||
    void set_parity(bool enable, bool odd_n_even);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable UART reception
 | 
			
		||||
     */
 | 
			
		||||
    void rx_start();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Disable UART reception
 | 
			
		||||
     */
 | 
			
		||||
    void rx_stop();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the sum of all bytes received
 | 
			
		||||
     *
 | 
			
		||||
     * @return the sum of all bytes received
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t rx_get_checksum();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of bytes received
 | 
			
		||||
     *
 | 
			
		||||
     * @return the number of bytes received
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t rx_get_count();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the previous data(s) sent
 | 
			
		||||
     *
 | 
			
		||||
     * @param prev index of data to get 1 for the previous
 | 
			
		||||
     * @return data
 | 
			
		||||
     */
 | 
			
		||||
    uint16_t rx_get_data(int prev = 1);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of parity errors that have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return number of parity errors that have occurred
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t rx_get_parity_errors();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of stop errors that have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return number of stop errors that have occurred
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t rx_get_stop_errors();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the number of framing errors that have occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @return number of framing errors that have occurred
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t rx_get_framing_errors();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start UART transmission
 | 
			
		||||
     */
 | 
			
		||||
    void tx_start(bool cts_enabled=false);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop UART transmission
 | 
			
		||||
     */
 | 
			
		||||
    void tx_stop();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the number of bytes to send
 | 
			
		||||
     *
 | 
			
		||||
     * @param count Number of bytes to send when started
 | 
			
		||||
     */
 | 
			
		||||
    void tx_set_count(uint32_t count);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set next sequence value to send
 | 
			
		||||
     *
 | 
			
		||||
     * When TX is started 'count' bytes will be sent. Each value will
 | 
			
		||||
     * be one greater than the previous.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value Next value to send
 | 
			
		||||
     */
 | 
			
		||||
    void tx_set_next(uint16_t value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the delay seen when deasserting the CTS line
 | 
			
		||||
     *
 | 
			
		||||
     * When delay is set to 0 then transmission will be immediately
 | 
			
		||||
     * stopped when CTS goes to 1.
 | 
			
		||||
     *
 | 
			
		||||
     * @param delay in nanoseconds
 | 
			
		||||
     */
 | 
			
		||||
    void cts_deassert_delay(uint32_t delay_ns);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,190 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define TESTER_CLOCK_FREQUENCY_HZ                     100000000
 | 
			
		||||
#define TESTER_CLOCK_PERIOD_NS                        10
 | 
			
		||||
#define TESTER_CONTROL                                0x00000000
 | 
			
		||||
#define TESTER_CONTROL_RESET                          0x00000000
 | 
			
		||||
#define TESTER_CONTROL_RESET_PERIPHERALS              (1 << 0)
 | 
			
		||||
#define TESTER_CONTROL_RESET_ALL                      (1 << 1)
 | 
			
		||||
#define TESTER_CONTROL_REPROGRAM                      (1 << 2)
 | 
			
		||||
#define TESTER_CONTROL_VERSION                        0x00000010
 | 
			
		||||
#define TESTER_CONTROL_VERSION_SIZE                   4
 | 
			
		||||
#define TESTER_REMAP                                  0x00001000
 | 
			
		||||
#define TESTER_SYS_IO                                 0x00002000
 | 
			
		||||
#define TESTER_SYS_IO_MODE                            (0x000 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_IO_MODE_DISABLED                   0
 | 
			
		||||
#define TESTER_SYS_IO_MODE_SPI_SERIAL_FLASH           1
 | 
			
		||||
#define TESTER_SYS_IO_MODE_I2C_IO_EXPANDER0           2
 | 
			
		||||
#define TESTER_SYS_IO_MODE_I2C_IO_EXPANDER1           3
 | 
			
		||||
#define TESTER_SYS_IO_MODE_I2C_IO_EXPANDER2           4
 | 
			
		||||
#define TESTER_SYS_IO_PWM_ENABLE                      (0x001 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_IO_PWM_PERIOD                      (0x002 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_IO_PWM_CYCLES_HIGH                 (0x006 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_AN_MUX_ANALOGIN_MEASUREMENT        (0x00A + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_NUM_POWER_SAMPLES                  (0x00C + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_NUM_POWER_CYCLES                   (0x010 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ADC_SNAPSHOT                       (0x018 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_SAMPLE_ADC                         (0x019 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN0_MEASUREMENT                  (0x030 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN0_MEASUREMENTS_SUM             (0x032 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN1_MEASUREMENT                  (0x03A + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN1_MEASUREMENTS_SUM             (0x03C + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN2_MEASUREMENT                  (0x044 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN2_MEASUREMENTS_SUM             (0x046 + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN3_MEASUREMENT                  (0x04E + 0x00002C00)
 | 
			
		||||
#define TESTER_SYS_ANIN3_MEASUREMENTS_SUM             (0x050 + 0x00002C00)
 | 
			
		||||
#define TESTER_PERIPHERAL                             0x00100000
 | 
			
		||||
#define TESTER_PERIPHERAL_SELECT                      0x00100000
 | 
			
		||||
#define TESTER_GPIO                                   0x00101000
 | 
			
		||||
#define TESTER_SPI_MASTER                             0x00102000
 | 
			
		||||
#define TESTER_SPI_MASTER_STARTS                      0x00102008
 | 
			
		||||
#define TESTER_SPI_MASTER_STOPS                       0x00102009
 | 
			
		||||
#define TESTER_SPI_MASTER_TRANSFERS                   0x0010200A
 | 
			
		||||
#define TESTER_SPI_MASTER_TRANSFERS_SIZE              2
 | 
			
		||||
#define TESTER_SPI_MASTER_TO_SLAVE_CHECKSUM           0x00102012
 | 
			
		||||
#define TESTER_SPI_MASTER_TO_SLAVE_CHECKSUM_SIZE      4
 | 
			
		||||
#define TESTER_SPI_MASTER_CTRL                        0x00102016
 | 
			
		||||
#define TESTER_SPI_MASTER_CTRL_SIZE                   2
 | 
			
		||||
#define TESTER_SPI_MASTER_HD_TX_CNT                   0x00102018
 | 
			
		||||
#define TESTER_SPI_MASTER_HD_TX_CNT_SIZE              2
 | 
			
		||||
#define TESTER_SPI_MASTER_HD_RX_CNT                   0x0010201A
 | 
			
		||||
#define TESTER_SPI_MASTER_HD_RX_CNT_SIZE              2
 | 
			
		||||
#define TESTER_SPI_MASTER_CS_TO_FIRST_SCLK_CNT        0x0010201C
 | 
			
		||||
#define TESTER_SPI_MASTER_CS_TO_FIRST_SCLK_CNT_SIZE   4
 | 
			
		||||
#define TESTER_SPI_MASTER_LAST_SCLK_TO_CS_CNT         0x00102020
 | 
			
		||||
#define TESTER_SPI_MASTER_LAST_SCLK_TO_CS_CNT_SIZE    4
 | 
			
		||||
#define TESTER_SPI_MASTER_CLK_MODE_OFFSET             0
 | 
			
		||||
#define TESTER_SPI_MASTER_CLK_MODE_SIZE               2
 | 
			
		||||
#define TESTER_SPI_MASTER_BIT_ORDER_OFFSET            2
 | 
			
		||||
#define TESTER_SPI_MASTER_BIT_ORDER_SIZE              1
 | 
			
		||||
#define TESTER_SPI_MASTER_DUPLEX_OFFSET               3
 | 
			
		||||
#define TESTER_SPI_MASTER_DUPLEX_SIZE                 1
 | 
			
		||||
#define TESTER_SPI_MASTER_SYM_SIZE_OFFSET             4
 | 
			
		||||
#define TESTER_SPI_MASTER_SYM_SIZE_SIZE               6
 | 
			
		||||
#define TESTER_SPI_SLAVE                              0x00106000
 | 
			
		||||
#define TESTER_SPI_SLAVE_STARTS                       0x00106008
 | 
			
		||||
#define TESTER_SPI_SLAVE_STOPS                        0x00106009
 | 
			
		||||
#define TESTER_SPI_SLAVE_TRANSFERS                    0x0010600A
 | 
			
		||||
#define TESTER_SPI_SLAVE_TRANSFERS_SIZE               2
 | 
			
		||||
#define TESTER_SPI_SLAVE_TO_MASTER_CHECKSUM           0x00106015
 | 
			
		||||
#define TESTER_SPI_SLAVE_TO_MASTER_CHECKSUM_SIZE      4
 | 
			
		||||
#define TESTER_SPI_SLAVE_CTRL                         0x00106019
 | 
			
		||||
#define TESTER_SPI_SLAVE_CTRL_SIZE                    2
 | 
			
		||||
#define TESTER_SPI_SLAVE_HD_TX_CNT                    0x0010601B
 | 
			
		||||
#define TESTER_SPI_SLAVE_HD_TX_CNT_SIZE               2
 | 
			
		||||
#define TESTER_SPI_SLAVE_HD_RX_CNT                    0x0010601D
 | 
			
		||||
#define TESTER_SPI_SLAVE_HD_RX_CNT_SIZE               2
 | 
			
		||||
#define TESTER_SPI_SLAVE_CLK_DIV                      0x0010601F
 | 
			
		||||
#define TESTER_SPI_SLAVE_CLK_DIV_SIZE                 2
 | 
			
		||||
#define TESTER_SPI_SLAVE_NUM_OF_SYMBOLS               0x00106021
 | 
			
		||||
#define TESTER_SPI_SLAVE_NUM_OF_SYMBOLS_SIZE          2
 | 
			
		||||
#define TESTER_SPI_SLAVE_START_DELAY_US               0x00106023
 | 
			
		||||
#define TESTER_SPI_SLAVE_START_DELAY_US_SIZE          1
 | 
			
		||||
#define TESTER_SPI_SLAVE_SYM_DELAY_TICKS              0x00106024
 | 
			
		||||
#define TESTER_SPI_SLAVE_SYM_DELAY_TICKS_SIZE         2
 | 
			
		||||
#define TESTER_SPI_SLAVE_CLK_MODE_OFFSET              0
 | 
			
		||||
#define TESTER_SPI_SLAVE_CLK_MODE_SIZE                2
 | 
			
		||||
#define TESTER_SPI_SLAVE_BIT_ORDER_OFFSET             2
 | 
			
		||||
#define TESTER_SPI_SLAVE_BIT_ORDER_SIZE               1
 | 
			
		||||
#define TESTER_SPI_SLAVE_DUPLEX_OFFSET                3
 | 
			
		||||
#define TESTER_SPI_SLAVE_DUPLEX_SIZE                  1
 | 
			
		||||
#define TESTER_SPI_SLAVE_SYM_SIZE_OFFSET              4
 | 
			
		||||
#define TESTER_SPI_SLAVE_SYM_SIZE_SIZE                6
 | 
			
		||||
#define TESTER_SPI_SLAVE_START_REQUEST_OFFSET         10
 | 
			
		||||
#define TESTER_SPI_SLAVE_START_REQUEST_SIZE           1
 | 
			
		||||
#define TESTER_IO_METRICS                             0x00103000
 | 
			
		||||
#define TESTER_IO_METRICS_CTRL                        0x00103000
 | 
			
		||||
#define TESTER_IO_METRICS_CTRL_ACTIVE_BIT             (1 << 0)
 | 
			
		||||
#define TESTER_IO_METRICS_CTRL_RESET_BIT              (1 << 1)
 | 
			
		||||
#define TESTER_IO_METRICS_BASE(i)                     (0x00103040 + 0x40 * (i))
 | 
			
		||||
#define TESTER_IO_METRICS_MIN_PULSE_LOW(i)            (TESTER_IO_METRICS_BASE(i) + 0x00)
 | 
			
		||||
#define TESTER_IO_METRICS_MIN_PULSE_LOW_SIZE          4
 | 
			
		||||
#define TESTER_IO_METRICS_MIN_PULSE_HIGH(i)           (TESTER_IO_METRICS_BASE(i) + 0x04)
 | 
			
		||||
#define TESTER_IO_METRICS_MIN_PULSE_HIGH_SIZE         4
 | 
			
		||||
#define TESTER_IO_METRICS_MAX_PULSE_LOW(i)            (TESTER_IO_METRICS_BASE(i) + 0x08)
 | 
			
		||||
#define TESTER_IO_METRICS_MAX_PULSE_LOW_SIZE          4
 | 
			
		||||
#define TESTER_IO_METRICS_MAX_PULSE_HIGH(i)           (TESTER_IO_METRICS_BASE(i) + 0x0C)
 | 
			
		||||
#define TESTER_IO_METRICS_MAX_PULSE_HIGH_SIZE         4
 | 
			
		||||
#define TESTER_IO_METRICS_RISING_EDGES(i)             (TESTER_IO_METRICS_BASE(i) + 0x10)
 | 
			
		||||
#define TESTER_IO_METRICS_RISING_EDGES_SIZE           4
 | 
			
		||||
#define TESTER_IO_METRICS_FALLING_EDGES(i)            (TESTER_IO_METRICS_BASE(i) + 0x14)
 | 
			
		||||
#define TESTER_IO_METRICS_FALLING_EDGES_SIZE          4
 | 
			
		||||
#define TESTER_UART_CONTROL                           (0x000 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_CONTROL_SIZE                      4
 | 
			
		||||
#define TESTER_UART_BAUD_DIVISOR                      (0x004 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_BAUD_DIVISOR_SIZE                 2
 | 
			
		||||
#define TESTER_UART_BIT_COUNT                         (0x010 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_BIT_COUNT_SIZE                    1
 | 
			
		||||
#define TESTER_UART_STOP_COUNT                        (0x011 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_STOP_COUNT_SIZE                   1
 | 
			
		||||
#define TESTER_UART_PARITY                            (0x012 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_PARITY_SIZE                       1
 | 
			
		||||
#define TESTER_UART_PARITY_ENABLE                     (1 << 0)
 | 
			
		||||
#define TESTER_UART_PARITY_ODD_N_EVEN                 (1 << 1)
 | 
			
		||||
#define TESTER_UART_RX_CONTROL                        (0x100 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_CONTROL_SIZE                   4
 | 
			
		||||
#define TESTER_UART_RX_CONTROL_ENABLE                 (1 << 0)
 | 
			
		||||
#define TESTER_UART_RX_CONTROL_RESET                  (1 << 1)
 | 
			
		||||
#define TESTER_UART_RX_CHECKSUM                       (0x104 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_CHECKSUM_SIZE                  4
 | 
			
		||||
#define TESTER_UART_RX_COUNT                          (0x108 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_COUNT_SIZE                     4
 | 
			
		||||
#define TESTER_UART_RX_PARITY_ERRORS                  (0x10C + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_PARITY_ERRORS_SIZE             4
 | 
			
		||||
#define TESTER_UART_RX_STOP_ERRORS                    (0x110 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_STOP_ERRORS_SIZE               4
 | 
			
		||||
#define TESTER_UART_RX_FRAMING_ERRORS                 (0x114 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_FRAMING_ERRORS_SIZE            4
 | 
			
		||||
#define TESTER_UART_RX_PREV_4                         (0x118 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_PREV_4_SIZE                    2
 | 
			
		||||
#define TESTER_UART_RX_PREV_3                         (0x11A + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_PREV_3_SIZE                    2
 | 
			
		||||
#define TESTER_UART_RX_PREV_2                         (0x11C + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_PREV_2_SIZE                    2
 | 
			
		||||
#define TESTER_UART_RX_PREV_1                         (0x11E + 0x00104000)
 | 
			
		||||
#define TESTER_UART_RX_PREV_1_SIZE                    2
 | 
			
		||||
#define TESTER_UART_TX_CONTROL                        (0x200 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_TX_CONTROL_SIZE                   4
 | 
			
		||||
#define TESTER_UART_TX_CONTROL_ENABLE                 (1 << 0)
 | 
			
		||||
#define TESTER_UART_TX_CONTROL_RESET                  (1 << 1)
 | 
			
		||||
#define TESTER_UART_TX_CONTROL_ENABLE_CTS             (1 << 2)
 | 
			
		||||
#define TESTER_UART_TX_COUNT                          (0x204 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_TX_COUNT_SIZE                     4
 | 
			
		||||
#define TESTER_UART_TX_NEXT                           (0x208 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_TX_NEXT_SIZE                      2
 | 
			
		||||
#define TESTER_UART_CTS_DEACTIVATE_DELAY              (0x210 + 0x00104000)
 | 
			
		||||
#define TESTER_UART_CTS_DEACTIVATE_DELAY_SIZE         4
 | 
			
		||||
#define TESTER_I2C_STARTS                             (0x000 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_STOPS                              (0x001 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_ACKS                               (0x002 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_NACKS                              (0x004 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_TRANSFERS                          (0x006 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_TRANSFERS_SIZE                     2
 | 
			
		||||
#define TESTER_I2C_TO_SLAVE_CHECKSUM                  (0x008 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_TO_SLAVE_CHECKSUM_SIZE             4
 | 
			
		||||
#define TESTER_I2C_STATE_NUM                          (0x00C + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_NUMBER_DEV_ADDR_MATCHES            (0x00D + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_DEVICE_ADDRESS                     (0x00E + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_SET_SDA                            (0x010 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_PREV_TO_SLAVE_4                    (0x011 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_PREV_TO_SLAVE_3                    (0x012 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_PREV_TO_SLAVE_2                    (0x013 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_PREV_TO_SLAVE_1                    (0x014 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_NEXT_FROM_SLAVE                    (0x015 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_NUM_WRITES                         (0x016 + 0x00105000)
 | 
			
		||||
#define TESTER_I2C_NUM_READS                          (0x018 + 0x00105000)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,465 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2019, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef TEST_UTILS_H
 | 
			
		||||
#define TEST_UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <list>
 | 
			
		||||
 | 
			
		||||
// test function prototypes
 | 
			
		||||
typedef void (*TF1)(PinName p0);
 | 
			
		||||
typedef void (*TF2)(PinName p0, PinName p1);
 | 
			
		||||
typedef void (*TF3)(PinName p0, PinName p1, PinName p2);
 | 
			
		||||
typedef void (*TF4)(PinName p0, PinName p1, PinName p2, PinName p3);
 | 
			
		||||
typedef void (*TF5)(PinName p0, PinName p1, PinName p2, PinName p3, PinName p4);
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FunctionType, FunctionType f>
 | 
			
		||||
struct FunctionCaller
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PortType, TF1 f>
 | 
			
		||||
struct FunctionCaller<PortType, TF1, f>
 | 
			
		||||
{
 | 
			
		||||
    void operator()(PortType &port)
 | 
			
		||||
    {
 | 
			
		||||
        f(port.pins[0]);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PortType, TF2 f>
 | 
			
		||||
struct FunctionCaller<PortType, TF2, f>
 | 
			
		||||
{
 | 
			
		||||
    void operator()(PortType &port)
 | 
			
		||||
    {
 | 
			
		||||
        f(port.pins[0], port.pins[1]);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PortType, TF3 f>
 | 
			
		||||
struct FunctionCaller<PortType, TF3, f>
 | 
			
		||||
{
 | 
			
		||||
    void operator()(PortType &port)
 | 
			
		||||
    {
 | 
			
		||||
        f(port.pins[0], port.pins[1], port.pins[2]);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PortType, TF4 f>
 | 
			
		||||
struct FunctionCaller<PortType, TF4, f>
 | 
			
		||||
{
 | 
			
		||||
    void operator()(PortType &port)
 | 
			
		||||
    {
 | 
			
		||||
        f(port.pins[0], port.pins[1], port.pins[2], port.pins[3]);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename PortType, TF5 f>
 | 
			
		||||
struct FunctionCaller<PortType, TF5, f>
 | 
			
		||||
{
 | 
			
		||||
    void operator()(PortType &port)
 | 
			
		||||
    {
 | 
			
		||||
        f(port.pins[0], port.pins[1], port.pins[2], port.pins[3], port.pins[4]);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename PortType>
 | 
			
		||||
bool peripheral_comparator(const PortType &port1, const PortType &port2)
 | 
			
		||||
{
 | 
			
		||||
    return port1.peripheral == port2.peripheral;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename PortType>
 | 
			
		||||
bool peripheral_less(const PortType &port1, const PortType &port2)
 | 
			
		||||
{
 | 
			
		||||
    return port1.peripheral < port2.peripheral;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType>
 | 
			
		||||
static bool find_port_pins(PortType &port)
 | 
			
		||||
{
 | 
			
		||||
    return pinmap_find_peripheral_pins(FormFactorType::pins(), FormFactorType::restricted_pins(),
 | 
			
		||||
                                       port.peripheral, PortType::PinMap::maps, port.ppins, PortType::pin_count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType>
 | 
			
		||||
void find_ports(std::list<PortType> &matched_ports, std::list<PortType> ¬_matched_ports)
 | 
			
		||||
{
 | 
			
		||||
    // Loop through every pin type
 | 
			
		||||
    for (uint32_t i = 0; i < PortType::pin_count; i++) {
 | 
			
		||||
        const PinMap *map = PortType::PinMap::maps[i];
 | 
			
		||||
        const char *pin_type = PortType::PinMap::pin_type_names[i];
 | 
			
		||||
 | 
			
		||||
        // Loop through each pin of a given type
 | 
			
		||||
        for (; map->pin != NC; map++) {
 | 
			
		||||
            PortType port;
 | 
			
		||||
            // Set pin being tested
 | 
			
		||||
            port.pins[i] = map->pin;
 | 
			
		||||
            port.peripheral = map->peripheral;
 | 
			
		||||
            // Only form factor pins can be tested
 | 
			
		||||
            if (!pinmap_list_has_pin(FormFactorType::pins(), port.pins[i])) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // Don't test restricted pins
 | 
			
		||||
            if (pinmap_list_has_pin(FormFactorType::restricted_pins(), port.pins[i])) {
 | 
			
		||||
                utest_printf("Skipping %s pin %s (%i)\r\n", pin_type,
 | 
			
		||||
                             FormFactorType::pin_to_string(port.pins[i]), port.pins[i]);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // skipp pin searching if single pin port type
 | 
			
		||||
            if (PortType::pin_count > 1) {
 | 
			
		||||
                find_port_pins<PortType, FormFactorType>(port);
 | 
			
		||||
            }
 | 
			
		||||
            if (port.empty()) {
 | 
			
		||||
                not_matched_ports.push_back(port);
 | 
			
		||||
            } else {
 | 
			
		||||
                matched_ports.push_back(port);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType, typename FunctionType, FunctionType f>
 | 
			
		||||
void test_all_ports(std::list<PortType> &matched_ports, std::list<PortType> ¬_matched_ports)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename std::list<PortType>::iterator Iter;
 | 
			
		||||
    utest_printf("***Testing %s on all form factor ports***\n", PortType::PinMap::name);
 | 
			
		||||
    const PinList *ff_pins = FormFactorType::pins();
 | 
			
		||||
    FunctionCaller<PortType, FunctionType, f> call;
 | 
			
		||||
 | 
			
		||||
    if (matched_ports.empty() && not_matched_ports.empty()) {
 | 
			
		||||
        utest_printf("Could not find pins for %s testing \n", PortType::PinMap::name);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < ff_pins->count; i++) {
 | 
			
		||||
        for (Iter it = matched_ports.begin(); it != matched_ports.end(); ++it) {
 | 
			
		||||
            PortType &port = *it;
 | 
			
		||||
            for (uint32_t j = 0; j < PortType::pin_count; j++) {
 | 
			
		||||
                if (ff_pins->pins[i] == port.pins[j]) {
 | 
			
		||||
                    utest_printf("%3s - %s pin tested on port: %s...", FormFactorType::pin_to_string(ff_pins->pins[i]),
 | 
			
		||||
                                 PortType::PinMap::pin_type_names[j], port.str());
 | 
			
		||||
                    if (port.status == PortType::StatusNotTested) {
 | 
			
		||||
                        call(port);
 | 
			
		||||
                        port.status = PortType::StatusPass;
 | 
			
		||||
                    }
 | 
			
		||||
                    utest_printf("%s\n", port.status == PortType::StatusPass ? "succeeded" : "failed");
 | 
			
		||||
                    goto end_port_iteration;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (Iter it = not_matched_ports.begin(); it != not_matched_ports.end(); ++it) {
 | 
			
		||||
            PortType &port = *it;
 | 
			
		||||
            for (uint32_t j = 0; j < PortType::pin_count; j++) {
 | 
			
		||||
                if (ff_pins->pins[i] == port.pins[j]) {
 | 
			
		||||
                    utest_printf("%3s - Could not find pins to test %s pin %s (%d)\n",
 | 
			
		||||
                                 FormFactorType::pin_to_string(ff_pins->pins[i]),
 | 
			
		||||
                                 PortType::PinMap::pin_type_names[j],
 | 
			
		||||
                                 FormFactorType::pin_to_string(ff_pins->pins[i]),
 | 
			
		||||
                                 ff_pins->pins[i]);
 | 
			
		||||
                    goto end_port_iteration;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
end_port_iteration:
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FunctionType, FunctionType f>
 | 
			
		||||
void test_peripheral(PortType &port)
 | 
			
		||||
{
 | 
			
		||||
    if (port.empty()) {
 | 
			
		||||
        utest_printf("%d - Could not find pins to test peripheral\n", port.peripheral);
 | 
			
		||||
    } else {
 | 
			
		||||
        utest_printf("%d - peripheral tested on port: %s...", port.peripheral, port.str());
 | 
			
		||||
        if (port.status == PortType::StatusNotTested) {
 | 
			
		||||
            FunctionCaller<PortType, FunctionType, f> call;
 | 
			
		||||
            call(port); // run test
 | 
			
		||||
            port.status = PortType::StatusPass;
 | 
			
		||||
        }
 | 
			
		||||
        utest_printf("%s\n", port.status == PortType::StatusPass ? "succeeded" : "failed");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FunctionType, FunctionType f>
 | 
			
		||||
void test_all_peripherals(std::list<PortType> &matched_ports, std::list<PortType> ¬_matched_ports)
 | 
			
		||||
{
 | 
			
		||||
    typedef typename std::list<PortType>::iterator Iter;
 | 
			
		||||
    utest_printf("***Testing all %s peripherals***\n", PortType::PinMap::name);
 | 
			
		||||
 | 
			
		||||
    if (matched_ports.empty() && not_matched_ports.empty()) {
 | 
			
		||||
        utest_printf("Could not find pins for %s testing \n", PortType::PinMap::name);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    matched_ports.sort(peripheral_less<PortType>);
 | 
			
		||||
    not_matched_ports.sort(peripheral_less<PortType>);
 | 
			
		||||
 | 
			
		||||
    for (Iter m_it = matched_ports.begin(), nm_it = not_matched_ports.begin();
 | 
			
		||||
            m_it != matched_ports.end() || nm_it != not_matched_ports.end();) {
 | 
			
		||||
        if (m_it != matched_ports.end() && nm_it != not_matched_ports.end()) {
 | 
			
		||||
            if ((*m_it).peripheral < (*nm_it).peripheral) {
 | 
			
		||||
                test_peripheral<PortType, FunctionType, f>(*m_it);
 | 
			
		||||
                ++m_it;
 | 
			
		||||
            } else {
 | 
			
		||||
                test_peripheral<PortType, FunctionType, f>(*nm_it);
 | 
			
		||||
                ++nm_it;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (m_it != matched_ports.end()) {
 | 
			
		||||
            test_peripheral<PortType, FunctionType, f>(*m_it);
 | 
			
		||||
            ++m_it;
 | 
			
		||||
        } else if (nm_it != not_matched_ports.end()) {
 | 
			
		||||
            test_peripheral<PortType, FunctionType, f>(*nm_it);
 | 
			
		||||
            ++nm_it;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType, typename PortType::TestFunctionType f>
 | 
			
		||||
void all_ports()
 | 
			
		||||
{
 | 
			
		||||
    std::list<PortType> matched_ports, not_matched_ports;
 | 
			
		||||
    find_ports<PortType, FormFactorType>(matched_ports, not_matched_ports);
 | 
			
		||||
    matched_ports.unique();
 | 
			
		||||
    not_matched_ports.unique();
 | 
			
		||||
    test_all_ports<PortType, FormFactorType, typename PortType::TestFunctionType, f>(matched_ports, not_matched_ports);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType, typename PortType::TestFunctionType f>
 | 
			
		||||
void all_peripherals()
 | 
			
		||||
{
 | 
			
		||||
    std::list<PortType> matched_ports, not_matched_ports;
 | 
			
		||||
    find_ports<PortType, FormFactorType>(matched_ports, not_matched_ports);
 | 
			
		||||
 | 
			
		||||
    matched_ports.sort(peripheral_less<PortType>);
 | 
			
		||||
    not_matched_ports.sort(peripheral_less<PortType>);
 | 
			
		||||
    matched_ports.unique(peripheral_comparator<PortType>);
 | 
			
		||||
    not_matched_ports.unique(peripheral_comparator<PortType>);
 | 
			
		||||
 | 
			
		||||
    test_all_peripherals<PortType, typename PortType::TestFunctionType, f>(matched_ports, not_matched_ports);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename PortType, typename FormFactorType, typename PortType::TestFunctionType f>
 | 
			
		||||
void one_peripheral()
 | 
			
		||||
{
 | 
			
		||||
    std::list<PortType> matched_ports, not_matched_ports;
 | 
			
		||||
    find_ports<PortType, FormFactorType>(matched_ports, not_matched_ports);
 | 
			
		||||
 | 
			
		||||
    utest_printf("***Testing one %s pin configuration***\n", PortType::PinMap::name);
 | 
			
		||||
    if (matched_ports.empty()) {
 | 
			
		||||
        utest_printf("Could not find pins for %s testing \n", PortType::PinMap::name);
 | 
			
		||||
    } else {
 | 
			
		||||
        test_peripheral<PortType, typename PortType::TestFunctionType, f>(matched_ports.front());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <uint32_t N, typename PinMapType, typename FormFactorType, typename TestFunctionType>
 | 
			
		||||
class Port;
 | 
			
		||||
 | 
			
		||||
template <uint32_t N, typename PinMapType, typename FormFactorType, typename TestFunctionType>
 | 
			
		||||
bool operator== (const Port<N, PinMapType, FormFactorType, TestFunctionType> &port1,
 | 
			
		||||
                 const Port<N, PinMapType, FormFactorType, TestFunctionType> &port2);
 | 
			
		||||
 | 
			
		||||
template <uint32_t N, typename PinMapType, typename FormFactorType, typename FunctionType>
 | 
			
		||||
class Port {
 | 
			
		||||
public:
 | 
			
		||||
    int peripheral;
 | 
			
		||||
    PinName pins[N];
 | 
			
		||||
    PinName *ppins[N];
 | 
			
		||||
 | 
			
		||||
    static const uint32_t pin_count = N;
 | 
			
		||||
    typedef PinMapType PinMap;
 | 
			
		||||
    typedef FunctionType TestFunctionType;
 | 
			
		||||
 | 
			
		||||
    enum Status { StatusPass, StatusFail, StatusNotTested };
 | 
			
		||||
    Status status;
 | 
			
		||||
 | 
			
		||||
    Port(): peripheral(NC), status(StatusNotTested)
 | 
			
		||||
    {
 | 
			
		||||
        init_pins();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Port(const Port &port)
 | 
			
		||||
    {
 | 
			
		||||
        init_pins();
 | 
			
		||||
        copy_from(port);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void init_pins()
 | 
			
		||||
    {
 | 
			
		||||
        for (uint32_t i = 0; i < N; i++) {
 | 
			
		||||
            pins[i] = NC;
 | 
			
		||||
            ppins[i] = &pins[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void copy_from(const Port &port)
 | 
			
		||||
    {
 | 
			
		||||
        peripheral = port.peripheral;
 | 
			
		||||
        status = port.status;
 | 
			
		||||
        for (uint32_t i = 0; i < N; i++) {
 | 
			
		||||
            pins[i] = port.pins[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool empty()
 | 
			
		||||
    {
 | 
			
		||||
        if (peripheral == NC) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        for (uint32_t i = 0; i < N; i++) {
 | 
			
		||||
            if (pins[i] == NC) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *str()
 | 
			
		||||
    {
 | 
			
		||||
        static char port_str[128];
 | 
			
		||||
        char pin_str[32];
 | 
			
		||||
        sprintf(port_str, "peripheral=(%d) ", peripheral);
 | 
			
		||||
        for (uint32_t i = 0; i < N; i++) {
 | 
			
		||||
            sprintf(pin_str, "%s=(%s) ", PinMap::pin_type_names[i], FormFactorType::pin_to_string(pins[i]));
 | 
			
		||||
            strcat(port_str, pin_str);
 | 
			
		||||
        }
 | 
			
		||||
        return port_str;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend bool operator==<> (const Port<N, PinMapType, FormFactorType, FunctionType> &port1, const Port<N, PinMapType, FormFactorType, FunctionType> &port2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <uint32_t N, typename PinMapType, typename FormFactorType, typename FunctionType>
 | 
			
		||||
const uint32_t Port<N, PinMapType, FormFactorType, FunctionType>::pin_count;
 | 
			
		||||
 | 
			
		||||
template <uint32_t N, typename PinMapType, typename FormFactorType, typename FunctionType>
 | 
			
		||||
bool operator== (const Port<N, PinMapType, FormFactorType, FunctionType> &port1, const Port<N, PinMapType, FormFactorType, FunctionType> &port2)
 | 
			
		||||
{
 | 
			
		||||
    if (port1.peripheral != port2.peripheral) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    for (uint32_t i = 0; i < N; i++) {
 | 
			
		||||
        if (port1.pins[i] != port2.pins[i]) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DefaultFormFactor {
 | 
			
		||||
public:
 | 
			
		||||
    static const PinList *pins()
 | 
			
		||||
    {
 | 
			
		||||
        return pinmap_ff_default_pins();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static const PinList *restricted_pins()
 | 
			
		||||
    {
 | 
			
		||||
        return pinmap_restricted_pins();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static const char *pin_to_string(PinName pin)
 | 
			
		||||
    {
 | 
			
		||||
        return pinmap_ff_default_pin_to_string(pin);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if DEVICE_SPI
 | 
			
		||||
struct SPIMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *SPIMaps::maps[] = { spi_master_mosi_pinmap(), spi_master_miso_pinmap(), spi_master_clk_pinmap(), spi_master_cs_pinmap() };
 | 
			
		||||
const char *const SPIMaps::pin_type_names[] = { "MOSI", "MISO", "SCLK", "SSEL" };
 | 
			
		||||
const char *const SPIMaps::name = "SPI";
 | 
			
		||||
typedef Port<4, SPIMaps, DefaultFormFactor, TF4> SPIPort;
 | 
			
		||||
 | 
			
		||||
struct SPINoCSMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *SPINoCSMaps::maps[] = { spi_master_mosi_pinmap(), spi_master_miso_pinmap(), spi_master_clk_pinmap()};
 | 
			
		||||
const char *const SPINoCSMaps::pin_type_names[] = { "MOSI", "MISO", "SCLK" };
 | 
			
		||||
const char *const SPINoCSMaps::name = "SPI";
 | 
			
		||||
typedef Port<3, SPINoCSMaps, DefaultFormFactor, TF3> SPINoCSPort;
 | 
			
		||||
 | 
			
		||||
struct SPISlaveMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *SPISlaveMaps::maps[] = { spi_slave_mosi_pinmap(), spi_slave_miso_pinmap(), spi_slave_clk_pinmap(), spi_slave_cs_pinmap() };
 | 
			
		||||
const char *const SPISlaveMaps::pin_type_names[] = { "MOSI", "MISO", "SCLK", "SSEL" };
 | 
			
		||||
const char *const SPISlaveMaps::name = "SPISlave";
 | 
			
		||||
typedef Port<4, SPISlaveMaps, DefaultFormFactor, TF4> SPISlavePort;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if DEVICE_I2C
 | 
			
		||||
struct I2CMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *I2CMaps::maps[] = { i2c_master_sda_pinmap(), i2c_master_scl_pinmap() };
 | 
			
		||||
const char *const I2CMaps::pin_type_names[] = { "SDA", "SCL" };
 | 
			
		||||
const char *const I2CMaps::name = "I2C";
 | 
			
		||||
typedef Port<2, I2CMaps, DefaultFormFactor, TF2> I2CPort;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if DEVICE_PWMOUT
 | 
			
		||||
struct PWMMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *PWMMaps::maps[] = { pwmout_pinmap() };
 | 
			
		||||
const char *const PWMMaps::pin_type_names[] = { "PWM_OUT" };
 | 
			
		||||
const char *const PWMMaps::name = "PWM";
 | 
			
		||||
typedef Port<1, PWMMaps, DefaultFormFactor, TF1> PWMPort;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGIN
 | 
			
		||||
struct AnaloginMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *AnaloginMaps::maps[] = { analogin_pinmap() };
 | 
			
		||||
const char *const AnaloginMaps::pin_type_names[] = { "ADC_IN" };
 | 
			
		||||
const char *const AnaloginMaps::name = "ADC";
 | 
			
		||||
typedef Port<1, AnaloginMaps, DefaultFormFactor, TF1> AnaloginPort;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGOUT
 | 
			
		||||
struct AnalogoutMaps {
 | 
			
		||||
    static const PinMap *maps[];
 | 
			
		||||
    static const char *const pin_type_names[];
 | 
			
		||||
    static const char *const name;
 | 
			
		||||
};
 | 
			
		||||
const PinMap *AnalogoutMaps::maps[] = { analogout_pinmap() };
 | 
			
		||||
const char *const AnalogoutMaps::pin_type_names[] = { "DAC_OUT" };
 | 
			
		||||
const char *const AnalogoutMaps::name = "DAC";
 | 
			
		||||
typedef Port<1, AnalogoutMaps, DefaultFormFactor, TF1> AnalogoutPort;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in New Issue