Update ColorChord for the ESP8266
This commit is contained in:
parent
ca4c90b1a8
commit
5a4c232d43
22 changed files with 1226 additions and 206 deletions
58
embedded8266/user/hpatimer.c
Normal file
58
embedded8266/user/hpatimer.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
|
||||
#include "hpatimer.h"
|
||||
#include <driver/adc.h>
|
||||
#include "osapi.h"
|
||||
#include "mem.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
//BUFFSIZE must be a power-of-two
|
||||
volatile uint8_t sounddata[HPABUFFSIZE];
|
||||
volatile uint16_t soundhead;
|
||||
|
||||
|
||||
#define FRC1_ENABLE_TIMER BIT7
|
||||
|
||||
typedef enum {
|
||||
DIVDED_BY_1 = 0,
|
||||
DIVDED_BY_16 = 4,
|
||||
DIVDED_BY_256 = 8,
|
||||
} TIMER_PREDIVED_MODE;
|
||||
|
||||
typedef enum {
|
||||
TM_LEVEL_INT = 1,
|
||||
TM_EDGE_INT = 0,
|
||||
} TIMER_INT_MODE;
|
||||
|
||||
#define FRC1_AUTO_RELOAD 64
|
||||
|
||||
static void timerhandle( void * v )
|
||||
{
|
||||
RTC_CLR_REG_MASK(FRC1_INT_ADDRESS, FRC1_INT_CLR_MASK);
|
||||
uint16_t r = hs_adc_read();
|
||||
sounddata[soundhead] = r>>6;
|
||||
soundhead = (soundhead+1)&(HPABUFFSIZE-1);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR StartHPATimer()
|
||||
{
|
||||
|
||||
RTC_REG_WRITE(FRC1_CTRL_ADDRESS, FRC1_AUTO_RELOAD|
|
||||
DIVDED_BY_16 | //5MHz main clock.
|
||||
FRC1_ENABLE_TIMER |
|
||||
TM_EDGE_INT );
|
||||
|
||||
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, 5000000/DFREQ);
|
||||
RTC_REG_WRITE(FRC1_COUNT_ADDRESS, 5000000/DFREQ);
|
||||
|
||||
//pwm_set_freq_duty(freq, duty);
|
||||
//pwm_start();
|
||||
// RTC_REG_WRITE(FRC1_LOAD_ADDRESS, local_single[0].h_time);
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(timerhandle, NULL);
|
||||
TM1_EDGE_INT_ENABLE();
|
||||
ETS_FRC1_INTR_ENABLE();
|
||||
system_timer_reinit();
|
||||
hs_adc_start();
|
||||
}
|
||||
|
16
embedded8266/user/hpatimer.h
Normal file
16
embedded8266/user/hpatimer.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _HPATIMER_H
|
||||
#define _HPATIMER_H
|
||||
|
||||
#include <c_types.h>
|
||||
//Using a system timer on the ESP to poll the ADC in at a regular interval...
|
||||
|
||||
//BUFFSIZE must be a power-of-two
|
||||
#define HPABUFFSIZE 512
|
||||
extern volatile uint8_t sounddata[HPABUFFSIZE];
|
||||
extern volatile uint16_t soundhead;
|
||||
|
||||
void StartHPATimer();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,3 +1,18 @@
|
|||
#include "mystuff.h"
|
||||
|
||||
char generic_print_buffer[384];
|
||||
|
||||
|
||||
void user_rf_pre_init(void)
|
||||
{
|
||||
//nothing.
|
||||
}
|
||||
|
||||
|
||||
char * strcat( char * dest, char * src )
|
||||
{
|
||||
return strcat(dest, src );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
extern char generic_print_buffer[384];
|
||||
|
||||
#define printf( ... ) os_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );
|
||||
#define printf( ... ) ets_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer );
|
||||
|
||||
#endif
|
||||
|
|
281
embedded8266/user/slc_register.h
Normal file
281
embedded8266/user/slc_register.h
Normal file
|
@ -0,0 +1,281 @@
|
|||
//Generated at 2012-10-23 19:55:03
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SLC_REGISTER_H_
|
||||
#define SLC_REGISTER_H_
|
||||
|
||||
#define REG_SLC_BASE 0x60000B00
|
||||
//version value:32'h091700
|
||||
|
||||
#define SLC_CONF0 (REG_SLC_BASE + 0x0)
|
||||
#ifndef ESP_MAC_5
|
||||
#define SLC_MODE 0x00000003
|
||||
#define SLC_MODE_S 12
|
||||
#endif
|
||||
#define SLC_DATA_BURST_EN (BIT(9))
|
||||
#define SLC_DSCR_BURST_EN (BIT(8))
|
||||
#define SLC_RX_NO_RESTART_CLR (BIT(7))
|
||||
#define SLC_RX_AUTO_WRBACK (BIT(6))
|
||||
#define SLC_RX_LOOP_TEST (BIT(5))
|
||||
#define SLC_TX_LOOP_TEST (BIT(4))
|
||||
#define SLC_AHBM_RST (BIT(3))
|
||||
#define SLC_AHBM_FIFO_RST (BIT(2))
|
||||
#define SLC_RXLINK_RST (BIT(1))
|
||||
#define SLC_TXLINK_RST (BIT(0))
|
||||
|
||||
#define SLC_INT_RAW (REG_SLC_BASE + 0x4)
|
||||
#define SLC_TX_DSCR_EMPTY_INT_RAW (BIT(21))
|
||||
#define SLC_RX_DSCR_ERR_INT_RAW (BIT(20))
|
||||
#define SLC_TX_DSCR_ERR_INT_RAW (BIT(19))
|
||||
#define SLC_TOHOST_INT_RAW (BIT(18))
|
||||
#define SLC_RX_EOF_INT_RAW (BIT(17))
|
||||
#define SLC_RX_DONE_INT_RAW (BIT(16))
|
||||
#define SLC_TX_EOF_INT_RAW (BIT(15))
|
||||
#define SLC_TX_DONE_INT_RAW (BIT(14))
|
||||
#define SLC_TOKEN1_1TO0_INT_RAW (BIT(13))
|
||||
#define SLC_TOKEN0_1TO0_INT_RAW (BIT(12))
|
||||
#define SLC_TX_OVF_INT_RAW (BIT(11))
|
||||
#define SLC_RX_UDF_INT_RAW (BIT(10))
|
||||
#define SLC_TX_START_INT_RAW (BIT(9))
|
||||
#define SLC_RX_START_INT_RAW (BIT(8))
|
||||
#define SLC_FRHOST_BIT7_INT_RAW (BIT(7))
|
||||
#define SLC_FRHOST_BIT6_INT_RAW (BIT(6))
|
||||
#define SLC_FRHOST_BIT5_INT_RAW (BIT(5))
|
||||
#define SLC_FRHOST_BIT4_INT_RAW (BIT(4))
|
||||
#define SLC_FRHOST_BIT3_INT_RAW (BIT(3))
|
||||
#define SLC_FRHOST_BIT2_INT_RAW (BIT(2))
|
||||
#define SLC_FRHOST_BIT1_INT_RAW (BIT(1))
|
||||
#define SLC_FRHOST_BIT0_INT_RAW (BIT(0))
|
||||
|
||||
#define SLC_INT_STATUS (REG_SLC_BASE + 0x8)
|
||||
#define SLC_TX_DSCR_EMPTY_INT_ST (BIT(21))
|
||||
#define SLC_RX_DSCR_ERR_INT_ST (BIT(20))
|
||||
#define SLC_TX_DSCR_ERR_INT_ST (BIT(19))
|
||||
#define SLC_TOHOST_INT_ST (BIT(18))
|
||||
#define SLC_RX_EOF_INT_ST (BIT(17))
|
||||
#define SLC_RX_DONE_INT_ST (BIT(16))
|
||||
#define SLC_TX_EOF_INT_ST (BIT(15))
|
||||
#define SLC_TX_DONE_INT_ST (BIT(14))
|
||||
#define SLC_TOKEN1_1TO0_INT_ST (BIT(13))
|
||||
#define SLC_TOKEN0_1TO0_INT_ST (BIT(12))
|
||||
#define SLC_TX_OVF_INT_ST (BIT(11))
|
||||
#define SLC_RX_UDF_INT_ST (BIT(10))
|
||||
#define SLC_TX_START_INT_ST (BIT(9))
|
||||
#define SLC_RX_START_INT_ST (BIT(8))
|
||||
#define SLC_FRHOST_BIT7_INT_ST (BIT(7))
|
||||
#define SLC_FRHOST_BIT6_INT_ST (BIT(6))
|
||||
#define SLC_FRHOST_BIT5_INT_ST (BIT(5))
|
||||
#define SLC_FRHOST_BIT4_INT_ST (BIT(4))
|
||||
#define SLC_FRHOST_BIT3_INT_ST (BIT(3))
|
||||
#define SLC_FRHOST_BIT2_INT_ST (BIT(2))
|
||||
#define SLC_FRHOST_BIT1_INT_ST (BIT(1))
|
||||
#define SLC_FRHOST_BIT0_INT_ST (BIT(0))
|
||||
|
||||
#define SLC_INT_ENA (REG_SLC_BASE + 0xC)
|
||||
#define SLC_TX_DSCR_EMPTY_INT_ENA (BIT(21))
|
||||
#define SLC_RX_DSCR_ERR_INT_ENA (BIT(20))
|
||||
#define SLC_TX_DSCR_ERR_INT_ENA (BIT(19))
|
||||
#define SLC_TOHOST_INT_ENA (BIT(18))
|
||||
#define SLC_RX_EOF_INT_ENA (BIT(17))
|
||||
#define SLC_RX_DONE_INT_ENA (BIT(16))
|
||||
#define SLC_TX_EOF_INT_ENA (BIT(15))
|
||||
#define SLC_TX_DONE_INT_ENA (BIT(14))
|
||||
#define SLC_TOKEN1_1TO0_INT_ENA (BIT(13))
|
||||
#define SLC_TOKEN0_1TO0_INT_ENA (BIT(12))
|
||||
#define SLC_TX_OVF_INT_ENA (BIT(11))
|
||||
#define SLC_RX_UDF_INT_ENA (BIT(10))
|
||||
#define SLC_TX_START_INT_ENA (BIT(9))
|
||||
#define SLC_RX_START_INT_ENA (BIT(8))
|
||||
#define SLC_FRHOST_BIT7_INT_ENA (BIT(7))
|
||||
#define SLC_FRHOST_BIT6_INT_ENA (BIT(6))
|
||||
#define SLC_FRHOST_BIT5_INT_ENA (BIT(5))
|
||||
#define SLC_FRHOST_BIT4_INT_ENA (BIT(4))
|
||||
#define SLC_FRHOST_BIT3_INT_ENA (BIT(3))
|
||||
#define SLC_FRHOST_BIT2_INT_ENA (BIT(2))
|
||||
#define SLC_FRHOST_BIT1_INT_ENA (BIT(1))
|
||||
#define SLC_FRHOST_BIT0_INT_ENA (BIT(0))
|
||||
|
||||
#define SLC_FRHOST_BIT_INT_ENA_ALL 0xff
|
||||
|
||||
#define SLC_INT_CLR (REG_SLC_BASE + 0x10)
|
||||
#define SLC_TX_DSCR_EMPTY_INT_CLR (BIT(21))
|
||||
#define SLC_RX_DSCR_ERR_INT_CLR (BIT(20))
|
||||
#define SLC_TX_DSCR_ERR_INT_CLR (BIT(19))
|
||||
#define SLC_TOHOST_INT_CLR (BIT(18))
|
||||
#define SLC_RX_EOF_INT_CLR (BIT(17))
|
||||
#define SLC_RX_DONE_INT_CLR (BIT(16))
|
||||
#define SLC_TX_EOF_INT_CLR (BIT(15))
|
||||
#define SLC_TX_DONE_INT_CLR (BIT(14))
|
||||
#define SLC_TOKEN1_1TO0_INT_CLR (BIT(13))
|
||||
#define SLC_TOKEN0_1TO0_INT_CLR (BIT(12))
|
||||
#define SLC_TX_OVF_INT_CLR (BIT(11))
|
||||
#define SLC_RX_UDF_INT_CLR (BIT(10))
|
||||
#define SLC_TX_START_INT_CLR (BIT(9))
|
||||
#define SLC_RX_START_INT_CLR (BIT(8))
|
||||
#define SLC_FRHOST_BIT7_INT_CLR (BIT(7))
|
||||
#define SLC_FRHOST_BIT6_INT_CLR (BIT(6))
|
||||
#define SLC_FRHOST_BIT5_INT_CLR (BIT(5))
|
||||
#define SLC_FRHOST_BIT4_INT_CLR (BIT(4))
|
||||
#define SLC_FRHOST_BIT3_INT_CLR (BIT(3))
|
||||
#define SLC_FRHOST_BIT2_INT_CLR (BIT(2))
|
||||
#define SLC_FRHOST_BIT1_INT_CLR (BIT(1))
|
||||
#define SLC_FRHOST_BIT0_INT_CLR (BIT(0))
|
||||
|
||||
#define SLC_RX_STATUS (REG_SLC_BASE + 0x14)
|
||||
#define SLC_RX_EMPTY (BIT(1))
|
||||
#define SLC_RX_FULL (BIT(0))
|
||||
|
||||
#define SLC_RX_FIFO_PUSH (REG_SLC_BASE + 0x18)
|
||||
#define SLC_RXFIFO_PUSH (BIT(16))
|
||||
#define SLC_RXFIFO_WDATA 0x000001FF
|
||||
#define SLC_RXFIFO_WDATA_S 0
|
||||
|
||||
#define SLC_TX_STATUS (REG_SLC_BASE + 0x1C)
|
||||
#define SLC_TX_EMPTY (BIT(1))
|
||||
#define SLC_TX_FULL (BIT(0))
|
||||
|
||||
#define SLC_TX_FIFO_POP (REG_SLC_BASE + 0x20)
|
||||
#define SLC_TXFIFO_POP (BIT(16))
|
||||
#define SLC_TXFIFO_RDATA 0x000007FF
|
||||
#define SLC_TXFIFO_RDATA_S 0
|
||||
|
||||
#define SLC_RX_LINK (REG_SLC_BASE + 0x24)
|
||||
#define SLC_RXLINK_PARK (BIT(31))
|
||||
#define SLC_RXLINK_RESTART (BIT(30))
|
||||
#define SLC_RXLINK_START (BIT(29))
|
||||
#define SLC_RXLINK_STOP (BIT(28))
|
||||
#define SLC_RXLINK_DESCADDR_MASK 0x000FFFFF
|
||||
#define SLC_RXLINK_ADDR_S 0
|
||||
|
||||
#define SLC_TX_LINK (REG_SLC_BASE + 0x28)
|
||||
#define SLC_TXLINK_PARK (BIT(31))
|
||||
#define SLC_TXLINK_RESTART (BIT(30))
|
||||
#define SLC_TXLINK_START (BIT(29))
|
||||
#define SLC_TXLINK_STOP (BIT(28))
|
||||
#define SLC_TXLINK_DESCADDR_MASK 0x000FFFFF
|
||||
#define SLC_TXLINK_ADDR_S 0
|
||||
|
||||
#define SLC_INTVEC_TOHOST (REG_SLC_BASE + 0x2C)
|
||||
#define SLC_TOHOST_INTVEC 0x000000FF
|
||||
#define SLC_TOHOST_INTVEC_S 0
|
||||
|
||||
#define SLC_TOKEN0 (REG_SLC_BASE + 0x30)
|
||||
#define SLC_TOKEN0_MASK 0x00000FFF
|
||||
#define SLC_TOKEN0_S 16
|
||||
#define SLC_TOKEN0_LOCAL_INC_MORE (BIT(14))
|
||||
#define SLC_TOKEN0_LOCAL_INC (BIT(13))
|
||||
#define SLC_TOKEN0_LOCAL_WR (BIT(12))
|
||||
#define SLC_TOKEN0_LOCAL_WDATA_MASK 0x00000FFF
|
||||
#define SLC_TOKEN0_LOCAL_WDATA_S 0
|
||||
|
||||
#define SLC_TOKEN1 (REG_SLC_BASE + 0x34)
|
||||
#define SLC_TOKEN1_MASK 0x00000FFF
|
||||
#define SLC_TOKEN1_S 16
|
||||
#define SLC_TOKEN1_LOCAL_INC_MORE (BIT(14))
|
||||
#define SLC_TOKEN1_LOCAL_INC (BIT(13))
|
||||
#define SLC_TOKEN1_LOCAL_WR (BIT(12))
|
||||
#define SLC_TOKEN1_LOCAL_WDATA 0x00000FFF
|
||||
#define SLC_TOKEN1_LOCAL_WDATA_S 0
|
||||
|
||||
#define SLC_CONF1 (REG_SLC_BASE + 0x38)
|
||||
#define SLC_STATE0 (REG_SLC_BASE + 0x3C)
|
||||
#define SLC_STATE1 (REG_SLC_BASE + 0x40)
|
||||
|
||||
#define SLC_BRIDGE_CONF (REG_SLC_BASE + 0x44)
|
||||
#ifndef ESP_MAC_5
|
||||
#define SLC_TX_PUSH_IDLE_NUM 0x0000FFFF
|
||||
#define SLC_TX_PUSH_IDLE_NUM_S 16
|
||||
#define SLC_TX_DUMMY_MODE (BIT(12))
|
||||
#endif
|
||||
#define SLC_FIFO_MAP_ENA 0x0000000F
|
||||
#define SLC_FIFO_MAP_ENA_S 8
|
||||
#define SLC_TXEOF_ENA 0x0000003F
|
||||
#define SLC_TXEOF_ENA_S 0
|
||||
|
||||
#define SLC_RX_EOF_DES_ADDR (REG_SLC_BASE + 0x48)
|
||||
#define SLC_TX_EOF_DES_ADDR (REG_SLC_BASE + 0x4C)
|
||||
#define SLC_FROM_HOST_LAST_DESC SLC_TX_EOF_DES_ADDR
|
||||
#define SLC_TO_HOST_LAST_DESC SLC_RX_EOF_DES_ADDR
|
||||
|
||||
#define SLC_RX_EOF_BFR_DES_ADDR (REG_SLC_BASE + 0x50)
|
||||
#define SLC_AHB_TEST (REG_SLC_BASE + 0x54)
|
||||
#define SLC_AHB_TESTADDR 0x00000003
|
||||
#define SLC_AHB_TESTADDR_S 4
|
||||
#define SLC_AHB_TESTMODE 0x00000007
|
||||
#define SLC_AHB_TESTMODE_S 0
|
||||
|
||||
#define SLC_SDIO_ST (REG_SLC_BASE + 0x58)
|
||||
#define SLC_BUS_ST 0x00000007
|
||||
#define SLC_BUS_ST_S 12
|
||||
#define SLC_SDIO_WAKEUP (BIT(8))
|
||||
#define SLC_FUNC_ST 0x0000000F
|
||||
#define SLC_FUNC_ST_S 4
|
||||
#define SLC_CMD_ST 0x00000007
|
||||
#define SLC_CMD_ST_S 0
|
||||
|
||||
#define SLC_RX_DSCR_CONF (REG_SLC_BASE + 0x5C)
|
||||
#ifdef ESP_MAC_5
|
||||
#define SLC_INFOR_NO_REPLACE (BIT(9))
|
||||
#define SLC_TOKEN_NO_REPLACE (BIT(8))
|
||||
#define SLC_POP_IDLE_CNT 0x000000FF
|
||||
#else
|
||||
#define SLC_RX_FILL_EN (BIT(20))
|
||||
#define SLC_RX_EOF_MODE (BIT(19))
|
||||
#define SLC_RX_FILL_MODE (BIT(18))
|
||||
#define SLC_INFOR_NO_REPLACE (BIT(17))
|
||||
#define SLC_TOKEN_NO_REPLACE (BIT(16))
|
||||
#define SLC_POP_IDLE_CNT 0x0000FFFF
|
||||
#endif
|
||||
#define SLC_POP_IDLE_CNT_S 0
|
||||
|
||||
#define SLC_TXLINK_DSCR (REG_SLC_BASE + 0x60)
|
||||
#define SLC_TXLINK_DSCR_BF0 (REG_SLC_BASE + 0x64)
|
||||
#define SLC_TXLINK_DSCR_BF1 (REG_SLC_BASE + 0x68)
|
||||
#define SLC_RXLINK_DSCR (REG_SLC_BASE + 0x6C)
|
||||
#define SLC_RXLINK_DSCR_BF0 (REG_SLC_BASE + 0x70)
|
||||
#define SLC_RXLINK_DSCR_BF1 (REG_SLC_BASE + 0x74)
|
||||
#define SLC_DATE (REG_SLC_BASE + 0x78)
|
||||
#define SLC_ID (REG_SLC_BASE + 0x7C)
|
||||
|
||||
#define SLC_HOST_CONF_W0 (REG_SLC_BASE + 0x80 + 0x14)
|
||||
#define SLC_HOST_CONF_W1 (REG_SLC_BASE + 0x80 + 0x18)
|
||||
#define SLC_HOST_CONF_W2 (REG_SLC_BASE + 0x80 + 0x20)
|
||||
#define SLC_HOST_CONF_W3 (REG_SLC_BASE + 0x80 + 0x24)
|
||||
#define SLC_HOST_CONF_W4 (REG_SLC_BASE + 0x80 + 0x28)
|
||||
|
||||
#define SLC_HOST_INTR_ST (REG_SLC_BASE + 0x80 + 0x1c)
|
||||
#define SLC_HOST_INTR_CLR (REG_SLC_BASE + 0x80 + 0x30)
|
||||
#define SLC_HOST_INTR_SOF_BIT (BIT(12))
|
||||
|
||||
#define SLC_HOST_INTR_ENA (REG_SLC_BASE + 0x80 + 0x34)
|
||||
#define SLC_RX_NEW_PACKET_INT_ENA (BIT23)
|
||||
#define SLC_HOST_TOHOST_BIT0_INT_ENA (BIT0)
|
||||
#define SLC_HOST_CONF_W5 (REG_SLC_BASE + 0x80 + 0x3C)
|
||||
#define SLC_HOST_INTR_RAW (REG_SLC_BASE + 0x80 + 0x8)
|
||||
#define SLC_HOST_INTR_ENA_BIT (BIT(23))
|
||||
//[15:12]: 0x3ff9xxxx -- 0b01 from_host
|
||||
// 0x3ffaxxxx -- 0b10 general
|
||||
// 0x3ffbxxxx -- 0b11 to_host
|
||||
#define SLC_DATA_ADDR_CLEAR_MASK (~(0xf<<12))
|
||||
#define SLC_FROM_HOST_ADDR_MASK (0x1<<12)
|
||||
#define SLC_TO_HOST_ADDR_MASK (0x3<<12)
|
||||
|
||||
#define SLC_SET_FROM_HOST_ADDR_MASK(v) do { \
|
||||
(v) &= SLC_DATA_ADDR_CLEAR_MASK; \
|
||||
(v) |= SLC_FROM_HOST_ADDR_MASK; \
|
||||
} while(0);
|
||||
|
||||
#define SLC_SET_TO_HOST_ADDR_MASK(v) do { \
|
||||
(v) &= SLC_DATA_ADDR_CLEAR_MASK; \
|
||||
(v) |= SLC_TO_HOST_ADDR_MASK; \
|
||||
} while(0);
|
||||
|
||||
|
||||
#define SLC_TX_DESC_DEBUG_REG 0x3ff0002c //[15:0] set to 0xcccc
|
||||
|
||||
|
||||
#endif // SLC_REGISTER_H_INCLUDED
|
||||
|
|
@ -6,69 +6,114 @@
|
|||
#include "osapi.h"
|
||||
#include "espconn.h"
|
||||
#include "mystuff.h"
|
||||
#include "ws2812.h"
|
||||
#include "ws2812_i2s.h"
|
||||
#include "hpatimer.h"
|
||||
#include <DFT32.h>
|
||||
#include <embeddednf.h>
|
||||
#include <embeddedout.h>
|
||||
|
||||
|
||||
#define PORT 7777
|
||||
#define SERVER_TIMEOUT 1000
|
||||
#define SERVER_TIMEOUT 1500
|
||||
#define MAX_CONNS 5
|
||||
#define MAX_FRAME 2000
|
||||
|
||||
#define procTaskPrio 0
|
||||
#define procTaskQueueLen 1
|
||||
|
||||
|
||||
static volatile os_timer_t some_timer;
|
||||
static struct espconn *pUdpServer;
|
||||
|
||||
|
||||
|
||||
//Note to self. In future consider looking at this: http://pastebin.com/6eLxSrNz
|
||||
|
||||
|
||||
|
||||
#define HPABUFFSIZE 512
|
||||
extern volatile uint8_t sounddata[HPABUFFSIZE];
|
||||
extern volatile uint16_t soundhead;
|
||||
uint16_t soundtail;
|
||||
|
||||
|
||||
//Call this once we've stacked together one full colorchord frame.
|
||||
static void NewFrame()
|
||||
{
|
||||
//uint8_t led_outs[NUM_LIN_LEDS*3];
|
||||
int i;
|
||||
HandleFrameInfo();
|
||||
UpdateLinearLEDs();
|
||||
|
||||
//SendSPI2812( ledOut, NUM_LIN_LEDS );
|
||||
ws2812_push( ledOut, NUM_LIN_LEDS * 3 );
|
||||
}
|
||||
|
||||
os_event_t procTaskQueue[procTaskQueueLen];
|
||||
static uint8_t printed_ip = 0;
|
||||
uint32_t samp_iir = 0;
|
||||
int wf = 0;
|
||||
|
||||
//Tasks that happen all the time.
|
||||
|
||||
os_event_t procTaskQueue[procTaskQueueLen];
|
||||
static void ICACHE_FLASH_ATTR
|
||||
procTask(os_event_t *events)
|
||||
static void procTask(os_event_t *events)
|
||||
{
|
||||
system_os_post(procTaskPrio, 0, 0 );
|
||||
|
||||
// printf( "%d\n", sounddata[soundtail] );
|
||||
|
||||
while( soundtail != soundhead )
|
||||
{
|
||||
int16_t samp = sounddata[soundtail];
|
||||
samp_iir = samp_iir - (samp_iir>>10) + samp;
|
||||
PushSample32( (samp - (samp_iir>>10))*16 );
|
||||
soundtail = (soundtail+1)&(HPABUFFSIZE-1);
|
||||
|
||||
wf++;
|
||||
if( wf == 128 )
|
||||
{
|
||||
NewFrame();
|
||||
wf = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( events->sig == 0 && events->par == 0 )
|
||||
{
|
||||
//Idle Event.
|
||||
struct station_config wcfg;
|
||||
char stret[256];
|
||||
char *stt = &stret[0];
|
||||
struct ip_info ipi;
|
||||
|
||||
int stat = wifi_station_get_connect_status();
|
||||
|
||||
// printf( "STAT: %d\n", stat );
|
||||
|
||||
if( stat == STATION_WRONG_PASSWORD || stat == STATION_NO_AP_FOUND || stat == STATION_CONNECT_FAIL )
|
||||
{
|
||||
wifi_set_opmode_current( 2 );
|
||||
stt += ets_sprintf( stt, "Connection failed: %d\n", stat );
|
||||
uart0_sendStr(stret);
|
||||
}
|
||||
|
||||
if( stat == STATION_GOT_IP && !printed_ip )
|
||||
{
|
||||
wifi_station_get_config( &wcfg );
|
||||
wifi_get_ip_info(0, &ipi);
|
||||
stt += ets_sprintf( stt, "STAT: %d\n", stat );
|
||||
stt += ets_sprintf( stt, "IP: %d.%d.%d.%d\n", (ipi.ip.addr>>0)&0xff,(ipi.ip.addr>>8)&0xff,(ipi.ip.addr>>16)&0xff,(ipi.ip.addr>>24)&0xff );
|
||||
stt += ets_sprintf( stt, "NM: %d.%d.%d.%d\n", (ipi.netmask.addr>>0)&0xff,(ipi.netmask.addr>>8)&0xff,(ipi.netmask.addr>>16)&0xff,(ipi.netmask.addr>>24)&0xff );
|
||||
stt += ets_sprintf( stt, "GW: %d.%d.%d.%d\n", (ipi.gw.addr>>0)&0xff,(ipi.gw.addr>>8)&0xff,(ipi.gw.addr>>16)&0xff,(ipi.gw.addr>>24)&0xff );
|
||||
stt += ets_sprintf( stt, "WCFG: /%s/%s/\n", wcfg.ssid, wcfg.password );
|
||||
uart0_sendStr(stret);
|
||||
printed_ip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Timer event.
|
||||
static void ICACHE_FLASH_ATTR
|
||||
myTimer(void *arg)
|
||||
static void myTimer(void *arg)
|
||||
{
|
||||
int i;
|
||||
uart0_sendStr(".");
|
||||
SetupConstants();
|
||||
|
||||
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
|
||||
gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);
|
||||
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
|
||||
//XXX LOOK HERE!!!
|
||||
//Right now, I am not actually using real data from the inputs, but rather doing this to test performance of my algorithm.
|
||||
//The next step is to take real ADC inpts.
|
||||
for( i = 0; i < 4000; i++ )
|
||||
{
|
||||
HandleProgressiveInt( 0xaa, 0xbb );
|
||||
}
|
||||
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
|
||||
// uart0_sendStr(".");
|
||||
// printf( "%d/%d\n",soundtail,soundhead );
|
||||
// printf( "%d/%d\n",soundtail,soundhead );
|
||||
// uint8_t ledout[] = { 0x00, 0xff, 0xaa, 0x00, 0xff, 0xaa, };
|
||||
// ws2812_push( ledout, 6 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,20 +121,15 @@ static void ICACHE_FLASH_ATTR
|
|||
static void ICACHE_FLASH_ATTR
|
||||
udpserver_recv(void *arg, char *pusrdata, unsigned short len)
|
||||
{
|
||||
int i = 0;
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
uint8_t buffer[MAX_FRAME];
|
||||
// uint8_t buffer[MAX_FRAME];
|
||||
|
||||
//Make sure watchdog is disabled. WS2812's take a while and can mess it up.
|
||||
ets_wdt_disable();
|
||||
os_intr_lock();
|
||||
WS2812OutBuffer( pusrdata, len );
|
||||
os_intr_unlock();
|
||||
ets_sprintf( buffer, "%d\r\n", len );
|
||||
uart0_sendStr(buffer);
|
||||
// uint8_t ledout[] = { 0x00, 0xff, 0xaa, 0x00, 0xff, 0xaa, };
|
||||
uart0_sendStr("X");
|
||||
// ws2812_push( pusrdata, len );
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR at_recvTask()
|
||||
void ICACHE_FLASH_ATTR charrx( uint8_t c )
|
||||
{
|
||||
//Called from UART.
|
||||
}
|
||||
|
@ -102,8 +142,19 @@ void user_init(void)
|
|||
|
||||
uart0_sendStr("\r\nCustom Server\r\n");
|
||||
|
||||
|
||||
wifi_set_opmode( 2 ); //We broadcast our ESSID, wait for peopel to join.
|
||||
|
||||
/*
|
||||
struct station_config stationConf;
|
||||
wifi_set_opmode( 1 ); //We broadcast our ESSID, wait for peopel to join.
|
||||
os_memcpy(&stationConf.ssid, "xxx", ets_strlen( "xxx" ) + 1);
|
||||
os_memcpy(&stationConf.password, "yyy", ets_strlen( "yyy" ) + 1);
|
||||
|
||||
wifi_set_opmode( 1 );
|
||||
wifi_station_set_config(&stationConf);
|
||||
wifi_station_connect();**/
|
||||
|
||||
pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
ets_memset( pUdpServer, 0, sizeof( struct espconn ) );
|
||||
espconn_create( pUdpServer );
|
||||
|
@ -112,31 +163,27 @@ void user_init(void)
|
|||
pUdpServer->proto.udp->local_port = 7777;
|
||||
espconn_regist_recvcb(pUdpServer, udpserver_recv);
|
||||
|
||||
wifi_station_dhcpc_start();
|
||||
|
||||
/* wifi_station_dhcpc_start();
|
||||
*/
|
||||
if( espconn_create( pUdpServer ) )
|
||||
{
|
||||
while(1) { uart0_sendStr( "\r\nFAULT\r\n" ); }
|
||||
}
|
||||
|
||||
//XXX TODO figure out how to safely re-allow this.
|
||||
ets_wdt_disable();
|
||||
|
||||
char outbuffer[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,0xff,0xff, 0x00,0xff,0x00 };
|
||||
WS2812OutBuffer( outbuffer, 1 ); //Initialize the output.
|
||||
|
||||
//Add a process
|
||||
system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen);
|
||||
|
||||
uart0_sendStr("\r\nCustom Server\r\n");
|
||||
WS2812OutBuffer( outbuffer, sizeof(outbuffer) );
|
||||
|
||||
|
||||
//Timer example
|
||||
os_timer_disarm(&some_timer);
|
||||
os_timer_setfn(&some_timer, (os_timer_func_t *)myTimer, NULL);
|
||||
os_timer_arm(&some_timer, 1000, 1);
|
||||
|
||||
os_timer_arm(&some_timer, 100, 1);
|
||||
|
||||
Init(); //Init colorchord
|
||||
|
||||
StartHPATimer(); //Init the high speed ADC timer.
|
||||
|
||||
ws2812_init();
|
||||
|
||||
system_os_post(procTaskPrio, 0, 0 );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
#include "ws2812.h"
|
||||
#include "ets_sys.h"
|
||||
#include "mystuff.h"
|
||||
#include "osapi.h"
|
||||
|
||||
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
|
||||
gpio_output_set(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no,0)
|
||||
|
||||
|
||||
//I just used a scope to figure out the right time periods.
|
||||
|
||||
void SEND_WS_0()
|
||||
{
|
||||
uint8_t time = 8;
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SEND_WS_1()
|
||||
{
|
||||
uint8_t time = 9;
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 1 );
|
||||
}
|
||||
time = 3;
|
||||
while(time--)
|
||||
{
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR + GPIO_ID_PIN(WSGPIO), 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void WS2812OutBuffer( uint8_t * buffer, uint16_t length )
|
||||
{
|
||||
uint16_t i;
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(WSGPIO), 0);
|
||||
for( i = 0; i < length; i++ )
|
||||
{
|
||||
uint8_t byte = buffer[i];
|
||||
if( byte & 0x80 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x40 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x20 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x10 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x08 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x04 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x02 ) SEND_WS_1(); else SEND_WS_0();
|
||||
if( byte & 0x01 ) SEND_WS_1(); else SEND_WS_0();
|
||||
}
|
||||
//reset will happen when it's low long enough.
|
||||
//(don't call this function twice within 10us)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef _WS2812_H
|
||||
#define _WS2812_H
|
||||
|
||||
#define WSGPIO 0
|
||||
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_sys.h"
|
||||
#include "gpio.h"
|
||||
|
||||
//You will have to os_intr_lock(); os_intr_unlock();
|
||||
|
||||
void WS2812OutBuffer( uint8_t * buffer, uint16_t length );
|
||||
|
||||
#endif
|
||||
|
452
embedded8266/user/ws2812_i2s.c
Normal file
452
embedded8266/user/ws2812_i2s.c
Normal file
|
@ -0,0 +1,452 @@
|
|||
/******************************************************************************
|
||||
* Copyright 2013-2015 Espressif Systems
|
||||
*
|
||||
* FileName: i2s_freertos.c
|
||||
*
|
||||
* Description: I2S output routines for a FreeRTOS system. Uses DMA and a queue
|
||||
* to abstract away the nitty-gritty details.
|
||||
*
|
||||
* Modification history:
|
||||
* 2015/06/01, v1.0 File created.
|
||||
* 2015/07/23, Switch to making it a WS2812 output device.
|
||||
*******************************************************************************
|
||||
|
||||
Notes:
|
||||
|
||||
This is pretty badly hacked together from the MP3 example.
|
||||
I spent some time trying to strip it down to avoid a lot of the TX_ stuff.
|
||||
That seems to work.
|
||||
|
||||
Major suggestions that I couldn't figure out:
|
||||
* Use interrupts to disable DMA, so it isn't running nonstop.
|
||||
* Use interrupts to flag when new data can be sent.
|
||||
|
||||
When I try using interrupts, it seems to work for a bit but things fall apart
|
||||
rather quickly and the engine just refuses to send anymore until reboot.
|
||||
|
||||
The way it works right now is to keep the DMA running forever and just update
|
||||
the data in the buffer so it continues sending the frame.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#include "slc_register.h"
|
||||
#include "mystuff.h"
|
||||
#include <c_types.h>
|
||||
#include "ws2812_i2s.h"
|
||||
#include "user_interface.h"
|
||||
#include "pin_mux_register.h"
|
||||
|
||||
//Creates an I2S SR of 93,750 Hz, or 3 MHz Bitclock (.333us/sample)
|
||||
// 12000000L/(div*bestbck*2)
|
||||
//It is likely you could speed this up a little.
|
||||
#define WS_I2S_BCK 16
|
||||
#define WS_I2S_DIV 4
|
||||
|
||||
#ifndef i2c_bbpll
|
||||
#define i2c_bbpll 0x67
|
||||
#define i2c_bbpll_en_audio_clock_out 4
|
||||
#define i2c_bbpll_en_audio_clock_out_msb 7
|
||||
#define i2c_bbpll_en_audio_clock_out_lsb 7
|
||||
#define i2c_bbpll_hostid 4
|
||||
|
||||
#define i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) rom_i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata)
|
||||
#define i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) rom_i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb)
|
||||
#define i2c_writeReg_Mask_def(block, reg_add, indata) \
|
||||
i2c_writeReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb, indata)
|
||||
#define i2c_readReg_Mask_def(block, reg_add) \
|
||||
i2c_readReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb)
|
||||
#endif
|
||||
#ifndef ETS_SLC_INUM
|
||||
#define ETS_SLC_INUM 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//From i2s_reg.h
|
||||
#define DR_REG_I2S_BASE (0x60000e00)
|
||||
|
||||
#define I2STXFIFO (DR_REG_I2S_BASE + 0x0000)
|
||||
#define I2SRXFIFO (DR_REG_I2S_BASE + 0x0004)
|
||||
#define I2SCONF (DR_REG_I2S_BASE + 0x0008)
|
||||
#define I2S_BCK_DIV_NUM 0x0000003F
|
||||
#define I2S_BCK_DIV_NUM_S 22
|
||||
#define I2S_CLKM_DIV_NUM 0x0000003F
|
||||
#define I2S_CLKM_DIV_NUM_S 16
|
||||
#define I2S_BITS_MOD 0x0000000F
|
||||
#define I2S_BITS_MOD_S 12
|
||||
#define I2S_RECE_MSB_SHIFT (BIT(11))
|
||||
#define I2S_TRANS_MSB_SHIFT (BIT(10))
|
||||
#define I2S_I2S_RX_START (BIT(9))
|
||||
#define I2S_I2S_TX_START (BIT(8))
|
||||
#define I2S_MSB_RIGHT (BIT(7))
|
||||
#define I2S_RIGHT_FIRST (BIT(6))
|
||||
#define I2S_RECE_SLAVE_MOD (BIT(5))
|
||||
#define I2S_TRANS_SLAVE_MOD (BIT(4))
|
||||
#define I2S_I2S_RX_FIFO_RESET (BIT(3))
|
||||
#define I2S_I2S_TX_FIFO_RESET (BIT(2))
|
||||
#define I2S_I2S_RX_RESET (BIT(1))
|
||||
#define I2S_I2S_TX_RESET (BIT(0))
|
||||
#define I2S_I2S_RESET_MASK 0xf
|
||||
|
||||
#define I2SINT_RAW (DR_REG_I2S_BASE + 0x000c)
|
||||
#define I2S_I2S_TX_REMPTY_INT_RAW (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_RAW (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_RAW (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_RAW (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_RAW (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_RAW (BIT(0))
|
||||
|
||||
|
||||
#define I2SINT_ST (DR_REG_I2S_BASE + 0x0010)
|
||||
#define I2S_I2S_TX_REMPTY_INT_ST (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_ST (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_ST (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_ST (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_ST (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_ST (BIT(0))
|
||||
|
||||
#define I2SINT_ENA (DR_REG_I2S_BASE + 0x0014)
|
||||
#define I2S_I2S_TX_REMPTY_INT_ENA (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_ENA (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_ENA (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_ENA (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_ENA (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_ENA (BIT(0))
|
||||
|
||||
#define I2SINT_CLR (DR_REG_I2S_BASE + 0x0018)
|
||||
#define I2S_I2S_TX_REMPTY_INT_CLR (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_CLR (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_CLR (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_CLR (BIT(2))
|
||||
#define I2S_I2S_PUT_DATA_INT_CLR (BIT(1))
|
||||
#define I2S_I2S_TAKE_DATA_INT_CLR (BIT(0))
|
||||
|
||||
#define I2STIMING (DR_REG_I2S_BASE + 0x001c)
|
||||
#define I2S_TRANS_BCK_IN_INV (BIT(22))
|
||||
#define I2S_RECE_DSYNC_SW (BIT(21))
|
||||
#define I2S_TRANS_DSYNC_SW (BIT(20))
|
||||
#define I2S_RECE_BCK_OUT_DELAY 0x00000003
|
||||
#define I2S_RECE_BCK_OUT_DELAY_S 18
|
||||
#define I2S_RECE_WS_OUT_DELAY 0x00000003
|
||||
#define I2S_RECE_WS_OUT_DELAY_S 16
|
||||
#define I2S_TRANS_SD_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_SD_OUT_DELAY_S 14
|
||||
#define I2S_TRANS_WS_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_WS_OUT_DELAY_S 12
|
||||
#define I2S_TRANS_BCK_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_BCK_OUT_DELAY_S 10
|
||||
#define I2S_RECE_SD_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_SD_IN_DELAY_S 8
|
||||
#define I2S_RECE_WS_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_WS_IN_DELAY_S 6
|
||||
#define I2S_RECE_BCK_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_BCK_IN_DELAY_S 4
|
||||
#define I2S_TRANS_WS_IN_DELAY 0x00000003
|
||||
#define I2S_TRANS_WS_IN_DELAY_S 2
|
||||
#define I2S_TRANS_BCK_IN_DELAY 0x00000003
|
||||
#define I2S_TRANS_BCK_IN_DELAY_S 0
|
||||
|
||||
#define I2S_FIFO_CONF (DR_REG_I2S_BASE + 0x0020)
|
||||
#define I2S_I2S_RX_FIFO_MOD 0x00000007
|
||||
#define I2S_I2S_RX_FIFO_MOD_S 16
|
||||
#define I2S_I2S_TX_FIFO_MOD 0x00000007
|
||||
#define I2S_I2S_TX_FIFO_MOD_S 13
|
||||
#define I2S_I2S_DSCR_EN (BIT(12))
|
||||
#define I2S_I2S_TX_DATA_NUM 0x0000003F
|
||||
#define I2S_I2S_TX_DATA_NUM_S 6
|
||||
#define I2S_I2S_RX_DATA_NUM 0x0000003F
|
||||
#define I2S_I2S_RX_DATA_NUM_S 0
|
||||
|
||||
|
||||
#define I2SRXEOF_NUM (DR_REG_I2S_BASE + 0x0024)
|
||||
#define I2S_I2S_RX_EOF_NUM 0xFFFFFFFF
|
||||
#define I2S_I2S_RX_EOF_NUM_S 0
|
||||
|
||||
#define I2SCONF_SIGLE_DATA (DR_REG_I2S_BASE + 0x0028)
|
||||
#define I2S_I2S_SIGLE_DATA 0xFFFFFFFF
|
||||
#define I2S_I2S_SIGLE_DATA_S 0
|
||||
|
||||
#define I2SCONF_CHAN (DR_REG_I2S_BASE + 0x002c)
|
||||
#define I2S_RX_CHAN_MOD 0x00000003
|
||||
#define I2S_RX_CHAN_MOD_S 3
|
||||
#define I2S_TX_CHAN_MOD 0x00000007
|
||||
#define I2S_TX_CHAN_MOD_S 0
|
||||
|
||||
|
||||
//From sdio_slv.h
|
||||
|
||||
|
||||
struct sdio_queue
|
||||
{
|
||||
uint32 blocksize:12;
|
||||
uint32 datalen:12;
|
||||
uint32 unused:5;
|
||||
uint32 sub_sof:1;
|
||||
uint32 eof:1;
|
||||
uint32 owner:1;
|
||||
|
||||
uint32 buf_ptr;
|
||||
uint32 next_link_ptr;
|
||||
};
|
||||
|
||||
struct sdio_slave_status_element
|
||||
{
|
||||
uint32 wr_busy:1;
|
||||
uint32 rd_empty :1;
|
||||
uint32 comm_cnt :3;
|
||||
uint32 intr_no :3;
|
||||
uint32 rx_length:16;
|
||||
uint32 res:8;
|
||||
};
|
||||
|
||||
union sdio_slave_status
|
||||
{
|
||||
struct sdio_slave_status_element elm_value;
|
||||
uint32 word_value;
|
||||
};
|
||||
|
||||
#define RX_AVAILIBLE 2
|
||||
#define TX_AVAILIBLE 1
|
||||
#define INIT_STAGE 0
|
||||
|
||||
#define SDIO_QUEUE_LEN 8
|
||||
#define MOSI 0
|
||||
#define MISO 1
|
||||
#define SDIO_DATA_ERROR 6
|
||||
|
||||
#define SLC_INTEREST_EVENT (SLC_TX_EOF_INT_ENA | SLC_RX_EOF_INT_ENA | SLC_RX_UDF_INT_ENA | SLC_TX_DSCR_ERR_INT_ENA)
|
||||
#define TRIG_TOHOST_INT() SET_PERI_REG_MASK(SLC_INTVEC_TOHOST , BIT0);\
|
||||
CLEAR_PERI_REG_MASK(SLC_INTVEC_TOHOST , BIT0)
|
||||
|
||||
|
||||
///Rest of program...
|
||||
|
||||
//Pointer to the I2S DMA buffer data
|
||||
//static unsigned int i2sBuf[I2SDMABUFCNT][I2SDMABUFLEN];
|
||||
//I2S DMA buffer descriptors
|
||||
//static struct sdio_queue i2sBufDesc[I2SDMABUFCNT];
|
||||
static struct sdio_queue i2sBufDescOut;
|
||||
static struct sdio_queue i2sBufDescZeroes;
|
||||
|
||||
static unsigned int i2sZeroes[32];
|
||||
static unsigned int i2sBlock[WS_BLOCKSIZE/4];
|
||||
|
||||
//Queue which contains empty DMA buffers
|
||||
//DMA underrun counter
|
||||
|
||||
|
||||
#ifdef USE_2812_INTERRUPTS
|
||||
|
||||
volatile uint8_t ws2812_dma_complete;
|
||||
|
||||
//This routine is called as soon as the DMA routine has something to tell us. All we
|
||||
//handle here is the RX_EOF_INT status, which indicate the DMA has sent a buffer whose
|
||||
//descriptor has the 'EOF' field set to 1.
|
||||
LOCAL void slc_isr(void) {
|
||||
//clear all intr flags
|
||||
// WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);//slc_intr_status);
|
||||
|
||||
// ws2812_dma_complete = 1;
|
||||
|
||||
//This is a little wacky. This function actually gets called twice.
|
||||
//Once for the initial transfer, but by the time we tell it to stop
|
||||
//The other zero transfer's already begun.
|
||||
// SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_STOP);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//Initialize I2S subsystem for DMA circular buffer use
|
||||
void ICACHE_FLASH_ATTR ws2812_init()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
//Reset DMA
|
||||
SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST);
|
||||
CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST);
|
||||
|
||||
//Clear DMA int flags
|
||||
SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
||||
CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
||||
|
||||
//Enable and configure DMA
|
||||
CLEAR_PERI_REG_MASK(SLC_CONF0, (SLC_MODE<<SLC_MODE_S));
|
||||
SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S));
|
||||
SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE);
|
||||
CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);
|
||||
|
||||
i2sBufDescOut.owner = 1;
|
||||
i2sBufDescOut.eof = 1;
|
||||
i2sBufDescOut.sub_sof = 0;
|
||||
i2sBufDescOut.datalen = WS_BLOCKSIZE; //Size (in bytes)
|
||||
i2sBufDescOut.blocksize = WS_BLOCKSIZE; //Size (in bytes)
|
||||
i2sBufDescOut.buf_ptr=(uint32_t)&i2sBlock[0];
|
||||
i2sBufDescOut.unused=0;
|
||||
i2sBufDescOut.next_link_ptr=(uint32_t)&i2sBufDescZeroes; //At the end, just redirect the DMA to the zero buffer.
|
||||
|
||||
i2sBufDescZeroes.owner = 1;
|
||||
i2sBufDescZeroes.eof = 1;
|
||||
i2sBufDescZeroes.sub_sof = 0;
|
||||
i2sBufDescZeroes.datalen = 32;
|
||||
i2sBufDescZeroes.blocksize = 32;
|
||||
i2sBufDescZeroes.buf_ptr=(uint32_t)&i2sZeroes[0];
|
||||
i2sBufDescZeroes.unused=0;
|
||||
i2sBufDescZeroes.next_link_ptr=(uint32_t)&i2sBufDescOut;
|
||||
|
||||
|
||||
for( x = 0; x < 32; x++ )
|
||||
{
|
||||
i2sZeroes[x] = 0x00;
|
||||
}
|
||||
for( x = 0; x < WS_BLOCKSIZE/4; x++ )
|
||||
{
|
||||
i2sBlock[x] = 0x00000000;//(x == 0 || x == 999)?0xaa:0x00;
|
||||
|
||||
/* uint16_t * tt = (uint16_t*)&i2sBlock[x];
|
||||
(*(tt+0)) = 0xA0F0;
|
||||
(*(tt+1)) = 0xC0E0;*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
// CLEAR_PERI_REG_MASK(SLC_TX_LINK,SLC_TXLINK_DESCADDR_MASK);
|
||||
// SET_PERI_REG_MASK(SLC_TX_LINK, ((uint32)&i2sBufDescZeroes) & SLC_TXLINK_DESCADDR_MASK); //any random desc is OK, we don't use TX but it needs something valid
|
||||
|
||||
CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDescOut) & SLC_RXLINK_DESCADDR_MASK);
|
||||
|
||||
#if USE_2812_INTERRUPTS
|
||||
|
||||
//Attach the DMA interrupt
|
||||
ets_isr_attach(ETS_SLC_INUM, slc_isr);
|
||||
//Enable DMA operation intr
|
||||
WRITE_PERI_REG(SLC_INT_ENA, SLC_RX_EOF_INT_ENA);
|
||||
//clear any interrupt flags that are set
|
||||
WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
|
||||
///enable DMA intr in cpu
|
||||
ets_isr_unmask(1<<ETS_SLC_INUM);
|
||||
|
||||
#endif
|
||||
|
||||
//Start transmission
|
||||
// SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START);
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);
|
||||
|
||||
//----
|
||||
|
||||
//Init pins to i2s functions
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA);
|
||||
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_I2SO_WS);
|
||||
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_I2SO_BCK);
|
||||
|
||||
//Enable clock to i2s subsystem
|
||||
i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);
|
||||
|
||||
//Reset I2S subsystem
|
||||
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
|
||||
//Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only)
|
||||
CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S));
|
||||
//Enable DMA in i2s subsystem
|
||||
SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);
|
||||
|
||||
//tx/rx binaureal
|
||||
// CLEAR_PERI_REG_MASK(I2SCONF_CHAN, (I2S_TX_CHAN_MOD<<I2S_TX_CHAN_MOD_S)|(I2S_RX_CHAN_MOD<<I2S_RX_CHAN_MOD_S));
|
||||
|
||||
#if USE_2812_INTERRUPTS
|
||||
|
||||
//Clear int
|
||||
SET_PERI_REG_MASK(I2SINT_CLR,
|
||||
I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
CLEAR_PERI_REG_MASK(I2SINT_CLR,
|
||||
I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
|
||||
#endif
|
||||
|
||||
//trans master&rece slave,MSB shift,right_first,msb right
|
||||
|
||||
CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
|
||||
(I2S_BITS_MOD<<I2S_BITS_MOD_S)|
|
||||
(I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
|
||||
(I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));
|
||||
SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
|
||||
I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
|
||||
(((WS_I2S_BCK-1)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
|
||||
(((WS_I2S_DIV-1)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S));
|
||||
|
||||
|
||||
//No idea if ints are needed...
|
||||
//clear int
|
||||
SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
//enable int
|
||||
SET_PERI_REG_MASK(I2SINT_ENA, I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA);
|
||||
|
||||
|
||||
//Start transmission
|
||||
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START);
|
||||
}
|
||||
|
||||
|
||||
//Tricky, send out WS2812 bits with coded pulses, one nibble, then the other.
|
||||
static const uint16_t bitpatterns[16] = {
|
||||
0b1000100010001000, 0b1000100010001110, 0b1000100011101000, 0b1000100011101110,
|
||||
0b1000111010001000, 0b1000111010001110, 0b1000111011101000, 0b1000111011101110,
|
||||
0b1110100010001000, 0b1110100010001110, 0b1110100011101000, 0b1110100011101110,
|
||||
0b1110111010001000, 0b1110111010001110, 0b1110111011101000, 0b1110111011101110,
|
||||
};
|
||||
|
||||
void ws2812_push( uint8_t * buffer, uint16_t buffersize )
|
||||
{
|
||||
uint16_t * bufferpl = (uint16_t*)&i2sBlock[0];
|
||||
uint16_t place;
|
||||
|
||||
// while( !ws2812_dma_complete );
|
||||
|
||||
if( buffersize * 4 > WS_BLOCKSIZE ) return;
|
||||
|
||||
for( place = 0; place < buffersize; place++ )
|
||||
{
|
||||
uint8_t btosend = buffer[place];
|
||||
*(bufferpl++) = bitpatterns[(btosend&0x0f)];
|
||||
*(bufferpl++) = bitpatterns[(btosend>>4)&0x0f];
|
||||
}
|
||||
|
||||
#ifdef USE_2812_INTERRUPTS
|
||||
|
||||
uint16_t leftover = buffersize & 0x1f;
|
||||
if( leftover ) leftover = 32 - leftover;
|
||||
for( place = 0; place < leftover; place++ )
|
||||
{
|
||||
*(bufferpl++) = 0;
|
||||
*(bufferpl++) = 0;
|
||||
}
|
||||
|
||||
buffersize += leftover;
|
||||
|
||||
uint16_t sizeout_words = buffersize * 2;
|
||||
|
||||
i2sBufDescOut.owner = 1;
|
||||
i2sBufDescOut.eof = 1;
|
||||
i2sBufDescOut.sub_sof = 0;
|
||||
i2sBufDescOut.datalen = sizeout_words*2; //Size (in bytes)
|
||||
i2sBufDescOut.blocksize = sizeout_words*2; //Size (in bytes)
|
||||
i2sBufDescOut.buf_ptr = (uint32_t)&i2sBlock[0];
|
||||
i2sBufDescOut.unused = 0;
|
||||
i2sBufDescOut.next_link_ptr=(uint32_t)&i2sBufDescZeroes; //At the end, just redirect the DMA to the zero buffer.
|
||||
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_STOP);
|
||||
CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDescOut) & SLC_RXLINK_DESCADDR_MASK);
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
20
embedded8266/user/ws2812_i2s.h
Normal file
20
embedded8266/user/ws2812_i2s.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef _I2S_TEST
|
||||
#define _I2S_TEST
|
||||
|
||||
//Stuff that should be for the header:
|
||||
|
||||
#include <c_types.h>
|
||||
|
||||
//Parameters for the I2S DMA behaviour
|
||||
//#define I2SDMABUFCNT (2) //Number of buffers in the I2S circular buffer
|
||||
//#define I2SDMABUFLEN (32*2) //Length of one buffer, in 32-bit words.
|
||||
|
||||
//NOTE: Blocksize MUST be divisible by 4. Cannot exceed 4092
|
||||
//Each LED takes up 12 block bytes.
|
||||
#define WS_BLOCKSIZE 4000
|
||||
|
||||
void ICACHE_FLASH_ATTR ws2812_init();
|
||||
void ws2812_push( uint8_t * buffer, uint16_t buffersize ); //Buffersize = Nr LEDs * 3
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue