diff --git a/lib_mic_array_board_support/api/mic_array_board_support.h b/lib_mic_array_board_support/api/mic_array_board_support.h index ce2e819..47a0ab8 100644 --- a/lib_mic_array_board_support/api/mic_array_board_support.h +++ b/lib_mic_array_board_support/api/mic_array_board_support.h @@ -10,11 +10,20 @@ #define MIC_BOARD_SUPPORT_BUTTON_PORTS PORT_BUT_A_TO_D + +#if defined(PORT_LED10_TO_12) #if defined(PORT_LED_OEN) #define MIC_BOARD_SUPPORT_LED_PORTS {PORT_LED0_TO_7, PORT_LED8, PORT_LED9, PORT_LED10_TO_12, PORT_LED_OEN} #else #define MIC_BOARD_SUPPORT_LED_PORTS {PORT_LED0_TO_7, PORT_LED8, PORT_LED9, PORT_LED10_TO_12} #endif +#elif defined(PORT_LED_12) +#define MIC_BOARD_SUPPORT_LED_PORTS {PORT_LED0_TO_7, PORT_LED8_TO_11, PORT_LED_12} +#else +#define MIC_BOARD_LED_STCP on tile[3] : XS1_PORT_1A +#define MIC_BOARD_LED_SHCP on tile[3] : XS1_PORT_1B +#define MIC_BOARD_LED_DATA on tile[3] : XS1_PORT_1E; +#endif /** This type is used to describe an event on a button. */ @@ -28,15 +37,31 @@ typedef enum { #define BUTTON_EVENT_NONE (-1) /** Structure to describe the LED ports*/ +#ifndef MIC_BOARD_LED_STCP typedef struct { +#if defined(PORT_LED0_TO_7) out port p_led0to7; /**=4.0.0) -VERSION = 2.2.3 +VERSION = 2.3.0 diff --git a/lib_mic_array_board_support/src/board_support.xc b/lib_mic_array_board_support/src/board_support.xc index cd2d5d4..6d22a5b 100644 --- a/lib_mic_array_board_support/src/board_support.xc +++ b/lib_mic_array_board_support/src/board_support.xc @@ -19,7 +19,12 @@ [[combinable]] void mabs_button_and_led_server(server interface mabs_led_button_if lb[n_lb], - static const unsigned n_lb, mabs_led_ports_t &leds, + static const unsigned n_lb, +#ifndef MIC_BOARD_LED_STCP + mabs_led_ports_t &leds, +#else + client interface ma_bga167_led_if leds, +#endif in port p_buttons){ mabs_button_state_t latest_button_pressed = BUTTON_RELEASED; @@ -40,7 +45,7 @@ void mabs_button_and_led_server(server interface mabs_led_button_if lb[n_lb], unsigned button_val; p_buttons :> button_val; while(1){ -// #pragma ordered + //[[ordered]] select { case lb[int i].set_led_brightness(unsigned led, unsigned brightness):{ if(led < MIC_BOARD_SUPPORT_LED_COUNT) @@ -84,19 +89,43 @@ void mabs_button_and_led_server(server interface mabs_led_button_if lb[n_lb], } case t when timerafter(time) :> unsigned now :{ - time = now + MIN_POLL_TIME_US; + time = now + 100*MIN_POLL_TIME_US; unsigned elapsed = (now-start_of_time)&LED_MAX_COUNT; elapsed>>=(20-8); unsigned d=0; +#if defined(MIC_BOARD_LED_STCP) + + for(unsigned i=0; i<13; i++) + d=(d>>1)+(0x1000*(led_brightness[i]<=elapsed)); + leds.set_leds(d); +#else +#if defined(PORT_LED0_TO_7) for(unsigned i=0;i<8;i++) d=(d>>1)+(0x80*(led_brightness[i]<=elapsed)); leds.p_led0to7 <: d; +#endif +#if defined(PORT_LED8) leds.p_led8 <: (led_brightness[8]<=elapsed); +#endif +#if defined(PORT_LED9) leds.p_led9 <: (led_brightness[9]<=elapsed); +#endif +#if defined(PORT_LED8_TO_11) + d=0; + for(unsigned i=8;i<12;i++) + d=(d>>1)+(0x80*(led_brightness[i]<=elapsed)); + leds.p_led8to11 <: d; +#endif +#if defined(PORT_LED10_TO_12) d=0; for(unsigned i=10;i<13;i++) d=(d>>1)+(0x4*(led_brightness[i]<=elapsed)); leds.p_led10to12 <: d; +#endif +#if defined(PORT_LED_12) + leds.p_led12 <: (led_brightness[12]<=elapsed); +#endif +#endif break; } /* diff --git a/lib_mic_array_board_support/src/ma_bga167_led_driver.xc b/lib_mic_array_board_support/src/ma_bga167_led_driver.xc new file mode 100644 index 0000000..e13f3c2 --- /dev/null +++ b/lib_mic_array_board_support/src/ma_bga167_led_driver.xc @@ -0,0 +1,128 @@ +// Copyright (c) 2015-2017, XMOS Ltd, All rights reserved + +#include "mic_array_board_support.h" + +#ifdef MIC_BOARD_LED_STCP + +out port p_led_stcp = MIC_BOARD_LED_STCP; +out port p_led_shcp = MIC_BOARD_LED_SHCP; +out port p_led_data = MIC_BOARD_LED_DATA; + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#define LED_COUNT MIC_BOARD_SUPPORT_LED_COUNT + +/* + * Timing data from: + * https://assets.nexperia.com/documents/data-sheet/74HC_HCT595.pdf + * + * Hold times are negligible (less than 1 tick) + */ + +/* + * The chip is really powered at 3.3V. The values for 4.5V + * seem to work fine, at least at room temperature. + */ +#define VCC 4 + +#if VCC==2 +/* + * Assuming Vcc = 2V, -40C to 85C + */ +#define T_DS_SHCP_SU 7 /* min setup time for DS before SHCP high */ +#define T_SHCP_Q7S_PD 20 /* max SHCP to Q7S propagation delay */ +#define T_CLK_PW 10 /* min pulse width for STCP and SHCP */ +#define T_CLK_PERIOD 21 /* min clock period for SHCP */ +#define T_SHCP_STCP_SU 10 /* min setup time for SHCP before SCTP high */ + +#elif VCC==4 +/* + * Assuming Vcc = 4.5V, -40C to 85C + */ +#define T_DS_SHCP_SU 2 /* min setup time for DS before SHCP high */ +#define T_SHCP_Q7S_PD 5 /* max SHCP to Q7S propagation delay */ +#define T_CLK_PW 2 /* min pulse width for STCP and SHCP */ +#define T_CLK_PERIOD 5 /* min clock period for SHCP */ +#define T_SHCP_STCP_SU 2 /* min setup time for SHCP before SCTP high */ + +#endif + +/* calculate minimum time that SHCP must be low for between high pulses */ +#define T_SHCP_LOW (MAX(T_CLK_PERIOD, (T_SHCP_Q7S_PD + T_DS_SHCP_SU)) - T_CLK_PW) + +static void wait_ticks(int ticks) +{ + timer tmr; + uint32_t t; + tmr :> t; + tmr when timerafter(t+ticks-1) :> void; +} + +/*************************************************************** +Numbers are for the VCC=2V, -40C to 85C case. + +shcp high for 10 ticks +shcp low for 17 ticks +ds change 7 ticks before clock high +ds changes every 27 ticks + + 270 100 170 + <----------------><-------><-------> + ________ ________ _______ +shcp _______| |________| |________| ... + + 70 (setup time) 70 + <--> <--> + __ ________________ ________________ ___________ +ds __/\________________\/________________/\___________... + + 200 70 (200ns is clk high to q7s valid, 70ns is setup time) + <------------><--> + _____________________ _________________ __________ +q7s _____________________/\_________________\/__________... + +***************************************************************/ + +static void led_driver(out port stcp, out port shcp, out port data, uint16_t led_value) +{ + stcp <: 0; + shcp <: 0; + data <: 0; + + data <: (uint32_t)led_value >> LED_COUNT-1; + wait_ticks(T_DS_SHCP_SU); + shcp <: 1; + + for (int i = 0; i < LED_COUNT-1; i++) { + wait_ticks(T_CLK_PW); + shcp <: 0; + wait_ticks(T_SHCP_LOW - T_DS_SHCP_SU); + + /* left shift led_value out (MSB first) */ + led_value <<= 1; + data <: (uint32_t)led_value >> LED_COUNT-1; + wait_ticks(T_DS_SHCP_SU); + shcp <: 1; + } + + wait_ticks(T_SHCP_STCP_SU); + stcp <: 1; + wait_ticks(T_CLK_PW); + shcp <: 0; + stcp <: 0; +} + +[[combinable]] +void mabs_bga167_led_driver(server interface ma_bga167_led_if leds) +{ + while (1) { + select { + case leds.set_leds(uint16_t led_value): + led_driver(p_led_stcp, p_led_shcp, p_led_data, led_value); + break; + } + } +} + +#endif + diff --git a/lib_mic_array_board_support/src/pll.xc b/lib_mic_array_board_support/src/pll.xc index 2f0ecdd..b2cd6cd 100644 --- a/lib_mic_array_board_support/src/pll.xc +++ b/lib_mic_array_board_support/src/pll.xc @@ -21,6 +21,8 @@ void mabs_init_pll(client i2c_master_if i2c, mabs_board_t board){ case SMART_MIC_BASE: case WIFI_MIC_ARRAY: + case SMART_MIC_BASE_4TILE: + case MIC_ARRAY_BASE_4TILE_BGA: // SI5351A Register Addresses #define SI5351A_OE_CTRL (0x03) // Register 3 - Output Enable Control #define SI5351A_FANOUT_EN (0xBB) // Register 187 - Fanout Enable Control diff --git a/lib_mic_array_board_support/wscript b/lib_mic_array_board_support/wscript index 5d06717..804f664 100644 --- a/lib_mic_array_board_support/wscript +++ b/lib_mic_array_board_support/wscript @@ -4,4 +4,4 @@ def use_module(bld): source=source, includes=['api'], depends_on=['lib_i2c(>=4.0.0)'], - version='2.2.3') + version='2.3.0')