Merge pull request #1193 from marbalon/master
New OSD stack with menus etc. and fixed driver with some new functions
This commit is contained in:
commit
4e10893190
|
@ -17,6 +17,9 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "version.h"
|
||||
|
@ -29,30 +32,45 @@
|
|||
#include "drivers/system.h"
|
||||
#include "drivers/nvic.h"
|
||||
#include "drivers/dma.h"
|
||||
#include "drivers/gpio.h"
|
||||
|
||||
#include "max7456.h"
|
||||
#include "max7456_symbols.h"
|
||||
|
||||
#define DISABLE_MAX7456 IOHi(max7456CsPin)
|
||||
//on shared SPI buss we want to change clock for OSD chip and restore for other devices
|
||||
#ifdef MAX7456_SPI_CLK
|
||||
#define ENABLE_MAX7456 {spiSetDivisor(MAX7456_SPI_INSTANCE, MAX7456_SPI_CLK);IOLo(max7456CsPin);}
|
||||
#else
|
||||
#define ENABLE_MAX7456 IOLo(max7456CsPin)
|
||||
#endif
|
||||
|
||||
uint16_t max_screen_size;
|
||||
static MAX7456_CHAR_TYPE max7456_screen[VIDEO_BUFFER_CHARS_PAL + 5];
|
||||
#define SCREEN_BUFFER ((MAX7456_CHAR_TYPE*)&max7456_screen[3])
|
||||
#ifdef MAX7456_RESTORE_CLK
|
||||
#define DISABLE_MAX7456 {IOHi(max7456CsPin);spiSetDivisor(MAX7456_SPI_INSTANCE, MAX7456_RESTORE_CLK);}
|
||||
#else
|
||||
#define DISABLE_MAX7456 IOHi(max7456CsPin)
|
||||
#endif
|
||||
|
||||
uint16_t max_screen_size = VIDEO_BUFFER_CHARS_PAL;
|
||||
// we write everything in SCREEN_BUFFER and then comapre
|
||||
// SCREEN_BUFFER with SHADOW_BUFFER to upgrade only changed chars
|
||||
// this solution is faster then redraw all screen
|
||||
|
||||
static uint8_t SCREEN_BUFFER[VIDEO_BUFFER_CHARS_PAL+40]; //for faster writes we use memcpy so we need some space to don't overwrite buffer
|
||||
static uint8_t SHADOW_BUFFER[VIDEO_BUFFER_CHARS_PAL];
|
||||
|
||||
//max chars to update in one idle
|
||||
#define MAX_CHARS2UPDATE 100
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
volatile uint8_t dma_transaction_in_progress = 0;
|
||||
#endif
|
||||
|
||||
static uint8_t video_signal_type = 0;
|
||||
static uint8_t spi_buff[MAX_CHARS2UPDATE*6];
|
||||
|
||||
static uint8_t video_signal_cfg = 0;
|
||||
static uint8_t video_signal_reg = VIDEO_MODE_PAL | OSD_ENABLE; //PAL by default
|
||||
static uint8_t max7456_lock = 0;
|
||||
static IO_t max7456CsPin = IO_NONE;
|
||||
|
||||
|
||||
MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void) {
|
||||
return SCREEN_BUFFER;
|
||||
}
|
||||
|
||||
static uint8_t max7456_send(uint8_t add, uint8_t data)
|
||||
{
|
||||
spiTransferByte(MAX7456_SPI_INSTANCE, add);
|
||||
|
@ -130,15 +148,21 @@ static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_s
|
|||
}
|
||||
|
||||
void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) {
|
||||
|
||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||
#ifdef MAX7456_DMA_CHANNEL_RX
|
||||
DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE);
|
||||
#else
|
||||
#endif
|
||||
// make sure spi dmd transfer is complete
|
||||
while (SPI_I2S_GetFlagStatus (MAX7456_SPI_INSTANCE, SPI_I2S_FLAG_TXE) == RESET) {};
|
||||
while (SPI_I2S_GetFlagStatus (MAX7456_SPI_INSTANCE, SPI_I2S_FLAG_BSY) == SET) {};
|
||||
|
||||
//Empty RX buffer. RX DMA takes care of it if enabled
|
||||
//this should be done after transmission finish!!!
|
||||
while (SPI_I2S_GetFlagStatus(MAX7456_SPI_INSTANCE, SPI_I2S_FLAG_RXNE) == SET) {
|
||||
MAX7456_SPI_INSTANCE->DR;
|
||||
}
|
||||
#endif
|
||||
|
||||
DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE);
|
||||
|
||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
||||
|
@ -150,53 +174,56 @@ void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) {
|
|||
SPI_I2S_DMAReq_Tx, DISABLE);
|
||||
|
||||
DISABLE_MAX7456;
|
||||
for (uint16_t x = 0; x < max_screen_size; x++)
|
||||
max7456_screen[x + 3] = MAX7456_CHAR(' ');
|
||||
dma_transaction_in_progress = 0;
|
||||
}
|
||||
|
||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_HTIF)) {
|
||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_HTIF);
|
||||
}
|
||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TEIF)) {
|
||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TEIF);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void max7456_init(uint8_t video_system)
|
||||
uint8_t max7456_get_rows_count(void)
|
||||
{
|
||||
if (video_signal_reg & VIDEO_MODE_PAL)
|
||||
return VIDEO_LINES_PAL;
|
||||
|
||||
return VIDEO_LINES_NTSC;
|
||||
}
|
||||
|
||||
//because MAX7456 need some time to detect video system etc. we need to wait for a while to initialize it at startup
|
||||
//and in case of restart we need to reinitialize chip
|
||||
void max7456_init2(void)
|
||||
{
|
||||
uint8_t max_screen_rows;
|
||||
uint8_t srdata = 0;
|
||||
uint16_t x;
|
||||
static uint8_t first_init = 1;
|
||||
|
||||
#ifdef MAX7456_SPI_CS_PIN
|
||||
max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN));
|
||||
#endif
|
||||
IOInit(max7456CsPin, OWNER_OSD, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
|
||||
//do not init MAX before camera power up correctly
|
||||
if (millis() < 1500)
|
||||
return;
|
||||
|
||||
//Minimum spi clock period for max7456 is 100ns (10Mhz)
|
||||
spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD);
|
||||
|
||||
delay(1000);
|
||||
// force soft reset on Max7456
|
||||
ENABLE_MAX7456;
|
||||
max7456_send(VM0_REG, MAX7456_RESET);
|
||||
delay(100);
|
||||
|
||||
srdata = max7456_send(0xA0, 0xFF);
|
||||
if ((0x01 & srdata) == 0x01) { //PAL
|
||||
video_signal_type = VIDEO_MODE_PAL;
|
||||
}
|
||||
else if ((0x02 & srdata) == 0x02) { //NTSC
|
||||
video_signal_type = VIDEO_MODE_NTSC;
|
||||
}
|
||||
|
||||
// Override detected type: 0-AUTO, 1-PAL, 2-NTSC
|
||||
switch(video_system) {
|
||||
switch(video_signal_cfg) {
|
||||
case PAL:
|
||||
video_signal_type = VIDEO_MODE_PAL;
|
||||
video_signal_reg = VIDEO_MODE_PAL | OSD_ENABLE;
|
||||
break;
|
||||
case NTSC:
|
||||
video_signal_type = VIDEO_MODE_NTSC;
|
||||
video_signal_reg = VIDEO_MODE_NTSC | OSD_ENABLE;
|
||||
break;
|
||||
default:
|
||||
srdata = max7456_send(MAX7456ADD_STAT, 0x00);
|
||||
if ((0x02 & srdata) == 0x02)
|
||||
video_signal_reg = VIDEO_MODE_NTSC | OSD_ENABLE;
|
||||
}
|
||||
|
||||
if (video_signal_type) { //PAL
|
||||
if (video_signal_reg & VIDEO_MODE_PAL) { //PAL
|
||||
max_screen_size = VIDEO_BUFFER_CHARS_PAL;
|
||||
max_screen_rows = VIDEO_LINES_PAL;
|
||||
} else { // NTSC
|
||||
|
@ -210,60 +237,151 @@ void max7456_init(uint8_t video_system)
|
|||
}
|
||||
|
||||
// make sure the Max7456 is enabled
|
||||
max7456_send(VM0_REG, OSD_ENABLE | video_signal_type);
|
||||
|
||||
max7456_send(VM0_REG, video_signal_reg);
|
||||
max7456_send(DMM_REG, CLEAR_DISPLAY);
|
||||
DISABLE_MAX7456;
|
||||
delay(100);
|
||||
|
||||
for (x = 0; x < max_screen_size; x++)
|
||||
SCREEN_BUFFER[x] = MAX7456_CHAR(' ');
|
||||
//clear shadow to force redraw all screen in non-dma mode
|
||||
memset(SHADOW_BUFFER, 0, max_screen_size);
|
||||
if (first_init)
|
||||
{
|
||||
max7456_refresh_all();
|
||||
first_init = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//here we init only CS and try to init MAX for first time
|
||||
void max7456_init(uint8_t video_system)
|
||||
{
|
||||
#ifdef MAX7456_SPI_CS_PIN
|
||||
max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN));
|
||||
#endif
|
||||
IOInit(max7456CsPin, OWNER_OSD, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD);
|
||||
// force soft reset on Max7456
|
||||
ENABLE_MAX7456;
|
||||
max7456_send(VM0_REG, MAX7456_RESET);
|
||||
DISABLE_MAX7456;
|
||||
video_signal_cfg = video_system;
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8));
|
||||
max7456_screen[1] = (uint16_t)(MAX7456ADD_DMAL | (0 << 8));
|
||||
max7456_screen[2] = (uint16_t)(MAX7456ADD_DMM | (1 << 8));
|
||||
max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8));
|
||||
max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8));
|
||||
|
||||
dmaSetHandler(MAX7456_DMA_IRQ_HANDLER_ID, max7456_dma_irq_handler, NVIC_PRIO_MAX7456_DMA, 0);
|
||||
#endif
|
||||
//real init will be made letter when driver idle detect
|
||||
}
|
||||
|
||||
// Copy string from ram into screen buffer
|
||||
void max7456_write_string(const char *string, int16_t address) {
|
||||
MAX7456_CHAR_TYPE *dest;
|
||||
|
||||
if (address >= 0)
|
||||
dest = SCREEN_BUFFER + address;
|
||||
else
|
||||
dest = SCREEN_BUFFER + (max_screen_size + address);
|
||||
|
||||
while(*string && dest < (SCREEN_BUFFER + max_screen_size)) {
|
||||
*dest++ = MAX7456_CHAR(*string++);
|
||||
//just fill with spaces with some tricks
|
||||
void max7456_clear_screen(void)
|
||||
{
|
||||
uint16_t x;
|
||||
uint32_t *p = (uint32_t*)&SCREEN_BUFFER[0];
|
||||
for (x = 0; x < VIDEO_BUFFER_CHARS_PAL/4; x++)
|
||||
p[x] = 0x20202020;
|
||||
}
|
||||
|
||||
uint8_t* max7456_get_screen_buffer(void) {
|
||||
return SCREEN_BUFFER;
|
||||
}
|
||||
|
||||
void max7456_write_char(uint8_t x, uint8_t y, uint8_t c)
|
||||
{
|
||||
SCREEN_BUFFER[y*30+x] = c;
|
||||
}
|
||||
|
||||
void max7456_write(uint8_t x, uint8_t y, char *buff)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
for (i = 0; *(buff+i); i++)
|
||||
if (x+i < 30) //do not write over screen
|
||||
SCREEN_BUFFER[y*30+x+i] = *(buff+i);
|
||||
}
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
uint8_t max7456_dma_in_progres(void)
|
||||
{
|
||||
return dma_transaction_in_progress;
|
||||
}
|
||||
#endif
|
||||
|
||||
void max7456_draw_screen(void) {
|
||||
uint8_t check;
|
||||
static uint16_t pos = 0;
|
||||
int k = 0, buff_len=0;
|
||||
|
||||
if (!max7456_lock) {
|
||||
//-----------------detect MAX7456 fail, or initialize it at startup when it is ready--------
|
||||
max7456_lock = 1;
|
||||
ENABLE_MAX7456;
|
||||
check = max7456_send(VM0_REG | 0x80, 0x00);
|
||||
DISABLE_MAX7456;
|
||||
|
||||
if ( check != video_signal_reg )
|
||||
max7456_init2();
|
||||
|
||||
//------------ end of (re)init-------------------------------------
|
||||
|
||||
for (k=0; k< MAX_CHARS2UPDATE; k++)
|
||||
{
|
||||
if (SCREEN_BUFFER[pos] != SHADOW_BUFFER[pos])
|
||||
{
|
||||
spi_buff[buff_len++] = MAX7456ADD_DMAH;
|
||||
spi_buff[buff_len++] = pos >> 8;
|
||||
spi_buff[buff_len++] = MAX7456ADD_DMAL;
|
||||
spi_buff[buff_len++] = pos & 0xff;
|
||||
spi_buff[buff_len++] = MAX7456ADD_DMDI;
|
||||
spi_buff[buff_len++] = SCREEN_BUFFER[pos];
|
||||
SHADOW_BUFFER[pos] = SCREEN_BUFFER[pos];
|
||||
k++;
|
||||
}
|
||||
|
||||
if (++pos >= max_screen_size) {
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (buff_len) {
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
if (buff_len > 0)
|
||||
max7456_send_dma(spi_buff, NULL, buff_len);
|
||||
#else
|
||||
ENABLE_MAX7456;
|
||||
for (k=0; k < buff_len; k++)
|
||||
spiTransferByte(MAX7456_SPI_INSTANCE, spi_buff[k]);
|
||||
DISABLE_MAX7456;
|
||||
#endif // MAX7456_DMA_CHANNEL_TX
|
||||
}
|
||||
max7456_lock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// this funcktion refresh all and should not be used when copter is armed
|
||||
void max7456_refresh_all(void)
|
||||
{
|
||||
if (!max7456_lock) {
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
max7456_send_dma(max7456_screen, NULL, max_screen_size * 2 + 10);
|
||||
#else
|
||||
while (dma_transaction_in_progress);
|
||||
#endif
|
||||
uint16_t xx;
|
||||
max7456_lock = 1;
|
||||
|
||||
ENABLE_MAX7456;
|
||||
max7456_send(MAX7456ADD_DMAH, 0);
|
||||
max7456_send(MAX7456ADD_DMAL, 0);
|
||||
max7456_send(MAX7456ADD_DMM, 1);
|
||||
for (xx = 0; xx < max_screen_size; ++xx) {
|
||||
|
||||
for (xx = 0; xx < max_screen_size; ++xx)
|
||||
{
|
||||
max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]);
|
||||
SCREEN_BUFFER[xx] = MAX7456_CHAR(' ');
|
||||
SHADOW_BUFFER[xx] = SCREEN_BUFFER[xx];
|
||||
}
|
||||
|
||||
max7456_send(MAX7456ADD_DMDI, 0xFF);
|
||||
max7456_send(MAX7456ADD_DMM, 0);
|
||||
DISABLE_MAX7456;
|
||||
max7456_lock = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,10 +393,10 @@ void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) {
|
|||
#endif
|
||||
while (max7456_lock);
|
||||
max7456_lock = 1;
|
||||
ENABLE_MAX7456;
|
||||
|
||||
ENABLE_MAX7456;
|
||||
// disable display
|
||||
max7456_send(VM0_REG, video_signal_type);
|
||||
max7456_send(VM0_REG, 0);
|
||||
|
||||
max7456_send(MAX7456ADD_CMAH, char_address); // set start address high
|
||||
|
||||
|
@ -296,10 +414,10 @@ void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) {
|
|||
max7456_send(MAX7456ADD_CMM, WRITE_NVR);
|
||||
|
||||
// wait until bit 5 in the status register returns to 0 (12ms)
|
||||
while ((max7456_send(MAX7456ADD_STAT, 0) & STATUS_REG_NVR_BUSY) != 0x00);
|
||||
while ((max7456_send(MAX7456ADD_STAT, 0x00) & STATUS_REG_NVR_BUSY) != 0x00);
|
||||
|
||||
max7456_send(VM0_REG, video_signal_type | 0x0C);
|
||||
DISABLE_MAX7456;
|
||||
|
||||
max7456_lock = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,17 +144,17 @@ enum VIDEO_TYPES { AUTO = 0, PAL, NTSC };
|
|||
|
||||
extern uint16_t max_screen_size;
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
#define MAX7456_CHAR_TYPE uint16_t
|
||||
#define MAX7456_CHAR(X) (MAX7456ADD_DMDI | ((X) << 8))
|
||||
#else
|
||||
#define MAX7456_CHAR_TYPE char
|
||||
#define MAX7456_CHAR(X) (X)
|
||||
#endif
|
||||
|
||||
void max7456_init(uint8_t system);
|
||||
void max7456_draw_screen(void);
|
||||
void max7456_write_string(const char *string, int16_t address);
|
||||
void max7456_write_nvm(uint8_t char_address, uint8_t *font_data);
|
||||
MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void);
|
||||
uint8_t max7456_get_rows_count(void);
|
||||
void max7456_write(uint8_t x, uint8_t y, char *buff);
|
||||
void max7456_write_char(uint8_t x, uint8_t y, uint8_t c);
|
||||
void max7456_clear_screen(void);
|
||||
void max7456_refresh_all(void);
|
||||
uint8_t* max7456_get_screen_buffer(void);
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
uint8_t max7456_dma_in_progres(void);
|
||||
#endif // MAX7456_DMA_CHANNEL_TX
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,58 +1,22 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define MAX_MENU_ROWS 8
|
||||
#define MAX_MENU_COLS 3
|
||||
|
||||
typedef struct {
|
||||
const char* title;
|
||||
uint8_t x_pos;
|
||||
} osd_col_t;
|
||||
|
||||
typedef struct {
|
||||
const char* title;
|
||||
void (*update)(int value_change_direction, uint8_t col);
|
||||
void (*print)(uint16_t pos, uint8_t col);
|
||||
} osd_row_t;
|
||||
|
||||
typedef struct {
|
||||
const char* title;
|
||||
uint8_t cols_number;
|
||||
uint8_t rows_number;
|
||||
osd_col_t cols[MAX_MENU_COLS];
|
||||
osd_row_t rows[MAX_MENU_ROWS];
|
||||
} osd_page_t;
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
OSD_MAIN_BATT_VOLTAGE,
|
||||
OSD_RSSI_VALUE,
|
||||
OSD_TIMER,
|
||||
OSD_THROTTLE_POS,
|
||||
OSD_CPU_LOAD,
|
||||
OSD_VTX_CHANNEL,
|
||||
OSD_VOLTAGE_WARNING,
|
||||
OSD_ARMED,
|
||||
OSD_DISARMED,
|
||||
OSD_MAIN_BATT_VOLTAGE,
|
||||
OSD_ARTIFICIAL_HORIZON,
|
||||
OSD_HORIZON_SIDEBARS,
|
||||
OSD_ONTIME,
|
||||
OSD_FLYTIME,
|
||||
OSD_FLYMODE,
|
||||
OSD_CRAFT_NAME,
|
||||
OSD_THROTTLE_POS,
|
||||
OSD_VTX_CHANNEL,
|
||||
OSD_CURRENT_DRAW,
|
||||
OSD_MAH_DRAWN,
|
||||
OSD_CRAFT_NAME,
|
||||
OSD_GPS_SPEED,
|
||||
OSD_GPS_SATS,
|
||||
OSD_ALTITUDE,
|
||||
OSD_MAX_ITEMS, // MUST BE LAST
|
||||
} osd_items_t;
|
||||
|
@ -63,12 +27,29 @@ typedef enum {
|
|||
} osd_unit_t;
|
||||
|
||||
typedef struct {
|
||||
// AUTO / PAL / NTSC in VIDEO_TYPES enum
|
||||
uint16_t item_pos[OSD_MAX_ITEMS];
|
||||
//alarms
|
||||
uint8_t rssi_alarm;
|
||||
uint16_t cap_alarm;
|
||||
uint16_t time_alarm;
|
||||
uint16_t alt_alarm;
|
||||
|
||||
uint8_t video_system;
|
||||
osd_unit_t units;
|
||||
int16_t item_pos[OSD_MAX_ITEMS];
|
||||
} osd_profile;
|
||||
|
||||
void updateOsd(void);
|
||||
typedef struct {
|
||||
int16_t max_speed;
|
||||
int16_t min_voltage; // /10
|
||||
int16_t max_current; // /10
|
||||
int16_t min_rssi;
|
||||
} tStatistic;
|
||||
|
||||
void osdInit(void);
|
||||
void OSD_Update(uint8_t guiKey);
|
||||
void OSD_OpenMenu(void);
|
||||
void OSD_HandleGui(uint8_t cmd);
|
||||
void OSD_ResetSettings(void);
|
||||
void OSD_Message(char *line1, char *line2, uint8_t timeout);
|
||||
void resetOsdConfig(osd_profile *osdProfile);
|
||||
void updateOsd(void);
|
||||
|
|
|
@ -913,24 +913,29 @@ const clivalue_t valueTable[] = {
|
|||
{ "vtx_channel", VAR_UINT8 | MASTER_VALUE, &masterConfig.vtx_channel, .config.minmax = { 0, 39 } },
|
||||
{ "vtx_power", VAR_UINT8 | MASTER_VALUE, &masterConfig.vtx_power, .config.minmax = { 0, 1 } },
|
||||
#endif
|
||||
|
||||
#ifdef OSD
|
||||
{ "osd_video_system", VAR_UINT8 | MASTER_VALUE, &masterConfig.osdProfile.video_system, .config.minmax = { 0, 2 } },
|
||||
{ "osd_units", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.osdProfile.units, .config.lookup = { TABLE_UNIT } },
|
||||
{ "osd_main_voltage_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE], .config.minmax = { -480, 480 } },
|
||||
{ "osd_rssi_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE], .config.minmax = { -480, 480 } },
|
||||
{ "osd_timer_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_TIMER], .config.minmax = { -480, 480 } },
|
||||
{ "osd_throttle_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS], .config.minmax = { -480, 480 } },
|
||||
{ "osd_cpu_load_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_CPU_LOAD], .config.minmax = { -480, 480 } },
|
||||
{ "osd_vtx_channel_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_VTX_CHANNEL], .config.minmax = { -480, 480 } },
|
||||
{ "osd_voltage_warning_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING], .config.minmax = { -480, 480 } },
|
||||
{ "osd_armed_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ARMED], .config.minmax = { -480, 480 } },
|
||||
{ "osd_disarmed_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_DISARMED], .config.minmax = { -480, 480 } },
|
||||
{ "osd_artificial_horizon", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ARTIFICIAL_HORIZON], .config.minmax = { -1, 0 } },
|
||||
{ "osd_horizon_sidebars", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_HORIZON_SIDEBARS], .config.minmax = { -1, 0 } },
|
||||
{ "osd_current_draw_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_CURRENT_DRAW], .config.minmax = { -480, 480 } },
|
||||
{ "osd_mah_drawn_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_MAH_DRAWN], .config.minmax = { -480, 480 } },
|
||||
{ "osd_craft_name_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_CRAFT_NAME], .config.minmax = { -480, 480 } },
|
||||
{ "osd_altitude_pos", VAR_INT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ALTITUDE], .config.minmax = { -480, 480 } },
|
||||
{ "osd_rssi_alarm", VAR_UINT8 | MASTER_VALUE, &masterConfig.osdProfile.rssi_alarm, .config.minmax = { 0, 100 } },
|
||||
{ "osd_cap_alarm", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.cap_alarm, .config.minmax = { 0, 20000 } },
|
||||
{ "osd_time_alarm", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.time_alarm, .config.minmax = { 0, 60 } },
|
||||
{ "osd_alt_alarm", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.alt_alarm, .config.minmax = { 0, 10000 } },
|
||||
|
||||
{ "osd_main_voltage_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_rssi_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_flytimer_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_FLYTIME], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_ontime_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ONTIME], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_flymode_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_FLYMODE], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_throttle_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_vtx_channel_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_VTX_CHANNEL], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_artificial_horizon", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ARTIFICIAL_HORIZON], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_current_draw_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_CURRENT_DRAW], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_mah_drawn_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_MAH_DRAWN], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_craft_name_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_CRAFT_NAME], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_gps_speed_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_GPS_SPEED], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_gps_sats_pos", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_GPS_SATS], .config.minmax = { 0, 65536 } },
|
||||
{ "osd_altitude", VAR_UINT16 | MASTER_VALUE, &masterConfig.osdProfile.item_pos[OSD_ALTITUDE], .config.minmax = { 0, 65536 } },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1197,11 +1197,16 @@ static bool processOutCommand(uint8_t cmdMSP)
|
|||
|
||||
case MSP_OSD_CONFIG:
|
||||
#ifdef OSD
|
||||
headSerialReply(3 + (OSD_MAX_ITEMS * 2));
|
||||
headSerialReply(8 + (OSD_MAX_ITEMS * 2));
|
||||
serialize8(1); // OSD supported
|
||||
// send video system (AUTO/PAL/NTSC)
|
||||
serialize8(masterConfig.osdProfile.video_system);
|
||||
serialize8(masterConfig.osdProfile.units);
|
||||
serialize8(masterConfig.osdProfile.rssi_alarm);
|
||||
serialize16(masterConfig.osdProfile.cap_alarm);
|
||||
serialize16(masterConfig.osdProfile.time_alarm);
|
||||
serialize16(masterConfig.osdProfile.alt_alarm);
|
||||
|
||||
for (i = 0; i < OSD_MAX_ITEMS; i++) {
|
||||
serialize16(masterConfig.osdProfile.item_pos[i]);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/bus_spi.h"
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/io.h"
|
||||
#include "drivers/gpio.h"
|
||||
#include "drivers/exti.h"
|
||||
#include "drivers/accgyro.h"
|
||||
#include "drivers/accgyro_mpu.h"
|
||||
#include "drivers/accgyro_mpu6500.h"
|
||||
|
||||
#include "hardware_revision.h"
|
||||
|
||||
uint8_t hardwareRevision = 1;
|
||||
|
||||
void detectHardwareRevision(void)
|
||||
{
|
||||
gpio_config_t gpio;
|
||||
|
||||
// GYRO CS as output
|
||||
gpio.pin = GPIO_Pin_5;
|
||||
gpio.mode = Mode_Out_PP;
|
||||
gpio.speed = Speed_2MHz;
|
||||
gpioInit(GPIOB, &gpio);
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_5);
|
||||
|
||||
gpio.pin = GPIO_Pin_7;
|
||||
gpio.mode = Mode_Out_PP;
|
||||
gpio.speed = Speed_2MHz;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
GPIO_SetBits(GPIOA, GPIO_Pin_7);
|
||||
|
||||
gpio.pin = GPIO_Pin_12;
|
||||
gpio.mode = Mode_Out_PP;
|
||||
gpio.speed = Speed_2MHz;
|
||||
gpioInit(GPIOB, &gpio);
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_12);
|
||||
}
|
||||
|
||||
|
||||
void updateHardwareRevision(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "drivers/exti.h"
|
||||
|
||||
extern uint8_t hardwareRevision;
|
||||
|
||||
void updateHardwareRevision(void);
|
||||
void detectHardwareRevision(void);
|
|
@ -18,6 +18,7 @@
|
|||
#pragma once
|
||||
|
||||
#define TARGET_BOARD_IDENTIFIER "RBFC"
|
||||
#define USE_HARDWARE_REVISION_DETECTION
|
||||
#define TARGET_CONFIG
|
||||
|
||||
#define LED0 PB3
|
||||
|
@ -76,6 +77,9 @@
|
|||
#define USE_MAX7456
|
||||
#define MAX7456_SPI_INSTANCE SPI2
|
||||
#define MAX7456_SPI_CS_PIN PA7
|
||||
#define MAX7456_SPI_CLK (SPI_CLOCK_STANDARD*2)
|
||||
#define MAX7456_RESTORE_CLK (SPI_CLOCK_FAST)
|
||||
|
||||
|
||||
#define M25P16_CS_PIN PB12
|
||||
#define M25P16_SPI_INSTANCE SPI2
|
||||
|
|
Loading…
Reference in New Issue