├── .gitignore
├── sync.ffs_db
├── Calibration.xlsx
├── nbproject
├── private
│ ├── SuppressibleMessageMemo.properties
│ ├── private.xml
│ └── configurations.xml
├── Makefile-genesis.properties
├── Makefile-variables.mk
├── project.xml
├── Package-default.bash
├── Makefile-impl.mk
├── Makefile-local-default.mk
└── configurations.xml
├── dist
└── default
│ └── production
│ ├── SolarCharger_RevE.production.o
│ ├── SolarCharger_RevE.production.elf
│ ├── SolarCharger_RevE.production.rlf
│ ├── SolarCharger_RevE.production.mum
│ └── memoryfile.xml
├── todo.txt
├── display.h
├── ui.h
├── adc.h
├── external_flash.h
├── buck.h
├── application_config.h
├── spi.h
├── rtcc.h
├── app_device_msd.h
├── external_flash.c
├── flash.h
├── fileio_media.h
├── adc.c
├── system.h
├── app_device_custom_hid.h
├── usb.h
├── log.h
├── configuration_bits.h
├── Makefile
├── app_device_custom_hid.c
├── fat16.h
├── i2c.h
├── hardware_config.h
├── app_device_msd.c
├── os.h
├── usb_events.c
├── log.c
├── api.h
├── main.c
├── usb_config.h
├── usb_device_hid.h
├── rtcc.c
├── system.c
├── usb_device_hid.c
├── ui.c
└── usb_descriptors.c
/.gitignore:
--------------------------------------------------------------------------------
1 | build/*
2 | debug/*
3 |
--------------------------------------------------------------------------------
/sync.ffs_db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soldernerd/SolarChargerRevE_Software/HEAD/sync.ffs_db
--------------------------------------------------------------------------------
/Calibration.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soldernerd/SolarChargerRevE_Software/HEAD/Calibration.xlsx
--------------------------------------------------------------------------------
/nbproject/private/SuppressibleMessageMemo.properties:
--------------------------------------------------------------------------------
1 | #
2 | #Thu Feb 23 23:59:10 CET 2017
3 | pk3/DEVID_MISMATCH=true
4 |
--------------------------------------------------------------------------------
/dist/default/production/SolarCharger_RevE.production.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soldernerd/SolarChargerRevE_Software/HEAD/dist/default/production/SolarCharger_RevE.production.o
--------------------------------------------------------------------------------
/dist/default/production/SolarCharger_RevE.production.elf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soldernerd/SolarChargerRevE_Software/HEAD/dist/default/production/SolarCharger_RevE.production.elf
--------------------------------------------------------------------------------
/dist/default/production/SolarCharger_RevE.production.rlf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soldernerd/SolarChargerRevE_Software/HEAD/dist/default/production/SolarCharger_RevE.production.rlf
--------------------------------------------------------------------------------
/todo.txt:
--------------------------------------------------------------------------------
1 | - Establish SPI communication
2 | - Debug and test data logging
3 | - Improve MPPT algorithm
4 | - Implement PWM power outputs
5 | - Implement 12bit ADC usage for temperature measurements
6 | - Reduce standby current consumption
7 | - Remove debugging display modes
--------------------------------------------------------------------------------
/display.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: display.h
3 | * Author: Luke
4 | *
5 | * Created on 11. September 2016, 13:52
6 | */
7 |
8 | #ifndef DISPLAY_H
9 | #define DISPLAY_H
10 |
11 | void display_prepare(uint8_t mode);
12 | void display_update(void);
13 |
14 | uint8_t display_get_character(uint8_t line, uint8_t position);
15 |
16 | #endif /* DISPLAY_H */
17 |
18 |
--------------------------------------------------------------------------------
/dist/default/production/SolarCharger_RevE.production.mum:
--------------------------------------------------------------------------------
1 |
2 | Memory Summary:
3 | Program space used D11Dh ( 53533) of 13FF8h bytes ( 65.4%)
4 | Data space used 9B6h ( 2486) of EB0h bytes ( 66.1%)
5 | Configuration bits used 4h ( 4) of 4h words (100.0%)
6 | Data stack space used 0h ( 0) of 300h bytes ( 0.0%)
7 |
8 |
--------------------------------------------------------------------------------
/nbproject/Makefile-genesis.properties:
--------------------------------------------------------------------------------
1 | #
2 | #Sun Oct 07 13:37:42 CEST 2018
3 | default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc8\\v2.00\\bin
4 | configurations-xml=2c0cd92c485fe36b26faa889627105b1
5 | com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=9d53b989b6ed2b6446aae58c2779ca87
6 | default.languagetoolchain.version=2.00
7 | host.platform=windows
8 | conf.ids=default
9 | default.com-microchip-mplab-nbide-toolchainXC8-XC8LanguageToolchain.md5=d0b8fdc2be6cb87257c6731763a65529
10 |
--------------------------------------------------------------------------------
/nbproject/Makefile-variables.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Generated - do not edit!
3 | #
4 | # NOCDDL
5 | #
6 | CND_BASEDIR=`pwd`
7 | # default configuration
8 | CND_ARTIFACT_DIR_default=dist/default/production
9 | CND_ARTIFACT_NAME_default=SolarCharger_RevE.production.hex
10 | CND_ARTIFACT_PATH_default=dist/default/production/SolarCharger_RevE.production.hex
11 | CND_PACKAGE_DIR_default=${CND_DISTDIR}/default/package
12 | CND_PACKAGE_NAME_default=solarchargerreve.tar
13 | CND_PACKAGE_PATH_default=${CND_DISTDIR}/default/package/solarchargerreve.tar
14 |
--------------------------------------------------------------------------------
/dist/default/production/memoryfile.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bytes
6 | 81912
7 | 53533
8 | 28379
9 |
10 |
11 | bytes
12 | 3760
13 | 2486
14 | 1274
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ui.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: ui.h
3 | * Author: Luke
4 | *
5 | * Created on 16. Oktober 2016, 22:31
6 | */
7 |
8 | #ifndef UI_H
9 | #define UI_H
10 |
11 | typedef enum
12 | {
13 | USER_INTERFACE_STATUS_OFF,
14 | USER_INTERFACE_STATUS_STARTUP_1,
15 | USER_INTERFACE_STATUS_STARTUP_2,
16 | USER_INTERFACE_STATUS_STARTUP_3,
17 | USER_INTERFACE_STATUS_STARTUP_4,
18 | USER_INTERFACE_STATUS_ON
19 | } userInterfaceStatus_t;
20 |
21 | void ui_init(void);
22 | void ui_run(void);
23 | userInterfaceStatus_t ui_get_status(void);
24 |
25 | #endif /* UI_H */
26 |
27 |
--------------------------------------------------------------------------------
/adc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: adc.h
3 | * Author: Luke
4 | *
5 | * Created on 9. September 2016, 22:57
6 | */
7 |
8 | #ifndef ADC_H
9 | #define ADC_H
10 |
11 | #include
12 | #include "system.h"
13 | #include "os.h"
14 |
15 | typedef enum
16 | {
17 | ADC_CHANNEL_TEMPERATURE_ONBOARD,
18 | ADC_CHANNEL_TEMPERATURE_EXTERNAL_1,
19 | ADC_CHANNEL_TEMPERATURE_EXTERNAL_2
20 | } adcChannel_t;
21 |
22 | void adc_init(void);
23 | void adc_calibrate(void);
24 | uint16_t adc_read(adcChannel_t channel);
25 | int16_t adc_calculate_temperature(uint16_t adc_value, calibrationIndex_t calibration);
26 |
27 | #endif /* ADC_H */
28 |
29 |
--------------------------------------------------------------------------------
/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.microchip.mplab.nbide.embedded.makeproject
4 |
5 |
6 | SolarCharger_RevE
7 | f404b41a-7781-42cb-a852-dc0c833ff906
8 | 0
9 | c
10 |
11 | h
12 |
13 | ISO-8859-1
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/external_flash.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: flash.h
3 | * Author: Luke
4 | *
5 | * Created on 8. Januar 2017, 17:13
6 | */
7 |
8 | #ifndef EXTERNAL_FLASH_H
9 | #define EXTERNAL_FLASH_H
10 |
11 | #include
12 | #include
13 | #include "flash.h"
14 |
15 | //Functions for mass storage device
16 | //This module provides the link between app_device_msd.h and flash.h
17 | //app_device_msd.h is concerned with the USB mass storage and doesn't care about how the data is stored
18 | //flash.h implements the communication with our flash chip and doesn't care about USB
19 | FILEIO_MEDIA_INFORMATION * ExternalFlash_MediaInitialize(void* config);
20 | uint16_t ExternalFlash_SectorSizeRead(void* config);
21 | uint32_t ExternalFlash_CapacityRead(void* config);
22 | uint8_t ExternalFlash_MediaDetect(void* config);
23 | uint8_t ExternalFlash_WriteProtectStateGet(void* config);
24 | uint8_t ExternalFlash_SectorRead(void* config, uint32_t sector_addr, uint8_t* buffer);
25 | uint8_t ExternalFlash_SectorWrite(void* config, uint32_t sector_addr, uint8_t* buffer, uint8_t allowWriteToZero);
26 |
27 | #endif /* EXTERNAL_FLASH_H */
28 |
29 |
--------------------------------------------------------------------------------
/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/main.c
7 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/system.h
8 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/os.c
9 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/api.h
10 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/display.c
11 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/api.c
12 | file:/C:/Users/luke/OneDrive/EmbeddedSystems/MPLAB/SolarCharger_RevE/os.h
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/nbproject/private/configurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Makefile
4 | 0
5 |
6 |
7 | :=MPLABComm-USB-Microchip:=<vid>04D8:=<pid>900A:=<rev>0002:=<man>Microchip Technology Inc.:=<prod>PICkit 3:=<sn>BUR163731379:=<drv>x:=<xpt>h:=end
8 | C:\Program Files (x86)\Microchip\xc8\v2.00\bin
9 |
10 | place holder 1
11 | place holder 2
12 |
13 |
14 |
15 |
16 | true
17 | 0
18 | 0
19 | 0
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/buck.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: buck.h
3 | * Author: Luke
4 | *
5 | * Created on 30. September 2016, 21:59
6 | */
7 |
8 | #ifndef BUCK_H
9 | #define BUCK_H
10 |
11 | #define BUCK_VOLTAGE_DIFFERENCE_MINIMUM 1000
12 | #define BUCK_INPUT_CURRENT_MINIMUM 5
13 | #define BUCK_ASYNCHRONOUS_INPUT_CURRENT_MAXIMUM 600
14 | #define BUCK_SYNCHRONOUS_INPUT_CURRENT_MINIMUM 200
15 |
16 | typedef enum
17 | {
18 | BUCK_STATUS_OFF = 0x00,
19 | BUCK_STATUS_STARTUP = 0x01,
20 | BUCK_STATUS_ASYNCHRONOUS = 0x02,
21 | BUCK_STATUS_SYNCHRONOUS = 0x03,
22 | BUCK_STATUS_REMOTE_OFF = 0x80,
23 | BUCK_STATUS_REMOTE_STARTUP = 0x81,
24 | BUCK_STATUS_REMOTE_ASYNCHRONOUS = 0x82,
25 | BUCK_STATUS_REMOTE_SYNCHRONOUS = 0x83
26 | } buckStatus_t;
27 |
28 | typedef enum
29 | {
30 | BUCK_MODE_ASYNCHRONOUS,
31 | BUCK_MODE_SYNCHRONOUS
32 | } buckMode_t;
33 |
34 | void buck_init(void);
35 | void buck_operate(void);
36 |
37 | uint8_t buck_get_dutycycle(void);
38 | buckStatus_t buck_get_mode(void);
39 |
40 | void buck_remote_set_enable(uint8_t remote);
41 | void buck_remote_set_on(uint8_t on);
42 | void buck_remote_set_synchronous(uint8_t synchronous);
43 | void buck_remote_set_dutycycle(uint8_t dutycycle);
44 | void buck_remote_change_dutycycle(int8_t change);
45 |
46 | uint8_t buck_remote_get_status();
47 | uint8_t buck_remote_get_dutycycle();
48 |
49 | #endif /* BUCK_H */
50 |
51 |
--------------------------------------------------------------------------------
/application_config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: application_config.h
3 | * Author: luke
4 | *
5 | * Created on 3. Oktober 2018, 17:16
6 | */
7 |
8 | #ifndef APPLICATION_CONFIG_H
9 | #define APPLICATION_CONFIG_H
10 |
11 | /*
12 | * A random generated signature to distinguish between bootloader and normal firmware
13 | */
14 |
15 | #define FIRMWARE_SIGNATURE 0x62A1
16 |
17 | /*
18 | * Firmware version
19 | */
20 |
21 | #define FIRMWARE_VERSION_MAJOR 0x00
22 | #define FIRMWARE_VERSION_MINOR 0x01
23 | #define FIRMWARE_VERSION_FIX 0x00
24 |
25 | /*
26 | * Application specific settings
27 | */
28 |
29 | #define REAL_TIME_CLOCK_AVAILABLE
30 | #define ANALOG_DIGITAL_CONVERTER_AVAILABLE
31 | #define I2C_TASK_SCHEDULING_AVAILABLE
32 |
33 | #define NUMBER_OF_TIMESLOTS 16
34 |
35 | #define USB_CHARGING_VOLTAGE_MINIMUM 12000
36 | #define POWER_OUTPUTS_VOLTAGE_MINIMUM -1
37 | #define BUCK_DUTYCYCLE_ASYNCHRONOUS_MINIMUM 40
38 | #define BUCK_DUTYCYCLE_SYNCHRONOUS_MINIMUM 150
39 | #define BUCK_DUTYCYCLE_MAXIMUM 242
40 | #define BUCK_BATTERY_VOLTAGE_MAXIMUM 13500
41 |
42 | //Page 0 (0x00 to 0xFF) reserved for parameters such as time and date
43 | #define EEPROM_RTCC_ADDRESS 0x040
44 |
45 | //Page 1 (0x100 to 0x1FF) reserved for bootloader
46 | #define EEPROM_BOOTLOADER_BYTE_ADDRESS 0x100
47 | #define BOOTLOADER_BYTE_FORCE_BOOTLOADER_MODE 0x94
48 | #define BOOTLOADER_BYTE_FORCE_NORMAL_MODE 0x78
49 |
50 | //Page 2 (0x200 to 0x2FF) reserved for calibration
51 | #define EEPROM_CALIBRATION_ADDRESS 0x0200
52 |
53 | #define OS_USER_INTERFACE_TIMEOUT 2000
54 |
55 | #endif /* APPLICATION_CONFIG_H */
56 |
57 |
--------------------------------------------------------------------------------
/spi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: spi.h
3 | * Author: luke
4 | *
5 | * Created on 26. Juli 2018, 15:18
6 | */
7 |
8 | #ifndef SPI_H
9 | #define SPI_H
10 |
11 | #include
12 |
13 | typedef enum
14 | {
15 | SPI_CONFIGURATION_INTERNAL,
16 | SPI_CONFIGURATION_EXTERNAL
17 | } spiConfiguration_t;
18 |
19 | typedef enum
20 | {
21 | SPI_MODE_MASTER,
22 | SPI_MODE_SLAVE
23 | } spiMode_t;
24 |
25 | typedef enum
26 | {
27 | SPI_FREQUENCY_12MHZ
28 | } spiFrequency_t;
29 |
30 | typedef enum
31 | {
32 | SPI_POLARITY_ACTIVELOW,
33 | SPI_POLARITY_ACTIVEHIGH
34 | } spiPolarity_t;
35 |
36 | typedef struct
37 | {
38 | spiMode_t mode;
39 | spiFrequency_t frequency;
40 | spiPolarity_t polarity;
41 | } spiConfigurationDetails_t;
42 |
43 | //Read or set a certain configuration
44 | void spi_set_configurationDetails(spiConfiguration_t configuration, spiConfigurationDetails_t details);
45 | void spi_get_configurationDetails(spiConfiguration_t configuration, spiConfigurationDetails_t details);
46 |
47 | //Initialize and configure SPI interface
48 | void spi_init(spiConfiguration_t configuration);
49 | void spi_set_configuration(spiConfiguration_t configuration);
50 | spiConfiguration_t spi_get_configuration(void);
51 |
52 | void spi_tx(uint8_t *data, uint16_t length);
53 | void spi_tx_tx(uint8_t *command, uint16_t command_length, uint8_t *data, uint16_t data_length);
54 | void spi_tx_rx(uint8_t *command, uint16_t command_length, uint8_t *data, uint16_t data_length);
55 |
56 | uint8_t* spi_get_external_tx_buffer(void);
57 | uint8_t* spi_get_external_rx_buffer(void);
58 |
59 | #endif /* SPI_H */
60 |
61 |
--------------------------------------------------------------------------------
/rtcc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: rtcc.h
3 | * Author: Luke
4 | *
5 | * Created on 25. September 2016, 13:32
6 | */
7 |
8 | #ifndef RTCC_H
9 | #define RTCC_H
10 |
11 | #include
12 |
13 | void rtcc_init(void);
14 | void rtcc_correct_day(void);
15 |
16 | //Year
17 | uint8_t rtcc_get_year(void);
18 | uint8_t rtcc_get_year_decimal(void);
19 | void rtcc_set_year(uint8_t year);
20 | void rtcc_increment_year(void);
21 | void rtcc_decrement_year(void);
22 |
23 | //Month
24 | uint8_t rtcc_get_month(void);
25 | uint8_t rtcc_get_month_decimal(void);
26 | void rtcc_set_month(uint8_t month);
27 | void rtcc_increment_month(void);
28 | void rtcc_decrement_month(void);
29 |
30 | //Day
31 | uint8_t rtcc_get_day(void);
32 | uint8_t rtcc_get_day_decimal(void);
33 | void rtcc_set_day(uint8_t day);
34 | void rtcc_increment_day(void);
35 | void rtcc_decrement_day(void);
36 |
37 | //Hours
38 | uint8_t rtcc_get_hours(void);
39 | uint8_t rtcc_get_hours_decimal(void);
40 | void rtcc_set_hours(uint8_t hours);
41 | void rtcc_increment_hours(void);
42 | void rtcc_decrement_hours(void);
43 |
44 | //Minutes
45 | uint8_t rtcc_get_minutes(void);
46 | uint8_t rtcc_get_minutes_decimal(void);
47 | void rtcc_set_minutes(uint8_t minutes);
48 | void rtcc_increment_minutes(void);
49 | void rtcc_decrement_minutes(void);
50 |
51 | //Seconds
52 | uint8_t rtcc_get_seconds(void);
53 | uint8_t rtcc_get_seconds_decimal(void);
54 | void rtcc_set_seconds(uint8_t seconds);
55 | void rtcc_increment_seconds(void);
56 | void rtcc_decrement_seconds(void);
57 |
58 | //Read and write date and time from/to EEPROM
59 | void rtcc_read_eeprom(void);
60 | void rtcc_write_eeprom(void);
61 |
62 | #endif /* RTCC_H */
63 |
64 |
--------------------------------------------------------------------------------
/nbproject/Package-default.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash -x
2 |
3 | #
4 | # Generated - do not edit!
5 | #
6 |
7 | # Macros
8 | TOP=`pwd`
9 | CND_CONF=default
10 | CND_DISTDIR=dist
11 | TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging
12 | TMPDIRNAME=tmp-packaging
13 | OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/SolarCharger_RevE.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
14 | OUTPUT_BASENAME=SolarCharger_RevE.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
15 | PACKAGE_TOP_DIR=solarchargerreve/
16 |
17 | # Functions
18 | function checkReturnCode
19 | {
20 | rc=$?
21 | if [ $rc != 0 ]
22 | then
23 | exit $rc
24 | fi
25 | }
26 | function makeDirectory
27 | # $1 directory path
28 | # $2 permission (optional)
29 | {
30 | mkdir -p "$1"
31 | checkReturnCode
32 | if [ "$2" != "" ]
33 | then
34 | chmod $2 "$1"
35 | checkReturnCode
36 | fi
37 | }
38 | function copyFileToTmpDir
39 | # $1 from-file path
40 | # $2 to-file path
41 | # $3 permission
42 | {
43 | cp "$1" "$2"
44 | checkReturnCode
45 | if [ "$3" != "" ]
46 | then
47 | chmod $3 "$2"
48 | checkReturnCode
49 | fi
50 | }
51 |
52 | # Setup
53 | cd "${TOP}"
54 | mkdir -p ${CND_DISTDIR}/${CND_CONF}/package
55 | rm -rf ${TMPDIR}
56 | mkdir -p ${TMPDIR}
57 |
58 | # Copy files and create directories and links
59 | cd "${TOP}"
60 | makeDirectory ${TMPDIR}/solarchargerreve/bin
61 | copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
62 |
63 |
64 | # Generate tar file
65 | cd "${TOP}"
66 | rm -f ${CND_DISTDIR}/${CND_CONF}/package/solarchargerreve.tar
67 | cd ${TMPDIR}
68 | tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/solarchargerreve.tar *
69 | checkReturnCode
70 |
71 | # Cleanup
72 | cd "${TOP}"
73 | rm -rf ${TMPDIR}
74 |
--------------------------------------------------------------------------------
/app_device_msd.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /*********************************************************************
21 | * Function: void APP_DeviceMSDInitialize(void);
22 | *
23 | * Overview: Initializes the Custom HID demo code
24 | *
25 | * PreCondition: None
26 | *
27 | * Input: None
28 | *
29 | * Output: None
30 | *
31 | ********************************************************************/
32 | void APP_DeviceMSDInitialize();
33 |
34 | /*********************************************************************
35 | * Function: void APP_DeviceMSDTasks(void);
36 | *
37 | * Overview: Keeps the Custom HID demo running.
38 | *
39 | * PreCondition: The demo should have been initialized and started via
40 | * the APP_DeviceMSDInitialize() and APP_DeviceMSDStart() demos
41 | * respectively.
42 | *
43 | * Input: None
44 | *
45 | * Output: None
46 | *
47 | ********************************************************************/
48 | void APP_DeviceMSDTasks();
49 |
--------------------------------------------------------------------------------
/external_flash.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include "string.h"
5 | #include "os.h"
6 | #include "external_flash.h"
7 |
8 | static FILEIO_MEDIA_INFORMATION mediaInformation;
9 |
10 | FILEIO_MEDIA_INFORMATION * ExternalFlash_MediaInitialize(void* config)
11 | {
12 | mediaInformation.validityFlags.bits.sectorSize = true;
13 | mediaInformation.sectorSize = FLASH_PAGE_SIZE;
14 | mediaInformation.errorCode = MEDIA_NO_ERROR;
15 | return &mediaInformation;
16 | }
17 |
18 | uint16_t ExternalFlash_SectorSizeRead(void* config)
19 | {
20 | return FLASH_PAGE_SIZE;
21 | }
22 |
23 | uint32_t ExternalFlash_CapacityRead(void* config)
24 | {
25 | //This is the truthful answer
26 | return ((uint32_t) FLASH_NUMBER_OF_PAGES - 1);
27 | }
28 |
29 | uint8_t ExternalFlash_MediaDetect(void* config)
30 | {
31 | return true;
32 | }
33 |
34 | uint8_t ExternalFlash_WriteProtectStateGet(void* config)
35 | {
36 |
37 | return false;
38 | }
39 |
40 | uint8_t ExternalFlash_SectorRead(void* config, uint32_t sector_addr, uint8_t* buffer)
41 | {
42 | uint16_t page = (uint16_t) sector_addr;
43 |
44 | //Error check. Make sure the host is trying to read from a legitimate address
45 | if(sector_addr >= FLASH_NUMBER_OF_PAGES)
46 | {
47 | return false;
48 | }
49 |
50 | //Read the data
51 | flash_sector_read(page, buffer);
52 |
53 | return true;
54 | }
55 |
56 | uint8_t ExternalFlash_SectorWrite(void* config, uint32_t sector_addr, uint8_t* buffer, uint8_t allowWriteToZero)
57 | {
58 | uint16_t page = (uint16_t) sector_addr;
59 |
60 | //First, error check the resulting address
61 | if(sector_addr >= FLASH_NUMBER_OF_PAGES)
62 | {
63 | return false;
64 | }
65 |
66 | //Write new data to flash
67 | flash_sector_write(page, buffer);
68 |
69 | return true;
70 | }
71 |
--------------------------------------------------------------------------------
/flash.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: flash.h
3 | * Author: Luke
4 | *
5 | * Created on 8. Januar 2017, 17:13
6 | *
7 | * Implements the communication with our AT45DB321E flash chip
8 | * This module needs to make sure we are the SPI_CONFIGURATION_INTERNAL configuration
9 | * Since this module is the only one using that configuration, it always sets the configuration back to SPI_CONFIGURATION_EXTERNAL
10 | * Configuration switching is implemented at the public function level, i.e the functions defined here
11 | * Static functions may safely assume that the configuration is already set correctly
12 | *
13 | */
14 |
15 | #ifndef FLASH_H
16 | #define FLASH_H
17 |
18 | #include
19 |
20 |
21 | #define FLASH_PAGE_SIZE 512
22 | #define FLASH_NUMBER_OF_PAGES 8192
23 |
24 | typedef enum
25 | {
26 | FLASH_POWER_STATE_NORMAL,
27 | FLASH_POWER_STATE_DEEP_POWER_DOWN,
28 | FLASH_POWER_STATE_ULTRA_DEEP_POWER_DOWN
29 | } flashPowerState_t;
30 |
31 | //Initialize flash (and corresponding SPI interface)
32 | void flash_init(void);
33 |
34 | //Some utility functions
35 | uint8_t flash_is_busy(void);
36 | flashPowerState_t flash_get_power_state(void);
37 | void flash_set_power_state(flashPowerState_t new_power_state);
38 |
39 | //Read or write an entire page
40 | void flash_sector_read(uint16_t page, uint8_t *data);
41 | void flash_sector_write(uint16_t page, uint8_t *data);
42 |
43 | //Read or write only part of a page
44 | void flash_partial_read(uint16_t page, uint16_t start, uint16_t length, uint8_t *data);
45 | void flash_partial_write(uint16_t page, uint16_t start, uint16_t length, uint8_t *data);
46 |
47 | //Read or write access via FLASH_BUFFER_2
48 | void flash_copy_page_to_buffer(uint16_t page);
49 | void flash_write_page_from_buffer(uint16_t page);
50 | void flash_read_from_buffer(uint16_t start, uint16_t length, uint8_t *data);
51 | void flash_write_to_buffer(uint16_t start, uint16_t length, uint8_t *data);
52 |
53 | #endif /* FLASH_H */
54 |
55 |
--------------------------------------------------------------------------------
/fileio_media.h:
--------------------------------------------------------------------------------
1 | // DOM-IGNORE-BEGIN
2 | /*******************************************************************************
3 | Copyright 2015 Microchip Technology Inc. (www.microchip.com)
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | To request to license the code under the MLA license (www.microchip.com/mla_license),
18 | please contact mla_licensing@microchip.com
19 | *******************************************************************************/
20 | //DOM-IGNORE-END
21 |
22 | #ifndef _FILEIO_MEDIA_H
23 | #define _FILEIO_MEDIA_H
24 |
25 | // Enumeration to define media error types
26 | typedef enum
27 | {
28 | MEDIA_NO_ERROR, // No errors
29 | MEDIA_DEVICE_NOT_PRESENT, // The requested device is not present
30 | MEDIA_CANNOT_INITIALIZE // Cannot initialize media
31 | } FILEIO_MEDIA_ERRORS;
32 |
33 | // Media information flags. The driver's MediaInitialize function will return a pointer to one of these structures.
34 | typedef struct
35 | {
36 | FILEIO_MEDIA_ERRORS errorCode; // The status of the initialization FILEIO_MEDIA_ERRORS
37 | // Flags
38 | union
39 | {
40 | uint8_t value;
41 | struct
42 | {
43 | uint8_t sectorSize : 1; // The sector size parameter is valid.
44 | uint8_t maxLUN : 1; // The max LUN parameter is valid.
45 | } bits;
46 | } validityFlags;
47 |
48 | uint16_t sectorSize; // The sector size of the target device.
49 | uint8_t maxLUN; // The maximum Logical Unit Number of the device.
50 | } FILEIO_MEDIA_INFORMATION;
51 |
52 | #endif
--------------------------------------------------------------------------------
/nbproject/Makefile-impl.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Generated Makefile - do not edit!
3 | #
4 | # Edit the Makefile in the project folder instead (../Makefile). Each target
5 | # has a pre- and a post- target defined where you can add customization code.
6 | #
7 | # This makefile implements macros and targets common to all configurations.
8 | #
9 | # NOCDDL
10 |
11 |
12 | # Building and Cleaning subprojects are done by default, but can be controlled with the SUB
13 | # macro. If SUB=no, subprojects will not be built or cleaned. The following macro
14 | # statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
15 | # and .clean-reqprojects-conf unless SUB has the value 'no'
16 | SUB_no=NO
17 | SUBPROJECTS=${SUB_${SUB}}
18 | BUILD_SUBPROJECTS_=.build-subprojects
19 | BUILD_SUBPROJECTS_NO=
20 | BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
21 | CLEAN_SUBPROJECTS_=.clean-subprojects
22 | CLEAN_SUBPROJECTS_NO=
23 | CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
24 |
25 |
26 | # Project Name
27 | PROJECTNAME=SolarCharger_RevE
28 |
29 | # Active Configuration
30 | DEFAULTCONF=default
31 | CONF=${DEFAULTCONF}
32 |
33 | # All Configurations
34 | ALLCONFS=default
35 |
36 |
37 | # build
38 | .build-impl: .build-pre
39 | ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf
40 |
41 |
42 | # clean
43 | .clean-impl: .clean-pre
44 | ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf
45 |
46 | # clobber
47 | .clobber-impl: .clobber-pre .depcheck-impl
48 | ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default clean
49 |
50 |
51 |
52 | # all
53 | .all-impl: .all-pre .depcheck-impl
54 | ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default build
55 |
56 |
57 |
58 | # dependency checking support
59 | .depcheck-impl:
60 | # @echo "# This code depends on make tool being used" >.dep.inc
61 | # @if [ -n "${MAKE_VERSION}" ]; then \
62 | # echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
63 | # echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
64 | # echo "include \$${DEPFILES}" >>.dep.inc; \
65 | # echo "endif" >>.dep.inc; \
66 | # else \
67 | # echo ".KEEP_STATE:" >>.dep.inc; \
68 | # echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
69 | # fi
70 |
--------------------------------------------------------------------------------
/nbproject/Makefile-local-default.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Generated Makefile - do not edit!
3 | #
4 | #
5 | # This file contains information about the location of compilers and other tools.
6 | # If you commmit this file into your revision control server, you will be able to
7 | # to checkout the project and build it from the command line with make. However,
8 | # if more than one person works on the same project, then this file might show
9 | # conflicts since different users are bound to have compilers in different places.
10 | # In that case you might choose to not commit this file and let MPLAB X recreate this file
11 | # for each user. The disadvantage of not commiting this file is that you must run MPLAB X at
12 | # least once so the file gets created and the project can be built. Finally, you can also
13 | # avoid using this file at all if you are only building from the command line with make.
14 | # You can invoke make with the values of the macros:
15 | # $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ...
16 | #
17 | SHELL=cmd.exe
18 | PATH_TO_IDE_BIN=C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/
19 | # Adding MPLAB X bin directory to path.
20 | PATH:=C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH)
21 | # Path to java used to run MPLAB X when this makefile was created
22 | MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\v5.00\sys\java\jre1.8.0_144/bin/"
23 | OS_CURRENT="$(shell uname -s)"
24 | MP_CC="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe"
25 | # MP_CPPC is not defined
26 | # MP_BC is not defined
27 | MP_AS="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe"
28 | MP_LD="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe"
29 | MP_AR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-ar.exe"
30 | DEP_GEN=${MP_JAVA_PATH}java -jar "C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar"
31 | MP_CC_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin"
32 | # MP_CPPC_DIR is not defined
33 | # MP_BC_DIR is not defined
34 | MP_AS_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin"
35 | MP_LD_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin"
36 | MP_AR_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin"
37 | # MP_BC_DIR is not defined
38 |
--------------------------------------------------------------------------------
/adc.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include "hardware_config.h"
5 | #include "os.h"
6 | #include "adc.h"
7 |
8 | extern calibration_t calibrationParameters[7];
9 |
10 | void adc_init(void)
11 | {
12 | ADCON0bits.VCFG1 = 0; // negative reference = GND
13 | ADCON0bits.VCFG0 = 1; // positive reference = AN3
14 | ADCON0bits.CHS = TEMPERATURE1_CHANNEL; // On-board sensor on AN12
15 | ADCON0bits.ADON = 1; // Enable ADC module
16 | ADCON1bits.ADFM = 0; // left justified
17 | ADCON1bits.ADCAL = 0; // no calibration
18 | ADCON1bits.ADCS = 0b110; // T_ad = Fosc/64
19 | }
20 |
21 | void adc_calibrate(void)
22 | {
23 | ADCON1bits.ADCAL = 1; // Calibrate
24 | //Start conversion
25 | ADCON0bits.GO_NOT_DONE = 1;
26 | //Wait for calibration to complete
27 | while(ADCON0bits.GO_NOT_DONE);
28 | ADCON1bits.ADCAL = 0; // Calibrate off
29 | }
30 |
31 | uint16_t adc_read(adcChannel_t channel)
32 | {
33 | uint16_t adc_value;
34 |
35 | switch(channel)
36 | {
37 | case ADC_CHANNEL_TEMPERATURE_ONBOARD:
38 | ADCON0bits.CHS = TEMPERATURE1_CHANNEL;
39 | break;
40 | case ADC_CHANNEL_TEMPERATURE_EXTERNAL_1:
41 | ADCON0bits.CHS = TEMPERATURE2_CHANNEL;
42 | break;
43 | case ADC_CHANNEL_TEMPERATURE_EXTERNAL_2:
44 | ADCON0bits.CHS = TEMPERATURE3_CHANNEL;
45 | break;
46 | default:
47 | return 0xFFFF;
48 | }
49 |
50 | //Wait for acquisition time
51 | switch(os.clockFrequency)
52 | {
53 | case CPU_FREQUENCY_8MHz:
54 | __delay_us(15);
55 | break;
56 | case CPU_FREQUENCY_48MHz:
57 | __delay_us(90);
58 | break;
59 | }
60 |
61 | //Start conversion
62 | ADCON0bits.GO_NOT_DONE = 1;
63 |
64 | //Wait for result to be ready
65 | while(ADCON0bits.GO_NOT_DONE);
66 |
67 | //Get result
68 | adc_value = ADRESH;
69 | adc_value <<= 2;
70 | adc_value |= ADRESL;
71 |
72 | return adc_value;
73 | }
74 |
75 | int16_t adc_calculate_temperature(uint16_t adc_value, calibrationIndex_t calibration)
76 | {
77 | int32_t tmp = (int32_t) adc_value;
78 | tmp += calibrationParameters[calibration].Offset;
79 | tmp *= calibrationParameters[calibration].Multiplier;
80 | tmp >>= calibrationParameters[calibration].Shift - 1;
81 | tmp += 1;
82 | tmp >>= 1;
83 | return (int16_t) tmp;
84 | }
--------------------------------------------------------------------------------
/system.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | #ifndef SYSTEM_H
21 | #define SYSTEM_H
22 |
23 | #include
24 | #include
25 | #include
26 | #include "adc.h"
27 |
28 | //Microcontroller flash memory erase/write page sizes.
29 | #define DRV_FILEIO_INTERNAL_FLASH_CONFIG_ERASE_BLOCK_SIZE 1024
30 | #define DRV_FILEIO_INTERNAL_FLASH_CONFIG_WRITE_BLOCK_SIZE 64
31 |
32 | #define MAIN_RETURN void
33 |
34 | /*** System States **************************************************/
35 | typedef enum
36 | {
37 | SYSTEM_STATE_USB_START,
38 | SYSTEM_STATE_USB_SUSPEND,
39 | SYSTEM_STATE_USB_RESUME
40 | } SYSTEM_STATE;
41 |
42 | /*********************************************************************
43 | * Function: void SYSTEM_Initialize( SYSTEM_STATE state )
44 | *
45 | * Overview: Initializes the system.
46 | *
47 | * PreCondition: None
48 | *
49 | * Input: SYSTEM_STATE - the state to initialize the system into
50 | *
51 | * Output: None
52 | *
53 | ********************************************************************/
54 | void SYSTEM_Initialize( SYSTEM_STATE state );
55 |
56 |
57 | /*********************************************************************
58 | * Function: void SYSTEM_Tasks(void)
59 | *
60 | * Overview: Runs system level tasks that keep the system running
61 | *
62 | * PreCondition: System has been initalized with SYSTEM_Initialize()
63 | *
64 | * Input: None
65 | *
66 | * Output: None
67 | *
68 | ********************************************************************/
69 | //void SYSTEM_Tasks(void);
70 | #define SYSTEM_Tasks()
71 |
72 | #endif //SYSTEM_H
73 |
--------------------------------------------------------------------------------
/app_device_custom_hid.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /*********************************************************************
21 | * Function: void APP_DeviceCustomHIDInitialize(void);
22 | *
23 | * Overview: Initializes the Custom HID demo code
24 | *
25 | * PreCondition: None
26 | *
27 | * Input: None
28 | *
29 | * Output: None
30 | *
31 | ********************************************************************/
32 | void APP_DeviceCustomHIDInitialize();
33 |
34 | /*********************************************************************
35 | * Function: void APP_DeviceCustomHIDStart(void);
36 | *
37 | * Overview: Starts running the Custom HID demo.
38 | *
39 | * PreCondition: The device should be configured into the configuration
40 | * that contains the custome HID interface. The APP_DeviceCustomHIDInitialize()
41 | * function should also have been called before calling this function.
42 | *
43 | * Input: None
44 | *
45 | * Output: None
46 | *
47 | ********************************************************************/
48 | void APP_DeviceCustomHIDStart();
49 |
50 | /*********************************************************************
51 | * Function: void APP_DeviceCustomHIDTasks(void);
52 | *
53 | * Overview: Keeps the Custom HID demo running.
54 | *
55 | * PreCondition: The demo should have been initialized and started via
56 | * the APP_DeviceCustomHIDInitialize() and APP_DeviceCustomHIDStart() demos
57 | * respectively.
58 | *
59 | * Input: None
60 | *
61 | * Output: None
62 | *
63 | ********************************************************************/
64 | void APP_DeviceCustomHIDTasks();
65 |
--------------------------------------------------------------------------------
/usb.h:
--------------------------------------------------------------------------------
1 | // DOM-IGNORE-BEGIN
2 | /*******************************************************************************
3 | Copyright 2015 Microchip Technology Inc. (www.microchip.com)
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | To request to license the code under the MLA license (www.microchip.com/mla_license),
18 | please contact mla_licensing@microchip.com
19 | *******************************************************************************/
20 | //DOM-IGNORE-END
21 |
22 |
23 | /*******************************************************************************
24 | Module for Microchip USB Library
25 |
26 | Company:
27 | Microchip Technology Inc.
28 |
29 | File Name:
30 | usb.h
31 |
32 | Summary:
33 | This header file exposes the core library APIs and definitions for the USB
34 | library.
35 |
36 | Description:
37 | This header file exposes the core library APIs and definitions for the USB
38 | library. The user is responsible for also including the header file for
39 | the specific driver they will be using.
40 | *******************************************************************************/
41 |
42 | #ifndef _USB_H_
43 | #define _USB_H_
44 |
45 | #include "usb_config.h"
46 |
47 | #include "usb_common.h" // Common USB library definitions
48 | #include "usb_ch9.h" // USB device framework definitions
49 |
50 | #if defined( USB_SUPPORT_DEVICE )
51 | #include "usb_device.h" // USB Device abstraction layer interface
52 | #endif
53 |
54 | #if defined( USB_SUPPORT_HOST )
55 | #include "usb_host.h" // USB Host abstraction layer interface
56 | #endif
57 |
58 | #include "usb_hal.h" // Hardware Abstraction Layer interface
59 |
60 | /* USB Library version number. This can be used to verify in an application
61 | specific version of the library is being used.
62 | */
63 | #define USB_MAJOR_VER 2 // Firmware version, major release number.
64 | #define USB_MINOR_VER 13 // Firmware version, minor release number.
65 | #define USB_DOT_VER 0 // Firmware version, dot release number.
66 |
67 | #endif // _USB_H_
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/log.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef LOG_H
3 | #define LOG_H
4 |
5 | #include
6 | #include
7 |
8 | #include "os.h"
9 | #include "fat16.h"
10 |
11 | #define LOG_FILENAME "LOG "
12 | #define LOG_EXTENSION "TXT"
13 | #define LOG_PERIOD 30
14 |
15 | /* Log structure *
16 | * 32 bytes per entry, 1 entry every 7.5 minutes
17 | * Bytes 0-3: Date and time
18 | * Year: 6 bits (2-digit year, i.e year - 2000)
19 | * Month 4 bits
20 | * Day 5 bits
21 | * Hours 5 bits
22 | * Minutes 6 bits
23 | * Seconds: 6 bits
24 | * Bytes 4-5: Input voltage: uint16_t in millivolts
25 | * Bytes 6-7: Input current: uint16_t in milliamps
26 | * Bytes 8-9: Output voltage: uint16_t in millivolts
27 | * Bytes 10-11: Output current: uint16_t in milliamps
28 | * Bytes 12-13: Input power: uint16_t in 2 milliwatts
29 | * Bytes 14-15: Output power: uint16_t in 2 milliwatts
30 | * Bytes 16-17: Input capacity: uint16_t in Ws (watt-seconds)
31 | * Bytes 18-19: Output capacity: uint16_t in Ws (watt-seconds)
32 | * Byte 20: On-board temperature: uint8_t in 0.5 degrees centigrade above -40
33 | * Byte 21: External temperature 1: uint8_t in 0.5 degrees centigrade above -40
34 | * Byte 22: External temperature 2: uint8_t in 0.5 degrees centigrade above -40
35 | * Byte 23: Charger on-time: uint8_t in 2 seconds
36 | * Byte 24: Low-power state time: uint8_t in 2 seconds
37 | * ...
38 | * Byte 30: Status byte:
39 | * Bit 7: Output 1 on
40 | * Bit 6: Output 2 on
41 | * Bit 5: Output 3 on
42 | * Bit 4: Output 4 on
43 | * Bit 3: USB charging on
44 | * Bit 2: Fan on
45 | * Bit 1: USB connected
46 | * Bit 0: User interface active
47 | * Byte 31: Checksum: All other bytes XOR-ed
48 | * ****************************************************************************/
49 |
50 | typedef struct
51 | {
52 | uint32_t dateTime;
53 | uint16_t inputVoltage;
54 | uint16_t inputCurrent;
55 | uint16_t outputVoltage;
56 | uint16_t outputCurrent;
57 | uint16_t inputPower;
58 | uint16_t outputPower;
59 | uint16_t inputCapacity;
60 | uint16_t outputCapacity;
61 | uint8_t temperatureOnboard;
62 | uint8_t temperatureExternal1;
63 | uint8_t temperatureExternal2;
64 | uint8_t chargerOnTime;
65 | uint8_t lowPowerTime;
66 | uint8_t unused[5];
67 | uint8_t status;
68 | uint8_t checksum;
69 | } logEntry_t;
70 |
71 | void log_start_new(void);
72 | void log_collect_data(void);
73 | void log_generate_entry(logEntry_t *log_entry);
74 | void log_write_to_disk(void);
75 | uint16_t log_get_number_of_samples(void);
76 |
77 | #endif /* LOG_H */
78 |
79 |
--------------------------------------------------------------------------------
/configuration_bits.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: configuration_bits.h
3 | * Author: luke
4 | *
5 | * Created on 7. Oktober 2018, 13:35
6 | */
7 |
8 | #ifndef CONFIGURATION_BITS_H
9 | #define CONFIGURATION_BITS_H
10 |
11 | // CONFIG1L
12 | #pragma config WDTEN = ON // Watchdog Timer (Enabled)
13 | #pragma config PLLDIV = 2 // PLL Prescaler Selection (Divide by 2 (8 MHz oscillator input))
14 | #pragma config CFGPLLEN = ON // PLL Enable Configuration Bit (PLL Enabled)
15 | #pragma config STVREN = ON // Stack Overflow/Underflow Reset (Enabled)
16 | #pragma config XINST = OFF // Extended Instruction Set (Disabled)
17 |
18 | // CONFIG1H
19 | #pragma config CPUDIV = OSC1 // CPU System Clock Postscaler (No CPU system clock divide)
20 | #pragma config CP0 = OFF // Code Protect (Program memory is not code-protected)
21 |
22 | // CONFIG2L
23 | #pragma config OSC = HSPLL // Oscillator (HS+PLL, USB-HS+PLL)
24 | #pragma config SOSCSEL = HIGH // T1OSC/SOSC Power Selection Bits (High Power T1OSC/SOSC circuit selected)
25 | #pragma config CLKOEC = OFF // EC Clock Out Enable Bit (CLKO output disabled on the RA6 pin)
26 | #pragma config FCMEN = OFF // Fail-Safe Clock Monitor (Disabled)
27 | #pragma config IESO = ON // Internal External Oscillator Switch Over Mode (Enabled)
28 |
29 | // CONFIG2H
30 | #pragma config WDTPS = 512 // Watchdog Postscaler (1:512)
31 |
32 | // CONFIG3L
33 | #pragma config DSWDTOSC = T1OSCREF // DSWDT Clock Select (DSWDT uses T1OSC/T1CKI)
34 | #pragma config RTCOSC = T1OSCREF // RTCC Clock Select (RTCC uses T1OSC/T1CKI)
35 | #pragma config DSBOREN = OFF // Deep Sleep BOR (Disabled)
36 | #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer (Disabled)
37 | #pragma config DSWDTPS = 8192 // Deep Sleep Watchdog Postscaler (1:8,192 (8.5 seconds))
38 |
39 | // CONFIG3H
40 | #pragma config IOL1WAY = OFF // IOLOCK One-Way Set Enable bit (The IOLOCK bit (PPSCON<0>) can be set and cleared as needed)
41 | #pragma config ADCSEL = BIT10 // ADC 10 or 12 Bit Select (10 - Bit ADC Enabled)
42 | #pragma config MSSP7B_EN = MSK7 // MSSP address masking (7 Bit address masking mode)
43 |
44 | // CONFIG4L
45 | #pragma config WPFP = PAGE_1 // Write/Erase Protect Page Start/End Location (Write Protect Program Flash Page 1)
46 | #pragma config WPCFG = OFF // Write/Erase Protect Configuration Region (Configuration Words page not erase/write-protected)
47 |
48 | // CONFIG4H
49 | #pragma config WPDIS = OFF // Write Protect Disable bit (WPFP<6:0>/WPEND region ignored)
50 | #pragma config WPEND = PAGE_0 // Write/Erase Protect Region Select bit (valid when WPDIS = 0) (Pages 0 through WPFP<6:0> erase/write protected)
51 | #pragma config LS48MHZ = SYS48X8// Low Speed USB mode with 48 MHz system clock bit (System clock at 48 MHz USB CLKEN divide-by is set to 8)
52 |
53 |
54 | #endif /* CONFIGURATION_BITS_H */
55 |
56 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # There exist several targets which are by default empty and which can be
3 | # used for execution of your targets. These targets are usually executed
4 | # before and after some main targets. They are:
5 | #
6 | # .build-pre: called before 'build' target
7 | # .build-post: called after 'build' target
8 | # .clean-pre: called before 'clean' target
9 | # .clean-post: called after 'clean' target
10 | # .clobber-pre: called before 'clobber' target
11 | # .clobber-post: called after 'clobber' target
12 | # .all-pre: called before 'all' target
13 | # .all-post: called after 'all' target
14 | # .help-pre: called before 'help' target
15 | # .help-post: called after 'help' target
16 | #
17 | # Targets beginning with '.' are not intended to be called on their own.
18 | #
19 | # Main targets can be executed directly, and they are:
20 | #
21 | # build build a specific configuration
22 | # clean remove built files from a configuration
23 | # clobber remove all built files
24 | # all build all configurations
25 | # help print help mesage
26 | #
27 | # Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
28 | # .help-impl are implemented in nbproject/makefile-impl.mk.
29 | #
30 | # Available make variables:
31 | #
32 | # CND_BASEDIR base directory for relative paths
33 | # CND_DISTDIR default top distribution directory (build artifacts)
34 | # CND_BUILDDIR default top build directory (object files, ...)
35 | # CONF name of current configuration
36 | # CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
37 | # CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
38 | # CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
39 | # CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
40 | # CND_PACKAGE_NAME_${CONF} name of package (current configuration)
41 | # CND_PACKAGE_PATH_${CONF} path to package (current configuration)
42 | #
43 | # NOCDDL
44 |
45 |
46 | # Environment
47 | MKDIR=mkdir
48 | CP=cp
49 | CCADMIN=CCadmin
50 | RANLIB=ranlib
51 |
52 |
53 | # build
54 | build: .build-post
55 |
56 | .build-pre:
57 | # Add your pre 'build' code here...
58 |
59 | .build-post: .build-impl
60 | # Add your post 'build' code here...
61 |
62 |
63 | # clean
64 | clean: .clean-post
65 |
66 | .clean-pre:
67 | # Add your pre 'clean' code here...
68 | # WARNING: the IDE does not call this target since it takes a long time to
69 | # simply run make. Instead, the IDE removes the configuration directories
70 | # under build and dist directly without calling make.
71 | # This target is left here so people can do a clean when running a clean
72 | # outside the IDE.
73 |
74 | .clean-post: .clean-impl
75 | # Add your post 'clean' code here...
76 |
77 |
78 | # clobber
79 | clobber: .clobber-post
80 |
81 | .clobber-pre:
82 | # Add your pre 'clobber' code here...
83 |
84 | .clobber-post: .clobber-impl
85 | # Add your post 'clobber' code here...
86 |
87 |
88 | # all
89 | all: .all-post
90 |
91 | .all-pre:
92 | # Add your pre 'all' code here...
93 |
94 | .all-post: .all-impl
95 | # Add your post 'all' code here...
96 |
97 |
98 | # help
99 | help: .help-post
100 |
101 | .help-pre:
102 | # Add your pre 'help' code here...
103 |
104 | .help-post: .help-impl
105 | # Add your post 'help' code here...
106 |
107 |
108 |
109 | # include project implementation makefile
110 | include nbproject/Makefile-impl.mk
111 |
112 | # include project make variables
113 | include nbproject/Makefile-variables.mk
114 |
--------------------------------------------------------------------------------
/app_device_custom_hid.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /** INCLUDES *******************************************************/
21 | #include "usb.h"
22 | #include "usb_device_hid.h"
23 | #include
24 | #include "system.h"
25 | #include "api.h"
26 |
27 | /** VARIABLES ******************************************************/
28 | unsigned char ReceivedDataBuffer[64];
29 | unsigned char ToSendDataBuffer[64];
30 |
31 | volatile USB_HANDLE USBOutHandle;
32 | volatile USB_HANDLE USBInHandle;
33 |
34 | /*********************************************************************
35 | * Function: void APP_DeviceCustomHIDInitialize(void);
36 | *
37 | * Overview: Initializes the Custom HID demo code
38 | *
39 | * PreCondition: None
40 | *
41 | * Input: None
42 | *
43 | * Output: None
44 | *
45 | ********************************************************************/
46 | void APP_DeviceCustomHIDInitialize()
47 | {
48 | //initialize the variable holding the handle for the last
49 | // transmission
50 | USBInHandle = 0;
51 |
52 | //enable the HID endpoint
53 | USBEnableEndpoint(CUSTOM_DEVICE_HID_EP, USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
54 |
55 | //Re-arm the OUT endpoint for the next packet
56 | USBOutHandle = (volatile USB_HANDLE)HIDRxPacket(CUSTOM_DEVICE_HID_EP,(uint8_t*)&ReceivedDataBuffer,64);
57 | }
58 |
59 | /*********************************************************************
60 | * Function: void APP_DeviceCustomHIDTasks(void);
61 | *
62 | * Overview: Keeps the Custom HID demo running.
63 | *
64 | * PreCondition: The demo should have been initialized and started via
65 | * the APP_DeviceCustomHIDInitialize() and APP_DeviceCustomHIDStart() demos
66 | * respectively.
67 | *
68 | * Input: None
69 | *
70 | * Output: None
71 | *
72 | ********************************************************************/
73 | void APP_DeviceCustomHIDTasks()
74 | {
75 | uint8_t idx;
76 |
77 | /* If the USB device isn't configured yet, we can't really do anything
78 | * else since we don't have a host to talk to. So jump back to the
79 | * top of the while loop. */
80 | if( USBGetDeviceState() < CONFIGURED_STATE )
81 | {
82 | return;
83 | }
84 |
85 | /* If we are currently suspended, then we need to see if we need to
86 | * issue a remote wakeup. In either case, we shouldn't process any
87 | * keyboard commands since we aren't currently communicating to the host
88 | * thus just continue back to the start of the while loop. */
89 | if( USBIsDeviceSuspended()== true )
90 | {
91 | return;
92 | }
93 |
94 | //Check if we have received an OUT data packet from the host
95 | if(HIDRxHandleBusy(USBOutHandle) == false)
96 | {
97 | //We just received a packet of data from the USB host.
98 | //Let the API handle it
99 |
100 | //Prepare the data to send next if the buffer is not currently in use
101 | if(!HIDTxHandleBusy(USBInHandle))
102 | {
103 | //Prepare the data
104 | api_prepare((uint8_t*) ReceivedDataBuffer, (uint8_t*) ToSendDataBuffer);
105 | //Prepare the USB module to send the data packet to the host
106 | USBInHandle = HIDTxPacket(CUSTOM_DEVICE_HID_EP, (uint8_t*)&ToSendDataBuffer[0], 64);
107 | }
108 |
109 | //Perform any other tasks the host may want us to do
110 | api_parse(ReceivedDataBuffer, 64, ToSendDataBuffer);
111 |
112 | //Re-arm the OUT endpoint, so we can receive the next OUT data packet
113 | //that the host may try to send us.
114 | USBOutHandle = HIDRxPacket(CUSTOM_DEVICE_HID_EP, (uint8_t*)&ReceivedDataBuffer, 64);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/fat16.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: fat16.h
3 | * Author: Luke
4 | *
5 | * Created on 30. October 2017, 21:59
6 | */
7 |
8 | #ifndef FAT16_H
9 | #define FAT16_H
10 |
11 | /******************************************************************************
12 | * The drive is organized as follows: *
13 | * - There are 8192 sectors of 512 bytes each, numbered from 0 to 8191 *
14 | * - There is one partition, occupying the entire space except the MBR *
15 | * - Sector 0: (1 sector) Master boot record (MBR) *
16 | * - Sector 1: (1 sector) First boot record (FBR) *
17 | * - Sectors 2-33: (32 sectors) File allocation table (FAT) *
18 | * - Sectors 34-37: (4 sectors) Root directory *
19 | * - Sectors 38-8191: (8154 sectors) Data
20 | ******************************************************************************/
21 |
22 | //General drive layout
23 | #define MBR_SECTOR 0
24 | #define FBR_SECTOR 1
25 | #define FAT_FIRST_SECTOR 2
26 | #define FAT_LAST_SECTOR 33
27 | #define FAT_MINIMUM_VALUE 2
28 | #define FAT_MAXIMUM_VALUE 8153
29 | #define ROOT_FIRST_SECTOR 34
30 | #define ROOT_LAST_SECTOR 37
31 | #define DATA_FIRST_SECTOR 38
32 | #define DATA_LAST_SECTOR 8191
33 | #define DATA_NUMBER_OF_SECTORS 8154
34 | #define BYTES_PER_SECTOR 512
35 | #define CLUSTERS_PER_FAT_SECTOR 256
36 |
37 | //MBR specifics
38 | #define MRB_PARTITION_STATUS 0x80
39 | #define MBR_PARTITION_TYPE 0x04
40 | #define MBR_PARTITION_SIZE 8191
41 | #define MBR_FIRST_PARTITION_SECTOR 1
42 | #define MBR_PARTITION_START_CYLINDER 0
43 | #define MBR_PARTITION_START_HEAD 0
44 | #define MBR_PARTITION_START_SECTOR 2
45 | #define MBR_LAST_PARTITION_SECTOR 8191
46 | #define MBR_PARTITION_END_CYLINDER 8
47 | #define MBR_PARTITION_END_HEAD 2
48 | #define MBR_PARTITION_END_SECTOR 3
49 | #define MBR_SIGNATURE 0X55AA
50 |
51 | //FBR specifics
52 | #define FBR_OEM_IDENTIFIER "MSDOS5.0"
53 | #define FBR_BYTES_PER_SECTOR 512
54 | #define FBR_SECTORS_PER_CLUSTER 1
55 | #define FBR_RESERVED_SECTORS 1
56 | #define FBR_NUMBER_OF_FATS 1
57 | #define FBR_ROOT_ENTRIES 64
58 | #define FBR_NUMBER_OF_SECTORS 8191
59 | #define FBR_MEDIA_DESCRIPTOR 0XF8
60 | #define FBR_SECTORS_PER_FAT 32
61 | #define FBR_SECTORS_PER_HEAD 63
62 | #define FBR_HEADS_PER_CYLINDER 16
63 | #define FBR_HIDDEN_SECTORS 0
64 | #define FBR_EXT_FLAGS 0b00000001
65 | #define FBR_ROOT_DIRECTORY_START 34
66 | #define FBR_SIGNATURE 0X55AA
67 |
68 | //A hello world file
69 | #define ROOT_DRIVE_NAME "SolarChargr"
70 | #define ROOT_FILE_NAME "FILE "
71 | #define ROOT_FILE_EXTENSION "TXT"
72 | #define ROOT_FILE_CONTENT "hello world!"
73 | #define ROOT_FILE_SIZE 12
74 | #define ROOT_FILE_FIRST_CLUSTER 2
75 |
76 | typedef struct
77 | {
78 | char fileName[8];
79 | char fileExtension[3];
80 | uint8_t attributes;
81 | uint8_t reserved1;
82 | uint8_t secondFractions;
83 | uint16_t createdTime;
84 | uint16_t createdDate;
85 | uint16_t lastAccessDate;
86 | uint16_t reserved2;
87 | uint16_t modifiedTime;
88 | uint16_t modifiedDate;
89 | uint16_t firstCluster;
90 | uint32_t fileSize;
91 | } rootEntry_t;
92 |
93 | typedef enum
94 | {
95 | DRIVE_NOT_FORMATED = 0x00,
96 | DRIVE_FORMATED = 0x01
97 | } formatStatus_t;
98 |
99 | void fat_init(void);
100 | formatStatus_t fat_get_format_status(void);
101 | uint8_t fat_format(void);
102 | uint8_t fat_find_file(char *name, char *extension);
103 | uint8_t fat_get_file_information(uint8_t file_number, rootEntry_t *data);
104 | uint32_t fat_get_file_size(uint8_t file_number);
105 | uint8_t fat_create_file(char *name, char *extension, uint32_t size);
106 | uint8_t fat_delete_file(uint8_t file_number);
107 | uint8_t fat_resize_file(uint8_t file_number, uint32_t new_file_size);
108 | uint8_t fat_modify_file(uint8_t file_number, uint32_t start_byte, uint16_t length, uint8_t *data);
109 | uint8_t fat_append_to_file(uint8_t file_number, uint16_t number_of_bytes, uint8_t *data);
110 | uint8_t fat_rename_file(uint8_t file_number, char *name, char *extension);
111 | uint8_t fat_read_from_file(uint8_t file_number, uint32_t start_byte, uint32_t length, uint8_t *data);
112 | uint8_t fat_read_from_file_fast(uint32_t start_byte, uint32_t length, uint8_t *data, uint16_t *cluster, uint16_t *cluster_number);
113 | uint8_t fat_copy_file(uint8_t file_number, char *name, char *extension);
114 |
115 | //Read or write access via FLASH_BUFFER_2
116 | uint8_t fat_copy_sector_to_buffer(uint8_t file_number, uint16_t sector);
117 | uint8_t fat_write_sector_from_buffer(uint8_t file_number, uint16_t sector);
118 | void fat_read_from_buffer(uint16_t start, uint16_t length, uint8_t *data);
119 | void fat_write_to_buffer(uint16_t start, uint16_t length, uint8_t *data);
120 |
121 | #endif /* FAT16_H */
122 |
123 |
--------------------------------------------------------------------------------
/i2c.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: i2c.h
3 | * Author: Luke
4 | *
5 | * Created on 4. September 2016, 09:26
6 | */
7 |
8 | #ifndef I2C_H
9 | #define I2C_H
10 |
11 | #include
12 | #include "application_config.h"
13 |
14 | /* ****************************************************************************
15 | * Type definitions
16 | * ****************************************************************************/
17 |
18 | typedef enum
19 | {
20 | I2C_FREQUENCY_100kHz,
21 | I2C_FREQUENCY_200kHz,
22 | I2C_FREQUENCY_400kHz
23 | } i2cFrequency_t;
24 |
25 | #ifdef ANALOG_DIGITAL_CONVERTER_AVAILABLE
26 | typedef enum
27 | {
28 | I2C_ADC_OUTPUT_VOLTAGE,
29 | I2C_ADC_OUTPUT_CURRENT,
30 | I2C_ADC_INPUT_CURRENT,
31 | I2C_ADC_INPUT_VOLTAGE
32 | } i2cAdcPort_t;
33 |
34 | typedef enum
35 | {
36 | I2C_ADC_RESOLUTION_12BIT,
37 | I2C_ADC_RESOLUTION_14BIT,
38 | I2C_ADC_RESOLUTION_16BIT,
39 | I2C_ADC_RESOLUTION_18BIT
40 | } i2cAdcResolution_t;
41 |
42 | typedef enum
43 | {
44 | I2C_ADC_GAIN_1,
45 | I2C_ADC_GAIN_2,
46 | I2C_ADC_GAIN_4,
47 | I2C_ADC_GAIN_8
48 | } i2cAdcGain_t;
49 | #endif /*ANALOG_DIGITAL_CONVERTER_AVAILABLE*/
50 |
51 | #ifdef I2C_TASK_SCHEDULING_AVAILABLE
52 | typedef enum
53 | {
54 | EEPROM_WRITE_TASK_NONE = 0,
55 | EEPROM_WRITE_TASK_REAL_TIME_CLOCK,
56 | EEPROM_WRITE_TASK_CALIBRATION_INPUT_VOLTAGE,
57 | EEPROM_WRITE_TASK_CALIBRATION_OUTPUT_VOLTAGE,
58 | EEPROM_WRITE_TASK_CALIBRATION_INPUT_CURRENT,
59 | EEPROM_WRITE_TASK_CALIBRATION_OUTPUT_CURRENT,
60 | EEPROM_WRITE_TASK_CALIBRATION_ONBOARD_TEMPERATURE,
61 | EEPROM_WRITE_TASK_CALIBRATION_EXTERNAL_TEMPERATURE_1,
62 | EEPROM_WRITE_TASK_CALIBRATION_EXTERNAL_TEMPERATURE_2
63 | } eeprom_write_task_t;
64 | #endif /*I2C_TASK_SCHEDULING_AVAILABLE*/
65 |
66 | /* ****************************************************************************
67 | * General I2C functionality
68 | * ****************************************************************************/
69 |
70 | void i2c_init(void);
71 | void i2c_reset(void);
72 | i2cFrequency_t i2c_get_frequency(void);
73 | void i2c_set_frequency(i2cFrequency_t frequency);
74 |
75 |
76 | /* ****************************************************************************
77 | * I2C Task Scheduling
78 | * ****************************************************************************/
79 |
80 | #ifdef I2C_TASK_SCHEDULING_AVAILABLE
81 | uint8_t get_eeprom_write_task_count(void);
82 | void schedule_eeprom_write_task(eeprom_write_task_t task);
83 | eeprom_write_task_t get_next_eeprom_write_task(void);
84 | void i2c_eeprom_tasks(void);
85 | #endif /*I2C_TASK_SCHEDULING_AVAILABLE*/
86 |
87 | /* ****************************************************************************
88 | * I2C Display Functionality
89 | * ****************************************************************************/
90 |
91 | void i2c_display_send_init_sequence(void);
92 | void i2c_display_cursor(uint8_t line, uint8_t position);
93 | void i2c_display_write(char *data);
94 | void i2c_display_write_fixed(char *data, uint8_t length);
95 |
96 |
97 | /* ****************************************************************************
98 | * I2C Dual Digipot Functionality
99 | * ****************************************************************************/
100 |
101 | void i2c_digipot_reset_on(void);
102 | void i2c_digipot_reset_off(void);
103 | void i2c_digipot_backlight(uint8_t level);
104 | void i2c_digipot_set_defaults(void);
105 |
106 |
107 | /* ****************************************************************************
108 | * I2C EEPROM Functionality
109 | * ****************************************************************************/
110 |
111 | void i2c_eeprom_writeByte(uint16_t address, uint8_t data);
112 | uint8_t i2c_eeprom_readByte(uint16_t address);
113 | void i2c_eeprom_write(uint16_t address, uint8_t *data, uint8_t length);
114 | void i2c_eeprom_read(uint16_t address, uint8_t *data, uint8_t length);
115 |
116 |
117 | /* ****************************************************************************
118 | * Calibration for ADC, stored in EEPROM
119 | * ****************************************************************************/
120 |
121 | #ifdef ANALOG_DIGITAL_CONVERTER_AVAILABLE
122 | void i2c_eeprom_read_calibration(void);
123 | #endif /*ANALOG_DIGITAL_CONVERTER_AVAILABLE*/
124 |
125 |
126 | /* ****************************************************************************
127 | * I2C ADC Functionality
128 | * ****************************************************************************/
129 |
130 | #ifdef ANALOG_DIGITAL_CONVERTER_AVAILABLE
131 | void i2c_adc_start(i2cAdcPort_t channel, i2cAdcResolution_t resolution, i2cAdcGain_t gain);
132 | int16_t i2c_adc_read(void);
133 | #endif /*ANALOG_DIGITAL_CONVERTER_AVAILABLE*/
134 |
135 |
136 | #endif /* I2C_H */
137 |
138 |
--------------------------------------------------------------------------------
/hardware_config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: hardware_config.h
3 | * Author: luke
4 | *
5 | * Created on 3. Oktober 2018, 17:19
6 | */
7 |
8 | #ifndef HARDWARE_CONFIG_H
9 | #define HARDWARE_CONFIG_H
10 |
11 | /*
12 | * Define your board revision here
13 | */
14 |
15 | #define BOARD_REVISION_F
16 |
17 | /******************************************************************************
18 | * Nothing should need to be changed below here *
19 | ******************************************************************************/
20 |
21 | /*
22 | * Replacement for some depreciated PLIB macros
23 | */
24 |
25 | #define PPSUnLock() {EECON2 = 0b01010101; EECON2 = 0b10101010; PPSCONbits.IOLOCK = 0;}
26 | #define PPSLock() {EECON2 = 0b01010101; EECON2 = 0b10101010; PPSCONbits.IOLOCK = 1;}
27 |
28 | /*
29 | * General definitions for setting pin functions
30 | */
31 |
32 | #define PIN_INPUT 1
33 | #define PIN_OUTPUT 0
34 | #define PIN_DIGITAL 1
35 | #define PIN_ANALOG 0
36 |
37 | /*
38 | * Physical properties, pinout
39 | */
40 |
41 | #define _XTAL_FREQ 8000000
42 |
43 | #define PPS_FUNCTION_SPI2_DATA_OUTPUT_VALUE 10
44 | #define PPS_FUNCTION_SPI2_DATA_INPUT_REGISTER RPINR21
45 | #define PPS_FUNCTION_SPI2_CLOCK_OUTPUT_VALUE 11
46 | #define PPS_FUNCTION_SPI2_CLOCK_INPUT_REGISTER RPINR22
47 | #define PPS_FUNCTION_SPI2_CHIPSELECT_OUTPUT_VALUE 12
48 | #define PPS_FUNCTION_SPI2_CHIPSELECT_INPUT_REGISTER RPINR23
49 | #define PPS_FUNCTION_CCP1_A_OUTPUT_VALUE 14
50 | #define PPS_FUNCTION_CCP1_B_OUTPUT_VALUE 15
51 |
52 | #define DISP_EN_TRIS TRISDbits.TRISD0
53 | #define DISP_EN_PIN LATDbits.LD0
54 |
55 | #define VCC_HIGH_TRIS TRISCbits.TRISC2
56 | #define VCC_HIGH_PIN LATCbits.LC2
57 |
58 | #define BUCK_ENABLE_TRIS TRISBbits.TRISB1
59 | #define BUCK_ENABLE_PIN LATBbits.LB1
60 | #define BUCK_LOWFET_TRIS TRISBbits.TRISB2
61 | #define BUCK_LOWFET_PIN LATBbits.LB2
62 | #define BUCK_LOWFET_RP_OUTPUT_REGISTER RPOR6
63 | #define BUCK_HIGHFET_TRIS TRISBbits.TRISB3
64 | #define BUCK_HIGHFET_PIN LATBbits.LB3
65 | #define BUCK_HIGHFET_RP_OUTPUT_REGISTER RPOR5
66 |
67 | #define PWROUT_ENABLE_TRIS TRISCbits.TRISC7
68 | #define PWROUT_ENABLE_PIN LATCbits.LC7
69 | #define PWROUT_CH1_TRIS TRISEbits.TRISE2
70 | #define PWROUT_CH1_PIN LATEbits.LE2
71 | #define PWROUT_CH2_TRIS TRISEbits.TRISE1
72 | #define PWROUT_CH2_PIN LATEbits.LE1
73 | #define PWROUT_CH3_TRIS TRISEbits.TRISE0
74 | #define PWROUT_CH3_PIN LATEbits.LE0
75 | #define PWROUT_CH4_TRIS TRISAbits.TRISA5
76 | #define PWROUT_CH4_PIN LATAbits.LA5
77 |
78 | #define USBCHARGER_EN_TRIS TRISDbits.TRISD3
79 | #define USBCHARGER_EN_PIN LATDbits.LD3
80 |
81 | #define SPI_MISO_TRIS TRISDbits.TRISD6
82 | #define SPI_MISO_PIN LATDbits.LD6
83 | #define SPI_MISO_RP_INPUT_VALUE 23
84 | #define SPI_MISO_RP_OUTPUT_REGISTER RPOR23
85 | #define SPI_MOSI_TRIS TRISDbits.TRISD4
86 | #define SPI_MOSI_PIN LATDbits.LD4
87 | #define SPI_MOSI_RP_INPUT_VALUE 21
88 | #define SPI_MOSI_RP_OUTPUT_REGISTER RPOR21
89 |
90 | #define SPI_SCLK_TRIS TRISDbits.TRISD5
91 | #define SPI_SCLK_PIN LATDbits.LD5
92 | #define SPI_SCLK_RP_INPUT_VALUE 22
93 | #define SPI_SCLK_RP_OUTPUT_REGISTER RPOR22
94 |
95 | #define SPI_SS1_TRIS TRISDbits.TRISD7
96 | #define SPI_SS1_PIN LATDbits.LD7
97 | #define SPI_SS1_RP_INPUT_VALUE 24
98 | #define SPI_SS1_RP_OUTPUT_REGISTER RPOR24
99 |
100 |
101 |
102 | #ifdef BOARD_REVISION_E
103 | #define SPI_SS2_TRIS TRISDbits.TRISD1
104 | #define SPI_SS2_PIN LATDbits.LD1
105 | #define SPI_SS2_RP_INPUT_VALUE NOT_AVAILABLE
106 | #define SPI_SS2_RP_OUTPUT_REGISTER NOT_AVAILABLE
107 | #define FANOUT_TRIS TRISDbits.TRISD2
108 | #define FANOUT_PIN LATDbits.LD2
109 | #endif /* BOARD_REVISION_E */
110 |
111 | #ifdef BOARD_REVISION_F
112 | #define SPI_SS2_TRIS TRISDbits.TRISD2
113 | //#define SPI_SS2_PIN LATDbits.LD2
114 | #define SPI_SS2_PORT PORTDbits.RD2
115 | #define SPI_SS2_LAT LATDbits.LD2
116 | #define SPI_SS2_RP_INPUT_VALUE 19
117 | #define SPI_SS2_RP_OUTPUT_REGISTER RPOR19
118 | #define FANOUT_TRIS TRISDbits.TRISD1
119 | #define FANOUT_PIN LATDbits.LD1
120 | #endif /* BOARD_REVISION_F */
121 |
122 | #define PUSHBUTTON_TRIS TRISAbits.TRISA0
123 | #define PUSHBUTTON_PIN PORTAbits.RA0
124 | #define PUSHBUTTON_LAT LATAbits.LA0
125 | #define PUSHBUTTON_ANCON ANCON0bits.PCFG0
126 | #define PUSHBUTTON_PPS 0
127 | #define ENCODER_A_TRIS TRISBbits.TRISB7
128 | #define ENCODER_A_PIN PORTBbits.RB7
129 | #define ENCODER_A_PPS 9
130 | #define ENCODER_B_TRIS TRISBbits.TRISB6
131 | #define ENCODER_B_PIN PORTBbits.RB6
132 | #define ENCODER_B_PPS 10
133 |
134 | #define VOLTAGE_REFERENCE_TRIS TRISAbits.TRISA3
135 | #define VOLTAGE_REFERENCE_ANCON ANCON0bits.PCFG3
136 | #define TEMPERATURE1_TRIS TRISBbits.TRISB0
137 | #define TEMPERATURE1_ANCON ANCON1bits.PCFG12
138 | #define TEMPERATURE1_CHANNEL 0b1100
139 | #define TEMPERATURE2_TRIS TRISAbits.TRISA1
140 | #define TEMPERATURE2_ANCON ANCON0bits.PCFG1
141 | #define TEMPERATURE2_CHANNEL 0b0001
142 | #define TEMPERATURE3_TRIS TRISAbits.TRISA2
143 | #define TEMPERATURE3_ANCON ANCON0bits.PCFG2
144 | #define TEMPERATURE3_CHANNEL 0b0010
145 |
146 | #endif /* HARDWARE_CONFIG_H */
147 |
148 |
--------------------------------------------------------------------------------
/app_device_msd.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | #include "system.h"
21 | #include "usb.h"
22 | #include "usb_device_msd.h"
23 | #include "external_flash.h"
24 |
25 |
26 | //The LUN variable definition is critical to the MSD function driver. This
27 | // array is a structure of function pointers that are the functions that
28 | // will take care of each of the physical media. For each additional LUN
29 | // that is added to the system, an entry into this array needs to be added
30 | // so that the stack can know where to find the physical layer functions.
31 | // In this example the media initialization function is named
32 | // "MediaInitialize", the read capacity function is named "ReadCapacity",
33 | // etc.
34 | LUN_FUNCTIONS LUN[MAX_LUN + 1] =
35 | {
36 | {
37 | //(FILEIO_MEDIA_INFORMATION* (*)(void *))&FILEIO_InternalFlash_MediaInitialize,
38 | (FILEIO_MEDIA_INFORMATION* (*)(void *))&ExternalFlash_MediaInitialize,
39 | //(uint32_t (*)(void *))&FILEIO_InternalFlash_CapacityRead,
40 | (uint32_t (*)(void *))&ExternalFlash_CapacityRead,
41 | //(uint16_t (*)(void *))&FILEIO_InternalFlash_SectorSizeRead,
42 | (uint16_t (*)(void *))&ExternalFlash_SectorSizeRead,
43 | //(bool (*)(void *))&FILEIO_InternalFlash_MediaDetect,
44 | (bool (*)(void *))&ExternalFlash_MediaDetect,
45 | //(uint8_t (*)(void *, uint32_t, uint8_t*))&FILEIO_InternalFlash_SectorRead,
46 | (uint8_t (*)(void *, uint32_t, uint8_t*))&ExternalFlash_SectorRead,
47 | //(uint8_t (*)(void *))&FILEIO_InternalFlash_WriteProtectStateGet,
48 | (uint8_t (*)(void *))&ExternalFlash_WriteProtectStateGet,
49 | //(uint8_t (*)(void *, uint32_t, uint8_t *, uint8_t))&FILEIO_InternalFlash_SectorWrite,
50 | (uint8_t (*)(void *, uint32_t, uint8_t *, uint8_t))&ExternalFlash_SectorWrite,
51 | (void *)NULL
52 | }
53 | };
54 |
55 | /* Standard Response to INQUIRY command stored in ROM */
56 | const InquiryResponse inq_resp = {
57 | 0x00, // peripheral device is connected, direct access block device
58 | 0x80, // removable
59 | 0x04, // version = 00=> does not conform to any standard, 4=> SPC-2
60 | 0x02, // response is in format specified by SPC-2
61 | 0x20, // n-4 = 36-4=32= 0x20
62 | 0x00, // sccs etc.
63 | 0x00, // bque=1 and cmdque=0,indicates simple queuing 00 is obsolete,
64 | // but as in case of other device, we are just using 00
65 | 0x00, // 00 obsolete, 0x80 for basic task queuing
66 | {'M','i','c','r','o','c','h','p'}, // this is the T10 assigned Vendor ID
67 | {'M','a','s','s',' ','S','t','o','r','a','g','e',' ',' ',' ',' '},
68 | {'0','0','0','1'}
69 | };
70 |
71 |
72 | /*********************************************************************
73 | * Function: void APP_DeviceMSDInitialize(void);
74 | *
75 | * Overview: Initializes the Custom HID demo code
76 | *
77 | * PreCondition: None
78 | *
79 | * Input: None
80 | *
81 | * Output: None
82 | *
83 | ********************************************************************/
84 | void APP_DeviceMSDInitialize()
85 | {
86 | #if (MSD_DATA_IN_EP == MSD_DATA_OUT_EP)
87 | USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
88 | #else
89 | USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
90 | USBEnableEndpoint(MSD_DATA_OUT_EP,USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
91 | #endif
92 |
93 | USBMSDInit();
94 | }
95 |
96 | /*********************************************************************
97 | * Function: void APP_DeviceMSDTasks(void);
98 | *
99 | * Overview: Keeps the Custom HID demo running.
100 | *
101 | * PreCondition: The demo should have been initialized and started via
102 | * the APP_DeviceMSDInitialize() and APP_DeviceMSDStart() demos
103 | * respectively.
104 | *
105 | * Input: None
106 | *
107 | * Output: None
108 | *
109 | ********************************************************************/
110 | void APP_DeviceMSDTasks()
111 | {
112 | /* If the USB device isn't configured yet, we can't really do anything
113 | * else since we don't have a host to talk to. So jump back to the
114 | * top of the while loop. */
115 | if( USBGetDeviceState() < CONFIGURED_STATE )
116 | {
117 | return;
118 | }
119 |
120 | /* If we are currently suspended, then we need to see if we need to
121 | * issue a remote wakeup. In either case, we shouldn't process any
122 | * keyboard commands since we aren't currently communicating to the host
123 | * thus just continue back to the start of the while loop. */
124 | if( USBIsDeviceSuspended()== true )
125 | {
126 | return;
127 | }
128 |
129 | MSDTasks();
130 | }
--------------------------------------------------------------------------------
/os.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: system.h
3 | * Author: Luke
4 | *
5 | * Created on 5. September 2016, 21:17
6 | */
7 |
8 | #ifndef OS_H
9 | #define OS_H
10 |
11 | #include
12 | #include "i2c.h"
13 | #include "spi.h"
14 |
15 | /*
16 | * Function prototypes
17 | */
18 |
19 | void reboot(void);
20 |
21 | /*
22 | * Type definitions
23 | */
24 |
25 | typedef enum
26 | {
27 | DISPLAY_MODE_OVERVIEW = 0x00,
28 | DISPLAY_MODE_DATETIME_OVERVIEW = 0x10,
29 | DISPLAY_MODE_DATETIME_YEAR = 0x11,
30 | DISPLAY_MODE_DATETIME_MONTH = 0x12,
31 | DISPLAY_MODE_DATETIME_DAY = 0x13,
32 | DISPLAY_MODE_DATETIME_HOURS = 0x14,
33 | DISPLAY_MODE_DATETIME_MINUTES = 0x15,
34 | DISPLAY_MODE_DATETIME_SECONDS = 0x16,
35 | DISPLAY_MODE_USB_CHARGER = 0x20,
36 | DISPLAY_MODE_OUTPUTS = 0x30,
37 | DISPLAY_MODE_OUTPUTS_1 = 0x31,
38 | DISPLAY_MODE_OUTPUTS_2 = 0x32,
39 | DISPLAY_MODE_OUTPUTS_3 = 0x33,
40 | DISPLAY_MODE_OUTPUTS_4 = 0x34,
41 | DISPLAY_MODE_CHARGER_DETAILS = 0x40,
42 | DISPLAY_MODE_EFFICIENCY = 0x50,
43 | DISPLAY_MODE_TEMPERATURE = 0x60,
44 | DISPLAY_MODE_STARTUP = 0x70
45 | } displayMode_t;
46 |
47 | typedef enum
48 | {
49 | CPU_FREQUENCY_32kHz,
50 | CPU_FREQUENCY_8MHz,
51 | CPU_FREQUENCY_48MHz
52 | } clockFrequency_t;
53 |
54 | typedef enum
55 | {
56 | BUCK_OFF,
57 | BUCK_FREQUENCY_62500,
58 | BUCK_FREQUENCY_93750,
59 | BUCK_FREQUENCY_187500
60 | } buckFrequency_t;
61 |
62 | typedef enum
63 | {
64 | OUTPUT_1 = 0x01,
65 | OUTPUT_2 = 0x02,
66 | OUTPUT_3 = 0x04,
67 | OUTPUT_4 = 0x08,
68 | OUTPUT_ALL = 0x0F,
69 | OUTPUT_USB = 0x10,
70 | OUTPUT_FAN = 0x20,
71 | } outputs_t;
72 |
73 | typedef enum
74 | {
75 | BOARD_VOLTAGE_LOW,
76 | BOARD_VOLTAGE_HIGH
77 | } boardVoltage_t;
78 |
79 | typedef enum
80 | {
81 | CALIBRATION_INDEX_INPUT_VOLTAGE = 0,
82 | CALIBRATION_INDEX_OUTPUT_VOLTAGE = 1,
83 | CALIBRATION_INDEX_INPUT_CURRENT = 2,
84 | CALIBRATION_INDEX_OUTPUT_CURRENT = 3,
85 | CALIBRATION_INDEX_ONBOARD_TEMPERATURE = 4,
86 | CALIBRATION_INDEX_EXTERNAL_TEMPERATURE_1 = 5,
87 | CALIBRATION_INDEX_EXTERNAL_TEMPERATURE_2 = 6,
88 | CALIBRATION_INDEX_COUNT = 7
89 | } calibrationIndex_t;
90 |
91 | typedef struct
92 | {
93 | int16_t NeutralOffset;
94 | int16_t NeutralMultiplier;
95 | int8_t NeutralShift;
96 | int16_t Offset;
97 | int16_t Multiplier;
98 | int8_t Shift;
99 | int16_t AutoCalibration;
100 | } calibration_t;
101 |
102 | typedef enum
103 | {
104 | EXTERNAL_MODE_SLAVE,
105 | EXTERNAL_MODE_MASTER
106 | } externalMode_t;
107 |
108 | typedef struct
109 | {
110 | //SPI settings
111 | externalMode_t spiMode;
112 | spiFrequency_t spiFrequency;
113 | spiPolarity_t spiPolarity;
114 | //I2C settings
115 | externalMode_t i2cMode;
116 | i2cFrequency_t i2cFrequency;
117 | uint8_t i2cSlaveModeSlaveAddress;
118 | uint8_t i2cMasterModeSlaveAddress;
119 | } communicationSettings_t;
120 |
121 |
122 | typedef struct
123 | {
124 | clockFrequency_t clockFrequency;
125 | boardVoltage_t boardVoltage;
126 | buckFrequency_t buckFrequency;
127 | uint8_t buckDutyCycle;
128 | int8_t buckLastStep;
129 | uint8_t outputs;
130 | volatile int8_t encoderCount;
131 | volatile int8_t buttonCount;
132 | volatile uint8_t timeSlot;
133 | volatile uint8_t done;
134 | int16_t input_voltage_adc[4];
135 | //int8_t input_voltage_calibration;
136 | int16_t input_voltage;
137 | //int16_t input_voltage_last;
138 | int16_t input_current_adc[4];
139 | int8_t input_current_calibration;
140 | int16_t input_current;
141 | //int16_t input_current_last;
142 | int16_t output_voltage_adc[4];
143 | //int8_t output_voltage_calibration;
144 | int16_t output_voltage;
145 | int16_t output_current_adc[4];
146 | int8_t output_current_calibration;
147 | int16_t output_current;
148 | //Temperature measurement
149 | int16_t temperature_onboard_adc;
150 | int16_t temperature_onboard;
151 | int16_t temperature_external_1_adc;
152 | int16_t temperature_external_1;
153 | int16_t temperature_external_2_adc;
154 | int16_t temperature_external_2;
155 | //Display
156 | uint8_t display_mode;
157 | //External communication configuration
158 | communicationSettings_t communicationSettings;
159 | } os_t;
160 |
161 |
162 | /*
163 | * Global variables
164 | */
165 |
166 | os_t os;
167 |
168 | /*
169 | * Function prototypes
170 | */
171 |
172 |
173 | void tmr_isr(void);
174 | void system_init(void);
175 | //void system_set_cpu_frequency(clockFrequency_t newFrequency);
176 | void system_delay_ms(uint8_t ms);
177 | //void system_power_save(void);
178 | void system_encoder_enable(void);
179 | void system_encoder_disable(void);
180 |
181 |
182 |
183 | uint8_t system_output_is_on(outputs_t output);
184 | void system_output_on(outputs_t output);
185 | void system_output_off(outputs_t output);
186 | void system_output_toggle(outputs_t output);
187 |
188 | /*
189 | void system_buck_set_frequency(buckFrequency_t buckFrequency);
190 | void system_buck_set_dutycycle(uint8_t dutyCycle);
191 | void system_buck_adjust_dutycycle(void);
192 | void system_buck_start(void);
193 | void system_buck_stop(void);
194 | * * */
195 |
196 | void system_calculate_input_voltage();
197 | void system_calculate_output_voltage();
198 | void system_calculate_input_current();
199 | void system_calculate_output_current();
200 |
201 |
202 | #endif /* OS_H */
203 |
204 |
--------------------------------------------------------------------------------
/usb_events.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /** INCLUDES *******************************************************/
21 | #include "system.h"
22 |
23 | #include "usb.h"
24 | #include "usb_device_hid.h"
25 | #include "usb_device_msd.h"
26 |
27 | //#include "internal_flash.h"
28 |
29 | #include "app_device_custom_hid.h"
30 | #include "app_device_msd.h"
31 |
32 |
33 | /*******************************************************************
34 | * Function: bool USER_USB_CALLBACK_EVENT_HANDLER(
35 | * USB_EVENT event, void *pdata, uint16_t size)
36 | *
37 | * PreCondition: None
38 | *
39 | * Input: USB_EVENT event - the type of event
40 | * void *pdata - pointer to the event data
41 | * uint16_t size - size of the event data
42 | *
43 | * Output: None
44 | *
45 | * Side Effects: None
46 | *
47 | * Overview: This function is called from the USB stack to
48 | * notify a user application that a USB event
49 | * occured. This callback is in interrupt context
50 | * when the USB_INTERRUPT option is selected.
51 | *
52 | * Note: None
53 | *******************************************************************/
54 | bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size)
55 | {
56 | switch((int)event)
57 | {
58 | case EVENT_TRANSFER:
59 | //Add application specific callback task or callback function here if desired.
60 | break;
61 |
62 | case EVENT_SOF:
63 | /* We are using the SOF as a timer to time the LED indicator. Call
64 | * the LED update function here. */
65 | //APP_LEDUpdateUSBStatus();
66 | break;
67 |
68 | case EVENT_SUSPEND:
69 | /* Update the LED status for the suspend event. */
70 | //APP_LEDUpdateUSBStatus();
71 |
72 | //Call the hardware platform specific handler for suspend events for
73 | //possible further action (like optionally going reconfiguring the application
74 | //for lower power states and going to sleep during the suspend event). This
75 | //would normally be done in USB compliant bus powered applications, although
76 | //no further processing is needed for purely self powered applications that
77 | //don't consume power from the host.
78 | SYSTEM_Initialize(SYSTEM_STATE_USB_SUSPEND);
79 | break;
80 |
81 | case EVENT_RESUME:
82 | /* Update the LED status for the resume event. */
83 | //APP_LEDUpdateUSBStatus();
84 |
85 | //Call the hardware platform specific resume from suspend handler (ex: to
86 | //restore I/O pins to higher power states if they were changed during the
87 | //preceding SYSTEM_Initialize(SYSTEM_STATE_USB_SUSPEND) call at the start
88 | //of the suspend condition.
89 | SYSTEM_Initialize(SYSTEM_STATE_USB_RESUME);
90 | break;
91 |
92 | case EVENT_CONFIGURED:
93 | /* When the device is configured, we can (re)initialize the demo
94 | * code. */
95 | APP_DeviceCustomHIDInitialize();
96 | APP_DeviceMSDInitialize();
97 | break;
98 |
99 | case EVENT_SET_DESCRIPTOR:
100 | break;
101 |
102 | case EVENT_EP0_REQUEST:
103 | /* We have received a non-standard USB request. The HID driver
104 | * needs to check to see if the request was for it. */
105 | USBCheckHIDRequest();
106 |
107 | /* Also check the MSD driver */
108 | USBCheckMSDRequest();
109 | break;
110 |
111 | case EVENT_BUS_ERROR:
112 | break;
113 |
114 | case EVENT_TRANSFER_TERMINATED:
115 | //Add application specific callback task or callback function here if desired.
116 | //The EVENT_TRANSFER_TERMINATED event occurs when the host performs a CLEAR
117 | //FEATURE (endpoint halt) request on an application endpoint which was
118 | //previously armed (UOWN was = 1). Here would be a good place to:
119 | //1. Determine which endpoint the transaction that just got terminated was
120 | // on, by checking the handle value in the *pdata.
121 | //2. Re-arm the endpoint if desired (typically would be the case for OUT
122 | // endpoints).
123 |
124 | MSDTransferTerminated(pdata);
125 | break;
126 |
127 | default:
128 | break;
129 | }
130 | return true;
131 | }
132 |
133 | /*******************************************************************************
134 | End of File
135 | */
136 |
137 |
--------------------------------------------------------------------------------
/log.c:
--------------------------------------------------------------------------------
1 | /*
2 | * File: log.c
3 | * Author: luke
4 | *
5 | * Created on 27. November 2017, 22:00
6 | */
7 |
8 |
9 |
10 | #include
11 | #include
12 |
13 | #include "log.h"
14 | #include "rtcc.h"
15 | #include "buck.h"
16 |
17 | char filename[9] = LOG_FILENAME;
18 | char extension[4] = LOG_EXTENSION;
19 |
20 | //Local variables to keep sums while accumulating data
21 | uint32_t inputVoltageSum;
22 | uint32_t inputCurrentSum;
23 | uint32_t outputVoltageSum;
24 | uint32_t outputCurrentSum;
25 | uint32_t inputPowerSum;
26 | uint32_t outputPowerSum;
27 | uint32_t inputCapacitySum;
28 | uint32_t outputCapacitySum;
29 | int32_t temperatureOnboardSum;
30 | int32_t temperatureExternal1Sum;
31 | int32_t temperatureExternal2Sum;
32 | uint16_t chargerOnTime;
33 | uint16_t lowPowerTime;
34 | uint8_t status;
35 | uint16_t averageCount;
36 |
37 | uint8_t lastSecond;
38 |
39 | static uint32_t _get_dateTime(void)
40 | {
41 | uint32_t datetime;
42 | uint8_t year = rtcc_get_year_decimal();
43 | uint8_t month = rtcc_get_month_decimal();
44 | uint8_t day = rtcc_get_day_decimal();
45 | uint8_t hours = rtcc_get_hours_decimal();
46 | uint8_t minutes = rtcc_get_minutes_decimal();
47 | uint8_t seconds = rtcc_get_seconds_decimal();
48 | datetime = (((uint32_t)(year&0b111111)) << 26);
49 | datetime |= (((uint32_t)(month&0b1111)) << 22);
50 | datetime |= (((uint32_t)day&0b11111)) << 17;
51 | datetime |= (((uint32_t)(hours&0b11111)) << 12);
52 | datetime |= (((uint16_t)(minutes&0b111111)) << 6);
53 | datetime |= (seconds&0b111111);
54 | return datetime;
55 | };
56 |
57 | static uint8_t _get_checksum(logEntry_t *log_entry)
58 | {
59 | uint8_t checksum;
60 | uint8_t *byte_array;
61 | uint8_t cntr;
62 | byte_array = (uint8_t*) log_entry;
63 | checksum = 0x00;
64 | for(cntr=0; cntr<31; ++cntr)
65 | {
66 | checksum ^= byte_array[cntr];
67 | }
68 | return checksum;
69 | }
70 |
71 | void log_start_new(void)
72 | {
73 | inputVoltageSum = 0;
74 | inputCurrentSum = 0;
75 | outputVoltageSum = 0;
76 | outputCurrentSum = 0;
77 | inputPowerSum = 0;
78 | outputPowerSum = 0;
79 | inputCapacitySum = 0;
80 | outputCapacitySum = 0;
81 | temperatureOnboardSum = 0;
82 | temperatureExternal1Sum = 0;
83 | temperatureExternal2Sum = 0;
84 | chargerOnTime = 0;
85 | lowPowerTime = 0;
86 | status = 0;
87 | averageCount = 0;
88 | lastSecond = rtcc_get_seconds_decimal();
89 | }
90 |
91 | uint16_t _get_input_power(void)
92 | {
93 | int32_t pwr;
94 | pwr = ((int32_t) os.input_voltage) * ((int32_t) os.input_current);
95 | pwr /= 1000;
96 | return (uint16_t) pwr;
97 | }
98 |
99 | uint16_t _get_output_power(void)
100 | {
101 | uint32_t pwr;
102 | pwr = ((int32_t) os.output_voltage) * ((int32_t) os.output_current);
103 | pwr /= 1000;
104 | return (uint16_t) pwr;
105 | }
106 |
107 | uint8_t _get_temperature(int16_t temperature)
108 | {
109 | temperature += 4025;
110 | temperature /= 50;
111 | return (uint8_t) temperature;
112 | }
113 |
114 | void log_collect_data(void)
115 | {
116 | uint16_t temp;
117 |
118 | //Quit if we've already logged data this second
119 | temp = rtcc_get_seconds_decimal();
120 | if(lastSecond==temp)
121 | {
122 | return;
123 | }
124 |
125 | //Store current second
126 | lastSecond = (uint8_t) temp;
127 |
128 | //Need to collect data
129 | inputVoltageSum += os.input_voltage;
130 | inputCurrentSum += os.input_current;
131 | outputVoltageSum += os.output_voltage;
132 | outputCurrentSum += os.output_current;
133 | temp = _get_input_power();
134 | inputPowerSum += temp>>1;
135 | inputCapacitySum += temp;
136 | temp = _get_output_power();
137 | outputPowerSum += temp>>1;
138 | outputCapacitySum += temp;
139 | temperatureOnboardSum += os.temperature_onboard;
140 | temperatureExternal1Sum += os.temperature_external_1;
141 | temperatureExternal2Sum += os.temperature_external_2;
142 | if(buck_get_mode()&0b01111111)
143 | {
144 | ++chargerOnTime;
145 | }
146 | if(os.boardVoltage==BOARD_VOLTAGE_LOW)
147 | {
148 | ++lowPowerTime;
149 | }
150 | if(system_output_is_on(OUTPUT_1))
151 | status |= 0b10000000;
152 | if(system_output_is_on(OUTPUT_2))
153 | status |= 0b01000000;
154 | if(system_output_is_on(OUTPUT_3))
155 | status |= 0b00100000;
156 | if(system_output_is_on(OUTPUT_4))
157 | status |= 0b00010000;
158 | if(system_output_is_on(OUTPUT_USB))
159 | status |= 0b00001000;
160 | if(system_output_is_on(OUTPUT_FAN))
161 | status |= 0b00000100;
162 | //if(USBDeviceState == ATTACHED_STATE) Need to get access to that first
163 | status |= 0b00000010;
164 | ++averageCount;
165 |
166 |
167 | }
168 |
169 | uint16_t log_get_number_of_samples(void)
170 | {
171 | return averageCount;
172 | }
173 |
174 | void log_generate_entry(logEntry_t *log_entry)
175 | {
176 | log_entry->dateTime = _get_dateTime();
177 | log_entry->inputVoltage = inputVoltageSum / averageCount;
178 | log_entry->inputCurrent = inputCurrentSum / averageCount;
179 | log_entry->outputVoltage = outputVoltageSum / averageCount;
180 | log_entry->outputCurrent = outputCurrentSum / averageCount;
181 | log_entry->inputPower = inputPowerSum / averageCount;
182 | log_entry->outputPower = outputPowerSum / averageCount;
183 | log_entry->inputCapacity = (inputCapacitySum+500) / 1000;
184 | log_entry->outputCapacity = (outputCapacitySum+500) / 1000;
185 | log_entry->temperatureOnboard = _get_temperature(temperatureOnboardSum/averageCount);
186 | log_entry->temperatureExternal1 = _get_temperature(temperatureExternal1Sum/averageCount);
187 | log_entry->temperatureExternal2 = _get_temperature(temperatureExternal2Sum/averageCount);
188 | log_entry->chargerOnTime = chargerOnTime >> 1;
189 | log_entry->lowPowerTime = lowPowerTime >> 1;
190 | log_entry->unused[0] = 0x00;
191 | log_entry->unused[1] = 0x00;
192 | log_entry->unused[2] = 0x00;
193 | log_entry->unused[3] = 0x00;
194 | log_entry->unused[4] = 0x00;
195 | log_entry->status = status;
196 | log_entry->checksum = _get_checksum(log_entry);
197 | }
198 |
199 | void log_write_to_disk(void)
200 | {
201 | uint8_t file_number;
202 | logEntry_t log_entry;
203 |
204 | //Prepare log entry
205 | log_generate_entry(&log_entry);
206 |
207 | //Find or create file
208 | file_number = fat_find_file(filename, extension);
209 | if(file_number==0xFF)
210 | {
211 | //File does not exist, create it
212 | file_number = fat_create_file(filename, extension, 0);
213 | }
214 |
215 | //Append entry to file
216 | fat_append_to_file(file_number, sizeof(logEntry_t), &log_entry);
217 | }
218 |
--------------------------------------------------------------------------------
/api.h:
--------------------------------------------------------------------------------
1 | /*
2 | * File: api.h
3 | * Author: luke
4 | *
5 | * Created on 25. Juli 2018, 11:07
6 | */
7 |
8 | #ifndef API_H
9 | #define API_H
10 |
11 | /******************************************************************************
12 | * API description
13 | ******************************************************************************
14 | *
15 | * Data requests. These must be sent as the first byte. Any commands may follow
16 | * 0x10: General status information
17 | * 0x11: First 2 lines of display content
18 | * 0x12: Last 2 lines of display content
19 | * 0x13: Get calibration part 1
20 | * 0x14: Get calibration part 2
21 | * 0x15: External communication configuration
22 | * 0x20: Echo (i.e. send back) all data received. Used to test connection.
23 | *
24 | * Extended data requests. Only parameters may follow
25 | * 0x80: Get information for a specific file. Parameter: uint8_t FileNumber
26 | * 0x81: Find file. Parameter: char[8] FileName, char[3] FileExtention
27 | * 0x82: Read file. Parameters: uint8_t FileNumber, uint32_t StartByte
28 | * 0x83: Read buffer. Parameters: uint16_t StartByte
29 | *
30 | * Single byte commands
31 | * 0x20: Reboot
32 | * 0x30: Turn output 1 off
33 | * 0x31: Turn output 1 on
34 | * 0x32: Turn output 2 off
35 | * 0x33: Turn output 2 on
36 | * 0x34: Turn output 3 off
37 | * 0x35: Turn output 3 on
38 | * 0x36: Turn output 4 off
39 | * 0x37: Turn output 4 on
40 | * 0x38: Turn USB output off
41 | * 0x39: Turn USB output on
42 | * 0x3A: Turn FAN output off
43 | * 0x3B: Turn FAN output 1 on
44 | * 0x3C: Turn encoder CCW
45 | * 0x3D: Turn encoder CW
46 | * 0x3E: Press push button
47 | * 0x3F: Write time and date to eeprom
48 | * 0x99: Stop parsing (there are no more commands in this buffer)
49 | *
50 | * Multi byte commands (followed by a 16 bit constant to prevent unintended use)
51 | * Some legacy commands don't require a constant for now
52 | * 0x40: Set year. Parameters: uint8_t 2-digit year
53 | * 0x41: Set month. Parameters: uint8_t month
54 | * 0x42: Set day. Parameters: uint8_t day
55 | * 0x43: Set hours. Parameters: uint8_t hours
56 | * 0x44: Set minutes. Parameters: uint8_t minutes
57 | * 0x45: Set seconds. Parameters: uint8_t seconds
58 | * 0x46: Enable remote buck control. Parameters: uint8_t unused
59 | * 0x47: Disable remote buck control. Parameters: uint8_t unused
60 | * 0x48: Turn buck on. Parameters: uint8_t unused
61 | * 0x49: Turn buck off. Parameters: uint8_t unused
62 | * 0x4A: Buck asynchronous mode. Parameters: uint8_t unused
63 | * 0x4B: Buck synchronous mode. Parameters: uint8_t unused
64 | * 0x4C: Buck decrement dutycycle. Parameters: uint8_t unused
65 | * 0x4D: Buck increment dutycycle. Parameters: uint8_t unused
66 | * 0x4E: Buck set dutycycle. Parameters: uint8_t new_dutycycle
67 | * 0x50: Resize file. Parameters: uint8_t FileNumber, uint32_t newFileSize, 0x4CEA
68 | * 0x51: Delete file. Parameters: uint8_t FileNumber, 0x66A0
69 | * 0x52: Create file. Parameters: char[8] FileName, char[3] FileExtention, uint32_t FileSize, 0xBD4F
70 | * 0x53: Rename file. Parameters: uint8_t FileNumber, char[8] NewFileName, char[3] NewFileExtention, 0x7E18
71 | * 0x54: Append to file. Parameters: uint8_t FileNumber, uint8_t NumberOfBytes, 0xFE4B, DATA
72 | * 0x55: Modify file. Parameters: uint8_t FileNumber, uint32_t StartByte, uint8_t NumerOfBytes, 0x0F9B, DATA
73 | * 0x56: Format drive. Parameters: none, 0xDA22
74 | * 0x57: Read file sector to buffer. Parameters: uint8_t file_number, uint16_t sector, 0x1B35
75 | * 0x58: Write buffer to file sector. Parameters: uint8_t file_number, uint16_t sector, 0x6A6D
76 | * 0x59: Modify buffer. Parameters: uint16_t StartByte, uint8_t NumerOfBytes, 0xE230, DATA
77 | * 0x5A: Copy file. Parameters: uint8_t FileNumber, char[8] NewFileName, char[3] NewFileExtention, 0x54D9
78 | * 0x60: Set calibration. Parameters: uint8_t item_to_set, uint16_t offset_or_slope, uint8_t slope_shift
79 | * 0x70: Change SPI mode. Parameters: uint8_t NewMode, 0x88E2
80 | * 0x71: Change SPI frequency. Parameters: uint8_t NewFrequency, 0xAEA8
81 | * 0x72: Change SPI polarity. Parameters: uint8_t NewPolarity, 0x0DBB
82 | * 0x73: Change I2C mode. Parameters: uint8_t NewMode, 0xB6B9
83 | * 0x74: Change I2C frequency. Parameters: uint8_t NewFrequency, 0x4E03
84 | * 0x75: Change I2C slave mode slave address. Parameters: uint8_t NewAddress, 0x88E2
85 | * 0x76: Change I2C master mode slave address. Parameters: uint8_t NewAddress, 0x540D
86 | *
87 | *
88 | ******************************************************************************/
89 |
90 | /******************************************************************************
91 | * Type definitions
92 | ******************************************************************************/
93 |
94 | typedef enum
95 | {
96 | DATAREQUEST_GET_COMMAND_RESPONSE = 0x00,
97 | DATAREQUEST_GET_STATUS = 0x10,
98 | DATAREQUEST_GET_DISPLAY_1 = 0x11,
99 | DATAREQUEST_GET_DISPLAY_2 = 0x12,
100 | DATAREQUEST_GET_CALIBRATION_1 = 0x13,
101 | DATAREQUEST_GET_CALIBRATION_2 = 0x14,
102 | DATAREQUEST_GET_ECHO = 0x20,
103 | DATAREQUEST_GET_FILE_DETAILS = 0x80,
104 | DATAREQUEST_FIND_FILE = 0x81,
105 | DATAREQUEST_READ_FILE = 0x82,
106 | DATAREQUEST_READ_BUFFER = 0x83
107 | } apiDataRequest_t;
108 |
109 |
110 |
111 | typedef enum
112 | {
113 | //Single byte commands
114 | COMMAND_REBOOT = 0x20,
115 | COMMAND_OUTPUT_1_OFF = 0x30,
116 | COMMAND_OUTPUT_1_ON = 0x31,
117 | COMMAND_OUTPUT_2_OFF = 0x32,
118 | COMMAND_OUTPUT_2_ON = 0x33,
119 | COMMAND_OUTPUT_3_OFF = 0x34,
120 | COMMAND_OUTPUT_3_ON = 0x35,
121 | COMMAND_OUTPUT_4_OFF = 0x36,
122 | COMMAND_OUTPUT_4_ON = 0x37,
123 | COMMAND_OUTPUT_USB_OFF = 0x38,
124 | COMMAND_OUTPUT_USB_ON = 0x39,
125 | COMMAND_OUTPUT_FAN_OFF = 0x3A,
126 | COMMAND_OUTPUT_FAN_ON = 0x3B,
127 | COMMAND_ENCODER_CCW = 0x3C,
128 | COMMAND_ENCODER_CW = 0x3D,
129 | COMMAND_ENCODER_PUSH = 0x3E,
130 | COMMAND_WRITE_RTCC_EEPROM = 0x3F,
131 | COMMAND_STOP_PARSING = 0x99,
132 | //Multi-byte commands
133 | COMMAND_SET_YEAR = 0x40,
134 | COMMAND_SET_MONTH = 0x41,
135 | COMMAND_SET_DAY = 0x42,
136 | COMMAND_SET_HOURS = 0x43,
137 | COMMAND_SET_MINUTES = 0x44,
138 | COMMAND_SET_SECONDS = 0x45,
139 | COMMAND_BUCK_REMOTE_ON = 0x46,
140 | COMMAND_BUCK_REMOTE_OFF = 0x47,
141 | COMMAND_BUCK_ON = 0x48,
142 | COMMAND_BUCK_OFF = 0x49,
143 | COMMAND_BUCK_ASYNCHRONOUS = 0x4A,
144 | COMMAND_BUCK_SYNCHRONOUS = 0x4B,
145 | COMMAND_BUCK_DECREMENT_DUTYCYCLE = 0x4C,
146 | COMMAND_BUCK_INCREMENT_DUTYCYCLE = 0x4D,
147 | COMMAND_BUCK_SET_DUTYCYCLE = 0x4E,
148 | COMMAND_FILE_RESIZE = 0x50,
149 | COMMAND_FILE_DELETE = 0x51,
150 | COMMAND_FILE_CREATE = 0x52,
151 | COMMAND_FILE_RENAME = 0x53,
152 | COMMAND_FILE_APPEND = 0x54,
153 | COMMAND_FILE_MODIFY = 0x55,
154 | COMMAND_FORMAT_DRIVE = 0x56,
155 | COMMAND_SECTOR_TO_BUFFER = 0x57,
156 | COMMAND_BUFFER_TO_SECTOR = 0x58,
157 | COMMAND_WRITE_BUFFER = 0x59,
158 | COMMAND_FILE_COPY = 0x5A,
159 | COMMAND_SET_CALIBRATION = 0x60,
160 | COMMAND_SET_SPI_MODE = 0x70,
161 | COMMAND_SET_SPI_FREQUENCY = 0x71,
162 | COMMAND_SET_SPI_POLARITY = 0x72,
163 | COMMAND_SET_I2C_MODE = 0x73,
164 | COMMAND_SET_I2C_FREQUENCY = 0x74,
165 | COMMAND_SET_I2C_SLAVE_MODE_ADDRESS = 0x75,
166 | COMMAND_SET_I2C_MASTER_MODE_ADDRESS = 0x76
167 | } apiCommand_t;
168 |
169 |
170 | /******************************************************************************
171 | * Function prototypes
172 | ******************************************************************************/
173 |
174 | void api_prepare(uint8_t *inBuffer, uint8_t *outBuffer);
175 | void api_parse(uint8_t *inBuffer, uint8_t receivedDataLength, uint8_t *outBuffer);
176 |
177 |
178 | #endif /* API_H */
179 |
180 |
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | * File: main.c
3 | * Author: Luke
4 | *
5 | * Created on 26. December 2016, 21:31
6 | */
7 |
8 |
9 | /** INCLUDES *******************************************************/
10 |
11 | #include "system.h"
12 |
13 | #include "usb.h"
14 | #include "usb_device_hid.h"
15 | #include "usb_device_msd.h"
16 | //
17 | //#include "internal_flash.h"
18 | //
19 | #include "app_device_custom_hid.h"
20 | #include "app_device_msd.h"
21 |
22 | //User defined code
23 | #include "hardware_config.h"
24 | #include "os.h"
25 | #include "i2c.h"
26 | #include "display.h"
27 | #include "ui.h"
28 | #include "rtcc.h"
29 | #include "buck.h"
30 | #include "adc.h"
31 | #include "flash.h"
32 | #include "fat16.h"
33 | #include "log.h"
34 |
35 |
36 | /********************************************************************
37 | * Function: void main(void)
38 | *
39 | * PreCondition: None
40 | *
41 | * Input: None
42 | *
43 | * Output: None
44 | *
45 | * Side Effects: None
46 | *
47 | * Overview: Main program entry point.
48 | *
49 | * Note: None
50 | *******************************************************************/
51 | MAIN_RETURN main(void)
52 | {
53 | //uint8_t cntr;
54 |
55 | //This is a user defined function
56 | system_init();
57 |
58 | SYSTEM_Initialize(SYSTEM_STATE_USB_START);
59 |
60 | USBDeviceInit();
61 | USBDeviceAttach();
62 |
63 | while(1)
64 | {
65 | //Do this as often as possible
66 | APP_DeviceMSDTasks();
67 |
68 | if(!os.done)
69 | {
70 | //Do this every time
71 |
72 | //Clear watchdog timer
73 | ClrWdt();
74 |
75 | //Shut down outputs when battery voltage drops too low
76 | if(os.output_voltage>4] = i2c_adc_read();
116 | i2c_adc_start(I2C_ADC_INPUT_VOLTAGE, I2C_ADC_RESOLUTION_14BIT, I2C_ADC_GAIN_1);
117 | system_calculate_output_voltage();
118 | break;
119 |
120 | case 4:
121 | if(ui_get_status()==USER_INTERFACE_STATUS_ON)
122 | {
123 | display_prepare(os.display_mode);
124 | }
125 | break;
126 |
127 | case 5:
128 | if(ui_get_status()==USER_INTERFACE_STATUS_ON)
129 | {
130 | display_update();
131 | }
132 | break;
133 |
134 | case 6:
135 | os.input_voltage_adc[(os.timeSlot&0b00110000)>>4] = i2c_adc_read();
136 | if(1 || buck_get_mode()!=BUCK_STATUS_OFF)
137 | {
138 | i2c_adc_start(I2C_ADC_OUTPUT_CURRENT, I2C_ADC_RESOLUTION_14BIT, I2C_ADC_GAIN_1);
139 | }
140 | system_calculate_input_voltage();
141 | break;
142 |
143 | case 8:
144 | APP_DeviceCustomHIDTasks();
145 | break;
146 |
147 | case 9:
148 | if(1 || buck_get_mode()!=BUCK_STATUS_OFF)
149 | {
150 | os.output_current_adc[(os.timeSlot&0b00110000)>>4] = i2c_adc_read();
151 | i2c_adc_start(I2C_ADC_INPUT_CURRENT, I2C_ADC_RESOLUTION_14BIT, I2C_ADC_GAIN_1);
152 | system_calculate_output_current();
153 | }
154 | break;
155 |
156 | case 11:
157 | APP_DeviceCustomHIDTasks();
158 | log_collect_data();
159 | // if(log_get_number_of_samples() == LOG_PERIOD)
160 | // {
161 | // log_write_to_disk();
162 | // log_start_new();
163 | // }
164 | break;
165 |
166 | case 12:
167 | if(1 || buck_get_mode()!=BUCK_STATUS_OFF)
168 | {
169 | os.input_current_adc[(os.timeSlot&0b00110000)>>4] = i2c_adc_read();
170 | system_calculate_input_current();
171 | }
172 | break;
173 |
174 | case 13:
175 | buck_operate();
176 | break;
177 |
178 |
179 | case 14:
180 | os.temperature_onboard = adc_calculate_temperature(os.temperature_onboard_adc, CALIBRATION_INDEX_ONBOARD_TEMPERATURE);
181 | os.temperature_onboard_adc = 0;
182 | os.temperature_external_1 = adc_calculate_temperature(os.temperature_external_1_adc, CALIBRATION_INDEX_EXTERNAL_TEMPERATURE_1);
183 | os.temperature_external_1_adc = 0;
184 | os.temperature_external_2 = adc_calculate_temperature(os.temperature_external_2_adc, CALIBRATION_INDEX_EXTERNAL_TEMPERATURE_2);
185 | os.temperature_external_2_adc = 0;
186 | adc_calibrate();
187 |
188 | if(os.temperature_onboard>3000)
189 | {
190 | FANOUT_PIN = 1;
191 | }
192 | else if(os.temperature_onboard<2500)
193 | {
194 | FANOUT_PIN = 0;
195 | }
196 | display_prepare(os.display_mode);
197 | break;
198 |
199 | case 15:
200 | if(ui_get_status()==USER_INTERFACE_STATUS_ON)
201 | {
202 | display_update();
203 | }
204 | break;
205 | }
206 | os.done = 1;
207 | }
208 |
209 | /*
210 | //Application specific tasks
211 | APP_DeviceCustomHIDTasks();
212 | APP_DeviceMSDTasks();
213 |
214 | for(cntr=0;cntr<16;++cntr)
215 | {
216 | ui_run();
217 | flash_dummy_read();
218 |
219 | adc_calibrate();
220 | os.temperature_onboard_adc += adc_read(ADC_CHANNEL_TEMPERATURE_ONBOARD);
221 | os.temperature_external_1_adc += adc_read(ADC_CHANNEL_TEMPERATURE_EXTERNAL_1);
222 | os.temperature_external_2_adc += adc_read(ADC_CHANNEL_TEMPERATURE_EXTERNAL_2);
223 |
224 | if(cntr==14)
225 | {
226 | os.temperature_onboard = adc_calculate_temperature(os.temperature_onboard_adc);
227 | os.temperature_onboard_adc = 0;
228 | os.temperature_external_1 = adc_calculate_temperature(os.temperature_external_1_adc);
229 | os.temperature_external_1_adc = 0;
230 | os.temperature_external_2 = adc_calculate_temperature(os.temperature_external_2_adc);
231 | os.temperature_external_2_adc = 0;
232 | display_prepare(os.display_mode);
233 |
234 | adc_calibrate();
235 | }
236 | if(cntr==15)
237 | {
238 | display_update();
239 | }
240 | system_delay_ms(8);
241 | }
242 | */
243 | }//end while(1)
244 | }//end main
245 |
246 | /*******************************************************************************
247 | End of File
248 | */
249 |
--------------------------------------------------------------------------------
/usb_config.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /*********************************************************************
21 | * Descriptor specific type definitions are defined in: usbd.h
22 | ********************************************************************/
23 |
24 | #ifndef USBCFG_H
25 | #define USBCFG_H
26 |
27 | #include "usb_ch9.h"
28 |
29 | /** DEFINITIONS ****************************************************/
30 | #define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
31 | // Using larger options take more SRAM, but
32 | // does not provide much advantage in most types
33 | // of applications. Exceptions to this, are applications
34 | // that use EP0 IN or OUT for sending large amounts of
35 | // application related data.
36 |
37 | #define USB_MAX_NUM_INT 2 //Set this number to match the maximum interface number used in the descriptors for this firmware project
38 | #define USB_MAX_EP_NUMBER 2 //Set this number to match the maximum endpoint number used in the descriptors for this firmware project
39 |
40 | //Device descriptor - if these two definitions are not defined then
41 | // a const USB_DEVICE_DESCRIPTOR variable by the exact name of device_dsc
42 | // must exist.
43 | #define USB_USER_DEVICE_DESCRIPTOR &device_dsc
44 | #define USB_USER_DEVICE_DESCRIPTOR_INCLUDE extern const USB_DEVICE_DESCRIPTOR device_dsc
45 |
46 | //Configuration descriptors - if these two definitions do not exist then
47 | // a const uint8_t *const variable named exactly USB_CD_Ptr[] must exist.
48 | #define USB_USER_CONFIG_DESCRIPTOR USB_CD_Ptr
49 | #define USB_USER_CONFIG_DESCRIPTOR_INCLUDE extern const uint8_t *const USB_CD_Ptr[]
50 |
51 |
52 | //------------------------------------------------------------------------------
53 | //Select an endpoint ping-pong bufferring mode. Some microcontrollers only
54 | //support certain modes. For most applications, it is recommended to use either
55 | //the USB_PING_PONG__FULL_PING_PONG or USB_PING_PONG__EP0_OUT_ONLY options.
56 | //The other settings are supported on some devices, but they are not
57 | //recommended, as they offer inferior control transfer timing performance.
58 | //See inline code comments in usb_device.c for additional details.
59 | //Enabling ping pong bufferring on an endpoint generally increases firmware
60 | //overhead somewhat, but when both buffers are used simultaneously in the
61 | //firmware, can offer better sustained bandwidth, especially for OUT endpoints.
62 | //------------------------------------------------------
63 | //#define USB_PING_PONG_MODE USB_PING_PONG__NO_PING_PONG //Not recommended
64 | #define USB_PING_PONG_MODE USB_PING_PONG__FULL_PING_PONG //A good all around setting
65 | //#define USB_PING_PONG_MODE USB_PING_PONG__EP0_OUT_ONLY //Another good setting
66 | //#define USB_PING_PONG_MODE USB_PING_PONG__ALL_BUT_EP0 //Not recommended
67 | //------------------------------------------------------------------------------
68 |
69 |
70 | //------------------------------------------------------------------------------
71 | //Select a USB stack operating mode. In the USB_INTERRUPT mode, the USB stack
72 | //main task handler gets called only when necessary as an interrupt handler.
73 | //This can potentially minimize CPU utilization, but adds context saving
74 | //and restoring overhead associated with interrupts, which can potentially
75 | //decrease performance.
76 | //When the USB_POLLING mode is selected, the USB stack main task handler
77 | //(ex: USBDeviceTasks()) must be called periodically by the application firmware
78 | //at a minimum rate as described in the inline code comments in usb_device.c.
79 | //------------------------------------------------------
80 | //#define USB_POLLING
81 | #define USB_INTERRUPT
82 | //------------------------------------------------------------------------------
83 |
84 | /* Parameter definitions are defined in usb_device.h */
85 | #define USB_PULLUP_OPTION USB_PULLUP_ENABLE
86 | //#define USB_PULLUP_OPTION USB_PULLUP_DISABLED
87 |
88 | #define USB_TRANSCEIVER_OPTION USB_INTERNAL_TRANSCEIVER
89 | //External Transceiver support is not available on all product families. Please
90 | // refer to the product family datasheet for more information if this feature
91 | // is available on the target processor.
92 | //#define USB_TRANSCEIVER_OPTION USB_EXTERNAL_TRANSCEIVER
93 |
94 | #define USB_SPEED_OPTION USB_FULL_SPEED
95 | //#define USB_SPEED_OPTION USB_LOW_SPEED //(this mode is only supported on some microcontrollers)
96 |
97 | //------------------------------------------------------------------------------------------------------------------
98 | //Option to enable auto-arming of the status stage of control transfers, if no
99 | //"progress" has been made for the USB_STATUS_STAGE_TIMEOUT value.
100 | //If progress is made (any successful transactions completing on EP0 IN or OUT)
101 | //the timeout counter gets reset to the USB_STATUS_STAGE_TIMEOUT value.
102 | //
103 | //During normal control transfer processing, the USB stack or the application
104 | //firmware will call USBCtrlEPAllowStatusStage() as soon as the firmware is finished
105 | //processing the control transfer. Therefore, the status stage completes as
106 | //quickly as is physically possible. The USB_ENABLE_STATUS_STAGE_TIMEOUTS
107 | //feature, and the USB_STATUS_STAGE_TIMEOUT value are only relevant, when:
108 | //1. The application uses the USBDeferStatusStage() API function, but never calls
109 | // USBCtrlEPAllowStatusStage(). Or:
110 | //2. The application uses host to device (OUT) control transfers with data stage,
111 | // and some abnormal error occurs, where the host might try to abort the control
112 | // transfer, before it has sent all of the data it claimed it was going to send.
113 | //
114 | //If the application firmware never uses the USBDeferStatusStage() API function,
115 | //and it never uses host to device control transfers with data stage, then
116 | //it is not required to enable the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature.
117 |
118 | #define USB_ENABLE_STATUS_STAGE_TIMEOUTS //Comment this out to disable this feature.
119 |
120 | //Section 9.2.6 of the USB 2.0 specifications indicate that:
121 | //1. Control transfers with no data stage: Status stage must complete within
122 | // 50ms of the start of the control transfer.
123 | //2. Control transfers with (IN) data stage: Status stage must complete within
124 | // 50ms of sending the last IN data packet in fullfilment of the data stage.
125 | //3. Control transfers with (OUT) data stage: No specific status stage timing
126 | // requirement. However, the total time of the entire control transfer (ex:
127 | // including the OUT data stage and IN status stage) must not exceed 5 seconds.
128 | //
129 | //Therefore, if the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is used, it is suggested
130 | //to set the USB_STATUS_STAGE_TIMEOUT value to timeout in less than 50ms. If the
131 | //USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is not enabled, then the USB_STATUS_STAGE_TIMEOUT
132 | //parameter is not relevant.
133 |
134 | #define USB_STATUS_STAGE_TIMEOUT (uint8_t)45 //Approximate timeout in milliseconds, except when
135 | //USB_POLLING mode is used, and USBDeviceTasks() is called at < 1kHz
136 | //In this special case, the timeout becomes approximately:
137 | //Timeout(in milliseconds) = ((1000 * (USB_STATUS_STAGE_TIMEOUT - 1)) / (USBDeviceTasks() polling frequency in Hz))
138 | //------------------------------------------------------------------------------------------------------------------
139 |
140 | #define USB_SUPPORT_DEVICE
141 |
142 | #define USB_NUM_STRING_DESCRIPTORS 4 //Include the lang ID codes string 0 in this count
143 |
144 | /*******************************************************************
145 | * Event disable options
146 | * Enable a definition to suppress a specific event. By default
147 | * all events are sent.
148 | *******************************************************************/
149 | //#define USB_DISABLE_SUSPEND_HANDLER
150 | //#define USB_DISABLE_WAKEUP_FROM_SUSPEND_HANDLER
151 | //#define USB_DISABLE_SOF_HANDLER
152 | //#define USB_DISABLE_TRANSFER_TERMINATED_HANDLER
153 | //#define USB_DISABLE_ERROR_HANDLER
154 | //#define USB_DISABLE_NONSTANDARD_EP0_REQUEST_HANDLER
155 | //#define USB_DISABLE_SET_DESCRIPTOR_HANDLER
156 | //#define USB_DISABLE_SET_CONFIGURATION_HANDLER
157 | //#define USB_DISABLE_TRANSFER_COMPLETE_HANDLER
158 |
159 | /** DEVICE CLASS USAGE *********************************************/
160 | #define USB_USE_HID
161 | #define USB_USE_MSD
162 |
163 | /** ENDPOINTS ALLOCATION *******************************************/
164 |
165 | /* HID */
166 | #define HID_INTF_ID 0x00
167 | #define CUSTOM_DEVICE_HID_EP 1
168 | #define HID_INT_OUT_EP_SIZE 3
169 | #define HID_INT_IN_EP_SIZE 3
170 | #define HID_NUM_OF_DSC 1
171 | #define HID_RPT01_SIZE 29
172 |
173 | /* MSD */
174 | #define MSD_INTF_ID 0x00
175 | #define MSD_IN_EP_SIZE 64u
176 | #define MSD_OUT_EP_SIZE 64u
177 | #define MAX_LUN 0u //Includes 0 (ex: 0 = 1 LUN, 1 = 2 LUN, etc.)
178 | #define MSD_DATA_IN_EP 2u
179 | #define MSD_DATA_OUT_EP 2u
180 | #define MSD_BUFFER_ADDRESS 0x600
181 | /** DEFINITIONS ****************************************************/
182 |
183 | #endif //USBCFG_H
184 |
--------------------------------------------------------------------------------
/usb_device_hid.h:
--------------------------------------------------------------------------------
1 | // DOM-IGNORE-BEGIN
2 | /*******************************************************************************
3 | Copyright 2015 Microchip Technology Inc. (www.microchip.com)
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | To request to license the code under the MLA license (www.microchip.com/mla_license),
18 | please contact mla_licensing@microchip.com
19 | *******************************************************************************/
20 | //DOM-IGNORE-END
21 |
22 | #ifndef HID_H
23 | #define HID_H
24 |
25 |
26 | /** INCLUDES *******************************************************/
27 |
28 | #include "usb_ch9.h"
29 |
30 | /** DEFINITIONS ****************************************************/
31 |
32 | /* Class-Specific Requests */
33 | #define GET_REPORT 0x01
34 | #define GET_IDLE 0x02
35 | #define GET_PROTOCOL 0x03
36 | #define SET_REPORT 0x09
37 | #define SET_IDLE 0x0A
38 | #define SET_PROTOCOL 0x0B
39 |
40 | /* Class Descriptor Types */
41 | #define DSC_HID 0x21
42 | #define DSC_RPT 0x22
43 | #define DSC_PHY 0x23
44 |
45 | /* Protocol Selection */
46 | #define BOOT_PROTOCOL 0x00
47 | #define RPT_PROTOCOL 0x01
48 |
49 | /* HID Interface Class Code */
50 | #define HID_INTF 0x03
51 |
52 | /* HID Interface Class SubClass Codes */
53 | #define BOOT_INTF_SUBCLASS 0x01
54 |
55 | /* HID Interface Class Protocol Codes */
56 | #define HID_PROTOCOL_NONE 0x00
57 | #define HID_PROTOCOL_KEYBOARD 0x01
58 | #define HID_PROTOCOL_MOUSE 0x02
59 |
60 | /********************************************************************
61 | Function:
62 | void USBCheckHIDRequest(void)
63 |
64 | Summary:
65 | This routine handles HID specific request that happen on EP0.
66 | This function should be called from the USBCBCheckOtherReq() call back
67 | function whenever implementing a HID device.
68 |
69 | Description:
70 | This routine handles HID specific request that happen on EP0. These
71 | include, but are not limited to, requests for the HID report
72 | descriptors. This function should be called from the
73 | USBCBCheckOtherReq() call back function whenever using an HID device.
74 |
75 | Typical Usage:
76 |
77 | void USBCBCheckOtherReq(void)
78 | {
79 | //Since the stack didn't handle the request I need to check
80 | // my class drivers to see if it is for them
81 | USBCheckHIDRequest();
82 | }
83 |
84 |
85 | PreCondition:
86 | None
87 |
88 | Parameters:
89 | None
90 |
91 | Return Values:
92 | None
93 |
94 | Remarks:
95 | None
96 |
97 | *******************************************************************/
98 | void USBCheckHIDRequest(void);
99 |
100 | /********************************************************************
101 | Function:
102 | bool HIDTxHandleBusy(USB_HANDLE handle)
103 |
104 | Summary:
105 | Retrieves the status of the buffer ownership
106 |
107 | Description:
108 | Retrieves the status of the buffer ownership. This function will
109 | indicate if the previous transfer is complete or not.
110 |
111 | This function will take the input handle (pointer to a BDT entry) and
112 | will check the UOWN bit. If the UOWN bit is set then that indicates
113 | that the transfer is not complete and the USB module still owns the data
114 | memory. If the UOWN bit is clear that means that the transfer is
115 | complete and that the CPU now owns the data memory.
116 |
117 | For more information about the BDT, please refer to the appropriate
118 | datasheet for the device in use.
119 |
120 | Typical Usage:
121 |
122 | //make sure that the last transfer isn't busy by checking the handle
123 | if(!HIDTxHandleBusy(USBInHandle))
124 | {
125 | //Send the data contained in the ToSendDataBuffer[] array out on
126 | // endpoint HID_EP
127 | USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer));
128 | }
129 |
130 |
131 | PreCondition:
132 | None.
133 |
134 | Parameters:
135 | USB_HANDLE handle - the handle for the transfer in question.
136 | The handle is returned by the HIDTxPacket() and HIDRxPacket()
137 | functions. Please insure that USB_HANDLE objects are initialized
138 | to NULL.
139 |
140 | Return Values:
141 | TRUE - the HID handle is still busy
142 | FALSE - the HID handle is not busy and is ready to send
143 | additional data.
144 |
145 | Remarks:
146 | None
147 |
148 | *******************************************************************/
149 | #define HIDTxHandleBusy(handle) USBHandleBusy(handle)
150 |
151 | /********************************************************************
152 | Function:
153 | bool HIDRxHandleBusy(USB_HANDLE handle)
154 |
155 | Summary:
156 | Retrieves the status of the buffer ownership
157 |
158 | Description:
159 | Retrieves the status of the buffer ownership. This function will
160 | indicate if the previous transfer is complete or not.
161 |
162 | This function will take the input handle (pointer to a BDT entry) and
163 | will check the UOWN bit. If the UOWN bit is set then that indicates
164 | that the transfer is not complete and the USB module still owns the data
165 | memory. If the UOWN bit is clear that means that the transfer is
166 | complete and that the CPU now owns the data memory.
167 |
168 | For more information about the BDT, please refer to the appropriate
169 | datasheet for the device in use.
170 |
171 | Typical Usage:
172 |
173 | if(!HIDRxHandleBusy(USBOutHandle))
174 | {
175 | //The data is available in the buffer that was specified when the
176 | // HIDRxPacket() was called.
177 | }
178 |
179 |
180 | PreCondition:
181 | None
182 |
183 | Parameters:
184 | USB_HANDLE handle - the handle for the transfer in question.
185 | The handle is returned by the HIDTxPacket() and HIDRxPacket()
186 | functions. Please insure that USB_HANDLE objects are initialized
187 | to NULL.
188 |
189 | Return Values:
190 | TRUE - the HID handle is still busy
191 | FALSE - the HID handle is not busy and is ready to receive
192 | additional data.
193 |
194 | Remarks:
195 | None
196 |
197 | *******************************************************************/
198 | #define HIDRxHandleBusy(handle) USBHandleBusy(handle)
199 |
200 | /********************************************************************
201 | Function:
202 | USB_HANDLE HIDTxPacket(uint8_t ep, uint8_t* data, uint16_t len)
203 |
204 | Summary:
205 | Sends the specified data out the specified endpoint
206 |
207 | Description:
208 | This function sends the specified data out the specified
209 | endpoint and returns a handle to the transfer information.
210 |
211 | Typical Usage:
212 |
213 | //make sure that the last transfer isn't busy by checking the handle
214 | if(!HIDTxHandleBusy(USBInHandle))
215 | {
216 | //Send the data contained in the ToSendDataBuffer[] array out on
217 | // endpoint HID_EP
218 | USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer));
219 | }
220 |
221 |
222 | PreCondition:
223 | None
224 |
225 | Parameters:
226 | uint8_t ep - the endpoint you want to send the data out of
227 | uint8_t* data - pointer to the data that you wish to send
228 | uint16_t len - the length of the data that you wish to send
229 |
230 | Return Values:
231 | USB_HANDLE - a handle for the transfer. This information
232 | should be kept to track the status of the transfer
233 |
234 | Remarks:
235 | None
236 |
237 | *******************************************************************/
238 | #define HIDTxPacket USBTxOnePacket
239 |
240 | /********************************************************************
241 | Function:
242 | USB_HANDLE HIDRxPacket(uint8_t ep, uint8_t* data, uint16_t len)
243 |
244 | Summary:
245 | Receives the specified data out the specified endpoint
246 |
247 | Description:
248 | Receives the specified data out the specified endpoint.
249 |
250 | Typical Usage:
251 |
252 | //Read 64-uint8_ts from endpoint HID_EP, into the ReceivedDataBuffer array.
253 | // Make sure to save the return handle so that we can check it later
254 | // to determine when the transfer is complete.
255 | USBOutHandle = HIDRxPacket(HID_EP,(uint8_t*)&ReceivedDataBuffer,64);
256 |
257 |
258 | PreCondition:
259 | None
260 |
261 | Parameters:
262 | uint8_t ep - the endpoint you want to receive the data into
263 | uint8_t* data - pointer to where the data will go when it arrives
264 | uint16_t len - the length of the data that you wish to receive
265 |
266 | Return Values:
267 | USB_HANDLE - a handle for the transfer. This information
268 | should be kept to track the status of the transfer
269 |
270 | Remarks:
271 | None
272 |
273 | *******************************************************************/
274 | #define HIDRxPacket USBRxOnePacket
275 |
276 | // Section: STRUCTURES *********************************************/
277 |
278 | //USB HID Descriptor header as detailed in section
279 | //"6.2.1 HID Descriptor" of the HID class definition specification
280 | typedef struct _USB_HID_DSC_HEADER
281 | {
282 | uint8_t bDescriptorType; //offset 9
283 | uint16_t wDscLength; //offset 10
284 | } USB_HID_DSC_HEADER;
285 |
286 | //USB HID Descriptor header as detailed in section
287 | //"6.2.1 HID Descriptor" of the HID class definition specification
288 | typedef struct _USB_HID_DSC
289 | {
290 | uint8_t bLength; //offset 0
291 | uint8_t bDescriptorType; //offset 1
292 | uint16_t bcdHID; //offset 2
293 | uint8_t bCountryCode; //offset 4
294 | uint8_t bNumDsc; //offset 5
295 |
296 |
297 | //USB_HID_DSC_HEADER hid_dsc_header[HID_NUM_OF_DSC];
298 | /* HID_NUM_OF_DSC is defined in usbcfg.h */
299 |
300 | } USB_HID_DSC;
301 |
302 | /** Section: EXTERNS ********************************************************/
303 | extern volatile CTRL_TRF_SETUP SetupPkt;
304 | extern const uint8_t configDescriptor1[];
305 | extern volatile uint8_t CtrlTrfData[USB_EP0_BUFF_SIZE];
306 |
307 | #endif //HID_H
308 |
--------------------------------------------------------------------------------
/rtcc.c:
--------------------------------------------------------------------------------
1 |
2 | #include "rtcc.h"
3 | #include "i2c.h"
4 | #include "os.h"
5 | #include
6 |
7 | static uint8_t _rtcc_bcd_to_decimal(uint8_t input)
8 | {
9 | uint8_t tens = (input & 0xF0) >> 4;
10 | uint8_t ones = input & 0x0F;
11 | return ((10*tens) + ones);
12 | }
13 |
14 | static void _rtcc_write_enable(void)
15 | {
16 | while(!RTCCFGbits.RTCWREN)
17 | {
18 | EECON2 = 0x55; //Make RTCWREN bit writable
19 | EECON2 = 0xAA;
20 | RTCCFGbits.RTCWREN = 1; //Enable writes
21 | }
22 | }
23 |
24 | static void _rtcc_write_disable(void)
25 | {
26 | while(RTCCFGbits.RTCWREN)
27 | {
28 | EECON2 = 0x55; //Make RTCWREN bit writable
29 | EECON2 = 0xAA;
30 | RTCCFGbits.RTCWREN = 0; //Enable writes
31 | }
32 | }
33 |
34 | static uint8_t _rtcc_increment_bcd(uint8_t value, uint8_t min, uint8_t max)
35 | {
36 | if(value==max)
37 | return min;
38 | ++value;
39 | if((value&0x0F)>0x09)
40 | {
41 | value += 0x10;
42 | value &= 0xF0;
43 | }
44 | return value;
45 | }
46 |
47 | static uint8_t _rtcc_decrement_bcd(uint8_t value, uint8_t min, uint8_t max)
48 | {
49 | if(value==min)
50 | return max;
51 | --value;
52 | if((value&0x0F)>0x09)
53 | {
54 | value &= 0xF0;
55 | value |= 0x09;
56 | }
57 | return value;
58 | }
59 |
60 | static uint8_t _number_of_days(void)
61 | {
62 | uint8_t month = rtcc_get_month();
63 | uint8_t bcd_year = rtcc_get_year();
64 | uint8_t year;
65 | if(month==0x04 || month==0x06 || month==0x09 || month==0x11)
66 | return 0x30;
67 | if(month==0x02)
68 | {
69 | year = bcd_year>>4;
70 | year *= 10;
71 | year += bcd_year & 0x0F;
72 | if(year&0b11) // no leap year
73 | return 0x28;
74 | else //leap year
75 | return 0x29;
76 | }
77 | return 0x31;
78 | }
79 |
80 | static uint8_t _rtcc_verify_bcd(uint8_t value, uint8_t min, uint8_t max)
81 | {
82 | //Ensure that both decimals are in the range 0-9
83 | if((value&0x0F)>0x09)
84 | {
85 | return min;
86 | }
87 | if((value&0xF0)>0x90)
88 | {
89 | return min;
90 | }
91 | //Ensure values are within their limits
92 | if(valuemax)
97 | {
98 | return max;
99 | }
100 | //All is well, return unchanged value
101 | return value;
102 | }
103 |
104 |
105 | void rtcc_init(void)
106 | {
107 | EECON2 = 0x55; //Make RTCWREN bit writable
108 | EECON2 = 0xAA;
109 | RTCCFGbits.RTCWREN = 1; //Enable writes
110 | RTCCFGbits.RTCEN = 1;
111 | RTCCFGbits.RTCOE = 0;
112 | RTCCAL = 0x00; //No calibration
113 |
114 | //Restore date and time from EEPROM
115 | rtcc_read_eeprom();
116 | }
117 |
118 | void rtcc_correct_day(void)
119 | {
120 | uint8_t day = rtcc_get_day();
121 | uint8_t max = _number_of_days();
122 | if(day>max)
123 | rtcc_set_day(max);
124 | }
125 |
126 |
127 | uint8_t rtcc_get_year(void)
128 | {
129 | RTCCFGbits.RTCPTR1 = 1;
130 | RTCCFGbits.RTCPTR0 = 1;
131 | while(RTCCFGbits.RTCSYNC);
132 | return RTCVALL;
133 | }
134 |
135 | uint8_t rtcc_get_year_decimal(void)
136 | {
137 | uint8_t bcd_year = rtcc_get_year();
138 | return _rtcc_bcd_to_decimal(bcd_year);
139 | }
140 |
141 | void rtcc_set_year(uint8_t year)
142 | {
143 | _rtcc_write_enable();
144 | RTCCFGbits.RTCPTR1 = 1;
145 | RTCCFGbits.RTCPTR0 = 1;
146 | RTCVALL = year;
147 | _rtcc_write_disable();
148 | }
149 |
150 | void rtcc_increment_year(void)
151 | {
152 | uint8_t year = rtcc_get_year();
153 | year = _rtcc_increment_bcd(year, 0x00, 0x99);
154 | rtcc_set_year(year);
155 | }
156 |
157 | void rtcc_decrement_year(void)
158 | {
159 | uint8_t year = rtcc_get_year();
160 | year = _rtcc_decrement_bcd(year, 0x00, 0x99);
161 | rtcc_set_year(year);
162 | }
163 |
164 |
165 | uint8_t rtcc_get_month(void)
166 | {
167 | RTCCFGbits.RTCPTR1 = 1;
168 | RTCCFGbits.RTCPTR0 = 0;
169 | while(RTCCFGbits.RTCSYNC);
170 | return RTCVALH;
171 | }
172 |
173 | uint8_t rtcc_get_month_decimal(void)
174 | {
175 | uint8_t bcd_month = rtcc_get_month();
176 | return _rtcc_bcd_to_decimal(bcd_month);
177 | }
178 |
179 | void rtcc_set_month(uint8_t month)
180 | {
181 | _rtcc_write_enable();
182 | RTCCFGbits.RTCPTR1 = 1;
183 | RTCCFGbits.RTCPTR0 = 0;
184 | RTCVALH = month;
185 | _rtcc_write_disable();
186 | }
187 |
188 | void rtcc_increment_month(void)
189 | {
190 | uint8_t month = rtcc_get_month();
191 | month = _rtcc_increment_bcd(month, 0x01, 0x12);
192 | rtcc_set_month(month);
193 | }
194 |
195 | void rtcc_decrement_month(void)
196 | {
197 | uint8_t month = rtcc_get_month();
198 | month = _rtcc_decrement_bcd(month, 0x01, 0x12);
199 | rtcc_set_month(month);
200 | }
201 |
202 |
203 | uint8_t rtcc_get_day(void)
204 | {
205 | RTCCFGbits.RTCPTR1 = 1;
206 | RTCCFGbits.RTCPTR0 = 0;
207 | while(RTCCFGbits.RTCSYNC);
208 | return RTCVALL;
209 | }
210 |
211 | uint8_t rtcc_get_day_decimal(void)
212 | {
213 | uint8_t bcd_day = rtcc_get_day();
214 | return _rtcc_bcd_to_decimal(bcd_day);
215 | }
216 |
217 | void rtcc_set_day(uint8_t day)
218 | {
219 | _rtcc_write_enable();
220 | RTCCFGbits.RTCPTR1 = 1;
221 | RTCCFGbits.RTCPTR0 = 0;
222 | RTCVALL = day;
223 | _rtcc_write_disable();
224 | }
225 |
226 | void rtcc_increment_day(void)
227 | {
228 | uint8_t day = rtcc_get_day();
229 | day = _rtcc_increment_bcd(day, 0x01, _number_of_days());
230 | rtcc_set_day(day);
231 | }
232 |
233 | void rtcc_decrement_day(void)
234 | {
235 | uint8_t day = rtcc_get_day();
236 | day = _rtcc_decrement_bcd(day, 0x01, _number_of_days());
237 | rtcc_set_day(day);
238 | }
239 |
240 |
241 | uint8_t rtcc_get_hours(void)
242 | {
243 | RTCCFGbits.RTCPTR1 = 0;
244 | RTCCFGbits.RTCPTR0 = 1;
245 | while(RTCCFGbits.RTCSYNC);
246 | return RTCVALL;
247 | }
248 |
249 | uint8_t rtcc_get_hours_decimal(void)
250 | {
251 | uint8_t bcd_hours = rtcc_get_hours();
252 | return _rtcc_bcd_to_decimal(bcd_hours);
253 | }
254 |
255 | void rtcc_set_hours(uint8_t hours)
256 | {
257 | _rtcc_write_enable();
258 | RTCCFGbits.RTCPTR1 = 0;
259 | RTCCFGbits.RTCPTR0 = 1;
260 | RTCVALL = hours;
261 | _rtcc_write_disable();
262 | }
263 |
264 | void rtcc_increment_hours(void)
265 | {
266 | uint8_t hours = rtcc_get_hours();
267 | hours = _rtcc_increment_bcd(hours, 0x00, 0x23);
268 | rtcc_set_hours(hours);
269 | }
270 |
271 | void rtcc_decrement_hours(void)
272 | {
273 | uint8_t hours = rtcc_get_hours();
274 | hours = _rtcc_decrement_bcd(hours, 0x00, 0x23);
275 | rtcc_set_hours(hours);
276 | }
277 |
278 |
279 | uint8_t rtcc_get_minutes(void)
280 | {
281 | RTCCFGbits.RTCPTR1 = 0;
282 | RTCCFGbits.RTCPTR0 = 0;
283 | while(RTCCFGbits.RTCSYNC);
284 | return RTCVALH;
285 | }
286 |
287 | uint8_t rtcc_get_minutes_decimal(void)
288 | {
289 | uint8_t bcd_minutes = rtcc_get_minutes();
290 | return _rtcc_bcd_to_decimal(bcd_minutes);
291 | }
292 |
293 | void rtcc_set_minutes(uint8_t minutes)
294 | {
295 | _rtcc_write_enable();
296 | RTCCFGbits.RTCPTR1 = 0;
297 | RTCCFGbits.RTCPTR0 = 0;
298 | RTCVALH = minutes;
299 | _rtcc_write_disable();
300 | }
301 |
302 | void rtcc_increment_minutes(void)
303 | {
304 | uint8_t minutes = rtcc_get_minutes();
305 | minutes = _rtcc_increment_bcd(minutes, 0x00, 0x59);
306 | rtcc_set_minutes(minutes);
307 | }
308 |
309 | void rtcc_decrement_minutes(void)
310 | {
311 | uint8_t minutes = rtcc_get_minutes();
312 | minutes = _rtcc_decrement_bcd(minutes, 0x00, 0x59);
313 | rtcc_set_minutes(minutes);
314 | }
315 |
316 |
317 | uint8_t rtcc_get_seconds(void)
318 | {
319 | RTCCFGbits.RTCPTR1 = 0;
320 | RTCCFGbits.RTCPTR0 = 0;
321 | while(RTCCFGbits.RTCSYNC);
322 | return RTCVALL;
323 | }
324 |
325 | uint8_t rtcc_get_seconds_decimal(void)
326 | {
327 | uint8_t bcd_seconds = rtcc_get_seconds();
328 | return _rtcc_bcd_to_decimal(bcd_seconds);
329 | }
330 |
331 | void rtcc_set_seconds(uint8_t seconds)
332 | {
333 | _rtcc_write_enable();
334 | RTCCFGbits.RTCPTR1 = 0;
335 | RTCCFGbits.RTCPTR0 = 0;
336 | RTCVALL = seconds;
337 | _rtcc_write_disable();
338 | }
339 |
340 | void rtcc_increment_seconds(void)
341 | {
342 | uint8_t seconds = rtcc_get_seconds();
343 | seconds = _rtcc_increment_bcd(seconds, 0x00, 0x59);
344 | rtcc_set_seconds(seconds);
345 | }
346 |
347 | void rtcc_decrement_seconds(void)
348 | {
349 | uint8_t seconds = rtcc_get_seconds();
350 | seconds = _rtcc_decrement_bcd(seconds, 0x00, 0x59);
351 | rtcc_set_seconds(seconds);
352 | }
353 |
354 | void rtcc_read_eeprom(void)
355 | {
356 | uint8_t date[6];
357 | uint8_t buffer;
358 | uint8_t error_found = 0;
359 |
360 | //Read values from eeprom
361 | i2c_eeprom_read(EEPROM_RTCC_ADDRESS, &date[0], 6);
362 |
363 | //Correct values from eeprom
364 | //If this is the first time this code runs, EEPROM may contain invalid data
365 |
366 | //year
367 | buffer = _rtcc_verify_bcd(date[0], 0x00, 0x99);
368 | if(buffer != date[0])
369 | {
370 | date[0] = buffer;
371 | error_found = 1;
372 | }
373 | rtcc_set_year(date[0]);
374 |
375 | //month
376 | buffer = _rtcc_verify_bcd(date[1], 0x01, 0x12);
377 | if(buffer != date[1])
378 | {
379 | date[1] = buffer;
380 | error_found = 1;
381 | }
382 | rtcc_set_month(date[1]);
383 |
384 | //day
385 | buffer = _rtcc_verify_bcd(date[2], 0x01, 0x31);
386 | if(buffer != date[2])
387 | {
388 | date[2] = buffer;
389 | error_found = 1;
390 | }
391 | rtcc_set_day(date[2]);
392 |
393 | //correct day if necessary
394 | rtcc_correct_day();
395 | buffer = rtcc_get_day();
396 | if(buffer != date[2])
397 | {
398 | date[2] = buffer;
399 | error_found = 1;
400 | }
401 |
402 | //hours
403 | buffer = _rtcc_verify_bcd(date[3], 0x00, 0x23);
404 | if(buffer != date[3])
405 | {
406 | date[3] = buffer;
407 | error_found = 1;
408 | }
409 | rtcc_set_hours(date[3]);
410 |
411 | //minutes
412 | buffer = _rtcc_verify_bcd(date[4], 0x00, 0x59);
413 | if(buffer != date[4])
414 | {
415 | date[4] = buffer;
416 | error_found = 1;
417 | }
418 | rtcc_set_minutes(date[4]);
419 |
420 | //seconds
421 | buffer = _rtcc_verify_bcd(date[5], 0x00, 0x59);
422 | if(buffer != date[5])
423 | {
424 | date[5] = buffer;
425 | error_found = 1;
426 | }
427 | rtcc_set_seconds(date[5]);
428 |
429 | //Write date/time to EEPROM if any correction was necessary
430 | if(error_found)
431 | {
432 | rtcc_write_eeprom();
433 | }
434 | }
435 |
436 | void rtcc_write_eeprom(void)
437 | {
438 | uint8_t date[6];
439 | date[0] = rtcc_get_year();
440 | date[1] = rtcc_get_month();
441 | date[2] = rtcc_get_day();
442 | date[3] = rtcc_get_hours();
443 | date[4] = rtcc_get_minutes();
444 | date[5] = rtcc_get_seconds();
445 |
446 | i2c_eeprom_write(EEPROM_RTCC_ADDRESS, &date[0], 6);
447 | }
--------------------------------------------------------------------------------
/nbproject/configurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 | fileio.h
9 | fileio_media.h
10 |
11 | system.h
12 | app_device_custom_hid.h
13 | app_device_msd.h
14 | usb_config.h
15 | os.h
16 | i2c.h
17 | ui.h
18 | display.h
19 | buck.h
20 | adc.h
21 | flash.h
22 | external_flash.h
23 | fat16.h
24 | log.h
25 | rtcc.h
26 | spi.h
27 | api.h
28 | application_config.h
29 | hardware_config.h
30 |
31 |
34 |
35 |
38 |
39 | usb_device.c
40 | usb_device_hid.c
41 | usb_device_msd.c
42 | usb_descriptors.c
43 | usb_events.c
44 |
45 | main.c
46 | system.c
47 | app_device_custom_hid.c
48 | app_device_msd.c
49 | os.c
50 | i2c.c
51 | ui.c
52 | display.c
53 | rtcc.c
54 | buck.c
55 | adc.c
56 | flash.c
57 | external_flash.c
58 | fat16.c
59 | log.c
60 | spi.c
61 | api.c
62 |
63 |
66 | Makefile
67 |
68 |
69 |
70 | .
71 |
72 | Makefile
73 |
74 |
75 |
76 | localhost
77 | PIC18F47J53
78 |
79 |
80 | PICkit3PlatformTool
81 | XC8
82 | 2.00
83 | 3
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | false
97 | false
98 |
99 |
100 |
101 |
102 |
103 |
104 | false
105 |
106 | false
107 |
108 | false
109 | false
110 | false
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
--------------------------------------------------------------------------------
/system.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | #include
21 | #include "system.h"
22 | #include "usb.h"
23 | #include "configuration_bits.h"
24 |
25 |
26 | /*********************************************************************
27 | * Function: void SYSTEM_Initialize( SYSTEM_STATE state )
28 | *
29 | * Overview: Initializes the system.
30 | *
31 | * PreCondition: None
32 | *
33 | * Input: SYSTEM_STATE - the state to initialize the system into
34 | *
35 | * Output: None
36 | *
37 | ********************************************************************/
38 | void SYSTEM_Initialize( SYSTEM_STATE state )
39 | {
40 | switch(state)
41 | {
42 | case SYSTEM_STATE_USB_START:
43 | //In this devices family of USB microcontrollers, the PLL will not power up and be enabled
44 | //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
45 | //This allows the device to power up at a lower initial operating frequency, which can be
46 | //advantageous when powered from a source which is not gauranteed to be adequate for 48MHz
47 | //operation. On these devices, user firmware needs to manually set the OSCTUNE bit to
48 | //power up the PLL.
49 | {
50 | unsigned int pll_startup_counter = 600;
51 | OSCTUNEbits.PLLEN = 1; //Enable the PLL and wait 2+ms until the PLL locks before enabling USB module
52 | while(pll_startup_counter--);
53 | }
54 | //Device switches over automatically to PLL output after PLL is locked and ready.
55 |
56 | //LED_Enable(LED_USB_DEVICE_STATE);
57 | //LED_Enable(LED_USB_DEVICE_HID_CUSTOM);
58 |
59 | //BUTTON_Enable(BUTTON_USB_DEVICE_HID_CUSTOM);
60 |
61 | //ADC_SetConfiguration(ADC_CONFIGURATION_DEFAULT);
62 | //ADC_Enable(ADC_CHANNEL_POTENTIOMETER);
63 | break;
64 |
65 | case SYSTEM_STATE_USB_SUSPEND:
66 | //Should also configure all other I/O pins for lowest power consumption.
67 | //Typically this is done by driving unused I/O pins as outputs and driving them high or low.
68 | //In this example, this is not done however, in case the user is expecting the I/O pins
69 | //to remain tri-state and has hooked something up to them.
70 | //Leaving the I/O pins floating will waste power and should not be done in a
71 | //real application.
72 |
73 | //Sleep on sleep, 125kHz selected as microcontroller clock source
74 | break;
75 |
76 | case SYSTEM_STATE_USB_RESUME:
77 | OSCCON = 0x70; //Primary clock source selected.
78 |
79 | //Adding a software start up delay will ensure
80 | //that the primary oscillator and PLL are running before executing any other
81 | //code. If the PLL isn't being used, (ex: primary osc = 48MHz externally applied EC)
82 | //then this code adds a small unnecessary delay, but it is harmless to execute anyway.
83 | {
84 | unsigned int pll_startup_counter = 800; //Long delay at 31kHz, but ~0.8ms at 48MHz
85 | while(pll_startup_counter--); //Clock will switch over while executing this delay loop
86 | }
87 | break;
88 | }
89 | }
90 |
91 | /*********************************************************************
92 | * Function: bool SYSTEM_UserSelfWriteUnlockVerification(void)
93 | *
94 | * Overview: Self erase/writes to flash memory could potentially corrupt the
95 | * firmware of the application, if the unlock sequence is ever executed
96 | * unintentionally, or if the table pointer is pointing to an invalid
97 | * range (not inside the MSD volume range). Therefore, in order to ensure
98 | * a fully reliable design that is suitable for mass production, it is strongly
99 | * recommended to implement several robustness checks prior to actually
100 | * performing any self erase/program unlock sequence. See additional inline
101 | * code comments.
102 | *
103 | * PreCondition: None
104 | *
105 | * Input: None
106 | *
107 | * Output: true - self write allowed, false - self write not allowed.
108 | *
109 | ********************************************************************/
110 | bool SYSTEM_UserSelfWriteUnlockVerification(void)
111 | {
112 | //Should verify that the voltage on Vdd/Vddcore is high enough to meet
113 | //the datasheet minimum voltage vs. frequency graph for the device.
114 | //If the microcontroller is "overclocked" (ex: by running at maximum rated
115 | //frequency, but then not suppling enough voltage to meet the datasheet
116 | //voltage vs. frequency graph), errant code execution could occur. It is
117 | //therefore strongly recommended to check the voltage prior to performing a
118 | //flash self erase/write unlock sequence. If the voltage is too low to meet
119 | //the voltage vs. frequency graph in the datasheet, the firmware should not
120 | //initiate a self erase/program operation, and instead it should either:
121 | //1. Clock switch to a lower frequency that does meet the voltage/frequency graph. Or,
122 | //2. Put the microcontroller to Sleep mode.
123 |
124 | //The method used to measure Vdd and/or Vddcore will depend upon the
125 | //microcontroller model and the module features available in the device, but
126 | //several options are available on many of the microcontrollers, ex:
127 | //1. HLVD module
128 | //2. WDTCON indicator bit
129 | //3. Perform ADC operation, with the VBG channel selected, using Vdd/Vss as
130 | // references to the ADC. Then perform math operations to calculate the Vdd.
131 | // On some micros, the ADC can also measure the Vddcore voltage, allowing
132 | // the firmware to calculate the absolute Vddcore voltage, if it has already
133 | // calculated and knows the ADC reference voltage.
134 | //4. Use integrated general purpose comparator(s) to sense Vdd/Vddcore voltage
135 | // is above proper threshold.
136 | //5. If the micrcontroller implements a user adjustable BOR circuit, enable
137 | // it and set the trip point high enough to avoid overclocking altogether.
138 |
139 | //Example pseudo code. Exact implementation will be application specific.
140 | //Please implement appropriate code that best meets your application requirements.
141 | //if(GetVddcoreVoltage() < MIN_ALLOWED_VOLTAGE)
142 | //{
143 | // ClockSwitchToSafeFrequencyForGivenVoltage(); //Or even better, go to sleep mode.
144 | // return false;
145 | //}
146 |
147 |
148 | //Should also verify the TBLPTR is pointing to a valid range (part of the MSD
149 | //volume, and not a part of the application firmware space).
150 | //Example code for PIC18 (commented out since the actual address range is
151 | //application specific):
152 | //if((TBLPTR > MSD_VOLUME_MAX_ADDRESS) || (TBLPTR < MSD_VOLUME_START_ADDRESS))
153 | //{
154 | // return false;
155 | //}
156 |
157 | return true;
158 | }
159 |
160 | #if defined(__XC8)
161 | void interrupt SYS_InterruptHigh(void)
162 | {
163 | #if defined(USB_INTERRUPT)
164 | USBDeviceTasks();
165 | #endif
166 |
167 | //User-defined ISR
168 | tmr_isr();
169 |
170 | }
171 | #else
172 | void YourHighPriorityISRCode();
173 | void YourLowPriorityISRCode();
174 |
175 | //On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
176 | //the reset, high priority interrupt, and low priority interrupt
177 | //vectors. However, the current Microchip USB bootloader
178 | //examples are intended to occupy addresses 0x00-0x7FF or
179 | //0x00-0xFFF depending on which bootloader is used. Therefore,
180 | //the bootloader code remaps these vectors to new locations
181 | //as indicated below. This remapping is only necessary if you
182 | //wish to program the hex file generated from this project with
183 | //the USB bootloader. If no bootloader is used, edit the
184 | //usb_config.h file and comment out the following defines:
185 | //#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
186 | //#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
187 |
188 | #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
189 | #define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
190 | #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
191 | #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
192 | #elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
193 | #define REMAPPED_RESET_VECTOR_ADDRESS 0x800
194 | #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
195 | #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
196 | #else
197 | #define REMAPPED_RESET_VECTOR_ADDRESS 0x00
198 | #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
199 | #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18
200 | #endif
201 |
202 | #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
203 | extern void _startup (void); // See c018i.c in your C18 compiler dir
204 | #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
205 | void _reset (void)
206 | {
207 | _asm goto _startup _endasm
208 | }
209 | #endif
210 |
211 | #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
212 | void Remapped_High_ISR (void)
213 | {
214 | _asm goto YourHighPriorityISRCode _endasm
215 | }
216 | #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
217 | void Remapped_Low_ISR (void)
218 | {
219 | _asm goto YourLowPriorityISRCode _endasm
220 | }
221 |
222 | #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
223 | //Note: If this project is built while one of the bootloaders has
224 | //been defined, but then the output hex file is not programmed with
225 | //the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
226 | //As a result, if an actual interrupt was enabled and occured, the PC would jump
227 | //to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space). This
228 | //executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
229 | //(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup". This
230 | //would effective reset the application.
231 |
232 | //To fix this situation, we should always deliberately place a
233 | //"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
234 | //"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18. When the output
235 | //hex file of this project is programmed with the bootloader, these sections do not
236 | //get bootloaded (as they overlap the bootloader space). If the output hex file is not
237 | //programmed using the bootloader, then the below goto instructions do get programmed,
238 | //and the hex file still works like normal. The below section is only required to fix this
239 | //scenario.
240 | #pragma code HIGH_INTERRUPT_VECTOR = 0x08
241 | void High_ISR (void)
242 | {
243 | _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
244 | }
245 | #pragma code LOW_INTERRUPT_VECTOR = 0x18
246 | void Low_ISR (void)
247 | {
248 | _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
249 | }
250 | #endif //end of "#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER)"
251 |
252 | #pragma code
253 |
254 |
255 | //These are your actual interrupt handling routines.
256 | #pragma interrupt YourHighPriorityISRCode
257 | void YourHighPriorityISRCode()
258 | {
259 | //Check which interrupt flag caused the interrupt.
260 | //Service the interrupt
261 | //Clear the interrupt flag
262 | //Etc.
263 | #if defined(USB_INTERRUPT)
264 | USBDeviceTasks();
265 | #endif
266 |
267 | } //This return will be a "retfie fast", since this is in a #pragma interrupt section
268 | #pragma interruptlow YourLowPriorityISRCode
269 | void YourLowPriorityISRCode()
270 | {
271 | //Check which interrupt flag caused the interrupt.
272 | //Service the interrupt
273 | //Clear the interrupt flag
274 | //Etc.
275 |
276 | } //This return will be a "retfie", since this is in a #pragma interruptlow section
277 | #endif
278 |
--------------------------------------------------------------------------------
/usb_device_hid.c:
--------------------------------------------------------------------------------
1 | // DOM-IGNORE-BEGIN
2 | /*******************************************************************************
3 | Copyright 2015 Microchip Technology Inc. (www.microchip.com)
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | To request to license the code under the MLA license (www.microchip.com/mla_license),
18 | please contact mla_licensing@microchip.com
19 | *******************************************************************************/
20 | //DOM-IGNORE-END
21 |
22 | /*******************************************************************************
23 | USB Device Human Interface Device (HID) Layer
24 |
25 | Company:
26 | Microchip Technology Inc.
27 |
28 | File Name:
29 | usb_device_hid.c
30 |
31 | Summary:
32 | USB Device Human Interface Device (HID) Layer interface API.
33 |
34 | Description:
35 | USB Device Human Interface Device (HID) Layer interface API.
36 | *******************************************************************************/
37 |
38 |
39 | // *****************************************************************************
40 | // *****************************************************************************
41 | // Section: Included Files
42 | // *****************************************************************************
43 | // *****************************************************************************
44 | #include "usb_config.h"
45 | #include "usb.h"
46 | #include "usb_device_hid.h"
47 |
48 | // *****************************************************************************
49 | // *****************************************************************************
50 | // Section: File Scope or Global Constants
51 | // *****************************************************************************
52 | // *****************************************************************************
53 |
54 | // *****************************************************************************
55 | // *****************************************************************************
56 | // Section: File Scope Data Types
57 | // *****************************************************************************
58 | // *****************************************************************************
59 | typedef struct __attribute__((packed))
60 | {
61 | unsigned :8;
62 | unsigned :8;
63 | uint8_t reportId;
64 | uint8_t duration;
65 | } USB_SETUP_SET_IDLE_RATE;
66 |
67 | typedef struct __attribute__((packed))
68 | {
69 | unsigned :8;
70 | unsigned :8;
71 | uint8_t protocol;
72 | } USB_SETUP_SET_PROTOCOL;
73 |
74 | // *****************************************************************************
75 | // *****************************************************************************
76 | // Section: Variables
77 | // *****************************************************************************
78 | // *****************************************************************************
79 | static uint8_t idle_rate;
80 | static uint8_t active_protocol; // [0] Boot Protocol [1] Report Protocol
81 |
82 | extern const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01;
83 |
84 | // *****************************************************************************
85 | // *****************************************************************************
86 | // Section: Prototypes
87 | // *****************************************************************************
88 | // *****************************************************************************
89 | #if defined USER_GET_REPORT_HANDLER
90 | void USER_GET_REPORT_HANDLER(void);
91 | #endif
92 |
93 | #if defined USER_SET_REPORT_HANDLER
94 | extern void USER_SET_REPORT_HANDLER(void);
95 | #endif
96 |
97 | // *****************************************************************************
98 | // *****************************************************************************
99 | // Section: Macros or Functions
100 | // *****************************************************************************
101 | // *****************************************************************************
102 |
103 | //To implement a set idle rate callback function in the application,
104 | //Make sure "#define USB_DEVICE_HID_IDLE_RATE_CALLBACK(reportID, newIdleRate) USBHIDCBSetIdleRateHandler(reportID, newIdleRate)"
105 | //is placed in your usb_config.h file, and then in your application .c file,
106 | //add the void USBHIDCBSetIdleRateHandler(reportID, newIdleRate) function
107 | //implementation that saves the new idle rate and report ID info, so that it
108 | //gets used later when sending subsequent HID input report packets to the host.
109 | #ifndef USB_DEVICE_HID_IDLE_RATE_CALLBACK
110 | #define USB_DEVICE_HID_IDLE_RATE_CALLBACK(reportId, idleRate)
111 | #else
112 | extern void USB_DEVICE_HID_IDLE_RATE_CALLBACK(uint8_t reportId, uint8_t idleRate);
113 | #endif
114 |
115 | /********************************************************************
116 | Function:
117 | void USBCheckHIDRequest(void)
118 |
119 | Summary:
120 | This routine handles HID specific request that happen on EP0.
121 | This function should be called from the USBCBCheckOtherReq() call back
122 | function whenever implementing a HID device.
123 |
124 | Description:
125 | This routine handles HID specific request that happen on EP0. These
126 | include, but are not limited to, requests for the HID report
127 | descriptors. This function should be called from the
128 | USBCBCheckOtherReq() call back function whenever using an HID device.
129 |
130 | Typical Usage:
131 |
132 | void USBCBCheckOtherReq(void)
133 | {
134 | //Since the stack didn't handle the request I need to check
135 | // my class drivers to see if it is for them
136 | USBCheckHIDRequest();
137 | }
138 |
139 |
140 | PreCondition:
141 | None
142 |
143 | Parameters:
144 | None
145 |
146 | Return Values:
147 | None
148 |
149 | Remarks:
150 | None
151 |
152 | *******************************************************************/
153 | void USBCheckHIDRequest(void)
154 | {
155 | if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return;
156 | if(SetupPkt.bIntfID != HID_INTF_ID) return;
157 |
158 | /*
159 | * There are two standard requests that hid.c may support.
160 | * 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
161 | * 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
162 | */
163 | if(SetupPkt.bRequest == USB_REQUEST_GET_DESCRIPTOR)
164 | {
165 | switch(SetupPkt.bDescriptorType)
166 | {
167 | case DSC_HID: //HID Descriptor
168 | if(USBActiveConfiguration == 1)
169 | {
170 | USBEP0SendROMPtr(
171 | (const uint8_t*)&configDescriptor1 + 18, //18 is a magic number. It is the offset from start of the configuration descriptor to the start of the HID descriptor.
172 | sizeof(USB_HID_DSC)+3,
173 | USB_EP0_INCLUDE_ZERO);
174 | }
175 | break;
176 | case DSC_RPT: //Report Descriptor
177 | //if(USBActiveConfiguration == 1)
178 | {
179 | USBEP0SendROMPtr(
180 | (const uint8_t*)&hid_rpt01,
181 | HID_RPT01_SIZE, //See usbcfg.h
182 | USB_EP0_INCLUDE_ZERO);
183 | }
184 | break;
185 | case DSC_PHY: //Physical Descriptor
186 | //Note: The below placeholder code is commented out. HID Physical Descriptors are optional and are not used
187 | //in many types of HID applications. If an application does not have a physical descriptor,
188 | //then the device should return STALL in response to this request (stack will do this automatically
189 | //if no-one claims ownership of the control transfer).
190 | //If an application does implement a physical descriptor, then make sure to declare
191 | //hid_phy01 (rom structure containing the descriptor data), and hid_phy01 (the size of the descriptors in uint8_ts),
192 | //and then uncomment the below code.
193 | //if(USBActiveConfiguration == 1)
194 | //{
195 | // USBEP0SendROMPtr((const uint8_t*)&hid_phy01, sizeof(hid_phy01), USB_EP0_INCLUDE_ZERO);
196 | //}
197 | break;
198 | }//end switch(SetupPkt.bDescriptorType)
199 | }//end if(SetupPkt.bRequest == GET_DSC)
200 |
201 | if(SetupPkt.RequestType != USB_SETUP_TYPE_CLASS_BITFIELD)
202 | {
203 | return;
204 | }
205 |
206 | switch(SetupPkt.bRequest)
207 | {
208 | case GET_REPORT:
209 | #if defined USER_GET_REPORT_HANDLER
210 | USER_GET_REPORT_HANDLER();
211 | #endif
212 | break;
213 | case SET_REPORT:
214 | #if defined USER_SET_REPORT_HANDLER
215 | USER_SET_REPORT_HANDLER();
216 | #endif
217 | break;
218 | case GET_IDLE:
219 | USBEP0SendRAMPtr(
220 | (uint8_t*)&idle_rate,
221 | 1,
222 | USB_EP0_INCLUDE_ZERO);
223 | break;
224 | case SET_IDLE:
225 | USBEP0Transmit(USB_EP0_NO_DATA);
226 | idle_rate = SetupPkt.W_Value.byte.HB;
227 | USB_DEVICE_HID_IDLE_RATE_CALLBACK(SetupPkt.W_Value.byte.LB, idle_rate);
228 | break;
229 | case GET_PROTOCOL:
230 | USBEP0SendRAMPtr(
231 | (uint8_t*)&active_protocol,
232 | 1,
233 | USB_EP0_NO_OPTIONS);
234 | break;
235 | case SET_PROTOCOL:
236 | USBEP0Transmit(USB_EP0_NO_DATA);
237 | active_protocol = SetupPkt.W_Value.byte.LB;
238 | break;
239 | }//end switch(SetupPkt.bRequest)
240 |
241 | }//end USBCheckHIDRequest
242 |
243 | /********************************************************************
244 | Function:
245 | USB_HANDLE HIDTxPacket(uint8_t ep, uint8_t* data, uint16_t len)
246 |
247 | Summary:
248 | Sends the specified data out the specified endpoint
249 |
250 | Description:
251 | This function sends the specified data out the specified
252 | endpoint and returns a handle to the transfer information.
253 |
254 | Typical Usage:
255 |
256 | //make sure that the last transfer isn't busy by checking the handle
257 | if(!HIDTxHandleBusy(USBInHandle))
258 | {
259 | //Send the data contained in the ToSendDataBuffer[] array out on
260 | // endpoint HID_EP
261 | USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer));
262 | }
263 |
264 |
265 | PreCondition:
266 | None
267 |
268 | Parameters:
269 | uint8_t ep - the endpoint you want to send the data out of
270 | uint8_t* data - pointer to the data that you wish to send
271 | uint16_t len - the length of the data that you wish to send
272 |
273 | Return Values:
274 | USB_HANDLE - a handle for the transfer. This information
275 | should be kept to track the status of the transfer
276 |
277 | Remarks:
278 | None
279 |
280 | *******************************************************************/
281 | // Implemented as a macro. See usb_function_hid.h
282 |
283 | /********************************************************************
284 | Function:
285 | USB_HANDLE HIDRxPacket(uint8_t ep, uint8_t* data, uint16_t len)
286 |
287 | Summary:
288 | Receives the specified data out the specified endpoint
289 |
290 | Description:
291 | Receives the specified data out the specified endpoint.
292 |
293 | Typical Usage:
294 |
295 | //Read 64-uint8_ts from endpoint HID_EP, into the ReceivedDataBuffer array.
296 | // Make sure to save the return handle so that we can check it later
297 | // to determine when the transfer is complete.
298 | USBOutHandle = HIDRxPacket(HID_EP,(uint8_t*)&ReceivedDataBuffer,64);
299 |
300 |
301 | PreCondition:
302 | None
303 |
304 | Parameters:
305 | uint8_t ep - the endpoint you want to receive the data into
306 | uint8_t* data - pointer to where the data will go when it arrives
307 | uint16_t len - the length of the data that you wish to receive
308 |
309 | Return Values:
310 | USB_HANDLE - a handle for the transfer. This information
311 | should be kept to track the status of the transfer
312 |
313 | Remarks:
314 | None
315 |
316 | *******************************************************************/
317 | // Implemented as a macro. See usb_function_hid.h
318 |
319 | /*******************************************************************************
320 | End of File
321 | */
322 |
--------------------------------------------------------------------------------
/ui.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "hardware_config.h"
5 | #include "os.h"
6 | #include "i2c.h"
7 | #include "rtcc.h"
8 | #include "ui.h"
9 |
10 | userInterfaceStatus_t userInterfaceStatus;
11 | uint16_t system_ui_inactive_count;
12 |
13 | userInterfaceStatus_t ui_get_status(void)
14 | {
15 | return userInterfaceStatus;
16 | }
17 |
18 | static void _ui_encoder(void)
19 | {
20 | switch(os.display_mode)
21 | {
22 | case DISPLAY_MODE_OVERVIEW:
23 | if(os.encoderCount>0)
24 | {
25 | os.display_mode = DISPLAY_MODE_DATETIME_OVERVIEW;
26 | }
27 | else if(os.encoderCount<0)
28 | {
29 | os.display_mode = DISPLAY_MODE_TEMPERATURE;
30 | }
31 | if(os.buttonCount)
32 | {
33 | ;
34 | }
35 | os.encoderCount = 0;
36 | os.buttonCount = 0;
37 | break;
38 |
39 | case DISPLAY_MODE_DATETIME_OVERVIEW:
40 | if(os.encoderCount>0)
41 | {
42 | os.display_mode = DISPLAY_MODE_USB_CHARGER;
43 | }
44 | else if(os.encoderCount<0)
45 | {
46 | os.display_mode = DISPLAY_MODE_OVERVIEW;
47 | }
48 | if(os.buttonCount)
49 | {
50 | os.display_mode = DISPLAY_MODE_DATETIME_YEAR;
51 | }
52 | os.encoderCount = 0;
53 | os.buttonCount = 0;
54 | break;
55 |
56 | case DISPLAY_MODE_DATETIME_YEAR:
57 | if(os.encoderCount>0)
58 | {
59 | rtcc_increment_year();
60 | }
61 | else if(os.encoderCount<0)
62 | {
63 | rtcc_decrement_year();
64 | }
65 | if(os.buttonCount)
66 | {
67 | rtcc_correct_day();
68 | os.display_mode = DISPLAY_MODE_DATETIME_MONTH;
69 | }
70 | os.encoderCount = 0;
71 | os.buttonCount = 0;
72 | break;
73 |
74 | case DISPLAY_MODE_DATETIME_MONTH:
75 | if(os.encoderCount>0)
76 | {
77 | rtcc_increment_month();
78 | }
79 | else if(os.encoderCount<0)
80 | {
81 | rtcc_decrement_month();
82 | }
83 | if(os.buttonCount)
84 | {
85 | rtcc_correct_day();
86 | os.display_mode = DISPLAY_MODE_DATETIME_DAY;
87 | }
88 | os.encoderCount = 0;
89 | os.buttonCount = 0;
90 | break;
91 |
92 | case DISPLAY_MODE_DATETIME_DAY:
93 | if(os.encoderCount>0)
94 | {
95 | rtcc_increment_day();
96 | }
97 | else if(os.encoderCount<0)
98 | {
99 | rtcc_decrement_day();
100 | }
101 | if(os.buttonCount)
102 | {
103 | os.display_mode = DISPLAY_MODE_DATETIME_HOURS;
104 | }
105 | os.encoderCount = 0;
106 | os.buttonCount = 0;
107 | break;
108 |
109 | case DISPLAY_MODE_DATETIME_HOURS:
110 | if(os.encoderCount>0)
111 | {
112 | rtcc_increment_hours();
113 | }
114 | else if(os.encoderCount<0)
115 | {
116 | rtcc_decrement_hours();
117 | }
118 | if(os.buttonCount)
119 | {
120 | os.display_mode = DISPLAY_MODE_DATETIME_MINUTES;
121 | }
122 | os.encoderCount = 0;
123 | os.buttonCount = 0;
124 | break;
125 |
126 | case DISPLAY_MODE_DATETIME_MINUTES:
127 | if(os.encoderCount>0)
128 | {
129 | rtcc_increment_minutes();
130 | }
131 | else if(os.encoderCount<0)
132 | {
133 | rtcc_decrement_minutes();
134 | }
135 | if(os.buttonCount)
136 | {
137 | os.display_mode = DISPLAY_MODE_DATETIME_SECONDS;
138 | }
139 | os.encoderCount = 0;
140 | os.buttonCount = 0;
141 | break;
142 |
143 | case DISPLAY_MODE_DATETIME_SECONDS:
144 | if(os.encoderCount>0)
145 | {
146 | rtcc_increment_seconds();
147 | }
148 | else if(os.encoderCount<0)
149 | {
150 | rtcc_decrement_seconds();
151 | }
152 | if(os.buttonCount)
153 | {
154 | os.display_mode = DISPLAY_MODE_DATETIME_OVERVIEW;
155 | rtcc_write_eeprom();
156 | }
157 | os.encoderCount = 0;
158 | os.buttonCount = 0;
159 | break;
160 |
161 | case DISPLAY_MODE_USB_CHARGER:
162 | if(os.encoderCount>0)
163 | {
164 | os.display_mode = DISPLAY_MODE_OUTPUTS;
165 | }
166 | else if(os.encoderCount<0)
167 | {
168 | os.display_mode = DISPLAY_MODE_DATETIME_OVERVIEW;
169 | }
170 | if(os.buttonCount)
171 | {
172 | if(os.output_voltage>USB_CHARGING_VOLTAGE_MINIMUM)
173 | {
174 | system_output_toggle(OUTPUT_USB);
175 | }
176 | }
177 | os.encoderCount = 0;
178 | os.buttonCount = 0;
179 | break;
180 |
181 | case DISPLAY_MODE_OUTPUTS:
182 | if(os.encoderCount>0)
183 | {
184 | os.display_mode = DISPLAY_MODE_CHARGER_DETAILS;
185 | }
186 | else if(os.encoderCount<0)
187 | {
188 | os.display_mode = DISPLAY_MODE_USB_CHARGER;
189 | }
190 | if(os.buttonCount)
191 | {
192 | os.display_mode = DISPLAY_MODE_OUTPUTS_1;
193 | }
194 | os.encoderCount = 0;
195 | os.buttonCount = 0;
196 | break;
197 |
198 | case DISPLAY_MODE_OUTPUTS_1:
199 | if(os.encoderCount>0)
200 | {
201 | if(os.output_voltage>POWER_OUTPUTS_VOLTAGE_MINIMUM)
202 | system_output_on(OUTPUT_1);
203 | }
204 | else if(os.encoderCount<0)
205 | {
206 | system_output_off(OUTPUT_1);
207 | }
208 | if(os.buttonCount)
209 | {
210 | os.display_mode = DISPLAY_MODE_OUTPUTS_2;
211 | }
212 | os.encoderCount = 0;
213 | os.buttonCount = 0;
214 | break;
215 |
216 | case DISPLAY_MODE_OUTPUTS_2:
217 | if(os.encoderCount>0)
218 | {
219 | if(os.output_voltage>POWER_OUTPUTS_VOLTAGE_MINIMUM)
220 | system_output_on(OUTPUT_2);
221 | }
222 | else if(os.encoderCount<0)
223 | {
224 | system_output_off(OUTPUT_2);
225 | }
226 | if(os.buttonCount)
227 | {
228 | os.display_mode = DISPLAY_MODE_OUTPUTS_3;
229 | }
230 | os.encoderCount = 0;
231 | os.buttonCount = 0;
232 | break;
233 |
234 | case DISPLAY_MODE_OUTPUTS_3:
235 | if(os.encoderCount>0)
236 | {
237 | if(os.output_voltage>POWER_OUTPUTS_VOLTAGE_MINIMUM)
238 | system_output_on(OUTPUT_3);
239 | }
240 | else if(os.encoderCount<0)
241 | {
242 | system_output_off(OUTPUT_3);
243 | }
244 | if(os.buttonCount)
245 | {
246 | os.display_mode = DISPLAY_MODE_OUTPUTS_4;
247 | }
248 | os.encoderCount = 0;
249 | os.buttonCount = 0;
250 | break;
251 |
252 | case DISPLAY_MODE_OUTPUTS_4:
253 | if(os.encoderCount>0)
254 | {
255 | if(os.output_voltage>POWER_OUTPUTS_VOLTAGE_MINIMUM)
256 | system_output_on(OUTPUT_4);
257 | }
258 | else if(os.encoderCount<0)
259 | {
260 | system_output_off(OUTPUT_4);
261 | }
262 | if(os.buttonCount)
263 | {
264 | os.display_mode = DISPLAY_MODE_OUTPUTS;
265 | }
266 | os.encoderCount = 0;
267 | os.buttonCount = 0;
268 | break;
269 |
270 | case DISPLAY_MODE_CHARGER_DETAILS:
271 | if(os.encoderCount>0)
272 | {
273 | os.display_mode = DISPLAY_MODE_EFFICIENCY;
274 | }
275 | else if(os.encoderCount<0)
276 | {
277 | os.display_mode = DISPLAY_MODE_OUTPUTS;
278 | }
279 | if(os.buttonCount)
280 | {
281 | ;
282 | }
283 | os.encoderCount = 0;
284 | os.buttonCount = 0;
285 | break;
286 |
287 | case DISPLAY_MODE_EFFICIENCY:
288 | if(os.encoderCount>0)
289 | {
290 | os.display_mode = DISPLAY_MODE_TEMPERATURE;
291 | }
292 | else if(os.encoderCount<0)
293 | {
294 | os.display_mode = DISPLAY_MODE_CHARGER_DETAILS;
295 | }
296 | if(os.buttonCount)
297 | {
298 | ;
299 | }
300 | os.encoderCount = 0;
301 | os.buttonCount = 0;
302 | break;
303 |
304 | case DISPLAY_MODE_TEMPERATURE:
305 | if(os.encoderCount>0)
306 | {
307 | os.display_mode = DISPLAY_MODE_OVERVIEW;
308 | }
309 | else if(os.encoderCount<0)
310 | {
311 | os.display_mode = DISPLAY_MODE_EFFICIENCY;
312 | }
313 | if(os.buttonCount)
314 | {
315 | ;
316 | }
317 | os.encoderCount = 0;
318 | os.buttonCount = 0;
319 | break;
320 |
321 | default:
322 | os.display_mode = DISPLAY_MODE_OVERVIEW;
323 | }
324 | }
325 |
326 | void ui_init(void)
327 | {
328 | system_ui_inactive_count = 0;
329 | //Enable high (3.3volts) board voltage
330 | VCC_HIGH_PIN = 1;
331 | userInterfaceStatus = USER_INTERFACE_STATUS_STARTUP_1;
332 | }
333 |
334 |
335 | void ui_run(void)
336 | {
337 | switch(userInterfaceStatus)
338 | {
339 | case USER_INTERFACE_STATUS_OFF:
340 | if (os.buttonCount!=0)
341 | {
342 | ui_init();
343 | os.buttonCount = 0;
344 | }
345 | break;
346 |
347 | case USER_INTERFACE_STATUS_STARTUP_1:
348 | //Switch CPU to 48MHz operating frequency
349 | //if(os.clockFrequency==CPU_FREQUENCY_32kHz)
350 | //{
351 | //system_set_cpu_frequency(CPU_FREQUENCY_48MHz);
352 | //}
353 | //Enable the user interface
354 | DISP_EN_PIN = 0;
355 | //Proceed to next state
356 | system_ui_inactive_count = 0;
357 | userInterfaceStatus = USER_INTERFACE_STATUS_STARTUP_2;
358 | break;
359 |
360 | case USER_INTERFACE_STATUS_STARTUP_2:
361 | //Put display into reset
362 | i2c_digipot_reset_on();
363 | //Proceed to next state
364 | system_ui_inactive_count = 0;
365 | userInterfaceStatus = USER_INTERFACE_STATUS_STARTUP_3;
366 | break;
367 |
368 | case USER_INTERFACE_STATUS_STARTUP_3:
369 | ++system_ui_inactive_count;
370 | //Turn off reset after 16ms
371 | if (system_ui_inactive_count>3)
372 | {
373 | i2c_digipot_reset_off();
374 | system_ui_inactive_count = 0;
375 | userInterfaceStatus = USER_INTERFACE_STATUS_STARTUP_4;
376 | }
377 | break;
378 |
379 | case USER_INTERFACE_STATUS_STARTUP_4:
380 | //Send init sequence
381 | i2c_display_send_init_sequence();
382 | //Turn backlight on
383 | i2c_digipot_backlight(150);
384 | //Enable rotary encoder inputs
385 | system_encoder_enable();
386 | //User interface is now up and running
387 | system_ui_inactive_count = 0;
388 | userInterfaceStatus = USER_INTERFACE_STATUS_ON;
389 | break;
390 |
391 | case USER_INTERFACE_STATUS_ON:
392 | if (os.encoderCount==0 && os.buttonCount==0)
393 | {
394 | ++system_ui_inactive_count;
395 | if(system_ui_inactive_count > OS_USER_INTERFACE_TIMEOUT)
396 | {
397 | //Disable rotary encoder inputs
398 | system_encoder_disable();
399 | //Disable the user interface
400 | DISP_EN_PIN = 1;
401 | //i2c_expander_low(I2C_EXPANDER_USER_INTERFACE);
402 | //User interface is now off
403 | system_ui_inactive_count = 0;
404 | userInterfaceStatus = USER_INTERFACE_STATUS_OFF;
405 | }
406 | }
407 | else
408 | {
409 | system_ui_inactive_count = 0;
410 | _ui_encoder();
411 | }
412 | break;
413 | }
414 | }
--------------------------------------------------------------------------------
/usb_descriptors.c:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | Copyright 2016 Microchip Technology Inc. (www.microchip.com)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
16 | To request to license the code under the MLA license (www.microchip.com/mla_license),
17 | please contact mla_licensing@microchip.com
18 | *******************************************************************************/
19 |
20 | /********************************************************************
21 | -usb_descriptors.c-
22 | -------------------------------------------------------------------
23 | Filling in the descriptor values in the usb_descriptors.c file:
24 | -------------------------------------------------------------------
25 |
26 | [Device Descriptors]
27 | The device descriptor is defined as a USB_DEVICE_DESCRIPTOR type.
28 | This type is defined in usb_ch9.h Each entry into this structure
29 | needs to be the correct length for the data type of the entry.
30 |
31 | [Configuration Descriptors]
32 | The configuration descriptor was changed in v2.x from a structure
33 | to a uint8_t array. Given that the configuration is now a byte array
34 | each byte of multi-byte fields must be listed individually. This
35 | means that for fields like the total size of the configuration where
36 | the field is a 16-bit value "64,0," is the correct entry for a
37 | configuration that is only 64 bytes long and not "64," which is one
38 | too few bytes.
39 |
40 | The configuration attribute must always have the _DEFAULT
41 | definition at the minimum. Additional options can be ORed
42 | to the _DEFAULT attribute. Available options are _SELF and _RWU.
43 | These definitions are defined in the usb_device.h file. The
44 | _SELF tells the USB host that this device is self-powered. The
45 | _RWU tells the USB host that this device supports Remote Wakeup.
46 |
47 | [Endpoint Descriptors]
48 | Like the configuration descriptor, the endpoint descriptors were
49 | changed in v2.x of the stack from a structure to a uint8_t array. As
50 | endpoint descriptors also has a field that are multi-byte entities,
51 | please be sure to specify both bytes of the field. For example, for
52 | the endpoint size an endpoint that is 64 bytes needs to have the size
53 | defined as "64,0," instead of "64,"
54 |
55 | Take the following example:
56 | // Endpoint Descriptor //
57 | 0x07, //the size of this descriptor //
58 | USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
59 | _EP02_IN, //EndpointAddress
60 | _INT, //Attributes
61 | 0x08,0x00, //size (note: 2 bytes)
62 | 0x02, //Interval
63 |
64 | The first two parameters are self-explanatory. They specify the
65 | length of this endpoint descriptor (7) and the descriptor type.
66 | The next parameter identifies the endpoint, the definitions are
67 | defined in usb_device.h and has the following naming
68 | convention:
69 | _EP<##>_
70 | where ## is the endpoint number and dir is the direction of
71 | transfer. The dir has the value of either 'OUT' or 'IN'.
72 | The next parameter identifies the type of the endpoint. Available
73 | options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
74 | typically used because the default control transfer endpoint is
75 | not defined in the USB descriptors. When _ISO option is used,
76 | addition options can be ORed to _ISO. Example:
77 | _ISO|_AD|_FE
78 | This describes the endpoint as an isochronous pipe with adaptive
79 | and feedback attributes. See usb_device.h and the USB
80 | specification for details. The next parameter defines the size of
81 | the endpoint. The last parameter in the polling interval.
82 |
83 | -------------------------------------------------------------------
84 | Adding a USB String
85 | -------------------------------------------------------------------
86 | A string descriptor array should have the following format:
87 |
88 | rom struct{byte bLength;byte bDscType;word string[size];}sdxxx={
89 | sizeof(sdxxx),DSC_STR,};
90 |
91 | The above structure provides a means for the C compiler to
92 | calculate the length of string descriptor sdxxx, where xxx is the
93 | index number. The first two bytes of the descriptor are descriptor
94 | length and type. The rest are string texts which must be
95 | in the unicode format. The unicode format is achieved by declaring
96 | each character as a word type. The whole text string is declared
97 | as a word array with the number of characters equals to .
98 | has to be manually counted and entered into the array
99 | declaration. Let's study this through an example:
100 | if the string is "USB" , then the string descriptor should be:
101 | (Using index 02)
102 | rom struct{byte bLength;byte bDscType;word string[3];}sd002={
103 | sizeof(sd002),DSC_STR,'U','S','B'};
104 |
105 | A USB project may have multiple strings and the firmware supports
106 | the management of multiple strings through a look-up table.
107 | The look-up table is defined as:
108 | rom const unsigned char *rom USB_SD_Ptr[]={&sd000,&sd001,&sd002};
109 |
110 | The above declaration has 3 strings, sd000, sd001, and sd002.
111 | Strings can be removed or added. sd000 is a specialized string
112 | descriptor. It defines the language code, usually this is
113 | US English (0x0409). The index of the string must match the index
114 | position of the USB_SD_Ptr array, &sd000 must be in position
115 | USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
116 | The look-up table USB_SD_Ptr is used by the get string handler
117 | function.
118 |
119 | -------------------------------------------------------------------
120 |
121 | The look-up table scheme also applies to the configuration
122 | descriptor. A USB device may have multiple configuration
123 | descriptors, i.e. CFG01, CFG02, etc. To add a configuration
124 | descriptor, user must implement a structure similar to CFG01.
125 | The next step is to add the configuration descriptor name, i.e.
126 | cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
127 | is a dummy place holder since configuration 0 is the un-configured
128 | state according to the definition in the USB specification.
129 |
130 | ********************************************************************/
131 |
132 | /*********************************************************************
133 | * Descriptor specific type definitions are defined in:
134 | * usb_device.h
135 | *
136 | * Configuration options are defined in:
137 | * usb_config.h
138 | ********************************************************************/
139 | #ifndef __USB_DESCRIPTORS_C
140 | #define __USB_DESCRIPTORS_C
141 |
142 | /** INCLUDES *******************************************************/
143 | #include "usb.h"
144 | #include "usb_device_hid.h"
145 | #include "usb_device_msd.h"
146 |
147 | /** CONSTANTS ******************************************************/
148 | #if defined(__18CXX)
149 | #pragma romdata
150 | #endif
151 |
152 | /* Device Descriptor */
153 | const USB_DEVICE_DESCRIPTOR device_dsc=
154 | {
155 | 0x12, // Size of this descriptor in bytes
156 | USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
157 | 0x0200, // USB Spec Release Number in BCD format
158 | 0x00, // Class Code
159 | 0x00, // Subclass code
160 | 0x00, // Protocol code
161 | USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
162 | 0x04D8, // Vendor ID (Microchip VID)
163 | 0xF08E, // Product ID: (PID granted by Microchip for soldernerd.com SolarCharger, Request #1586)
164 | 0x0100, // Device release number in BCD format
165 | 0x01, // Manufacturer string index
166 | 0x02, // Product string index
167 | 0x00, // Device serial number string index
168 | 0x01 // Number of possible configurations
169 | };
170 |
171 | /* Configuration 1 Descriptor */
172 | const uint8_t configDescriptor1[]={
173 | /* Configuration Descriptor */
174 | 0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
175 | USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
176 | 0x40,0x00, // Total length of data for this cfg
177 | 2, // Number of interfaces in this cfg
178 | 1, // Index value of this configuration
179 | 0, // Configuration string index
180 | _DEFAULT | _SELF, // Attributes, see usb_device.h
181 | 50, // Max power consumption (2X mA)
182 |
183 | /* Interface Descriptor */
184 | 0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
185 | USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
186 | 0, // Interface Number
187 | 0, // Alternate Setting Number
188 | 2, // Number of endpoints in this intf
189 | HID_INTF, // Class code
190 | 0, // Subclass code
191 | 0, // Protocol code
192 | 0, // Interface string index
193 |
194 | /* HID Class-Specific Descriptor */
195 | 0x09,//sizeof(USB_HID_DSC)+3, // Size of this descriptor in bytes
196 | DSC_HID, // HID descriptor type
197 | 0x11,0x01, // HID Spec Release Number in BCD format (1.11)
198 | 0x00, // Country Code (0x00 for Not supported)
199 | HID_NUM_OF_DSC, // Number of class descriptors, see usbcfg.h
200 | DSC_RPT, // Report descriptor type
201 | HID_RPT01_SIZE,0x00,//sizeof(hid_rpt01), // Size of the report descriptor
202 |
203 | /* Endpoint Descriptor */
204 | 0x07,/*sizeof(USB_EP_DSC)*/
205 | USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
206 | CUSTOM_DEVICE_HID_EP | _EP_IN, //EndpointAddress
207 | _INTERRUPT, //Attributes
208 | 0x40,0x00, //size
209 | 0x01, //Interval
210 |
211 | /* Endpoint Descriptor */
212 | 0x07,/*sizeof(USB_EP_DSC)*/
213 | USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
214 | CUSTOM_DEVICE_HID_EP | _EP_OUT, //EndpointAddress
215 | _INTERRUPT, //Attributes
216 | 0x40,0x00, //size
217 | 0x01, //Interval
218 |
219 | /* Interface Descriptor */
220 | 9, // Size of this descriptor in bytes
221 | USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
222 | 1, // Interface Number
223 | 0, // Alternate Setting Number
224 | 2, // Number of endpoints in this intf
225 | MSD_INTF, // Class code
226 | MSD_INTF_SUBCLASS, // Subclass code
227 | MSD_PROTOCOL, // Protocol code
228 | 0, // Interface string index
229 |
230 | /* Endpoint Descriptor */
231 | 7,
232 | USB_DESCRIPTOR_ENDPOINT,
233 | _EP02_IN,_BULK,
234 | MSD_IN_EP_SIZE,0x00,
235 | 0x01,
236 |
237 | 7,
238 | USB_DESCRIPTOR_ENDPOINT,
239 | _EP02_OUT,
240 | _BULK,
241 | MSD_OUT_EP_SIZE,0x00,
242 | 0x01
243 | };
244 |
245 |
246 | //Language code(s) supported string descriptor
247 | const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
248 | sizeof(sd000),
249 | USB_DESCRIPTOR_STRING,
250 | {0x0409} //0x0409 = Language ID code for US English
251 | };
252 |
253 | //Manufacturer string descriptor
254 | const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
255 | sizeof(sd001),USB_DESCRIPTOR_STRING,
256 | {'S','o','l','d','e','r','n','e','r','d','.','c','o','m',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}
257 | };
258 |
259 | //Product string descriptor
260 | const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[22];}sd002={
261 | sizeof(sd002),USB_DESCRIPTOR_STRING,
262 | {'M','P','P','T','S','o','l','a','r',' ','C','h','a','r','g','e','r',' ','R','e','v','E'}
263 | };
264 |
265 | //Serial number string descriptor. Note: This should be unique for each unit
266 | //built on the assembly line. Plugging in two units simultaneously with the
267 | //same serial number into a single machine can cause problems. Additionally, not
268 | //all hosts support all character values in the serial number string. The MSD
269 | //Bulk Only Transport (BOT) specs v1.0 restrict the serial number to consist only
270 | //of ASCII characters "0" through "9" and capital letters "A" through "F".
271 | const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[12];}sd003={
272 | sizeof(sd003),USB_DESCRIPTOR_STRING,
273 | {'1','2','3','4','5','6','7','8','9','0','9','9'}};
274 |
275 |
276 | //Class specific descriptor - HID
277 | const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={
278 | {
279 | 0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
280 | 0x09, 0x01, // Usage (Vendor Usage 1)
281 | 0xA1, 0x01, // Collection (Application)
282 | 0x19, 0x01, // Usage Minimum
283 | 0x29, 0x40, // Usage Maximum //64 input usages total (0x01 to 0x40)
284 | 0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
285 | 0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
286 | 0x75, 0x08, // Report Size: 8-bit field size
287 | 0x95, 0x40, // Report Count: Make sixty-four 8-bit fields (the next time the parser hits an "Input", "Output", or "Feature" item)
288 | 0x81, 0x00, // Input (Data, Array, Abs): Instantiates input packet fields based on the above report size, count, logical min/max, and usage.
289 | 0x19, 0x01, // Usage Minimum
290 | 0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40)
291 | 0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same report size and count as "Input" fields, since nothing new/different was specified to the parser since the "Input" item.
292 | 0xC0} // End Collection
293 | };
294 |
295 |
296 | //Array of configuration descriptors
297 | const uint8_t *const USB_CD_Ptr[]=
298 | {
299 | (const uint8_t *const)&configDescriptor1
300 | };
301 |
302 | //Array of string descriptors
303 | const uint8_t *const USB_SD_Ptr[]=
304 | {
305 | (const uint8_t *const)&sd000,
306 | (const uint8_t *const)&sd001,
307 | (const uint8_t *const)&sd002,
308 | (const uint8_t *const)&sd003
309 | };
310 |
311 | /** EOF usb_descriptors.c ***************************************************/
312 |
313 | #endif
314 |
--------------------------------------------------------------------------------