Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
Show changes
Showing with 93362 additions and 301 deletions
#include "gpio.h" #include "gpio.h"
#include "portexpander.h"
#include "max32665.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <stdio.h>
#define NUM_LEDS 15 #define NUM_LEDS 15
#define DEFAULT_DIM_TOP 1
static const gpio_cfg_t rgb_dat_pin = {PORT_1, PIN_14, GPIO_FUNC_OUT, GPIO_PAD_NONE}; #define DEFAULT_DIM_BOTTOM 8
static const gpio_cfg_t rgb_clk_pin = {PORT_1, PIN_15, GPIO_FUNC_OUT, GPIO_PAD_NONE}; #define MAX_DIM 8
static uint8_t leds[NUM_LEDS][4];
static const gpio_cfg_t rgb_dat_pin = {
PORT_1, PIN_14, GPIO_FUNC_OUT, GPIO_PAD_NONE
};
static const gpio_cfg_t rgb_clk_pin = {
PORT_1, PIN_15, GPIO_FUNC_OUT, GPIO_PAD_NONE
};
static uint8_t leds[NUM_LEDS][3];
static uint8_t gamma_table[3][256];
static uint8_t active_groups;
static uint8_t bottom_dim; //index 11-14
static uint8_t top_dim; //index 0-10
static bool powersave;
static long powerup_wait_cycles = 500;
/***** Functions *****/ /***** Functions *****/
// ***************************************************************************** // *****************************************************************************
...@@ -70,7 +85,6 @@ static hsv rgb2hsv(rgb in) ...@@ -70,7 +85,6 @@ static hsv rgb2hsv(rgb in)
} }
#endif #endif
static rgb hsv2rgb(hsv in) static rgb hsv2rgb(hsv in)
{ {
float hh, p, q, t, ff; float hh, p, q, t, ff;
...@@ -84,7 +98,8 @@ static rgb hsv2rgb(hsv in) ...@@ -84,7 +98,8 @@ static rgb hsv2rgb(hsv in)
return out; return out;
} }
hh = in.h; hh = in.h;
if(hh >= 360.0) hh = 0.0; if (hh >= 360.0)
hh = 0.0;
hh /= 60.0; hh /= 60.0;
i = (long)hh; i = (long)hh;
ff = hh - i; ff = hh - i;
...@@ -147,32 +162,74 @@ static void shift(uint8_t data) ...@@ -147,32 +162,74 @@ static void shift(uint8_t data)
static void leds_start(void) static void leds_start(void)
{ {
shift(0x00); shift(0x00); shift(0x00); shift(0x00); shift(0x00);
shift(0x00);
shift(0x00);
shift(0x00);
} }
static void leds_shift(uint8_t r, uint8_t g, uint8_t b, uint8_t dim) static void leds_shift(uint8_t r, uint8_t g, uint8_t b, uint8_t dim)
{ {
shift(0xE0 | (dim & 0x1F)); shift(b); shift(g); shift(r); shift(0xE0 | (dim & 0x1F));
shift(b);
shift(g);
shift(r);
} }
static void leds_stop(void) static void leds_stop(void)
{ {
shift(0xFF); shift(0xFF); shift(0xFF); shift(0xFF); shift(0xFF);
shift(0xFF);
shift(0xFF);
shift(0xFF);
}
static uint8_t led_to_dim_value(uint8_t led)
{
return (led < 11) ? top_dim : bottom_dim;
}
void leds_set_dim_top(uint8_t value)
{
top_dim = (value > MAX_DIM) ? MAX_DIM : value;
} }
void leds_set_dim(uint8_t led, uint8_t dim) void leds_set_dim_bottom(uint8_t value)
{ {
leds[led][3] = dim; bottom_dim = (value > MAX_DIM) ? MAX_DIM : value;
} }
void leds_set(uint8_t led, uint8_t r, uint8_t g, uint8_t b) void leds_prep(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{ {
leds[led][0] = r; leds[led][0] = r;
leds[led][1] = g; leds[led][1] = g;
leds[led][2] = b; leds[led][2] = b;
} }
void leds_set_hsv(uint8_t led, float h, float s, float v) void leds_get_rgb(uint8_t led, uint8_t *rgb)
{
rgb[0] = leds[led][0];
rgb[1] = leds[led][1];
rgb[2] = leds[led][2];
}
#if 0
//don't use, is buggy
void leds_set_autodim(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
if(led==NUM_LEDS){
leds_set(led,r,g,b);
return;
}
leds[led][3] = max(r,max(g,b));
float gain = (float)255/leds[led][3]; //might cause rounding->overflow errors might debug later idk~
leds[led][0] = (uint8_t)(r*gain);
leds[led][1] = (uint8_t)(g*gain);
leds[led][2] = (uint8_t)(b*gain);
}
#endif
void leds_prep_hsv(uint8_t led, float h, float s, float v)
{ {
hsv in = { h, s, v }; hsv in = { h, s, v };
rgb out = hsv2rgb(in); rgb out = hsv2rgb(in);
...@@ -181,15 +238,118 @@ void leds_set_hsv(uint8_t led, float h, float s, float v) ...@@ -181,15 +238,118 @@ void leds_set_hsv(uint8_t led, float h, float s, float v)
leds[led][2] = out.b * 255; leds[led][2] = out.b * 255;
} }
static bool is_led_on(uint8_t led) // scheduled to be on after next update
{
if (!led_to_dim_value(led)) {
return false;
}
for (int i = 0; i < 3; i++) {
if (leds[led][i] != 0) {
return true;
}
}
return false;
}
static uint8_t led_to_group(uint8_t led)
{
if (led == 14) {
return 1;
} else if (led >= 11) {
return 2;
}
return 3;
}
static uint8_t
check_privilege(void) //returns number of hierarchical groups with power
{
for (int i = 0; i < NUM_LEDS; i++) {
if (is_led_on(i)) {
return led_to_group(i);
}
}
return 0;
}
static uint8_t power_pin_conversion(uint8_t group)
{
if (group == 2) {
return 1;
}
if (group == 1) {
return 2;
}
return 0;
}
static void power_all(void)
{
portexpander_out_clr(PIN_0 | PIN_1 | PIN_2);
}
void leds_update_power(void)
{
if (!powersave) {
return;
}
uint8_t new_groups =
check_privilege(); //there must be a prettier way to do this but meh
if (new_groups == active_groups) {
return;
}
uint8_t out_val = 0;
for (int i = new_groups; i < 3; ++i) {
out_val |= (1 << power_pin_conversion(i));
}
portexpander_out_put(PIN_0 | PIN_1 | PIN_2, out_val);
if (active_groups < new_groups) {
for (int i = 0; i < powerup_wait_cycles; i++) {
__NOP();
}
}
active_groups = new_groups;
}
void leds_powersave(bool eco)
{
powersave = eco;
if (!powersave) {
power_all();
} else {
leds_update_power();
}
}
void leds_update(void) void leds_update(void)
{ {
leds_start(); leds_start();
for (int i = NUM_LEDS - 1; i >= 0; i--) { for (int i = NUM_LEDS - 1; i >= 0; i--) {
leds_shift(leds[i][0], leds[i][1], leds[i][2], leds[i][3]); leds_shift(
gamma_table[0][leds[i][0]],
gamma_table[1][leds[i][1]],
gamma_table[2][leds[i][2]],
led_to_dim_value(i)
);
} }
leds_stop(); leds_stop();
} }
void leds_flashlight(bool power)
{
portexpander_out_put(PIN_7, (power) ? 0 : 0xFF);
}
void leds_set_gamma_table(uint8_t rgb_channel, uint8_t table[256])
{
for (int i = 0; i < 256; i++) {
gamma_table[rgb_channel][i] = table[i];
}
}
void leds_init(void) void leds_init(void)
{ {
GPIO_Config(&rgb_clk_pin); GPIO_Config(&rgb_clk_pin);
...@@ -200,11 +360,19 @@ void leds_init(void) ...@@ -200,11 +360,19 @@ void leds_init(void)
memset(leds, 0, sizeof(leds)); memset(leds, 0, sizeof(leds));
powersave = TRUE;
top_dim = DEFAULT_DIM_TOP;
bottom_dim = DEFAULT_DIM_BOTTOM;
for (int i = 0; i < NUM_LEDS; i++) { for (int i = 0; i < NUM_LEDS; i++) {
leds[i][3] = 8; for (int j = 0; j < 3; j++) {
leds[i][j] = 0;
}
}
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 3; j++) {
int k = (i * (1 + i) + 255) >> 8;
gamma_table[j][i] = (k * (k + 1) + 255) >> 8;
}
} }
leds_update(); leds_update();
} }
#ifndef LED_H #ifndef LED_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
void leds_set_dim(uint8_t led, uint8_t dim); void leds_set_dim_top(uint8_t value);
void leds_set(uint8_t led, uint8_t r, uint8_t g, uint8_t b); void leds_set_dim_bottom(uint8_t value);
void leds_set_hsv(uint8_t led, float h, float s, float v); void leds_prep(uint8_t led, uint8_t r, uint8_t g, uint8_t b);
void leds_get_rgb(uint8_t led, uint8_t * rgb);
void leds_prep_hsv(uint8_t led, float h, float s, float v);
void leds_update_power(void);
void leds_update(void); void leds_update(void);
void leds_init(void); void leds_init(void);
void leds_powersave(bool eco);
void leds_flashlight(bool power);
void leds_set_gamma_table(uint8_t rgb_channel, uint8_t table[256]);
#endif #endif
...@@ -8,7 +8,8 @@ sources = files( ...@@ -8,7 +8,8 @@ sources = files(
'leds.c', 'leds.c',
'pmic.c', 'pmic.c',
'portexpander.c', 'portexpander.c',
'pb.c' 'pb.c',
'display.c'
) )
deps = [ deps = [
......
...@@ -34,11 +34,15 @@ ...@@ -34,11 +34,15 @@
* *
******************************************************************************/ ******************************************************************************/
#include <stddef.h>
#include "mxc_config.h" #include "mxc_config.h"
#include "mxc_assert.h" #include "mxc_assert.h"
#include "pb.h" #include "pb.h"
#include "portexpander.h" #include "portexpander.h"
#include "MAX77650-Arduino-Library.h"
#include <stddef.h>
static const uint8_t expander_pins[] = { 5, 0x0, 3, 6 };
static pb_callback pb_callbacks[4] = { NULL };
/******************************************************************************/ /******************************************************************************/
int PB_Init(void) int PB_Init(void)
...@@ -59,24 +63,71 @@ int PB_Init(void) ...@@ -59,24 +63,71 @@ int PB_Init(void)
return retval; return retval;
} }
static void pe_pb_callback(gpio_int_pol_t edge_type, void *cbdata)
{
unsigned int pb = (unsigned int)cbdata;
if (pb_callbacks[pb - 1]) {
pb_callbacks[pb - 1](pb, edge_type == GPIO_INT_FALLING);
}
}
static void gpio_pb_callback(void *cbdata)
{
unsigned int pb = (unsigned int)cbdata;
if (pb_callbacks[pb - 1]) {
int level = GPIO_InGet(&pb_pin[pb - 1]);
pb_callbacks[pb - 1](pb, !level);
}
}
/******************************************************************************/ /******************************************************************************/
int PB_RegisterCallback(unsigned int pb, pb_callback callback) int PB_RegisterCallback(unsigned int pb, pb_callback callback)
{ {
MXC_ASSERT(pb < num_pbs); MXC_ASSERT((pb > 0) && (pb <= num_pbs));
if (pb == 2) {
return E_INVALID;
}
pb_callbacks[pb - 1] = callback;
uint8_t mask = (1 << expander_pins[pb - 1]);
// TODO: portexpander support
if (callback) { if (callback) {
if (portexpander_detected()) {
// Register callback // Register callback
GPIO_RegisterCallback(&pb_pin[pb], callback, (void*)pb); portexpander_register_callback(
mask, pe_pb_callback, (void *)pb
);
// Configure and enable interrupt // Configure and enable interrupt
GPIO_IntConfig(&pb_pin[pb], GPIO_INT_EDGE, GPIO_INT_FALLING); portexpander_int_config(mask, GPIO_INT_BOTH);
GPIO_IntEnable(&pb_pin[pb]); portexpander_int_enable(mask);
NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(pb_pin[pb].port));
} else { } else {
// Register callback
GPIO_RegisterCallback(
&pb_pin[pb - 1], gpio_pb_callback, (void *)pb
);
// Configure and enable interrupt
GPIO_IntConfig(
&pb_pin[pb - 1], GPIO_INT_EDGE, GPIO_INT_BOTH
);
GPIO_IntEnable(&pb_pin[pb - 1]);
NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(
pb_pin[pb - 1].port)
);
}
} else {
if (portexpander_detected()) {
// Disable interrupt and clear callback // Disable interrupt and clear callback
GPIO_IntDisable(&pb_pin[pb]); portexpander_int_disable(mask);
GPIO_RegisterCallback(&pb_pin[pb], NULL, NULL); portexpander_register_callback(mask, NULL, NULL);
} else {
// Disable interrupt and clear callback
GPIO_IntDisable(&pb_pin[pb - 1]);
GPIO_RegisterCallback(&pb_pin[pb - 1], NULL, NULL);
}
} }
return E_NO_ERROR; return E_NO_ERROR;
...@@ -85,45 +136,66 @@ int PB_RegisterCallback(unsigned int pb, pb_callback callback) ...@@ -85,45 +136,66 @@ int PB_RegisterCallback(unsigned int pb, pb_callback callback)
//****************************************************************************** //******************************************************************************
void PB_IntEnable(unsigned int pb) void PB_IntEnable(unsigned int pb)
{ {
// TODO: portexpander support MXC_ASSERT((pb > 0) && (pb <= num_pbs));
MXC_ASSERT(pb < num_pbs); if (pb == 2) {
GPIO_IntEnable(&pb_pin[pb]); return;
}
if (portexpander_detected()) {
portexpander_int_enable((1 << expander_pins[pb - 1]));
} else {
GPIO_IntEnable(&pb_pin[pb - 1]);
}
} }
//****************************************************************************** //******************************************************************************
void PB_IntDisable(unsigned int pb) void PB_IntDisable(unsigned int pb)
{ {
// TODO: portexpander support MXC_ASSERT((pb > 0) && (pb <= num_pbs));
MXC_ASSERT(pb < num_pbs); if (pb == 2) {
GPIO_IntDisable(&pb_pin[pb]); return;
}
if (portexpander_detected()) {
portexpander_int_disable((1 << expander_pins[pb - 1]));
} else {
GPIO_IntDisable(&pb_pin[pb - 1]);
}
} }
//****************************************************************************** //******************************************************************************
void PB_IntClear(unsigned int pb) void PB_IntClear(unsigned int pb)
{ {
// TODO: portexpander support MXC_ASSERT((pb > 0) && (pb <= num_pbs));
MXC_ASSERT(pb < num_pbs); if (pb == 2) {
GPIO_IntClr(&pb_pin[pb]); return;
}
if (portexpander_detected()) {
portexpander_int_clr((1 << expander_pins[pb - 1]));
} else {
GPIO_IntClr(&pb_pin[pb - 1]);
}
} }
//****************************************************************************** //******************************************************************************
int PB_Get(unsigned int pb) int PB_Get(unsigned int pb)
{ {
static const uint8_t expander_pins[] = { 5, 0x0, 3, 6 }; static const uint8_t expander_pins[] = { 5, 0x0, 3, 6 };
MXC_ASSERT(pb < 4); MXC_ASSERT(pb <= 4);
switch (pb) { switch (pb) {
case 1: case 1:
case 3: case 3:
case 4: case 4:
if (portexpander_detected()) { if (portexpander_detected()) {
uint8_t port = portexpander_get(); return portexpander_in_get(
return (port & (1 << expander_pins[pb-1])) == 0; (1 << expander_pins[pb - 1])) == 0;
} else { } else {
return GPIO_InGet(&pb_pin[pb - 1]) == 0; return GPIO_InGet(&pb_pin[pb - 1]) == 0;
} }
break; break;
case 2: case 2:
// TODO: read pmic button return MAX77650_getDebounceStatusnEN0();
break; break;
} }
return 0; return 0;
......
/**
* @file pb.h
* @brief Pushbutton driver header file.
*/
/* ****************************************************************************
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
*
* 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 MAXIM INTEGRATED 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.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
* $Date: 2018-10-31 15:32:51 +0000 (Wed, 31 Oct 2018) $
* $Revision: 38826 $
*
*************************************************************************** */
#ifndef _PB_H_
#define _PB_H_
#include "gpio.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup bsp
* @defgroup pushbutton_evkit Push button driver board support
* @{
*/
/* **** Global Variables **** */
extern const gpio_cfg_t pb_pin[];
extern const unsigned int num_pbs;
/* **** Function Prototypes **** */
/**
* @brief Initialize all push buttons.
* @return \c #E_NO_ERROR Push buttons initialized successfully.
* @return "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
*
*/
int PB_Init(void);
/**
* Type alias @c pb_callback for the push button callback.
* @details The function is of type:
* @code
* void pb_callback(unsigned int pb, bool falling)
* @endcode
* To receive notification of a push button event, define a callback
* function and pass it as a pointer to the PB_RegisterCallback(unsigned int pb, pb_callback callback) function.
* @param pb push button index that triggered the callback.
*/
typedef void (*pb_callback)(unsigned int pb, bool falling);
/**
* @brief Register or Unregister a callback handler for events on the @p pb push button.
* @details
* - Calling this function with a pointer to a function @p callback, configures the pushbutton @p pb and enables the
* interrupt to handle the push button events.
* - Calling this function with a <tt>NULL</tt> pointer will disable the interrupt and unregister the
* callback function.
* @p pb must be a value between 0 and \c num_pbs.
*
* @param pb push button index to receive event callbacks.
* @param callback Callback function pointer of type @c pb_callback
* @return #E_NO_ERROR if configured and callback registered successfully.
* @return "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
*/
int PB_RegisterCallback(unsigned int pb, pb_callback callback);
/**
* @brief Register or Unregister a callback handler for rising and falling events on the @p pb push button.
* @details
* - Calling this function with a pointer to a function @p callback, configures the pushbutton @p pb and enables the
* interrupt to handle the push button events.
* - Calling this function with a <tt>NULL</tt> pointer will disable the interrupt and unregister the
* callback function.
* @p pb must be a value between 0 and \c num_pbs.
*
* @param pb push button index to receive event callbacks.
* @param callback Callback function pointer of type @c pb_callback
* @return #E_NO_ERROR if configured and callback registered successfully.
* @return "Error Code" @ref MXC_Error_Codes "Error Code" if unsuccessful.
*/
int PB_RegisterRiseFallCallback(unsigned int pb, pb_callback callback);
/**
* @brief Enable a callback interrupt.
* @note PB_RegisterCallback must be called prior to enabling the callback interrupt.
* @param pb push button index value between 0 and \c num_pbs.
*/
void PB_IntEnable(unsigned int pb);
/**
* @brief Disable a callback interrupt.
* @param pb push button index
*/
void PB_IntDisable(unsigned int pb);
/**
* @brief Clear a callback interrupt.
* @param pb push button index value between 0 and \c num_pbs.
*/
void PB_IntClear(unsigned int pb);
/**
* @brief Get the current state of the push button.
* @param pb push button index value between 0 and \c num_pbs.
* @return TRUE The button is pressed.
* @return FALSE The button is not pressed.
*/
int PB_Get(unsigned int pb);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif /* _PB_H_ */
#include "i2c.h" #include "i2c.h"
#include "pmic.h" #include "pmic.h"
#include "lp.h"
#include "MAX77650-Arduino-Library.h" #include "MAX77650-Arduino-Library.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h>
static const gpio_cfg_t pmic_interrupt_pin = { static const gpio_cfg_t pmic_interrupt_pin = {
PORT_0, PIN_12, GPIO_FUNC_IN, GPIO_PAD_PULL_UP PORT_0, PIN_12, GPIO_FUNC_IN, GPIO_PAD_PULL_UP
...@@ -18,11 +20,13 @@ void pmic_init(void) ...@@ -18,11 +20,13 @@ void pmic_init(void)
printf("MAX7765x DIDM: 0x%02x CID: 0x%02x\n", didm, cid); printf("MAX7765x DIDM: 0x%02x CID: 0x%02x\n", didm, cid);
MAX77650_setIP_SBB0(0b11); //Limit switch current of SBB0 to 500mA for noise reduction MAX77650_setIP_SBB0(
0b11); //Limit switch current of SBB0 to 500mA for noise reduction
//MAX77650_setIP_SBB0(0b00); //Limit switch current of SBB0 to 1000 mA //MAX77650_setIP_SBB0(0b00); //Limit switch current of SBB0 to 1000 mA
MAX77650_setTV_SBB0(0b101000); //Set output Voltage of SBB0 to 1.8V MAX77650_setTV_SBB0(0b101000); //Set output Voltage of SBB0 to 1.8V
MAX77650_setADE_SBB0(0b0); //Disable Active Discharge at SBB0 Output MAX77650_setADE_SBB0(0b0); //Disable Active Discharge at SBB0 Output
MAX77650_setEN_SBB0(0b110); //Enable SBB0 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states MAX77650_setEN_SBB0(
0b110); //Enable SBB0 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states
//MAX77650_setIP_SBB1(0b11); //Limit output of SBB1 to 500mA //MAX77650_setIP_SBB1(0b11); //Limit output of SBB1 to 500mA
#if BOARD_EVKIT #if BOARD_EVKIT
...@@ -31,17 +35,20 @@ void pmic_init(void) ...@@ -31,17 +35,20 @@ void pmic_init(void)
MAX77650_setTV_SBB1(0b001001); //Set output Voltage of SBB1 to 3.3V MAX77650_setTV_SBB1(0b001001); //Set output Voltage of SBB1 to 3.3V
#endif #endif
MAX77650_setADE_SBB1(0b0); //Disable Active Discharge at SBB1 Output MAX77650_setADE_SBB1(0b0); //Disable Active Discharge at SBB1 Output
MAX77650_setEN_SBB1(0b110); //Enable SBB1 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states MAX77650_setEN_SBB1(
0b110); //Enable SBB1 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states
MAX77650_setIP_SBB2(0b11); //Limit switch current of SBB2 to 500mA for noise reduction MAX77650_setIP_SBB2(
0b11); //Limit switch current of SBB2 to 500mA for noise reduction
#if BOARD_EVKIT #if BOARD_EVKIT
MAX77650_setTV_SBB2(0b110010); //Set output Voltage of SBB2 to 3.3V MAX77650_setTV_SBB2(0b110010); //Set output Voltage of SBB2 to 3.3V
#else #else
//MAX77650_setTV_SBB2(0b110100); //Set output Voltage of SBB2 to 5.0V //MAX77650_setTV_SBB2(0b110100); //Set output Voltage of SBB2 to 5.0V
MAX77650_setTV_SBB2(0b010010); //Set output Voltage of SBB2 to 3.3V MAX77650_setTV_SBB2(0b010010); //Set output Voltage of SBB2 to 3.3V
#endif #endif
MAX77650_setADE_SBB2(0b0); //Disable Active Discharge at SBB2 Output MAX77650_setADE_SBB2(0b1); //Enable Active Discharge at SBB2 Output
MAX77650_setEN_SBB2(0b110); //Enable SBB2 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states MAX77650_setEN_SBB2(
0b110); //Enable SBB2 is on irrespective of FPS whenever the on/off controller is in its "On via Software" or "On via On/Off Controller" states
// Prepare the PMIC LEDs // Prepare the PMIC LEDs
MAX77650_setLED_FS0(0b11); MAX77650_setLED_FS0(0b11);
...@@ -69,16 +76,23 @@ void pmic_init(void) ...@@ -69,16 +76,23 @@ void pmic_init(void)
MAX77650_setCHG_CC(0b1011); // 90 mA fast charge current MAX77650_setCHG_CC(0b1011); // 90 mA fast charge current
MAX77650_setCHG_EN(1); // Turn on charger MAX77650_setCHG_EN(1); // Turn on charger
MAX77650_setVSYS_REG(0b11000); // Set VSYS to 4.7 V to reduce voltage across bypass diode MAX77650_setVSYS_REG(
0b11000); // Set VSYS to 4.7 V to reduce voltage across bypass diode
/* Setup interrupt & callback */ /* Setup interrupt & callback */
GPIO_Config(&pmic_interrupt_pin); GPIO_Config(&pmic_interrupt_pin);
GPIO_RegisterCallback(&pmic_interrupt_pin, pmic_interrupt_callback, NULL); GPIO_RegisterCallback(
&pmic_interrupt_pin, pmic_interrupt_callback, NULL
);
GPIO_IntConfig(&pmic_interrupt_pin, GPIO_INT_EDGE, GPIO_INT_FALLING); GPIO_IntConfig(&pmic_interrupt_pin, GPIO_INT_EDGE, GPIO_INT_FALLING);
GPIO_IntEnable(&pmic_interrupt_pin); GPIO_IntEnable(&pmic_interrupt_pin);
NVIC_SetPriority((IRQn_Type)MXC_GPIO_GET_IRQ(pmic_interrupt_pin.port), 2); NVIC_SetPriority(
(IRQn_Type)MXC_GPIO_GET_IRQ(pmic_interrupt_pin.port), 2
);
NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(pmic_interrupt_pin.port)); NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(pmic_interrupt_pin.port));
/* Allow the PMIC to interrupt us in deepsleep */
LP_EnableGPIOWakeup((gpio_cfg_t *)&pmic_interrupt_pin);
/* Setup power button interrupt */ /* Setup power button interrupt */
MAX77650_setINT_M_GLBL(~(MAX77650_INT_nEN_R | MAX77650_INT_nEN_F)); MAX77650_setINT_M_GLBL(~(MAX77650_INT_nEN_R | MAX77650_INT_nEN_F));
/* Clear existing interrupts */ /* Clear existing interrupts */
...@@ -99,7 +113,9 @@ void pmic_poll(void) ...@@ -99,7 +113,9 @@ void pmic_poll(void)
if (int_flag & (MAX77650_INT_nEN_R | MAX77650_INT_nEN_F)) { if (int_flag & (MAX77650_INT_nEN_R | MAX77650_INT_nEN_F)) {
if (pmic_button_callback != NULL) { if (pmic_button_callback != NULL) {
(*pmic_button_callback)(int_flag & MAX77650_INT_nEN_F); (*pmic_button_callback)(
int_flag & MAX77650_INT_nEN_F
);
} }
} }
/* TODO: Other pmic interrupts */ /* TODO: Other pmic interrupts */
...@@ -111,6 +127,20 @@ void pmic_set_button_callback(pmic_button_callback_fn cb) ...@@ -111,6 +127,20 @@ void pmic_set_button_callback(pmic_button_callback_fn cb)
pmic_button_callback = cb; pmic_button_callback = cb;
} }
int pmic_get_led(uint8_t led)
{
if (led == 0) {
return MAX77650_getBRT_LED0();
}
if (led == 1) {
return MAX77650_getBRT_LED1();
}
if (led == 2) {
return MAX77650_getBRT_LED2();
}
return -EINVAL;
}
void pmic_set_led(uint8_t led, uint8_t val) void pmic_set_led(uint8_t led, uint8_t val)
{ {
if (led == 0) { if (led == 0) {
...@@ -125,5 +155,4 @@ void pmic_set_led(uint8_t led, uint8_t val) ...@@ -125,5 +155,4 @@ void pmic_set_led(uint8_t led, uint8_t val)
MAX77650_setLED_FS2(val > 0 ? 0b01 : 0); MAX77650_setLED_FS2(val > 0 ? 0b01 : 0);
MAX77650_setBRT_LED2(val); MAX77650_setBRT_LED2(val);
} }
} }
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
void pmic_init(void); void pmic_init(void);
void pmic_set_led(uint8_t led, uint8_t val); void pmic_set_led(uint8_t led, uint8_t val);
int pmic_get_led(uint8_t led);
void pmic_poll(void); void pmic_poll(void);
/* weak, so it can be overwritten by applications */ /* weak, so it can be overwritten by applications */
......
/* PCAL6408A I2C port expander */
/* **** Includes **** */
#include "portexpander.h" #include "portexpander.h"
#include "mxc_config.h"
#include "mxc_assert.h"
#include "i2c.h" #include "i2c.h"
#include <stdio.h> #include <stdio.h>
...@@ -7,58 +12,325 @@ ...@@ -7,58 +12,325 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
/* **** Definitions **** */
/* clang-format off */
#define PE_ADDR 0x42
#define PE_C_INPUT_PORT 0x00
#define PE_C_OUTPUT_PORT 0x01
#define PE_C_POLARITY_INV 0x02
#define PE_C_CONFIG 0x03
#define PE_C_OUTPUT_DRIVE_STR_0 0x40
#define PE_C_OUTPUT_DRIVE_STR_1 0x41
#define PE_C_INPUT_LATCH 0x42
#define PE_C_PULL_ENABLE 0x43
#define PE_C_PULL_SEL 0x44
#define PE_C_INT_MASK 0x45
#define PE_C_INT_STATUS 0x46
#define PE_C_OUTPUT_PORT_CONFIG 0x4F
#define PE_CONFIG_OUT 0
#define PE_CONFIG_IN 1
#define PE_PULL_DOWN 0
#define PE_PULL_UP 1
#define PE_OUT_PUSH_PULL 0
#define PE_OUT_OPEN_DRAIN 1
/* clang-format on */
#define PE_INPUT_MASK ((uint8_t)0b01101000) // 3, 5, 6 = input
/* **** Globals **** */
static bool detected = false; static bool detected = false;
void portexpander_init(void) static volatile bool interrupt_pending;
static uint8_t type_state = 0xFF;
static uint8_t output_state = 0xFF;
static uint8_t pull_enable_state = 0x00;
static uint8_t pull_selection_state = 0xFF;
static uint8_t int_mask_state = 0xFF;
static gpio_int_pol_t int_edge_config[8] = { 0 };
static pe_callback callbacks[8] = { NULL };
static void *cbparam[8] = { NULL };
const gpio_cfg_t pe_int_pin = { PORT_1, PIN_7, GPIO_FUNC_IN, GPIO_PAD_PULL_UP };
static const portexpander_cfg_t pe_pin_config[] = {
{ PE_INPUT_MASK, GPIO_FUNC_IN, GPIO_PAD_PULL_UP },
{ ~PE_INPUT_MASK, GPIO_FUNC_OUT, GPIO_PAD_PULL_UP },
};
/* **** Functions **** */
static int portexpander_write(uint8_t command, uint8_t data)
{ {
uint8_t addr = 0x21; uint8_t i2c_data[2] = { command, data };
int ret; return I2C_MasterWrite(MXC_I2C1_BUS0, PE_ADDR, i2c_data, 2, 0);
}
// Enable pull-ups for buttons /* ************************************************************************** */
uint8_t command[] = {0x43, 0x68}; static int portexpander_read(uint8_t command, uint8_t *data)
ret = I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 2, 0); {
I2C_MasterWrite(MXC_I2C1_BUS0, PE_ADDR, &command, 1, 1);
return I2C_MasterRead(MXC_I2C1_BUS0, PE_ADDR, data, 1, 0);
}
/* ************************************************************************** */
int portexpander_init(void)
{
int ret;
// Set _all_ outputs to open-drain to support the high side p-channel transistors.
ret = portexpander_write(PE_C_OUTPUT_PORT_CONFIG, PE_OUT_OPEN_DRAIN);
if (ret != 2) { if (ret != 2) {
printf("portexpander NOT detected\n"); printf("portexpander NOT detected\n");
detected = false; detected = false;
return; return E_NO_DEVICE;
} }
detected = true; detected = true;
// Set _all_ outputs to open-drain to support the high side p-channel transistors. // Set outputs to high
command[0] = 0x4F; command[1] = 0x01; portexpander_out_set(~PE_INPUT_MASK);
I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 2, 0);
// Enable pull-ups for buttons
// Enable outputs for the transistors, the LED and the LCD reset
for (size_t i = 0; i < sizeof(pe_pin_config) / sizeof(pe_pin_config[0]);
i++) {
ret = portexpander_config(&pe_pin_config[i]);
MXC_ASSERT(ret == E_NO_ERROR);
}
// Enable outputs for transistors and the LED // Latch inputs so we can figure out whether an interrupt was caused by a rising or falling edge
command[0] = 0x03; command[1] = 0x68; portexpander_write(PE_C_INPUT_LATCH, PE_INPUT_MASK);
I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 2, 0);
// Set outputs to high (i.e. open-drain) // Configure interrupt GPIO
command[0] = 0x01; command[1] = 0x97; MXC_ASSERT(GPIO_Config(&pe_int_pin) == E_NO_ERROR);
I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 2, 0);
// Turn on LEDs // Configure and enable portexpander interrupt
// TODO: only turn on LEDs if value != 0,0,0 && dim > 0 GPIO_RegisterCallback(
command[0] = 0x01; command[1] = 0x90; &pe_int_pin, &portexpander_interrupt_callback, NULL
I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 2, 0); );
MXC_ASSERT(
GPIO_IntConfig(&pe_int_pin, GPIO_INT_EDGE, GPIO_INT_FALLING) ==
E_NO_ERROR);
GPIO_IntEnable(&pe_int_pin);
NVIC_EnableIRQ((IRQn_Type)MXC_GPIO_GET_IRQ(pe_int_pin.port));
return E_SUCCESS;
} }
uint8_t portexpander_get(void) /* ************************************************************************** */
int portexpander_config(const portexpander_cfg_t *cfg)
{ {
uint8_t addr = 0x21; // Set the GPIO type
uint8_t command[] = {0x00}; switch (cfg->func) {
case GPIO_FUNC_IN:
type_state |= cfg->mask;
break;
case GPIO_FUNC_OUT:
type_state &= ~cfg->mask;
break;
default:
return E_BAD_PARAM;
}
if (portexpander_write(PE_C_CONFIG, type_state) != 2) {
return E_NO_DEVICE;
}
switch (cfg->pad) {
case GPIO_PAD_NONE:
pull_enable_state &= ~cfg->mask;
break;
case GPIO_PAD_PULL_UP:
pull_selection_state |= cfg->mask;
pull_enable_state |= cfg->mask;
break;
case GPIO_PAD_PULL_DOWN:
pull_selection_state &= ~cfg->mask;
pull_enable_state |= cfg->mask;
break;
default:
return E_BAD_PARAM;
}
portexpander_write(PE_C_PULL_SEL, pull_selection_state);
portexpander_write(PE_C_PULL_ENABLE, pull_enable_state);
return E_NO_ERROR;
}
/* ************************************************************************** */
uint8_t portexpander_in_get(uint8_t mask)
{
// Reading the input port clears interrupts, so we need to check them here to avoid losing information
portexpander_poll();
uint8_t buf = 0xFF; uint8_t buf = 0xFF;
if (detected) { if (detected) {
I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, command, 1, 1); portexpander_read(PE_C_INPUT_PORT, &buf);
I2C_MasterRead(MXC_I2C1_BUS0, addr << 1, &buf, 1, 0);
} }
return buf; return buf & mask;
} }
/* ************************************************************************** */
bool portexpander_detected(void) bool portexpander_detected(void)
{ {
return detected; return detected;
} }
/* ************************************************************************** */
void portexpander_out_set(uint8_t mask)
{
if (detected) {
output_state |= mask;
portexpander_write(PE_C_OUTPUT_PORT, output_state);
}
}
/* ************************************************************************** */
void portexpander_out_clr(uint8_t mask)
{
if (detected) {
output_state &= ~mask;
portexpander_write(PE_C_OUTPUT_PORT, output_state);
}
}
/* ************************************************************************** */
uint8_t portexpander_out_get(uint8_t mask)
{
return output_state & mask;
}
/* ************************************************************************** */
void portexpander_out_put(uint8_t mask, uint8_t val)
{
if (detected) {
output_state = (output_state & ~mask) | (val & mask);
portexpander_write(PE_C_OUTPUT_PORT, output_state);
}
}
/* ************************************************************************** */
void portexpander_out_toggle(uint8_t mask)
{
if (detected) {
output_state ^= mask;
portexpander_write(PE_C_OUTPUT_PORT, output_state);
}
}
/* ************************************************************************** */
void portexpander_int_config(uint8_t mask, gpio_int_pol_t edge)
{
if (detected) {
for (uint8_t pin = 0; pin < 8; ++pin) {
if (mask & (1 << pin)) {
int_edge_config[pin] = edge;
}
}
}
}
/* ************************************************************************** */
void portexpander_int_enable(uint8_t mask)
{
if (detected) {
int_mask_state &= ~mask;
portexpander_write(PE_C_INT_MASK, int_mask_state);
}
}
/* ************************************************************************** */
void portexpander_int_disable(uint8_t mask)
{
if (detected) {
int_mask_state |= mask;
portexpander_write(PE_C_INT_MASK, int_mask_state);
}
}
/* ************************************************************************** */
uint8_t portexpander_int_status()
{
uint8_t buf = 0;
if (detected) {
portexpander_read(PE_C_INT_STATUS, &buf);
}
return buf;
}
/* ************************************************************************** */
void portexpander_int_clr(uint8_t mask)
{
if (detected) {
uint8_t tmp_mask = int_mask_state | mask;
// Setting an interrupt mask clears the corresponding interrupt
portexpander_write(PE_C_INT_MASK, tmp_mask);
portexpander_write(PE_C_INT_MASK, int_mask_state);
}
}
/* ************************************************************************** */
int portexpander_register_callback(
uint8_t mask, pe_callback callback, void *cbdata
) {
if (!detected) {
return E_NO_DEVICE;
}
for (uint8_t pin = 0; pin < 8; ++pin) {
if (mask & (1 << pin)) {
callbacks[pin] = callback;
cbparam[pin] = cbdata;
}
}
return E_NO_ERROR;
}
/* ************************************************************************** */
__attribute__((weak)) void portexpander_interrupt_callback(void *_)
{
GPIO_IntDisable(&pe_int_pin);
GPIO_IntClr(&pe_int_pin);
interrupt_pending = true;
}
/* ************************************************************************** */
void portexpander_poll()
{
if (detected && interrupt_pending) {
interrupt_pending = false;
uint8_t caused_by = portexpander_int_status();
// Port read resets interrupts
uint8_t port_levels = portexpander_in_get(0xFF);
GPIO_IntEnable(&pe_int_pin);
for (uint8_t pin = 0; pin < 8; ++pin) {
if ((caused_by & (1 << pin)) && callbacks[pin]) {
gpio_int_pol_t edge_type =
(port_levels & (1 << pin) ?
GPIO_INT_RISING :
GPIO_INT_FALLING);
if ((int_edge_config[pin] == GPIO_INT_BOTH) ||
(edge_type == int_edge_config[pin])) {
callbacks[pin](edge_type, cbparam[pin]);
}
}
}
}
}
#ifndef PORTEXPANDER_H #ifndef PORTEXPANDER_H
#define PORTEXPANDER_H #define PORTEXPANDER_H
#include "mxc_config.h"
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
void portexpander_init(void); /**
uint8_t portexpander_get(void); * Structure type for configuring the portexpander.
*/
typedef struct {
uint8_t mask; /**< Pin mask (multiple pins may be set) */
gpio_func_t func; /**< Function type */
gpio_pad_t pad; /**< Pad type */
} portexpander_cfg_t;
typedef void (*pe_callback)(gpio_int_pol_t edge_type, void *cbdata);
int portexpander_init(void);
bool portexpander_detected(void); bool portexpander_detected(void);
int portexpander_config(const portexpander_cfg_t *cfg);
uint8_t portexpander_in_get(uint8_t mask);
void portexpander_out_set(uint8_t mask);
void portexpander_out_clr(uint8_t mask);
void portexpander_out_put(uint8_t mask, uint8_t val);
void portexpander_out_toggle(uint8_t mask);
uint8_t portexpander_out_get(uint8_t mask);
void portexpander_int_config(uint8_t mask, gpio_int_pol_t edge);
void portexpander_int_enable(uint8_t mask);
void portexpander_int_disable(uint8_t mask);
uint8_t portexpander_int_status();
void portexpander_int_clr(uint8_t mask);
int portexpander_register_callback(uint8_t mask, pe_callback callback, void *cbdata);
void portexpander_poll();
void portexpander_interrupt_callback(void *_);
#endif #endif
Subproject commit 1c9e3886f69f9ca83c1af49968d8e4389035ff44
includes = include_directories(
'./',
)
sources = files(
'./tiny-AES-c/aes.c',
'./SHA256/mark2/sha256.c',
)
lib = static_library(
'crypto',
sources,
include_directories: includes,
c_args: '-w',
)
libcrypto = declare_dependency(
include_directories: includes,
link_with: lib,
)
Subproject commit 3f69a5899e58e2e398e8c32ce7b3a954dd593ed4
#include <stdlib.h>
#include <libgen.h>
#define CTX_MAX_DRAWLIST_SIZE 4096000
#define CTX_BACKEND_TEXT 0 // we keep then non-backend code paths
// for code handling aroud, this should
// be run-time to permit doing text_to_path
#define CTX_RASTERIZER 0
#define CTX_BITPACK_PACKER 1 // pack vectors
#define CTX_BITPACK 1
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
#include <sys/time.h>
#define CTX_EXTRAS 1
#define CTX_FONTS_FROM_FILE 1
#define CTX_AVX2 0
#define CTX_IMPLEMENTATION
#define CTX_PARSER 1
#include "ctx-nofont.h"
static int usage(){
fprintf (stderr, "tool to generate native ctx embedded font format\n");
fprintf (stderr, "\n");
fprintf (stderr, "usage: ctx-fontgen <file.ttf> [name [set1-set2-set3]]\n");
fprintf (stderr, "\nrecognized sets: latin1, ascii, extra, all, emoji\n");
fprintf (stderr, "\na final argument of \"binary\" might be appended, causing\nthe generated file to be binary ctx.\n");
return -1;
}
CtxDrawlist output_font={NULL,};
uint32_t glyphs[65536];
int n_glyphs = 0;
void
add_glyph (Ctx *ctx, uint32_t glyph)
{
for (int i = 0; i < n_glyphs; i++)
{
if (glyphs[i] == glyph)
return;
}
ctx_reset (ctx);
ctx_font_size (ctx, CTX_BAKE_FONT_SIZE);
ctx_move_to (ctx, 0, 0);
if (ctx_glyph (ctx, glyph, 1))
return;
glyphs[n_glyphs++] = glyph;
ctx->drawlist.flags = CTX_TRANSFORMATION_BITPACK;
ctx_drawlist_compact (&ctx->drawlist);
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (glyph, (uint8_t*)buf);
uint32_t args[2] = {glyph, ctx_glyph_width (ctx, glyph) * 256};
ctx_drawlist_add_u32 (&output_font, CTX_DEFINE_GLYPH, args);
for (int i = 3; i < ctx->drawlist.count - 1; i++)
{
CtxEntry *entry = &ctx->drawlist.entries[i];
args[0] = entry->data.u32[0];
args[1] = entry->data.u32[1];
ctx_drawlist_add_u32 (&output_font, entry->code, &args[0]);
}
}
static int find_glyph (CtxDrawlist *drawlist, uint32_t unichar)
{
for (int i = 0; i < drawlist->count; i++)
{
if (drawlist->entries[i].code == CTX_DEFINE_GLYPH &&
drawlist->entries[i].data.u32[0] == unichar)
{
return i;
// XXX this could be prone to insertion of valid header
// data in included bitmaps.. is that an issue?
}
}
fprintf (stderr, "Eeeek %i\n", unichar);
return -1;
}
int main (int argc, char **argv)
{
int binary = 0;
const char *path;
const char *name = "regular";
const char *subsets = "latin1";
Ctx *ctx;
path = argv[1];
if (!path)
{
return usage();
}
if (argv[2])
{
name = argv[2];
if (argv[3])
subsets = argv[3];
if (argv[4] && !strcmp(argv[4], "binary"))
binary=1;
}
ctx_load_font_ttf_file ("import", argv[1]);
ctx = ctx_new ();
_ctx_set_transformation (ctx, CTX_TRANSFORMATION_RELATIVE);
ctx_font (ctx, "import");
if (strstr (subsets, "all"))
for (int glyph = 0; glyph < 65536*8; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "latin1"))
for (int glyph = 0; glyph < 256; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "ascii"))
for (int glyph = 0; glyph < 127; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "terminal"))
{
char* string = "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼! #$%&'()*+,-.🔒"
"⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"
"└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■"
"!#$%&'()*+,-./◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "cp437"))
{
char* string = " ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼!\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^,`abcdefghijklmnopqrstuvwxyz{|}~⌂"
"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»"
"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
"αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "vt100"))
{
char* string =
" !\"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "extras"))
{
char *string =
"éñÑßæøåö£ÆÖØÅ€§π°üÜ…”““”«»©®™⭾⏎⌫·←↑↓→☀☁☂☢☭☮☯☽✉⚙⚠␣²◆♥♦♣♠÷≈±╴−╶";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "emoji"))
{
char *string = "๛ ☬☣☠☀☁☂☃☢☭☮☯☼☽✉✓❤№℃∞◌◎☎☐☑♉♩♪♫♬☆◦☄☉☏☤☥☹☺☻♲♨♼♽♾⚀⚁🥕⚂⚃⚄⚅⚙⚠␣⚡⌨⌚⏏⋯•‥․‣•↺↻⌘☕✈✉✓✔✕✖✗✘☑☒☐☓✶❄❍❢❣❤❥❤❥❦❧➲㎏㎆㎅㎇㎤㎥㎦㎝㎧㎨㎞㎐㎏㎑㎒㎓㎠㎡㎢★⁈ ⁉ ⁂✵✺✽✾✿❀❁❂❉❆✡✠🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯🤷🤸🤹🤺🥂🥇🥈🥉🥤🥨🥬🥰🥱🥳🥴🥵🥶🥺🦁🦄🦉🦊🦋🦎🦓🦔🦕🦖🦘🦙🦚🦜🦝🦟🦴🦽🦾🦿🧁🧉🧐🧙🧚🧛🧜🧟🧠🧡🧥🧤🧦🧪🧬🧭🧮🧯🧰🧱🧲🧵🧷🧸🧺🧻🛹🛸🛵🛴🛰🛬🛫🛩🛠🛣🛤🛥🛒🛏🛌🛂🛁🚶🚴🚲🚬🚩🚗🚜🚴🚘🚖🚔🚚🚑🚍🚆🚀🙈🙉🙊🙄🙃🙂🙁🙀😿😾😽😼😻😺😹😸😷😶😵😴😳😲😱😰😯😮😭😬😫😪😩😨😧😦😥😤😣😢😡😠😟😞😝😜😛😚😙😘😗😖😕😔😓😒😑😐😏😎😍😌😋😊😉😈😇😆😅😄😃😂😁😀🗝🗜🗞🗓🗒🗑🗄🖼🖤🖥🖨🖖🖕🖐🖍🖌🖋🖊🖇🕺🕹🕸🕷🕶🕵🕴🕰🕯🔭🔬🔫🔪🔩🔨🔧🔦🔥🔤🔢🔣🔡🔠🔗🔕🔔🔓🔒🔑🔐🔏🔌🔋🔊🔉🔈🔇🔅🔆📽📻📺📹📸📷📳📱📰📯📭📬📫📪📨📦📡📞📚📖📐📏📎📍📌📉📈📄📃📂📁💿💾💻💸💶💳💰💯💫💩💧💦💤💣💢💡💞💖💕💔💓💊💃💀👾👽👻👺👹👸👷👶👵👴👯👭👬👫👣👓👋👍👎🐾🐼🐻🐺🐹🐸🐷🐶🐵🐳🐲🐱🐰🐯🐮🐭🐬🐧🐦🐥🐤🐣🐢🐡🐠🐟🐞🐝🐜🐛🐙🐘🐔🐓🐒🐑🐐🐏🐎🐍🐌🐋🐊🐉🐈🐇🐆🐅🐄🐃🐂🐁🐀🏺🏹🏸🏷🏴🏳🏵🏰🏭🏬🏫🏪🏧🏢🏠🏡🏐🏍🏆🏅🏁🎼🎶🎵🎲🎰🎮🎬🎨🎧🎥🎞🎃🎄🍸🍷🍄🌿🍀🍁🍒🌵🌳🌲🌩🌪🌨🌧🌦🌥🌤🌡🌠🌟🌞🌝🌜🌛🌚🌙🌘🌗🌖🌕🌔🌓🌒🌑🌐🌏🌎🌍🌌🌋🌊🌅🌄🌂🌀";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
for (int i = 0; i < n_glyphs; i++)
for (int j = 0; j < n_glyphs; j++)
{
float kerning = ctx_glyph_kern (ctx, glyphs[i], glyphs[j]);
if (kerning > 0.2)
{
CtxCommand command;
int pos = find_glyph (&output_font, glyphs[i]);
pos ++;
while (pos < output_font.count &&
output_font.entries[pos].code != CTX_DEFINE_GLYPH)
pos++;
command.code = CTX_KERNING_PAIR;
command.kern.glyph_before = glyphs[i];
command.kern.glyph_after = glyphs[j];
command.kern.amount = kerning * 256;
ctx_drawlist_insert_entry (&output_font, pos, (CtxEntry*)&command);
}
}
ctx_free (ctx);
if (!binary)
{
printf ("#ifndef CTX_FONT_%s\n", name);
printf ("/* this is a ctx encoded font based on %s */\n", basename (argv[1]));
printf ("/* CTX_SUBDIV:%i CTX_BAKE_FONT_SIZE:%i */\n", CTX_SUBDIV, CTX_BAKE_FONT_SIZE);
printf ("/* glyphs covered: \n\n");
int col = 0;
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
if (entry->code == '@')
{
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (entry->data.u32[0], (uint8_t*)buf);
switch (buf[0])
{
case '\\':
printf ("\\");
break;
default:
printf ("%s", buf);
}
col++;
if (col > 73)
{
col = 0;
printf ("\n ");
}
}
}
printf (" */\n");
printf ("static const struct __attribute__ ((packed)) {uint8_t code; uint32_t a; uint32_t b;}\nctx_font_%s[]={\n", name);
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
if (entry->code > 32 && entry->code < 127)
{
printf ("{'%c', 0x%08x, 0x%08x},", entry->code,
entry->data.u32[0],
entry->data.u32[1]);
}
else
{
printf ("{%i, 0x%08x, 0x%08x},", entry->code,
entry->data.u32[0],
entry->data.u32[1]);
}
if (entry->code == '@')
{
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (entry->data.u32[0], (uint8_t*)buf);
switch (buf[0])
{
case '\\':
printf ("/* \\ x-advance: %f */", entry->data.u32[1]/256.0);
break;
default:
printf ("/* %s x-advance: %f */", buf, entry->data.u32[1]/256.0);
}
}
else
{
}
printf ("\n");
}
printf ("};\n");
printf ("#define CTX_FONT_%s 1\n", name);
printf ("#endif\n");
}
else
{
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
for (int c = 0; c < (int)sizeof (CtxEntry); c++)
printf ("%c",((uint8_t*)(entry))[c]);
}
}
return 0;
}
Source diff could not be displayed: it is too large. Options to address this: view the blob.
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
/* clang-format off */
#define CTX_MIN_EDGE_LIST_SIZE 256
#define CTX_MAX_EDGE_LIST_SIZE 512
#define CTX_MIN_JOURNAL_SIZE 512
#define CTX_MAX_JOURNAL_SIZE 512
#define CTX_LIMIT_FORMATS 1
#define CTX_DITHER 1
#define CTX_ENABLE_RGB565_BYTESWAPPED 1
#define CTX_BITPACK_PACKER 0
#define CTX_COMPOSITING_GROUPS 0
#define CTX_RENDERSTREAM_STATIC 0
#define CTX_GRADIENT_CACHE 1
#define CTX_ENABLE_CLIP 1
#define CTX_BLOATY_FAST_PATHS 0
#define CTX_1BIT_CLIP 1
#define CTX_RASTERIZER_AA 15
#define CTX_RASTERIZER_FORCE_AA 0
#define CTX_SHAPE_CACHE 0
#define CTX_SHAPE_CACHE_DIM 16*18
#define CTX_SHAPE_CACHE_ENTRIES 128
#define CTX_RASTERIZER_MAX_CIRCLE_SEGMENTS 36
#define CTX_RASTERIZER 1
#define CTX_EVENTS 0
#define CTX_STRINGPOOL_SIZE 512
#define CTX_ENABLE_SHADOW_BLUR 0
#define CTX_FORMATTER 0
#define CTX_PARSER 0
#define CTX_FONTS_FROM_FILE 0
/* clang-format on */
#define CTX_IMPLEMENTATION
/* Defining this causes the internal font to be dropped. */
#define _CTX_INTERNAL_FONT_
#include "font-fira-mono.h"
#include "ctx.h"
Source diff could not be displayed: it is too large. Options to address this: view the blob.
File added
ctx.h is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
ctx.h 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with ctx; if not, see <https://www.gnu.org/licenses/>.
2002, 2012, 2015, 2019, 2020 Øyvind Kolås <pippin@gimp.org>
includes = include_directories(
'./',
)
libm_native = meson.get_compiler('c', native: true).find_library('m')
ctx_fontgen_bin = executable(
'ctx-fontgen',
'ctx-fontgen.c',
native: true,
include_directories: includes,
dependencies: libm_native,
c_args: ['-w', '-DNO_LIBCURL']
)
ctx_fontgen = generator(
ctx_fontgen_bin,
output: 'font-@BASENAME@.h',
arguments: ['@INPUT@', 'mono', 'ascii-extras'],
capture: true,
)
font = ctx_fontgen.process('fira-mono.ttf')
sources = files(
'ctx.c',
)
lib = static_library(
'ctx',
sources,
font,
include_directories: includes,
dependencies: periphdriver,
c_args: ['-O3', '-w']
)
libctx = declare_dependency(
include_directories: includes,
link_with: lib,
)