Add GPIO controlled power supply support

This commit is contained in:
Wenting Zhang 2023-12-07 20:36:15 -05:00
parent d6f6bd5514
commit b323d10693
9 changed files with 294 additions and 5 deletions

View file

@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD 17)
# initalize pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/home/wenting/pico/pico-sdk")
set(PICO_SDK_PATH "/Users/wenting/pico/pico-sdk")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
@ -23,6 +23,7 @@ add_executable(fw
fw.c
utils.c
fusb302.c
power.c
ptn3460.c
tcpm_driver.c
tps65185.c
@ -48,6 +49,7 @@ target_link_libraries(fw
hardware_spi
hardware_dma
hardware_i2c
hardware_pwm
)
pico_add_extra_outputs(fw)

167
fw/config.h Normal file
View file

@ -0,0 +1,167 @@
//
// Copyright 2023 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
/* BOARD REVISION CONFIGURATION */
// Eariler revisions are not supported
//#define BOARD_REV_R0P5
#define BOARD_REV_R0P6
/* SCREEN CONFIGURATION */
// #define SCREEN_6_0_INCH
// #define SCREEN_7_8_INCH
// #define SCREEN_10_3_INCH
// #define SCREEN_10_8_INCH
#define SCREEN_13_3_INCH
// #define SCREEN_800_600
// #define SCREEN_1024_758
// #define SCREEN_1448_1072
#define SCREEN_1600_1200
// #define SCREEN_1872_1404
// #define SCREEN_1920_1080
// #define SCREEN_2200_1650
#define SCREEN_MONO
// #define SCREEN_DES_COLOR
/* SET BASED ON PREVIOUS DEFINES, DO NOT MODIFY */
#if defined(BOARD_REV_R0P5)
#define POWER_TPS65185
#elif defined(BOARD_REV_R0P6)
#define POWER_GPIO
#else
#error "Unknown board revision"
#endif
// Used in EDID
#define SCREEN_ASPECT_16_10 0x00
#define SCREEN_ASPECT_4_3 0x40
#define SCREEN_ASPECT_5_4 0x80
#define SCREEN_ASPECT_16_9 0xC0
// Screen dimension in mm
#if defined(SCREEN_6_0_INCH)
#define SCREEN_SIZE_X 122
#define SCREEN_SIZE_Y 91
#define SCREEN_ASPECT SCREEN_ASPECT_4_3
#elif defined(SCREEN_7_8_INCH)
#define SCREEN_SIZE_X 158
#define SCREEN_SIZE_Y 119
#define SCREEN_ASPECT SCREEN_ASPECT_4_3
#elif defined(SCREEN_10_3_INCH)
#define SCREEN_SIZE_X 209
#define SCREEN_SIZE_Y 157
#define SCREEN_ASPECT SCREEN_ASPECT_4_3
#elif defined(SCREEN_10_8_INCH)
#define SCREEN_SIZE_X 239
#define SCREEN_SIZE_Y 134
#define SCREEN_ASPECT SCREEN_ASPECT_16_9
#elif defined(SCREEN_13_3_INCH)
#define SCREEN_SIZE_X 270
#define SCREEN_SIZE_Y 203
#define SCREEN_ASPECT SCREEN_ASPECT_4_3
#else
#error "Unknown screen size"
#endif
// Screen timing
#if defined(SCREEN_800_600)
// 800x600 @ 60, 40MHz DMT
#define SCREEN_CLK 40000
#define SCREEN_HACT 800
#define SCREEN_VACT 600
#define SCREEN_HBLK 256
#define SCREEN_HFP 40
#define SCREEN_HSYNC 128
#define SCREEN_VBLK 28
#define SCREEN_VFP 1
#define SCREEN_VSYNC 4
#elif defined(SCREEN_1024_758)
// 1024x758 @ 60, 62.5MHz CVT
#define SCREEN_CLK 62500
#define SCREEN_HACT 1024
#define SCREEN_VACT 758
#define SCREEN_HBLK 304
#define SCREEN_HFP 48
#define SCREEN_HSYNC 104
#define SCREEN_VBLK 29
#define SCREEN_VFP 3
#define SCREEN_VSYNC 10
#elif defined(SCREEN_1448_1072)
// 1448x1072 @ 60, 128.5MHz CVT
#define SCREEN_CLK 128500
#define SCREEN_HACT 1448
#define SCREEN_VACT 1072
#define SCREEN_HBLK 480
#define SCREEN_HFP 88
#define SCREEN_HSYNC 152
#define SCREEN_VBLK 40
#define SCREEN_VFP 3
#define SCREEN_VSYNC 10
#elif defined(SCREEN_1600_1200)
// 1600x1200 @ 60, 162MHz DMT
#define SCREEN_CLK 162000
#define SCREEN_HACT 1600
#define SCREEN_VACT 1200
#define SCREEN_HBLK 560
#define SCREEN_HFP 64
#define SCREEN_HSYNC 192
#define SCREEN_VBLK 50
#define SCREEN_VFP 1
#define SCREEN_VSYNC 3
#elif defined(SCREEN_1872_1404)
// 1872x1404 @ 60, 162MHz Custom
#define SCREEN_CLK 162000
#define SCREEN_HACT 1872
#define SCREEN_VACT 1404
#define SCREEN_HBLK 38
#define SCREEN_HFP 6
#define SCREEN_HSYNC 10
#define SCREEN_VBLK 10
#define SCREEN_VFP 1
#define SCREEN_VSYNC 3
#elif defined(SCREEN_1920_1080)
// 1920x1080 @ 60, 148.5MHz CEA-861/DMT
#define SCREEN_CLK 148500
#define SCREEN_HACT 1920
#define SCREEN_VACT 1080
#define SCREEN_HBLK 280
#define SCREEN_HFP 88
#define SCREEN_HSYNC 44
#define SCREEN_VBLK 45
#define SCREEN_VFP 4
#define SCREEN_VSYNC 5
#elif defined(SCREEN_2200_1650)
// 2200x1650 @ 60, 224MHz Custom
#define SCREEN_CLK 224000
#define SCREEN_HACT 2200
#define SCREEN_VACT 1650
#define SCREEN_HBLK 36
#define SCREEN_HFP 6
#define SCREEN_HSYNC 10
#define SCREEN_VBLK 20
#define SCREEN_VFP 1
#define SCREEN_VSYNC 5
#endif

View file

@ -27,8 +27,7 @@
#include "tcpm_driver.h"
#include "usb_pd.h"
#include "ptn3460.h"
#include "tps65185.h"
#include "max17135.h"
#include "power.h"
#include "fpga.h"
int main()
@ -52,7 +51,8 @@ int main()
gpio_put(10, 0);
gpio_set_dir(10, GPIO_OUT);
tps_init();
power_init();
power_enable(true); // TODO: should be dependent on DP signal valid
fpga_init();
ptn3460_init();

View file

@ -57,6 +57,10 @@ void max_set_vcom(uint16_t vcom) {
max_write(0x03, vcom & 0xff);
}
void max_enable(bool en) {
// TODO
}
void max_init(void) {
//max_set_vcom(100); // -1V
printf("Product Revision: %08x\n", max_read(0x06));

View file

@ -21,4 +21,6 @@
//
#pragma once
void tps_init(void);
void max_init(void);
void max_set_vcom(uint16_t vcom);
void max_enable(bool en);

64
fw/power.c Normal file
View file

@ -0,0 +1,64 @@
//
// Copyright 2023 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "config.h"
#if defined(POWER_GPIO)
#define PWR_EN_GPIO 21
#define PWR_VCOM_GPIO 22
void power_init(void) {
gpio_put(PWR_EN_GPIO, 0);
gpio_init(PWR_EN_GPIO);
gpio_set_dir(PWR_EN_GPIO, GPIO_OUT);
gpio_set_function(PWR_VCOM_GPIO, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(PWR_VCOM_GPIO);
// Set period to 256 cycles
pwm_set_wrap(slice_num, 255);
pwm_set_gpio_level(PWR_VCOM_GPIO, 127);
}
void power_enable(bool en) {
gpio_put(PWR_EN_GPIO, en);
uint slice_num = pwm_gpio_to_slice_num(PWR_VCOM_GPIO);
pwm_set_enabled(slice_num, en);
}
// vcom is in mV
void power_set_vcom(int vcom) {
// Adjustable range:
// 0 = -3.27V
// 255 = -0.70V
int level = vcom / 10 + 324;
uint8_t level_u8;
if (level < 0)
level_u8 = 0;
else if (level > 255)
level_u8 = 255;
else
level_u8 = level;
pwm_set_gpio_level(PWR_VCOM_GPIO, level_u8);
}
#endif

44
fw/power.h Normal file
View file

@ -0,0 +1,44 @@
//
// Copyright 2023 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
#if defined(POWER_TPS65185)
#include "tps65185.h"
#define power_init() tps_init()
#define power_enable(x) tps_enable(x)
#define power_set_vcom(x) tps_set_vcom(x)
#elif defined(POWER_MAX17135)
#include "max17135.h"
#define power_init() max_init()
#define power_enable(x) max_enable(x)
#define power_set_vcom(x) max_set_vcom(x)
#elif defined(POWER_GPIO)
void power_init(void);
void power_enable(bool en);
void power_set_vcom(uint16_t vcom);
#endif

View file

@ -60,6 +60,10 @@ void tps_set_vcom(uint16_t vcom) {
tps_write(0x03, vcom & 0xff);
}
void tps_enable(bool en) {
gpio_put(TPS_EN_PIN, en);
}
void tps_init(void) {
gpio_init(TPS_EN_PIN);
gpio_put(TPS_EN_PIN, 1);

View file

@ -22,3 +22,5 @@
#pragma once
void tps_init(void);
void tps_enable(bool en);
void tps_set_vcom(uint16_t vcom);