commiting examples
This commit is contained in:
53
Examples/NeoPixel Example/ADC.c
Normal file
53
Examples/NeoPixel Example/ADC.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <samd21g18a.h>
|
||||
#include "ADC.h"
|
||||
|
||||
volatile uint16_t adc_value;
|
||||
|
||||
void ADC_init(void)
|
||||
{
|
||||
/* enable peripheral clock */
|
||||
PM->APBCMASK.bit.ADC_ = 1;
|
||||
|
||||
/* enable generic clock */
|
||||
GCLK->CLKCTRL.bit.ID = GCLK_CLKCTRL_ID_ADC_Val; // configure generic clock for ADC
|
||||
GCLK->CLKCTRL.bit.GEN = GCLK_CLKCTRL_GEN_GCLK0_Val; // source is generic clock generator 0
|
||||
GCLK->CLKCTRL.bit.CLKEN = 1; // enable generic clock
|
||||
|
||||
/* select GPIO pins alternative function */
|
||||
PORT->Group[1].PINCFG[8].bit.PMUXEN = 1; // enable alternative function for pin PB08
|
||||
PORT->Group[1].PINCFG[3].bit.PMUXEN = 1; // enable alternative function for pin PA03 (analog function AREF)
|
||||
PORT->Group[1].PMUX[4].bit.PMUXE = MUX_PB08B_ADC_AIN2; // PB08 alternative function B (ADC in 2)
|
||||
|
||||
/* configure peripheral */
|
||||
ADC->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV256_Val; // prescaler
|
||||
ADC->CTRLB.bit.DIFFMODE = 0x00; // single-ended mode
|
||||
ADC->CTRLB.bit.LEFTADJ = 0x00; // right adjusted result
|
||||
ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_16BIT_Val; // conversion resolution is 16 bit (for accumulation)
|
||||
ADC->CTRLB.bit.FREERUN = 1; // fee run mode
|
||||
ADC->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_16_Val; // result is the accumulation of 16 samples
|
||||
ADC->AVGCTRL.bit.ADJRES = 0x04; // result is averaged over 16 samples
|
||||
ADC->INPUTCTRL.bit.MUXNEG = ADC_INPUTCTRL_MUXNEG_GND_Val; // negative input is internal ground
|
||||
ADC->INPUTCTRL.bit.MUXPOS = ADC_INPUTCTRL_MUXPOS_PIN2_Val; // positive input on ADC in 2 (pin PB08)
|
||||
|
||||
/* enable result ready interrupt */
|
||||
ADC->INTENSET.reg = ADC_INTENSET_RESRDY;
|
||||
NVIC_EnableIRQ(ADC_IRQn);
|
||||
|
||||
/* enable peripheral */
|
||||
ADC->CTRLA.reg |= ADC_CTRLA_ENABLE;
|
||||
}
|
||||
|
||||
void ADC_deinit(void)
|
||||
{
|
||||
/* disable result ready interrupt */
|
||||
ADC->INTENCLR.reg = ADC_INTENCLR_RESRDY;
|
||||
NVIC_DisableIRQ(ADC_IRQn);
|
||||
}
|
||||
|
||||
void ADC_Handler(void)
|
||||
{
|
||||
adc_value = (ADC->RESULT.reg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
9
Examples/NeoPixel Example/ADC.h
Normal file
9
Examples/NeoPixel Example/ADC.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef ADC_H_
|
||||
#define ADC_H_
|
||||
|
||||
extern volatile uint16_t adc_value;
|
||||
|
||||
void ADC_init(void);
|
||||
void ADC_deinit(void);
|
||||
|
||||
#endif /* ADC_H_ */
|
||||
84
Examples/NeoPixel Example/DMA.c
Normal file
84
Examples/NeoPixel Example/DMA.c
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <samd21g18a.h>
|
||||
#include <string.h>
|
||||
#include "DMA.h"
|
||||
|
||||
#define MAX_DESCRIPTORS 2
|
||||
|
||||
__attribute__((__aligned__(16))) static DmacDescriptor descriptor_section[MAX_DESCRIPTORS];
|
||||
__attribute__((__aligned__(16))) static DmacDescriptor write_back_section[MAX_DESCRIPTORS];
|
||||
static int used_channels = 0;
|
||||
|
||||
int volatile dma_frame = 0;
|
||||
|
||||
void DMA_init(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/* enable peripheral clock */
|
||||
PM->APBBMASK.bit.DMAC_ = 1;
|
||||
|
||||
/* enable AHB master clock */
|
||||
PM->AHBMASK.bit.DMAC_ = 1;
|
||||
|
||||
/* configure DMA controller */
|
||||
DMAC->BASEADDR.reg = (uint32_t)descriptor_section; // descriptor memory section start
|
||||
DMAC->WRBADDR.reg = (uint32_t)write_back_section; // descriptor write-back memory section start
|
||||
DMAC->CTRL.bit.LVLEN0 = 1; // enable level 0 priority
|
||||
DMAC->CTRL.bit.LVLEN1 = 1; // enable level 1 priority
|
||||
DMAC->CTRL.bit.LVLEN2 = 1; // enable level 2 priority
|
||||
DMAC->CTRL.bit.LVLEN3 = 1; // enable level 3 priority
|
||||
|
||||
/* DMA is initialized */
|
||||
initialized = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* add the first least significant free channel with its descriptor (TODO: implement linked descriptors) */
|
||||
void DMA_add_channel(int source, DmacDescriptor *descriptor)
|
||||
{
|
||||
/* disable DMA if enabled */
|
||||
if (DMAC->CTRL.bit.DMAENABLE)
|
||||
DMAC->CTRL.bit.DMAENABLE = 0;
|
||||
while (DMAC->CTRL.bit.DMAENABLE)
|
||||
;
|
||||
|
||||
/* add transfer descriptor to transfer descriptor section (before enabling channel!) */
|
||||
memcpy(descriptor_section + used_channels * sizeof(DmacDescriptor), descriptor, sizeof(DmacDescriptor));
|
||||
|
||||
/* configure and enable first least significant free channel */
|
||||
DMAC->CHID.bit.ID = used_channels++; // use first free channel
|
||||
DMAC->CHCTRLB.bit.LVL = 0x00; // channel priority level 0
|
||||
DMAC->CHCTRLB.bit.TRIGACT = 0x02; // one trigger each beat transfer
|
||||
DMAC->CHCTRLB.bit.TRIGSRC = source; // select trigger source
|
||||
DMAC->CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; // enable channel
|
||||
|
||||
/* enable DMA block transfer complete interrupt */
|
||||
DMAC->CHINTENSET.bit.TCMPL = 1; // enable DMA block transfer complete interrupt
|
||||
NVIC_EnableIRQ(DMAC_IRQn); // enable DMA interrupt in NVIC
|
||||
}
|
||||
|
||||
void DMA_enable(void)
|
||||
{
|
||||
/* enable DMA controller */
|
||||
DMAC->CTRL.bit.DMAENABLE = 1;
|
||||
}
|
||||
|
||||
void DMAC_Handler(void)
|
||||
{
|
||||
//static int count;
|
||||
for (int channel = 0 ; channel < used_channels ; channel++) // check interrupt for every registered channel
|
||||
{
|
||||
DMAC->CHID.bit.ID = channel;
|
||||
if (DMAC->CHINTFLAG.bit.TCMPL && DMAC->CHINTENSET.bit.TCMPL)
|
||||
{
|
||||
if (DMAC->CHID.bit.ID == 0x00) // handle SPI transfer complete interrupt
|
||||
{
|
||||
DMAC->CHINTFLAG.bit.TCMPL = 1; // acknowledge interrupt
|
||||
DMAC->CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE; // re-enable DMA channel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
Examples/NeoPixel Example/DMA.h
Normal file
13
Examples/NeoPixel Example/DMA.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef DMA_H_
|
||||
#define DMA_H_
|
||||
|
||||
#define DMA_SOURCE_SERCOM0 0x02
|
||||
#define DMA_SOURCE_ADC 0x27
|
||||
|
||||
extern volatile int dma_frame;
|
||||
|
||||
void DMA_init(void);
|
||||
void DMA_add_channel(int source, DmacDescriptor *descriptor);
|
||||
void DMA_enable(void);
|
||||
|
||||
#endif /* DMA_H_ */
|
||||
89
Examples/NeoPixel Example/FIFO.c
Normal file
89
Examples/NeoPixel Example/FIFO.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <stdint.h>
|
||||
#include "FIFO.h"
|
||||
|
||||
#define FIFO_SUCCESS 1
|
||||
#define FIFO_FAIL 0
|
||||
#define SIZE 1024
|
||||
|
||||
static uint8_t RX_buffer[SIZE];
|
||||
static uint8_t *RX_head, *RX_tail;
|
||||
static uint8_t TX_buffer[SIZE];
|
||||
static uint8_t *TX_head, *TX_tail;
|
||||
|
||||
void FIFO_init(void)
|
||||
{
|
||||
RX_head = RX_tail = &RX_buffer[0];
|
||||
TX_head = TX_tail = &TX_buffer[0];
|
||||
}
|
||||
|
||||
int RX_FIFO_empty(void)
|
||||
{
|
||||
return RX_head == RX_tail;
|
||||
}
|
||||
|
||||
int RX_FIFO_full(void)
|
||||
{
|
||||
uint8_t *ptr = RX_tail + 1;
|
||||
if (ptr == &RX_buffer[SIZE])
|
||||
ptr = &RX_buffer[0];
|
||||
return ptr == RX_head;
|
||||
}
|
||||
|
||||
int RX_FIFO_count(void)
|
||||
{
|
||||
return RX_tail >= RX_head ? RX_tail - RX_head : SIZE - (RX_head - RX_tail);
|
||||
}
|
||||
|
||||
int RX_FIFO_put(uint8_t data)
|
||||
{
|
||||
if (RX_FIFO_full())
|
||||
return FIFO_FAIL;
|
||||
*RX_tail++ = data;
|
||||
if (RX_tail == &RX_buffer[SIZE])
|
||||
RX_tail = &RX_buffer[0];
|
||||
return FIFO_SUCCESS;
|
||||
}
|
||||
|
||||
int RX_FIFO_get(uint8_t *data)
|
||||
{
|
||||
if (RX_FIFO_empty())
|
||||
return FIFO_FAIL;
|
||||
*data = *RX_head++;
|
||||
if (RX_head == &RX_buffer[SIZE])
|
||||
RX_head = &RX_buffer[0];
|
||||
return FIFO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int TX_FIFO_empty(void)
|
||||
{
|
||||
return TX_head == TX_tail;
|
||||
}
|
||||
|
||||
int TX_FIFO_full(void)
|
||||
{
|
||||
uint8_t *ptr = TX_tail + 1;
|
||||
if (ptr == &TX_buffer[SIZE])
|
||||
ptr = &TX_buffer[0];
|
||||
return ptr == TX_head;
|
||||
}
|
||||
|
||||
int TX_FIFO_put(uint8_t data)
|
||||
{
|
||||
if (TX_FIFO_full())
|
||||
return FIFO_FAIL;
|
||||
*TX_tail++ = data;
|
||||
if (TX_tail == &TX_buffer[SIZE])
|
||||
TX_tail = &TX_buffer[0];
|
||||
return FIFO_SUCCESS;
|
||||
}
|
||||
|
||||
int TX_FIFO_get(uint8_t *data)
|
||||
{
|
||||
if (TX_FIFO_empty())
|
||||
return FIFO_FAIL;
|
||||
*data = *TX_head++;
|
||||
if (TX_head == &TX_buffer[SIZE])
|
||||
TX_head = &TX_buffer[0];
|
||||
return FIFO_SUCCESS;
|
||||
}
|
||||
15
Examples/NeoPixel Example/FIFO.h
Normal file
15
Examples/NeoPixel Example/FIFO.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef FIFO_H_
|
||||
#define FIFO_H_
|
||||
|
||||
void FIFO_init(void);
|
||||
int RX_FIFO_empty(void);
|
||||
int RX_FIFO_full(void);
|
||||
int RX_FIFO_count(void);
|
||||
int RX_FIFO_put(uint8_t data);
|
||||
int RX_FIFO_get(uint8_t *data);
|
||||
int TX_FIFO_empty(void);
|
||||
int TX_FIFO_full(void);
|
||||
int TX_FIFO_put(uint8_t data);
|
||||
int TX_FIFO_get(uint8_t *data);
|
||||
|
||||
#endif /* FIFO_H_ */
|
||||
415
Examples/NeoPixel Example/NeoPixel.c
Normal file
415
Examples/NeoPixel Example/NeoPixel.c
Normal file
@@ -0,0 +1,415 @@
|
||||
#include <samd21g18a.h>
|
||||
#include "NeoPixel.h"
|
||||
#include "Timer.h"
|
||||
#include "DMA.h"
|
||||
#include "SPI.h"
|
||||
#include "ADC.h"
|
||||
|
||||
static uint8_t pixel_buffer[NUM_PIXELS * 3]; // 3 bytes per pixel (G-R-B)
|
||||
static uint8_t dma_buffer[NUM_PIXELS * 3 * 3 + 90]; // each byte is expanded to 3 bytes + 90 bytes (zero) for latching
|
||||
static const uint32_t bit_expand[256]; // lookup table for bit expansion
|
||||
|
||||
static Animation current_animation;
|
||||
static int frame;
|
||||
|
||||
void NeoPixel_init(void)
|
||||
{
|
||||
/* initialize pixel buffer */
|
||||
NeoPixel_clear_pixels();
|
||||
|
||||
/* initialize DMA buffer */
|
||||
for (int i = 0 ; i < sizeof dma_buffer ; i++)
|
||||
dma_buffer[i] = 0x00;
|
||||
|
||||
/* configure and enable DMA controller */
|
||||
/* set up transfer descriptor */
|
||||
DmacDescriptor descriptor;
|
||||
descriptor.DSTADDR.reg = (uint32_t)&SERCOM0->SPI.DATA; // destination address is SPI DATA register
|
||||
descriptor.SRCADDR.reg = (uint32_t)(dma_buffer + sizeof dma_buffer); // source address is the DMA buffer
|
||||
descriptor.DESCADDR.reg = 0; // only one transfer descriptor
|
||||
descriptor.BTCTRL.bit.BEATSIZE = DMAC_BTCTRL_BEATSIZE_BYTE_Val; // beat size is one byte
|
||||
descriptor.BTCTRL.bit.DSTINC = 0; // destination address increment disabled
|
||||
descriptor.BTCTRL.bit.SRCINC = 1; // source address increment enabled
|
||||
descriptor.BTCTRL.bit.STEPSEL = DMAC_BTCTRL_STEPSEL_SRC_Val; // flexible source address increment size
|
||||
descriptor.BTCTRL.bit.STEPSIZE = DMAC_BTCTRL_STEPSIZE_X1_Val; // source address increment is one byte
|
||||
descriptor.BTCTRL.bit.BLOCKACT = DMAC_BTCTRL_BLOCKACT_NOACT_Val; // request interrupt at end of block transfer
|
||||
descriptor.BTCNT.reg = sizeof dma_buffer; // beat count
|
||||
descriptor.BTCTRL.bit.VALID = 1; // descriptor is valid
|
||||
/* initialize DMA controller */
|
||||
DMA_init();
|
||||
/* add and enable SERCOM0 (SPI) channel */
|
||||
DMA_add_channel(DMA_SOURCE_SERCOM0, &descriptor);
|
||||
/* enable DMA */
|
||||
DMA_enable();
|
||||
|
||||
/* initialize timer */
|
||||
Timer_init();
|
||||
|
||||
/* initialize SPI */
|
||||
SPI_init();
|
||||
}
|
||||
|
||||
/* set pixel color (pixel are numbered from 0 to NUM_PIXELS - 1) */
|
||||
void NeoPixel_set_pixel(int pixel, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
if (pixel < 0 || pixel >= NUM_PIXELS)
|
||||
return;
|
||||
int n = pixel * 3;
|
||||
pixel_buffer[n] = green;
|
||||
pixel_buffer[n + 1] = red;
|
||||
pixel_buffer[n + 2] = blue;
|
||||
}
|
||||
|
||||
/* all pixels off */
|
||||
void NeoPixel_clear_pixels(void)
|
||||
{
|
||||
for (int i = 0 ; i < NUM_PIXELS * 3 ; i++)
|
||||
pixel_buffer[i] = 0;
|
||||
}
|
||||
|
||||
/* update DMA buffer */
|
||||
void NeoPixel_update(void)
|
||||
{
|
||||
for (int i = 0, j = 0 ; i < sizeof pixel_buffer ; i++, j += 3)
|
||||
{
|
||||
uint32_t expanded = bit_expand[pixel_buffer[i]];
|
||||
dma_buffer[j] = expanded >> 16;
|
||||
dma_buffer[j + 1] = expanded >> 8;
|
||||
dma_buffer[j + 2] = expanded;
|
||||
}
|
||||
}
|
||||
|
||||
void NeoPixel_update_animation(void)
|
||||
{
|
||||
static int v = 1;
|
||||
static int on = 0;
|
||||
int sound_value = 0;
|
||||
|
||||
if (frame_time) // if all DMA transfers for a frame has occurred
|
||||
{
|
||||
frame_time = 0; // acknowledge/clear flag from timer
|
||||
/* update pixel buffer */
|
||||
switch (current_animation)
|
||||
{
|
||||
case KITT:
|
||||
NeoPixel_clear_pixels();
|
||||
NeoPixel_set_pixel(frame, 255, 0, 0);
|
||||
NeoPixel_set_pixel(frame - v, 255, 0, 0);
|
||||
NeoPixel_set_pixel(frame - 2*v, 200, 0, 0);
|
||||
NeoPixel_set_pixel(frame - 3*v, 100, 0, 0);
|
||||
NeoPixel_set_pixel(frame - 4*v, 50, 0, 0);
|
||||
if (frame == NUM_PIXELS - 1 || frame == 0)
|
||||
v = -v;
|
||||
frame += v;
|
||||
break;
|
||||
case BREATHING:
|
||||
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
||||
NeoPixel_set_pixel(i, 0 , 0, frame*4);
|
||||
if (frame == 63 || frame == 0)
|
||||
v = -v;
|
||||
frame += v;
|
||||
break;
|
||||
case BLINK:
|
||||
if (!(frame++ % 20))
|
||||
if (!on)
|
||||
{
|
||||
on = 1;
|
||||
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
||||
NeoPixel_set_pixel(i, 0, 255, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
on = 0;
|
||||
NeoPixel_clear_pixels();
|
||||
}
|
||||
break;
|
||||
case SOUND:
|
||||
#define THRESHOLD 200
|
||||
if (adc_value < THRESHOLD) // threshold
|
||||
sound_value = 0;
|
||||
else
|
||||
sound_value = (adc_value - THRESHOLD) * ((255.0 - 0.0)/(400.0 - THRESHOLD)); // linear map: y = (x - x1) * (y2 - y1)/(x2 - x1)
|
||||
if (sound_value >= 255)
|
||||
sound_value = 255;
|
||||
for (int i = 0 ; i < NUM_PIXELS ; i++)
|
||||
NeoPixel_set_pixel(i, sound_value, sound_value, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* send frame to DMA buffer */
|
||||
NeoPixel_update();
|
||||
}
|
||||
}
|
||||
|
||||
void NeoPixel_set_animation(Animation animation)
|
||||
{
|
||||
current_animation = animation;
|
||||
if (animation == SOUND)
|
||||
ADC_init();
|
||||
else
|
||||
ADC_deinit();
|
||||
frame = 1;
|
||||
NeoPixel_clear_pixels();
|
||||
}
|
||||
|
||||
/* bit expansion lookup table */
|
||||
static const uint32_t bit_expand[256] = {
|
||||
0b100100100100100100100100,
|
||||
0b100100100100100100100110,
|
||||
0b100100100100100100110100,
|
||||
0b100100100100100100110110,
|
||||
0b100100100100100110100100,
|
||||
0b100100100100100110100110,
|
||||
0b100100100100100110110100,
|
||||
0b100100100100100110110110,
|
||||
0b100100100100110100100100,
|
||||
0b100100100100110100100110,
|
||||
0b100100100100110100110100,
|
||||
0b100100100100110100110110,
|
||||
0b100100100100110110100100,
|
||||
0b100100100100110110100110,
|
||||
0b100100100100110110110100,
|
||||
0b100100100100110110110110,
|
||||
0b100100100110100100100100,
|
||||
0b100100100110100100100110,
|
||||
0b100100100110100100110100,
|
||||
0b100100100110100100110110,
|
||||
0b100100100110100110100100,
|
||||
0b100100100110100110100110,
|
||||
0b100100100110100110110100,
|
||||
0b100100100110100110110110,
|
||||
0b100100100110110100100100,
|
||||
0b100100100110110100100110,
|
||||
0b100100100110110100110100,
|
||||
0b100100100110110100110110,
|
||||
0b100100100110110110100100,
|
||||
0b100100100110110110100110,
|
||||
0b100100100110110110110100,
|
||||
0b100100100110110110110110,
|
||||
0b100100110100100100100100,
|
||||
0b100100110100100100100110,
|
||||
0b100100110100100100110100,
|
||||
0b100100110100100100110110,
|
||||
0b100100110100100110100100,
|
||||
0b100100110100100110100110,
|
||||
0b100100110100100110110100,
|
||||
0b100100110100100110110110,
|
||||
0b100100110100110100100100,
|
||||
0b100100110100110100100110,
|
||||
0b100100110100110100110100,
|
||||
0b100100110100110100110110,
|
||||
0b100100110100110110100100,
|
||||
0b100100110100110110100110,
|
||||
0b100100110100110110110100,
|
||||
0b100100110100110110110110,
|
||||
0b100100110110100100100100,
|
||||
0b100100110110100100100110,
|
||||
0b100100110110100100110100,
|
||||
0b100100110110100100110110,
|
||||
0b100100110110100110100100,
|
||||
0b100100110110100110100110,
|
||||
0b100100110110100110110100,
|
||||
0b100100110110100110110110,
|
||||
0b100100110110110100100100,
|
||||
0b100100110110110100100110,
|
||||
0b100100110110110100110100,
|
||||
0b100100110110110100110110,
|
||||
0b100100110110110110100100,
|
||||
0b100100110110110110100110,
|
||||
0b100100110110110110110100,
|
||||
0b100100110110110110110110,
|
||||
0b100110100100100100100100,
|
||||
0b100110100100100100100110,
|
||||
0b100110100100100100110100,
|
||||
0b100110100100100100110110,
|
||||
0b100110100100100110100100,
|
||||
0b100110100100100110100110,
|
||||
0b100110100100100110110100,
|
||||
0b100110100100100110110110,
|
||||
0b100110100100110100100100,
|
||||
0b100110100100110100100110,
|
||||
0b100110100100110100110100,
|
||||
0b100110100100110100110110,
|
||||
0b100110100100110110100100,
|
||||
0b100110100100110110100110,
|
||||
0b100110100100110110110100,
|
||||
0b100110100100110110110110,
|
||||
0b100110100110100100100100,
|
||||
0b100110100110100100100110,
|
||||
0b100110100110100100110100,
|
||||
0b100110100110100100110110,
|
||||
0b100110100110100110100100,
|
||||
0b100110100110100110100110,
|
||||
0b100110100110100110110100,
|
||||
0b100110100110100110110110,
|
||||
0b100110100110110100100100,
|
||||
0b100110100110110100100110,
|
||||
0b100110100110110100110100,
|
||||
0b100110100110110100110110,
|
||||
0b100110100110110110100100,
|
||||
0b100110100110110110100110,
|
||||
0b100110100110110110110100,
|
||||
0b100110100110110110110110,
|
||||
0b100110110100100100100100,
|
||||
0b100110110100100100100110,
|
||||
0b100110110100100100110100,
|
||||
0b100110110100100100110110,
|
||||
0b100110110100100110100100,
|
||||
0b100110110100100110100110,
|
||||
0b100110110100100110110100,
|
||||
0b100110110100100110110110,
|
||||
0b100110110100110100100100,
|
||||
0b100110110100110100100110,
|
||||
0b100110110100110100110100,
|
||||
0b100110110100110100110110,
|
||||
0b100110110100110110100100,
|
||||
0b100110110100110110100110,
|
||||
0b100110110100110110110100,
|
||||
0b100110110100110110110110,
|
||||
0b100110110110100100100100,
|
||||
0b100110110110100100100110,
|
||||
0b100110110110100100110100,
|
||||
0b100110110110100100110110,
|
||||
0b100110110110100110100100,
|
||||
0b100110110110100110100110,
|
||||
0b100110110110100110110100,
|
||||
0b100110110110100110110110,
|
||||
0b100110110110110100100100,
|
||||
0b100110110110110100100110,
|
||||
0b100110110110110100110100,
|
||||
0b100110110110110100110110,
|
||||
0b100110110110110110100100,
|
||||
0b100110110110110110100110,
|
||||
0b100110110110110110110100,
|
||||
0b100110110110110110110110,
|
||||
0b110100100100100100100100,
|
||||
0b110100100100100100100110,
|
||||
0b110100100100100100110100,
|
||||
0b110100100100100100110110,
|
||||
0b110100100100100110100100,
|
||||
0b110100100100100110100110,
|
||||
0b110100100100100110110100,
|
||||
0b110100100100100110110110,
|
||||
0b110100100100110100100100,
|
||||
0b110100100100110100100110,
|
||||
0b110100100100110100110100,
|
||||
0b110100100100110100110110,
|
||||
0b110100100100110110100100,
|
||||
0b110100100100110110100110,
|
||||
0b110100100100110110110100,
|
||||
0b110100100100110110110110,
|
||||
0b110100100110100100100100,
|
||||
0b110100100110100100100110,
|
||||
0b110100100110100100110100,
|
||||
0b110100100110100100110110,
|
||||
0b110100100110100110100100,
|
||||
0b110100100110100110100110,
|
||||
0b110100100110100110110100,
|
||||
0b110100100110100110110110,
|
||||
0b110100100110110100100100,
|
||||
0b110100100110110100100110,
|
||||
0b110100100110110100110100,
|
||||
0b110100100110110100110110,
|
||||
0b110100100110110110100100,
|
||||
0b110100100110110110100110,
|
||||
0b110100100110110110110100,
|
||||
0b110100100110110110110110,
|
||||
0b110100110100100100100100,
|
||||
0b110100110100100100100110,
|
||||
0b110100110100100100110100,
|
||||
0b110100110100100100110110,
|
||||
0b110100110100100110100100,
|
||||
0b110100110100100110100110,
|
||||
0b110100110100100110110100,
|
||||
0b110100110100100110110110,
|
||||
0b110100110100110100100100,
|
||||
0b110100110100110100100110,
|
||||
0b110100110100110100110100,
|
||||
0b110100110100110100110110,
|
||||
0b110100110100110110100100,
|
||||
0b110100110100110110100110,
|
||||
0b110100110100110110110100,
|
||||
0b110100110100110110110110,
|
||||
0b110100110110100100100100,
|
||||
0b110100110110100100100110,
|
||||
0b110100110110100100110100,
|
||||
0b110100110110100100110110,
|
||||
0b110100110110100110100100,
|
||||
0b110100110110100110100110,
|
||||
0b110100110110100110110100,
|
||||
0b110100110110100110110110,
|
||||
0b110100110110110100100100,
|
||||
0b110100110110110100100110,
|
||||
0b110100110110110100110100,
|
||||
0b110100110110110100110110,
|
||||
0b110100110110110110100100,
|
||||
0b110100110110110110100110,
|
||||
0b110100110110110110110100,
|
||||
0b110100110110110110110110,
|
||||
0b110110100100100100100100,
|
||||
0b110110100100100100100110,
|
||||
0b110110100100100100110100,
|
||||
0b110110100100100100110110,
|
||||
0b110110100100100110100100,
|
||||
0b110110100100100110100110,
|
||||
0b110110100100100110110100,
|
||||
0b110110100100100110110110,
|
||||
0b110110100100110100100100,
|
||||
0b110110100100110100100110,
|
||||
0b110110100100110100110100,
|
||||
0b110110100100110100110110,
|
||||
0b110110100100110110100100,
|
||||
0b110110100100110110100110,
|
||||
0b110110100100110110110100,
|
||||
0b110110100100110110110110,
|
||||
0b110110100110100100100100,
|
||||
0b110110100110100100100110,
|
||||
0b110110100110100100110100,
|
||||
0b110110100110100100110110,
|
||||
0b110110100110100110100100,
|
||||
0b110110100110100110100110,
|
||||
0b110110100110100110110100,
|
||||
0b110110100110100110110110,
|
||||
0b110110100110110100100100,
|
||||
0b110110100110110100100110,
|
||||
0b110110100110110100110100,
|
||||
0b110110100110110100110110,
|
||||
0b110110100110110110100100,
|
||||
0b110110100110110110100110,
|
||||
0b110110100110110110110100,
|
||||
0b110110100110110110110110,
|
||||
0b110110110100100100100100,
|
||||
0b110110110100100100100110,
|
||||
0b110110110100100100110100,
|
||||
0b110110110100100100110110,
|
||||
0b110110110100100110100100,
|
||||
0b110110110100100110100110,
|
||||
0b110110110100100110110100,
|
||||
0b110110110100100110110110,
|
||||
0b110110110100110100100100,
|
||||
0b110110110100110100100110,
|
||||
0b110110110100110100110100,
|
||||
0b110110110100110100110110,
|
||||
0b110110110100110110100100,
|
||||
0b110110110100110110100110,
|
||||
0b110110110100110110110100,
|
||||
0b110110110100110110110110,
|
||||
0b110110110110100100100100,
|
||||
0b110110110110100100100110,
|
||||
0b110110110110100100110100,
|
||||
0b110110110110100100110110,
|
||||
0b110110110110100110100100,
|
||||
0b110110110110100110100110,
|
||||
0b110110110110100110110100,
|
||||
0b110110110110100110110110,
|
||||
0b110110110110110100100100,
|
||||
0b110110110110110100100110,
|
||||
0b110110110110110100110100,
|
||||
0b110110110110110100110110,
|
||||
0b110110110110110110100100,
|
||||
0b110110110110110110100110,
|
||||
0b110110110110110110110100,
|
||||
0b110110110110110110110110
|
||||
};
|
||||
18
Examples/NeoPixel Example/NeoPixel.h
Normal file
18
Examples/NeoPixel Example/NeoPixel.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef NEOPIXEL_H_
|
||||
#define NEOPIXEL_H_
|
||||
|
||||
#define NUM_PIXELS 24
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KITT, BREATHING, BLINK, SOUND,
|
||||
} Animation;
|
||||
|
||||
void NeoPixel_init(void);
|
||||
void NeoPixel_set_pixel(int pixel, uint8_t red, uint8_t green, uint8_t blue);
|
||||
void NeoPixel_clear_pixels(void);
|
||||
void NeoPixel_update(void);
|
||||
void NeoPixel_set_animation(Animation animation);
|
||||
void NeoPixel_update_animation(void);
|
||||
|
||||
#endif /* NEOPIXEL_H_ */
|
||||
31
Examples/NeoPixel Example/SPI.c
Normal file
31
Examples/NeoPixel Example/SPI.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <samd21g18a.h>
|
||||
#include "SPI.h"
|
||||
|
||||
/* initialize SPI on SERCOM0 with MOSI on pad 0 (pin PA08) */
|
||||
void SPI_init(void)
|
||||
{
|
||||
/* enable peripheral clock */
|
||||
PM->APBCMASK.bit.SERCOM0_ = 1;
|
||||
|
||||
/* enable generic clock */
|
||||
GCLK->CLKCTRL.bit.ID = GCLK_CLKCTRL_ID_SERCOM0_CORE_Val; // configure generic clock for SERCOM0
|
||||
GCLK->CLKCTRL.bit.GEN = GCLK_CLKCTRL_GEN_GCLK0_Val; // source is generic clock generator 0
|
||||
GCLK->CLKCTRL.bit.CLKEN = 1; // enable generic clock
|
||||
|
||||
/* select GPIO pins alternative function */
|
||||
PORT->Group[0].PINCFG[8].bit.PMUXEN = 1; // enable alternative function for pin PA08
|
||||
PORT->Group[0].PMUX[4].bit.PMUXE = MUX_PA08C_SERCOM0_PAD0; // PA08 alternative function C (SERCOM0 pad 0)
|
||||
|
||||
/* configure peripheral */
|
||||
SERCOM0->SPI.CTRLA.bit.DOPO = 0x00; // MOSI on pad 0 (pin PA08)
|
||||
SERCOM0->SPI.CTRLA.bit.CPHA = 0x00;
|
||||
SERCOM0->SPI.CTRLA.bit.CPOL = 0x00; // transfer mode 0
|
||||
SERCOM0->SPI.CTRLA.bit.DORD = 0x00; // MSB first
|
||||
SERCOM0->SPI.CTRLA.bit.MODE = 0x03; // SPI master operation
|
||||
SERCOM0->SPI.CTRLB.bit.CHSIZE = 0x00; // 8 bit character size
|
||||
SERCOM0->SPI.BAUD.reg = 9; // SPI frequency 2.4 MHz (BAUD = gclk/(2*f_baud) - 1)
|
||||
|
||||
/* enable peripheral */
|
||||
SERCOM0->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
|
||||
}
|
||||
|
||||
6
Examples/NeoPixel Example/SPI.h
Normal file
6
Examples/NeoPixel Example/SPI.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef SPI_H_
|
||||
#define SPI_H_
|
||||
|
||||
void SPI_init(void);
|
||||
|
||||
#endif /* SPI_H_ */
|
||||
200
Examples/NeoPixel Example/Serial.c
Normal file
200
Examples/NeoPixel Example/Serial.c
Normal file
@@ -0,0 +1,200 @@
|
||||
#include <asf.h>
|
||||
#include "Serial.h"
|
||||
#include "FIFO.h"
|
||||
|
||||
/* initialize USART on SERCOM2 with TX on pad 2 (pin PA10) and RX on pad 3 (pin PA11) */
|
||||
void Serial_init(void)
|
||||
{
|
||||
/* initialize FIFO buffers */
|
||||
FIFO_init();
|
||||
|
||||
/* enable peripheral clock */
|
||||
PM->APBCMASK.bit.SERCOM2_ = 1;
|
||||
|
||||
/* enable generic clock */
|
||||
GCLK->CLKCTRL.bit.ID = GCLK_CLKCTRL_ID_SERCOM2_CORE_Val; // configure generic clock for SERCOM2
|
||||
GCLK->CLKCTRL.bit.GEN = GCLK_CLKCTRL_GEN_GCLK0_Val; // source is generic clock generator 0
|
||||
GCLK->CLKCTRL.bit.CLKEN = 1; // enable generic clock
|
||||
|
||||
/* enable GPIO pins alternative function */
|
||||
PORT->Group[0].PINCFG[10].bit.PMUXEN = 1; // enable alternative function for pins PA10 and PA11
|
||||
PORT->Group[0].PINCFG[11].bit.PMUXEN = 1;
|
||||
PORT->Group[0].DIRCLR.reg = PORT_PA11;
|
||||
PORT->Group[0].PINCFG[11].bit.INEN = 1;
|
||||
PORT->Group[0].PMUX[5].bit.PMUXE = MUX_PA10D_SERCOM2_PAD2; // PA10 alternative function D (SERCOM2 pad 2)
|
||||
PORT->Group[0].PMUX[5].bit.PMUXO = MUX_PA11D_SERCOM2_PAD3; // PA11 alternative function D (SERCOM2 pad 3)
|
||||
|
||||
/* configure peripheral */
|
||||
SERCOM2->USART.CTRLA.bit.MODE = SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val; // USART internal clock operation
|
||||
SERCOM2->USART.CTRLA.bit.RXPO = 0x03; // RX on pad 3 (pin PA11)
|
||||
SERCOM2->USART.CTRLA.bit.TXPO = 0x01; // TX on pad 2 (pin PA10)
|
||||
SERCOM2->USART.CTRLA.bit.DORD = 1; // LSB first
|
||||
SERCOM2->USART.CTRLA.bit.CMODE = 0x00; // asynchronous communication (UART)
|
||||
SERCOM2->USART.CTRLA.bit.FORM = 0x00; // no parity
|
||||
SERCOM2->USART.CTRLA.bit.SAMPR = 0x00; // 16 bit oversampling with arithmetic baud rate generation
|
||||
SERCOM2->USART.CTRLB.bit.CHSIZE = 0x00; // 8 bit data
|
||||
SERCOM2->USART.CTRLB.bit.SBMODE = 0x00; // one stop bit
|
||||
SERCOM2->USART.BAUD.reg = 63018; // BAUD = 65535 * (1 - num_samples * f_baud/f_clck)
|
||||
SERCOM2->USART.CTRLB.bit.RXEN = 1; // enable receiver
|
||||
SERCOM2->USART.CTRLB.bit.TXEN = 1; // enable transmitter
|
||||
|
||||
/* enable interrupt */
|
||||
SERCOM2->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC; // enable Reception Complete interrupt
|
||||
NVIC_EnableIRQ(SERCOM2_IRQn); // enable interrupts in NVIC
|
||||
|
||||
/* enable peripheral */
|
||||
SERCOM2->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
|
||||
|
||||
/* avoid corrupted bytes at start */
|
||||
delay_ms(100);
|
||||
}
|
||||
|
||||
/* blocking implementation */
|
||||
void Serial_transmit(uint8_t data)
|
||||
{
|
||||
while (!TX_FIFO_put(data))
|
||||
;
|
||||
/* TX buffer has new data: re enable DRE interrupt */
|
||||
if (!(SERCOM2->USART.INTENSET.reg & SERCOM_USART_INTENSET_DRE))
|
||||
SERCOM2->USART.INTENSET.reg = SERCOM_USART_INTENSET_DRE;
|
||||
SERCOM2->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC;
|
||||
}
|
||||
|
||||
/* blocking implementation */
|
||||
uint8_t Serial_receive(void)
|
||||
{
|
||||
uint8_t data;
|
||||
while (!RX_FIFO_get(&data))
|
||||
;
|
||||
/* RX buffer has space: re enable RXC interrupt */
|
||||
if (!(SERCOM2->USART.INTENSET.reg & SERCOM_USART_INTENSET_RXC))
|
||||
SERCOM2->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC;
|
||||
return data;
|
||||
}
|
||||
|
||||
int Serial_receive_timeout(uint8_t *data, int timeout)
|
||||
{
|
||||
int count = 0;
|
||||
while (!RX_FIFO_get(data))
|
||||
{
|
||||
count++;
|
||||
if (count == timeout)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Serial_write(const char *string)
|
||||
{
|
||||
while (*string)
|
||||
Serial_transmit(*string++);
|
||||
}
|
||||
|
||||
void Serial_writeln(const char *string)
|
||||
{
|
||||
Serial_write(string);
|
||||
Serial_write("\r\n");
|
||||
}
|
||||
|
||||
void Serial_read(char *string, int length)
|
||||
{
|
||||
while (length--)
|
||||
*string++ = Serial_receive();
|
||||
*string = '\0';
|
||||
}
|
||||
|
||||
void Serial_read_string(char *string)
|
||||
{
|
||||
while ((*string++ = Serial_receive()) != '\n')
|
||||
;
|
||||
*string = '\0';
|
||||
}
|
||||
|
||||
int Serial_available(void)
|
||||
{
|
||||
return RX_FIFO_count();
|
||||
}
|
||||
|
||||
/* find a string in RX buffer (blocking until found) */
|
||||
void Serial_find(const char *string)
|
||||
{
|
||||
const char *p = string;
|
||||
char c;
|
||||
while (*p != '\0')
|
||||
if ((c = Serial_receive()) == *p)
|
||||
p++;
|
||||
else if (p != string)
|
||||
{
|
||||
const char *q = p;
|
||||
while (p > string)
|
||||
{
|
||||
p--;
|
||||
if (*p == c)
|
||||
{
|
||||
int diff = q - p;
|
||||
const char *i;
|
||||
for (i = string ; i < p ; i++)
|
||||
if (*i != *(i + diff))
|
||||
break; // for loop
|
||||
if (i == p)
|
||||
{
|
||||
p++;
|
||||
break; // while loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find a string in RX buffer (returns 0 if timed out) */
|
||||
int Serial_find_timeout(const char *string, int timeout)
|
||||
{
|
||||
const char *p = string;
|
||||
char c;
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (!Serial_receive_timeout(&c, timeout))
|
||||
return 0;
|
||||
else if (c == *p)
|
||||
p++;
|
||||
else if (p != string)
|
||||
{
|
||||
const char *q = p;
|
||||
while (p > string)
|
||||
{
|
||||
p--;
|
||||
if (*p == c)
|
||||
{
|
||||
int diff = q - p;
|
||||
const char *i;
|
||||
for (i = string ; i < p ; i++)
|
||||
if (*i != *(i + diff))
|
||||
break; // for loop
|
||||
if (i == p)
|
||||
{
|
||||
p++;
|
||||
break; // while loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SERCOM2_Handler(void)
|
||||
{
|
||||
/* handle RX interrupt */
|
||||
if (SERCOM2->USART.INTFLAG.bit.RXC && SERCOM2->USART.INTENSET.bit.RXC) // if RXC interrupt is triggered and enabled
|
||||
if (!RX_FIFO_put(SERCOM2->USART.DATA.reg))
|
||||
SERCOM2->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_RXC; // if RX buffer is full disable RXC interrupt
|
||||
/* handle TX interrupt */
|
||||
if (SERCOM2->USART.INTFLAG.bit.DRE && SERCOM2->USART.INTENSET.bit.DRE) // if DRE interrupt is triggered and enabled
|
||||
{
|
||||
uint8_t data;
|
||||
if (!TX_FIFO_get(&data))
|
||||
SERCOM2->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE; // if TX buffer is empty disable DRE interrupt
|
||||
else
|
||||
SERCOM2->USART.DATA.reg = data;
|
||||
}
|
||||
}
|
||||
16
Examples/NeoPixel Example/Serial.h
Normal file
16
Examples/NeoPixel Example/Serial.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef SERIAL_H_
|
||||
#define SERIAL_H_
|
||||
|
||||
void Serial_init(void);
|
||||
void Serial_transmit(uint8_t data);
|
||||
uint8_t Serial_receive(void);
|
||||
int Serial_receive_timeout(uint8_t *data, int timeout);
|
||||
void Serial_write(const char *string);
|
||||
void Serial_writeln(const char *string);
|
||||
void Serial_read(char *string, int length);
|
||||
void Serial_read_string(char *string);
|
||||
int Serial_available(void);
|
||||
void Serial_find(const char *string);
|
||||
int Serial_find_timeout(const char *string, int timeout);
|
||||
|
||||
#endif /* SERIAL_H_ */
|
||||
45
Examples/NeoPixel Example/Timer.c
Normal file
45
Examples/NeoPixel Example/Timer.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Timer.c
|
||||
*
|
||||
* Created: 08/03/2018 10.49.38
|
||||
* Author: Luca
|
||||
*/
|
||||
|
||||
#include <samd21g18a.h>
|
||||
#include "Timer.h"
|
||||
|
||||
volatile int frame_time = 0;
|
||||
|
||||
void Timer_init(void)
|
||||
{
|
||||
/* enable peripheral clock */
|
||||
PM->APBCMASK.bit.TC3_ = 1;
|
||||
|
||||
/* enable generic clock */
|
||||
GCLK->CLKCTRL.bit.ID = GCLK_CLKCTRL_ID_TCC2_TC3_Val; // configure generic clock for Timer/Counter 3
|
||||
GCLK->CLKCTRL.bit.GEN = GCLK_CLKCTRL_GEN_GCLK0_Val; // source is generic clock generator 0 (48 MHz)
|
||||
GCLK->CLKCTRL.bit.CLKEN = 1; // enable generic clock
|
||||
|
||||
/* configure peripheral */
|
||||
TC3->COUNT16.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16_Val;
|
||||
TC3->COUNT16.CTRLA.bit.PRESCSYNC = TC_CTRLA_PRESCSYNC_PRESC_Val;
|
||||
TC3->COUNT16.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_MFRQ_Val;
|
||||
TC3->COUNT16.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV256_Val;
|
||||
TC3->COUNT16.CC[0].reg = 6250; // with a GCLK @ 48 MHz and a prescaler of 256 the top value yields a frequency of 30 Hz
|
||||
|
||||
/* enable timer overflow interrupt */
|
||||
TC3->COUNT16.INTENSET.bit.OVF = 1;
|
||||
NVIC_EnableIRQ(TC3_IRQn);
|
||||
|
||||
/* enable Timer/Counter 3 */
|
||||
TC3->COUNT16.CTRLA.bit.ENABLE = 1;
|
||||
}
|
||||
|
||||
void TC3_Handler(void)
|
||||
{
|
||||
if (TC3->COUNT16.INTFLAG.bit.OVF && TC3->COUNT16.INTENSET.bit.OVF)
|
||||
{
|
||||
TC3->COUNT16.INTFLAG.bit.OVF = 1; // acknowledge interrupt
|
||||
frame_time = 1; // set frame flag
|
||||
}
|
||||
}
|
||||
16
Examples/NeoPixel Example/Timer.h
Normal file
16
Examples/NeoPixel Example/Timer.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Timer.h
|
||||
*
|
||||
* Created: 08/03/2018 10.50.09
|
||||
* Author: Luca
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIMER_H_
|
||||
#define TIMER_H_
|
||||
|
||||
extern volatile int frame_time;
|
||||
|
||||
void Timer_init(void);
|
||||
|
||||
#endif /* TIMER_H_ */
|
||||
321
Examples/NeoPixel Example/WiFi.c
Normal file
321
Examples/NeoPixel Example/WiFi.c
Normal file
@@ -0,0 +1,321 @@
|
||||
#include <asf.h>
|
||||
#include <ctype.h>
|
||||
#include "WiFi.h"
|
||||
#include "Serial.h"
|
||||
#include "string_func.h"
|
||||
#include "utility.h"
|
||||
|
||||
//#define SSID // insert your wifi SSID
|
||||
//#define PASSWORD // insert here your wifi network password
|
||||
|
||||
#ifndef SSID
|
||||
#error network not defined
|
||||
#endif
|
||||
|
||||
#ifndef PASSWORD
|
||||
#error password not defined
|
||||
#endif
|
||||
|
||||
static int cipmux = 0;
|
||||
|
||||
static enum State
|
||||
{
|
||||
STATION = 1,AP = 2,AP_STATION = 3,
|
||||
} wifi_state;
|
||||
|
||||
|
||||
void WiFi_init(void)
|
||||
{
|
||||
Serial_init();
|
||||
WiFi_restart();
|
||||
|
||||
/* initialize AP mode and start TCP server */
|
||||
//WiFi_set_wifi_mode(2);
|
||||
//WiFi_set_IP_address("192.168.5.1");
|
||||
//WiFi_set_softAP_options("HI Pedini", "",5, 0);
|
||||
//WiFi_enable_multiple_connections(1);
|
||||
//WiFi_create_server(3301);
|
||||
|
||||
/* initialize station mode, connect to router and open UDP socket */
|
||||
WiFi_set_wifi_mode(1);
|
||||
WiFi_join_access_point(SSID, PASSWORD);
|
||||
WiFi_enable_multiple_connections(0);
|
||||
WiFi_register_UDP_port(0,"0",0,1000,2);
|
||||
}
|
||||
|
||||
/***** basic AT commands *****/
|
||||
|
||||
void WiFi_restart(void)
|
||||
{
|
||||
Serial_write("AT+RST\r\n");
|
||||
Serial_find("ready\r\n");
|
||||
}
|
||||
|
||||
void WiFi_set_baud_rate(int baud,int data_bits,int stop_bits,int parity,int flow_ctl)
|
||||
{
|
||||
char buf[10];
|
||||
Serial_write("AT+UART_CUR=");
|
||||
Serial_write(inttoa(baud,buf));
|
||||
Serial_transmit(',');
|
||||
Serial_write(inttoa(data_bits,buf));
|
||||
Serial_transmit(',');
|
||||
Serial_write(inttoa(stop_bits,buf));
|
||||
Serial_transmit(',');
|
||||
Serial_write(inttoa(parity,buf));
|
||||
Serial_transmit(',');
|
||||
Serial_write(inttoa(flow_ctl,buf));
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
/***** WiFi related commands ******/
|
||||
|
||||
/* set WiFi mode:
|
||||
* 1 -> station mode
|
||||
* 2 -> softAP mode
|
||||
* 3 -> softAP + station mode
|
||||
*/
|
||||
void WiFi_set_wifi_mode(int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 1: Serial_write("AT+CWMODE_CUR=1\r\n");
|
||||
wifi_state = STATION;
|
||||
break;
|
||||
case 2: Serial_write("AT+CWMODE_CUR=2\r\n");
|
||||
wifi_state = AP;
|
||||
break;
|
||||
case 3: Serial_write("AT+CWMODE_CUR=3\r\n");
|
||||
wifi_state = AP_STATION;
|
||||
break;
|
||||
}
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_list_access_points(char *list)
|
||||
{
|
||||
//TODO with getline (gets/fgets) like function
|
||||
}
|
||||
|
||||
/* join access point */
|
||||
void WiFi_join_access_point(const char *ssid,const char *password)
|
||||
{
|
||||
if (wifi_state != STATION && wifi_state != AP_STATION)
|
||||
return;
|
||||
Serial_write("AT+CWJAP_CUR=\"");
|
||||
Serial_write(ssid);
|
||||
Serial_write("\",\"");
|
||||
Serial_write(password);
|
||||
Serial_write("\"\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
/* quit access point */
|
||||
void WiFi_quit_access_point(void)
|
||||
{
|
||||
Serial_write("AT+CWQAP\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
/* set options as soft access point */
|
||||
void WiFi_set_softAP_options(const char *ssid,const char *password,int channel_id,int encription)
|
||||
{
|
||||
if (wifi_state != AP && wifi_state != AP_STATION)
|
||||
return;
|
||||
char buf[10];
|
||||
Serial_write("AT+CWSAP_CUR=\"");
|
||||
Serial_write(ssid);
|
||||
Serial_write("\",\"");
|
||||
Serial_write(password);
|
||||
Serial_write("\",");
|
||||
Serial_write(inttoa(channel_id,buf));
|
||||
Serial_transmit(',');
|
||||
Serial_write(inttoa(encription,buf));
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_list_stations(char *list)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
/***** TCP/IP related commands *****/
|
||||
|
||||
/* set transfer mode
|
||||
* 0 : normal mode
|
||||
* 1 : transparent mode
|
||||
*/
|
||||
void WiFi_set_IP_mode(int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 0: Serial_write("AT+CIPMODE=0\r\n");
|
||||
break;
|
||||
case 1: Serial_write("AT+CIPMODE=1\r\n");
|
||||
break;
|
||||
}
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_set_IP_address(const char *ip)
|
||||
{
|
||||
Serial_write("AT+CIPAP_CUR=\"");
|
||||
Serial_write(ip);
|
||||
Serial_write("\"");
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
/* enable multiple connections (must be 1 before starting TCP server) */
|
||||
void WiFi_enable_multiple_connections(int enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
Serial_write("AT+CIPMUX=1\r\n");
|
||||
cipmux = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial_write("AT+CIPMUX=0\r\n");
|
||||
cipmux = 0;
|
||||
}
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_establish_TCP_connection(int connection_id,const char *ip,int port)
|
||||
{
|
||||
if (cipmux == 0)
|
||||
{
|
||||
Serial_write("AT+CIPSTART=\"");
|
||||
Serial_write("TCP");
|
||||
Serial_write("\",\"");
|
||||
Serial_write(ip);
|
||||
Serial_write("\",");
|
||||
char buf[10];
|
||||
Serial_write(inttoa(port,buf));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial_write("AT+CIPSTART=");
|
||||
Serial_transmit(connection_id + '0');
|
||||
Serial_write(",\"");
|
||||
Serial_write("TCP");
|
||||
Serial_write("\",\"");
|
||||
Serial_write(ip);
|
||||
Serial_write("\",");
|
||||
char buf[10];
|
||||
Serial_write(inttoa(port,buf));
|
||||
}
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_register_UDP_port(int connection_id,const char *remote_ip,int remote_port,int local_port,int mode)
|
||||
{
|
||||
if (cipmux == 0)
|
||||
{
|
||||
Serial_write("AT+CIPSTART=\"");
|
||||
Serial_write("UDP");
|
||||
Serial_write("\",\"");
|
||||
Serial_write(remote_ip);
|
||||
Serial_write("\",");
|
||||
char buf[10];
|
||||
Serial_write(inttoa(remote_port,buf));
|
||||
Serial_write(",");
|
||||
Serial_write(inttoa(local_port,buf));
|
||||
Serial_write(",");
|
||||
Serial_write(inttoa(mode,buf));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial_write("AT+CIPSTART=");
|
||||
Serial_transmit(connection_id + '0');
|
||||
Serial_write(",\"UDP\",\"");
|
||||
Serial_write(remote_ip);
|
||||
Serial_write("\",");
|
||||
char buf[10];
|
||||
Serial_write(inttoa(remote_port,buf));
|
||||
Serial_write(",");
|
||||
Serial_write(inttoa(local_port,buf));
|
||||
Serial_write(",");
|
||||
Serial_write(inttoa(mode,buf));
|
||||
}
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_close_connection(int connection_id)
|
||||
{
|
||||
Serial_write("AT+CIPCLOSE=");
|
||||
Serial_transmit(connection_id + '0');
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
/* start TCP server on port "port" (CIPMUX must be 1) */
|
||||
int WiFi_create_TCP_server(int port)
|
||||
{
|
||||
if (cipmux == 0)
|
||||
return WIFI_FAIL;
|
||||
Serial_write("AT+CIPSERVER=1,");
|
||||
char port_string[10];
|
||||
Serial_write(inttoa(port,port_string));
|
||||
Serial_write("\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* stop TCP server */
|
||||
void WiFi_delete_server(void)
|
||||
{
|
||||
Serial_write("AT+CIPSERVER=0\r\n");
|
||||
Serial_find("OK\r\n");
|
||||
}
|
||||
|
||||
void WiFi_send_data(int connection_id,const char data[])
|
||||
{
|
||||
Serial_write("AT+CIPSEND=");
|
||||
Serial_transmit(connection_id + '0');
|
||||
Serial_transmit(',');
|
||||
int length = strlength(data);
|
||||
char buf[10];
|
||||
Serial_write(inttoa(length,buf));
|
||||
Serial_write("\r\n");
|
||||
Serial_find(">");
|
||||
Serial_write(data);
|
||||
Serial_find("SEND OK\r\n");
|
||||
}
|
||||
|
||||
int WiFi_receive_data(char data[],int limit)
|
||||
{
|
||||
if (cipmux == 0)
|
||||
{
|
||||
if (!Serial_find_timeout("+IPD,", 100))
|
||||
return 0;
|
||||
int bytes_received = 0;
|
||||
char c;
|
||||
while (isdigit(c = Serial_receive()))
|
||||
bytes_received = c - '0' + bytes_received * 10;
|
||||
int i = 0;
|
||||
while (--limit > 0 && i < bytes_received)
|
||||
data[i++] = Serial_receive();
|
||||
data[i] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Serial_find_timeout("+IPD,", 100))
|
||||
return 0;
|
||||
int connection_id = Serial_receive() - '0';
|
||||
(void)Serial_receive();
|
||||
int bytes_received = 0;
|
||||
char c;
|
||||
while (isdigit(c = Serial_receive()))
|
||||
bytes_received = c - '0' + bytes_received * 10;
|
||||
int i = 0;
|
||||
while (--limit > 0 && i < bytes_received)
|
||||
data[i++] = Serial_receive();
|
||||
data[i] = '\0';
|
||||
}
|
||||
return 1; // return if received AND connection?
|
||||
}
|
||||
25
Examples/NeoPixel Example/WiFi.h
Normal file
25
Examples/NeoPixel Example/WiFi.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef WIFI_H_
|
||||
#define WIFI_H_
|
||||
|
||||
#define WIFI_SUCCESS 1
|
||||
#define WIFI_FAIL 0
|
||||
|
||||
void WiFi_init(void);
|
||||
void WiFi_restart(void);
|
||||
void WiFi_set_baud_rate(int baud,int data_bits,int stop_bits,int parity,int flow_ctl);
|
||||
void WiFi_set_wifi_mode(int mode);
|
||||
void WiFi_join_access_point(const char ssid[],const char password[]);
|
||||
void WiFi_quit_access_point(void);
|
||||
void WiFi_set_IP_mode(int mode);
|
||||
void WiFi_set_IP_address(const char *ip);
|
||||
void WiFi_set_softAP_options(const char *ssid,const char *password,int channel_id,int encription);
|
||||
void WiFi_enable_multiple_connections(int enable);
|
||||
void WiFi_establish_TCP_connection(int connection_id, const char *ip,int port);
|
||||
void WiFi_register_UDP_port(int connection_id,const char *remote_ip, int remote_port, int local_port, int mode);
|
||||
void WiFi_close_connection(int connection_id);
|
||||
int WiFi_create_TCP_server(int port);
|
||||
void WiFi_delete_server(void);
|
||||
void WiFi_send_data(int connection_id,const char data[]);
|
||||
int WiFi_receive_data(char data[],int limit);
|
||||
|
||||
#endif /* WIFI_H_ */
|
||||
93
Examples/NeoPixel Example/asf.h
Normal file
93
Examples/NeoPixel Example/asf.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief Autogenerated API include file for the Atmel Software Framework (ASF)
|
||||
*
|
||||
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ASF_H
|
||||
#define ASF_H
|
||||
|
||||
/*
|
||||
* This file includes all API header files for the selected drivers from ASF.
|
||||
* Note: There might be duplicate includes required by more than one driver.
|
||||
*
|
||||
* The file is automatically generated and will be re-written when
|
||||
* running the ASF driver selector tool. Any changes will be discarded.
|
||||
*/
|
||||
|
||||
// From module: Common SAM0 compiler driver
|
||||
#include <compiler.h>
|
||||
#include <status_codes.h>
|
||||
|
||||
// From module: Common build items for user board support templates
|
||||
#include <user_board.h>
|
||||
|
||||
// From module: Delay routines
|
||||
#include <delay.h>
|
||||
|
||||
// From module: Generic board support
|
||||
#include <board.h>
|
||||
|
||||
// From module: Interrupt management - SAM implementation
|
||||
#include <interrupt.h>
|
||||
|
||||
// From module: Part identification macros
|
||||
#include <parts.h>
|
||||
|
||||
// From module: SYSTEM - Clock Management for SAMD21/R21/DA/HA
|
||||
#include <clock.h>
|
||||
#include <gclk.h>
|
||||
|
||||
// From module: SYSTEM - Core System Driver
|
||||
#include <system.h>
|
||||
|
||||
// From module: SYSTEM - I/O Pin Multiplexer
|
||||
#include <pinmux.h>
|
||||
|
||||
// From module: SYSTEM - Interrupt Driver
|
||||
#include <system_interrupt.h>
|
||||
|
||||
// From module: SYSTEM - Power Management for SAM D20/D21/R21/D09/D10/D11/DA/HA
|
||||
#include <power.h>
|
||||
|
||||
// From module: SYSTEM - Reset Management for SAM D20/D21/R21/D09/D10/D11/DA/HA
|
||||
#include <reset.h>
|
||||
|
||||
#endif // ASF_H
|
||||
50
Examples/NeoPixel Example/config/conf_board.h
Normal file
50
Examples/NeoPixel Example/config/conf_board.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief User board configuration template
|
||||
*
|
||||
* Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
|
||||
#ifndef CONF_BOARD_H
|
||||
#define CONF_BOARD_H
|
||||
|
||||
#endif // CONF_BOARD_H
|
||||
200
Examples/NeoPixel Example/config/conf_clocks.h
Normal file
200
Examples/NeoPixel Example/config/conf_clocks.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM D21 Clock configuration
|
||||
*
|
||||
* Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
#include <clock.h>
|
||||
|
||||
/****************** GCLK_GEN0 @ 48 MHz configuration *************************/
|
||||
|
||||
#ifndef CONF_CLOCKS_H_INCLUDED
|
||||
# define CONF_CLOCKS_H_INCLUDED
|
||||
|
||||
/* System clock bus configuration */
|
||||
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT false
|
||||
# define CONF_CLOCK_FLASH_WAIT_STATES 1
|
||||
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
# define CONF_CLOCK_APBC_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
|
||||
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
|
||||
# define CONF_CLOCK_OSC8M_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
|
||||
# define CONF_CLOCK_XOSC_ENABLE false
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
|
||||
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
|
||||
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
|
||||
# define CONF_CLOCK_XOSC_ON_DEMAND true
|
||||
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE false
|
||||
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
|
||||
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536
|
||||
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
|
||||
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_XOSC32K_ON_DEMAND true
|
||||
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
|
||||
# define CONF_CLOCK_OSC32K_ENABLE true
|
||||
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
|
||||
# define CONF_CLOCK_OSC32K_ON_DEMAND true
|
||||
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
|
||||
# define CONF_CLOCK_DFLL_ENABLE false
|
||||
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED
|
||||
# define CONF_CLOCK_DFLL_ON_DEMAND false
|
||||
|
||||
/* DFLL open loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_FINE_VALUE (512)
|
||||
|
||||
/* DFLL closed loop mode configuration */
|
||||
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR (48000000 / 32768)
|
||||
# define CONF_CLOCK_DFLL_QUICK_LOCK true
|
||||
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
|
||||
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
|
||||
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
|
||||
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4)
|
||||
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4)
|
||||
|
||||
/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
|
||||
# define CONF_CLOCK_DPLL_ENABLE true
|
||||
# define CONF_CLOCK_DPLL_ON_DEMAND true
|
||||
# define CONF_CLOCK_DPLL_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_DPLL_LOCK_BYPASS false
|
||||
# define CONF_CLOCK_DPLL_WAKE_UP_FAST false
|
||||
# define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false
|
||||
|
||||
# define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_GCLK
|
||||
# define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
|
||||
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_DIVIDER 1
|
||||
# define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000
|
||||
|
||||
/* DPLL GCLK reference configuration */
|
||||
# define CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
/* DPLL GCLK lock timer configuration */
|
||||
# define CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR GCLK_GENERATOR_1
|
||||
|
||||
/* Set this to true to configure the GCLK when running clocks_init. If set to
|
||||
* false, none of the GCLK generators will be configured in clocks_init(). */
|
||||
# define CONF_CLOCK_CONFIGURE_GCLK true
|
||||
|
||||
/* Configure GCLK generator 0 (Main Clock) */
|
||||
# define CONF_CLOCK_GCLK_0_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DPLL
|
||||
# define CONF_CLOCK_GCLK_0_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 1 */
|
||||
# define CONF_CLOCK_GCLK_1_ENABLE true
|
||||
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K
|
||||
# define CONF_CLOCK_GCLK_1_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 2 (RTC) */
|
||||
# define CONF_CLOCK_GCLK_2_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_2_PRESCALER 32
|
||||
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 3 */
|
||||
# define CONF_CLOCK_GCLK_3_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_3_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 4 */
|
||||
# define CONF_CLOCK_GCLK_4_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_4_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 5 */
|
||||
# define CONF_CLOCK_GCLK_5_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_5_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 6 */
|
||||
# define CONF_CLOCK_GCLK_6_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_6_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 7 */
|
||||
# define CONF_CLOCK_GCLK_7_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_7_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
|
||||
|
||||
/* Configure GCLK generator 8 */
|
||||
# define CONF_CLOCK_GCLK_8_ENABLE false
|
||||
# define CONF_CLOCK_GCLK_8_RUN_IN_STANDBY false
|
||||
# define CONF_CLOCK_GCLK_8_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
|
||||
# define CONF_CLOCK_GCLK_8_PRESCALER 1
|
||||
# define CONF_CLOCK_GCLK_8_OUTPUT_ENABLE false
|
||||
|
||||
#endif /* CONF_CLOCKS_H_INCLUDED */
|
||||
|
||||
45
Examples/NeoPixel Example/main.c
Normal file
45
Examples/NeoPixel Example/main.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <asf.h>
|
||||
#include "NeoPixel.h"
|
||||
#include "WiFi.h"
|
||||
#include "string_func.h"
|
||||
|
||||
uint8_t buffer[24 * 3 * 3 + 90];
|
||||
|
||||
int main (void)
|
||||
{
|
||||
/* initialize clock system (conf_clocks.h) */
|
||||
system_init();
|
||||
delay_init();
|
||||
|
||||
/* initialize NeoPixel strip */
|
||||
NeoPixel_init();
|
||||
|
||||
/* initialize WiFi */
|
||||
WiFi_init();
|
||||
|
||||
/* set default animation */
|
||||
NeoPixel_set_animation(KITT);
|
||||
|
||||
char data[100];
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* update animation */
|
||||
NeoPixel_update_animation();
|
||||
|
||||
/* do other things */
|
||||
if (WiFi_receive_data(data, sizeof data))
|
||||
{
|
||||
if (strcomp(data, "BREATHING") == 0)
|
||||
NeoPixel_set_animation(BREATHING);
|
||||
else if (strcomp(data, "KITT") == 0)
|
||||
NeoPixel_set_animation(KITT);
|
||||
else if (strcomp(data, "BLINK") == 0)
|
||||
NeoPixel_set_animation(BLINK);
|
||||
else if (strcomp(data, "SOUND") == 0)
|
||||
NeoPixel_set_animation(SOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
76
Examples/NeoPixel Example/string_func.c
Normal file
76
Examples/NeoPixel Example/string_func.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "string_func.h"
|
||||
|
||||
#define NULL (void*)0
|
||||
|
||||
int strlength(const char *string)
|
||||
{
|
||||
const char *p = string;
|
||||
while (*p != '\0')
|
||||
p++;
|
||||
return p - string;
|
||||
}
|
||||
|
||||
int strcomp(const char *s1,const char *s2)
|
||||
{
|
||||
while (*s1 == *s2)
|
||||
{
|
||||
if (*s1 == '\0')
|
||||
return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *s1 - *s2;
|
||||
}
|
||||
|
||||
char *strstring(const char *haystack,const char *needle)
|
||||
{
|
||||
const char *p;
|
||||
const char *q;
|
||||
while (*haystack != '\0')
|
||||
{
|
||||
p = haystack;
|
||||
q = needle;
|
||||
while (*q == *p)
|
||||
{
|
||||
if (*q == '\0')
|
||||
return (char*)haystack;
|
||||
q++;
|
||||
p++;
|
||||
|
||||
}
|
||||
if (*q == '\0')
|
||||
return (char*)haystack;
|
||||
haystack++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strcharacter(const char *string,char c)
|
||||
{
|
||||
while (*string != c)
|
||||
string++;
|
||||
return (char*)string;
|
||||
}
|
||||
|
||||
char *parse_until(const char *src,char *dest,char until)
|
||||
{
|
||||
char *p = dest;
|
||||
while ((*dest = *src) != until)
|
||||
{
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
*dest = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
char *reverse(char string[])
|
||||
{
|
||||
for (int i = 0 , j = strlength(string) - 1 ; i < j ; i++ , j--)
|
||||
{
|
||||
char temp = string[i];
|
||||
string[i] = string[j];
|
||||
string[j] = temp;
|
||||
}
|
||||
return &string[0];
|
||||
}
|
||||
11
Examples/NeoPixel Example/string_func.h
Normal file
11
Examples/NeoPixel Example/string_func.h
Normal file
@@ -0,0 +1,11 @@
|
||||
int strlength(const char *string);
|
||||
|
||||
int strcomp(const char *s1,const char *s2);
|
||||
|
||||
char *strstring(const char *haystack,const char *needle);
|
||||
|
||||
char *strcharacter(const char *string,char c);
|
||||
|
||||
char *parse_until(const char *src,char *dest,char until);
|
||||
|
||||
char *reverse(char string[]);
|
||||
68
Examples/NeoPixel Example/utility.c
Normal file
68
Examples/NeoPixel Example/utility.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <ctype.h>
|
||||
#include "string_func.h"
|
||||
#include "utility.h"
|
||||
|
||||
int atoint(const char *a)
|
||||
{
|
||||
while (isspace(*a))
|
||||
a++;
|
||||
int sign = 1;
|
||||
if (*a == '-')
|
||||
sign = -1;
|
||||
if (*a == '+' || *a == '-')
|
||||
a++;
|
||||
int i = 0;
|
||||
while (isdigit(*a))
|
||||
i = *a++ - '0' + i*10;
|
||||
return sign*i;
|
||||
}
|
||||
|
||||
char *inttoa(int i,char *a)
|
||||
{
|
||||
char *p = a;
|
||||
do
|
||||
{
|
||||
*a++ = i % 10 + '0';
|
||||
} while ((i /= 10) > 0);
|
||||
*a = '\0';
|
||||
return reverse(p);
|
||||
}
|
||||
|
||||
double atofloat(const char *a)
|
||||
{
|
||||
while (isspace(*a))
|
||||
a++;
|
||||
int sign = *a == '-' ? -1 : 1;
|
||||
if (*a == '+' || *a == '-')
|
||||
a++;
|
||||
double val = 0.0;
|
||||
while (isdigit(*a))
|
||||
val = *a++ - '0' + val * 10.0;
|
||||
if (*a == '.')
|
||||
a++;
|
||||
double power = 1.0;
|
||||
while (isdigit(*a))
|
||||
{
|
||||
val = *a++ - '0' + val * 10.0;
|
||||
power *= 10.0;
|
||||
}
|
||||
val = sign*val/power;
|
||||
if (*a == 'e' || *a == 'E')
|
||||
a++;
|
||||
sign = *a == '-' ? -1 : 1;
|
||||
if (*a == '+' || *a == '-')
|
||||
a++;
|
||||
int n = 0;
|
||||
while (isdigit(*a))
|
||||
n = *a++ - '0' + n * 10;
|
||||
if (sign == 1)
|
||||
while (n-- > 0)
|
||||
val *= 10.0;
|
||||
else
|
||||
while (n-- > 0)
|
||||
val /= 10.0;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
5
Examples/NeoPixel Example/utility.h
Normal file
5
Examples/NeoPixel Example/utility.h
Normal file
@@ -0,0 +1,5 @@
|
||||
int atoint(const char *a);
|
||||
|
||||
char *inttoa(int i,char *a);
|
||||
|
||||
double atofloat(const char *a);
|
||||
Reference in New Issue
Block a user