stm32-h103 examples: Cosmetic and coding style fixes.

This commit is contained in:
Uwe Hermann 2011-11-03 00:57:46 +01:00
parent a3ce2924df
commit 44bf853e6e
16 changed files with 317 additions and 363 deletions

View File

@ -2,7 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>,
* 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,6 @@ u16 exti_line_state;
void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
}
void gpio_setup(void)
@ -48,9 +47,7 @@ void button_setup(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
/* Set GPIO0 (in GPIO port A) to 'input open-drain'. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO0);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO0);
}
int main(void)

View File

@ -2,7 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>,
* 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,6 @@ u16 exti_line_state;
void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
}
void gpio_setup(void)
@ -50,23 +49,23 @@ void exti_setup(void)
/* Enable AFIO clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
/* Enable EXTI0 interrupt */
/* Enable EXTI0 interrupt. */
nvic_enable_irq(NVIC_EXTI0_IRQ);
/* Set GPIO0 (in GPIO port A) to 'input float'. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO0);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO0);
/* configure EXTI subsystem */
/* Configure the EXTI subsystem. */
exti_select_source(EXTI0, GPIOA);
exti_set_trigger(EXTI0, EXTI_TRIGGER_BOTH);
exti_enable_request(EXTI0);
}
void exti0_isr()
void exti0_isr(void)
{
exti_line_state = GPIOA_IDR;
/* The LED (PC12) is on, but turns off when the button is pressed. */
if ((exti_line_state & (1 << 0)) != 0) {
gpio_clear(GPIOC, GPIO12);
} else {
@ -78,15 +77,12 @@ void exti0_isr()
int main(void)
{
clock_setup();
gpio_setup();
exti_setup();
/* Blink the LED (PC12) on the board. */
while (1) {
while (1)
__asm("nop");
}
return 0;
}

View File

@ -2,7 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>,
* 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,7 +32,6 @@ u16 exti_direction = FALLING;
void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
}
void gpio_setup(void)
@ -53,21 +52,20 @@ void exti_setup(void)
/* Enable AFIO clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
/* Enable EXTI0 interrupt */
/* Enable EXTI0 interrupt. */
nvic_enable_irq(NVIC_EXTI0_IRQ);
/* Set GPIO0 (in GPIO port A) to 'input open-drain'. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO0);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO0);
/* configure EXTI subsystem */
/* Configure the EXTI subsystem. */
exti_select_source(EXTI0, GPIOA);
exti_direction = FALLING;
exti_set_trigger(EXTI0, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI0);
}
void exti0_isr()
void exti0_isr(void)
{
exti_reset_request(EXTI0);
@ -84,15 +82,12 @@ void exti0_isr()
int main(void)
{
clock_setup();
gpio_setup();
exti_setup();
/* Blink the LED (PC12) on the board. */
while (1) {
while (1)
__asm("nop");
}
return 0;
}

View File

@ -27,7 +27,6 @@ void clock_setup(void)
/* Enable GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
}
void gpio_setup(void)

View File

@ -18,14 +18,13 @@
*/
/*
* This example is implementing the protocol of ZJ168 addressable led
* This example is implementing the protocol of ZJ168 addressable LED
* strips. These strips use the LPD6803 controller. You may be able to
* find the datasheet here:
* http://www.adafruit.com/datasheets/LPD6803.pdf
*/
#include <stdlib.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/gpio.h>
@ -68,10 +67,9 @@ void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
/* Enable GPIOC clock. */
/* Enable GPIOB and GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
}
void gpio_setup(void)
@ -79,28 +77,33 @@ void gpio_setup(void)
/* Set GPIO12 (in GPIO port C) to 'output push-pull'. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
/* Set GPIO13 (in GPIO port B) to 'output push-pull'. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
/* Set GPIO15 (in GPIO port B) to 'output push-pull'. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
}
void send_colors(struct color *colors, int count) {
void send_colors(struct color *colors, int count)
{
int i, k;
/* initialize spi pins */
/* Initialize SPI pins. */
SCLK(0);
MOSI(0);
/* start frame */
for (i=0; i<32; i++) {
/* Start frame */
for (i = 0; i < 32; i++) {
SCLK(1);
SMALL_DELAY();
SCLK(0);
SMALL_DELAY();
}
/* color cell output */
/* Color cell output */
for (k = 0; k < count; k++) {
/* Start bit */
MOSI(1);
@ -110,7 +113,7 @@ void send_colors(struct color *colors, int count) {
SMALL_DELAY();
/* Blue */
for (i=0; i<5; i++) {
for (i = 0; i < 5; i++) {
MOSI(((colors[k].b & ((1 << 4) >> i)) != 0));
SCLK(1);
SMALL_DELAY();
@ -118,7 +121,7 @@ void send_colors(struct color *colors, int count) {
SMALL_DELAY();
}
/* Red */
for (i=0; i<5; i++) {
for (i = 0; i < 5; i++) {
MOSI(((colors[k].r & ((1 << 4) >> i)) != 0));
SCLK(1);
SMALL_DELAY();
@ -126,7 +129,7 @@ void send_colors(struct color *colors, int count) {
SMALL_DELAY();
}
/* Green */
for (i=0; i<5; i++) {
for (i = 0; i < 5; i++) {
MOSI(((colors[k].g & ((1 << 4) >> i)) != 0));
SCLK(1);
SMALL_DELAY();
@ -137,7 +140,7 @@ void send_colors(struct color *colors, int count) {
/* End frame */
MOSI(0);
for (k=0; k < count; k++) {
for (k = 0; k < count; k++) {
SCLK(1);
SMALL_DELAY();
SCLK(0);
@ -145,18 +148,19 @@ void send_colors(struct color *colors, int count) {
}
}
void reset_colors(struct color *colors, int count) {
void reset_colors(struct color *colors, int count)
{
int i;
for (i=0; i<count; i++) {
for (i = 0; i < count; i++) {
colors[i].r = 0;
colors[i].g = 0;
colors[i].b = 0;
}
}
void init_colors(struct color *colors, int count) {
void init_colors(struct color *colors, int count)
{
colors[0].r = 0x1F;
colors[0].g = 0;
colors[0].b = 0;
@ -170,28 +174,29 @@ void init_colors(struct color *colors, int count) {
count = count;
}
void step_colors(struct color *colors, int count) {
void step_colors(struct color *colors, int count)
{
int i;
struct color tmp_color1;
struct color tmp_color2;
/* random blinking */
/*
for (i=0; i<count; i++) {
colors[i].r = rand()&0x01;
colors[i].g = rand()&0x01;
colors[i].b = rand()&0x01;
#if 0
/* Random blinking. */
for (i = 0; i < count; i++) {
colors[i].r = rand() & 0x01;
colors[i].g = rand() & 0x01;
colors[i].b = rand() & 0x01;
}
*/
/* generate next colors */
#endif
/* Generate next colors. */
tmp_color1.r = colors[0].r;
tmp_color1.g = colors[0].g;
tmp_color1.b = colors[0].b;
colors[0].r = colors[count-1].r;
colors[0].g = colors[count-1].g;
colors[0].b = colors[count-1].b;
for(i=1; i<count; i++) {
colors[0].r = colors[count - 1].r;
colors[0].g = colors[count - 1].g;
colors[0].b = colors[count - 1].b;
for (i = 1; i < count; i++) {
tmp_color2.r = colors[i].r;
tmp_color2.g = colors[i].g;
tmp_color2.b = colors[i].b;
@ -202,7 +207,6 @@ void step_colors(struct color *colors, int count) {
tmp_color1.g = tmp_color2.g;
tmp_color1.b = tmp_color2.b;
}
}
int main(void)
@ -224,10 +228,8 @@ int main(void)
step_colors(colors, COLOR_COUNT);
/* Wait a little */
for (i = 0; i < 1000000; i++) /* Wait a bit. */
__asm__("nop");
}
return 0;

View File

@ -31,7 +31,6 @@ u16 exti_direction = FALLING;
void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
}
void gpio_setup(void)
@ -39,13 +38,9 @@ void gpio_setup(void)
/* Enable GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
/*
* Set GPIO12 (PORTC) (led) to
* 'output alternate function push-pull'.
*/
/* Set GPIO12 (in GPIO port C) to 'output push-pull'. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
}
void exti_setup(void)
@ -56,30 +51,29 @@ void exti_setup(void)
/* Enable AFIO clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
/* Enable EXTI0 interrupt */
/* Enable EXTI0 interrupt. */
nvic_enable_irq(NVIC_EXTI0_IRQ);
/* Set GPIO0 (in GPIO port A) to 'input open-drain'. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, GPIO0);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO0);
/* configure EXTI subsystem */
/* Configure the EXTI subsystem. */
exti_select_source(EXTI0, GPIOA);
exti_direction = FALLING;
exti_set_trigger(EXTI0, EXTI_TRIGGER_FALLING);
exti_enable_request(EXTI0);
}
void exti0_isr()
void exti0_isr(void)
{
exti_reset_request(EXTI0);
if (exti_direction == FALLING) {
//gpio_toggle(GPIOA, GPIO12);
// gpio_toggle(GPIOA, GPIO12);
exti_direction = RISING;
exti_set_trigger(EXTI0, EXTI_TRIGGER_RISING);
} else {
//gpio_toggle(GPIOA, GPIO12);
// gpio_toggle(GPIOA, GPIO12);
timer_generate_event(TIM1, TIM_EGR_COMG);
exti_direction = FALLING;
exti_set_trigger(EXTI0, EXTI_TRIGGER_FALLING);
@ -88,50 +82,43 @@ void exti0_isr()
void tim_setup(void)
{
/* Enable TIM1 clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_TIM1EN);
/* Enable GPIOA, GPIOB and Alternate Function clocks. */
rcc_peripheral_enable_clock(&RCC_APB2ENR,
RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_IOPBEN |
RCC_APB2ENR_AFIOEN);
RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN);
/*
* Set TIM1 chanel output pins to
* Set TIM1 channel output pins to
* 'output alternate function push-pull'.
*/
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_TIM1_CH1 |
GPIO_TIM1_CH2 |
GPIO_TIM1_CH3);
GPIO_TIM1_CH1 | GPIO_TIM1_CH2 | GPIO_TIM1_CH3);
/*
* Set TIM1 complementary chanel output pins to
* Set TIM1 complementary channel output pins to
* 'output alternate function push-pull'.
*/
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,
GPIO_TIM1_CH1N |
GPIO_TIM1_CH2N |
GPIO_TIM1_CH3N);
GPIO_TIM1_CH1N | GPIO_TIM1_CH2N | GPIO_TIM1_CH3N);
/* Enable TIM1 commutation interrupt. */
nvic_enable_irq(NVIC_TIM1_TRG_COM_IRQ);
/* Reset TIM1 peripheral */
/* Reset TIM1 peripheral. */
timer_reset(TIM1);
/* Timer global mode:
* - No divider
* - alignment edge
* - direction up
* - Alignment edge
* - Direction up
*/
timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT,
TIM_CR1_CMS_EDGE,
TIM_CR1_DIR_UP);
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
/* Reset prescaler value. */
timer_set_prescaler(TIM1, 0);
@ -142,13 +129,13 @@ void tim_setup(void)
/* Enable preload. */
timer_enable_preload(TIM1);
/* Continous mode. */
/* Continuous mode. */
timer_continuous_mode(TIM1);
/* Period (32kHz) */
/* Period (32kHz). */
timer_set_period(TIM1, 72000000 / 32000);
/* Configure break and deadtime */
/* Configure break and deadtime. */
timer_set_deadtime(TIM1, 10);
timer_set_enabled_off_state_in_idle_mode(TIM1);
timer_set_enabled_off_state_in_run_mode(TIM1);
@ -239,19 +226,23 @@ void tim_setup(void)
timer_enable_oc_output(TIM1, TIM_OC3N);
/* ---- */
/* ARR reload enable */
/* ARR reload enable. */
timer_enable_preload(TIM1);
/* Enable preload of complementary channel configurations and update on COM event */
/*
* Enable preload of complementary channel configurations and
* update on COM event.
*/
timer_enable_preload_complementry_enable_bits(TIM1);
/* Enable outputs in the break subsystem */
/* Enable outputs in the break subsystem. */
timer_enable_break_main_output(TIM1);
/* Counter enable */
/* Counter enable. */
timer_enable_counter(TIM1);
/* Enable commutation interrupt */
/* Enable commutation interrupt. */
timer_enable_irq(TIM1, TIM_DIER_COMIE);
}
@ -262,12 +253,13 @@ void tim1_trg_com_isr(void)
/* Clear the COM trigger interrupt flag. */
timer_clear_flag(TIM1, TIM_SR_COMIF);
/* A simplified and inefficient implementation of PWM On
/*
* A simplified and inefficient implementation of PWM On
* scheme. Look at the implementation in Open-BLDC on
* http://open-bldc.org for the proper implementation. This
* one only serves as an example.
*
* Table of the pwm scheme zone configurations when driving:
* Table of the PWM scheme zone configurations when driving:
* @verbatim
* | 1| 2| 3| 4| 5| 6|
* -+--+--+--+--+--+--+
@ -388,7 +380,7 @@ void tim1_trg_com_isr(void)
timer_disable_oc_output(TIM1, TIM_OC3);
timer_enable_oc_output(TIM1, TIM_OC3N);
step=0;
step = 0;
break;
}
gpio_toggle(GPIOC, GPIO12);
@ -401,9 +393,8 @@ int main(void)
tim_setup();
exti_setup();
while (1) {
while (1)
__asm("nop");
}
return 0;
}

View File

@ -41,10 +41,9 @@ u16 frequency_sequence[18] = {
1000,
500,
1000,
5000
5000,
};
int frequency_sel = 0;
u16 compare_time;
@ -55,7 +54,6 @@ int debug = 0;
void clock_setup(void)
{
rcc_clock_setup_in_hse_8mhz_out_72mhz();
}
void gpio_setup(void)
@ -63,38 +61,31 @@ void gpio_setup(void)
/* Enable GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
/*
* Set GPIO12 (PORTC) (led) to
* 'output alternate function push-pull'.
*/
/* Set GPIO12 (in GPIO port C) to 'output push-pull'. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
gpio_set(GPIOC, GPIO12);
}
void tim_setup(void)
{
/* Enable TIM2 clock. */
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN);
/* Enable TIM2 interrupt. */
nvic_enable_irq(NVIC_TIM2_IRQ);
/* Reset TIM2 peripheral */
/* Reset TIM2 peripheral. */
timer_reset(TIM2);
/* Timer global mode:
* - No divider
* - alignment edge
* - direction up
* - Alignment edge
* - Direction up
*/
timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
TIM_CR1_CMS_EDGE,
TIM_CR1_DIR_UP);
TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
/* Reset prescaler value. */
timer_set_prescaler(TIM2, 36000);
@ -105,7 +96,7 @@ void tim_setup(void)
/* Continous mode. */
timer_continuous_mode(TIM2);
/* Period (36kHz) */
/* Period (36kHz). */
timer_set_period(TIM2, 65535);
/* Disable outputs. */
@ -126,19 +117,19 @@ void tim_setup(void)
timer_set_oc_value(TIM2, TIM_OC1, 1000);
/* ---- */
/* ARR reload enable */
/* ARR reload enable. */
timer_disable_preload(TIM2);
/* Counter enable */
/* Counter enable. */
timer_enable_counter(TIM2);
/* Enable commutation interrupt */
/* Enable commutation interrupt. */
timer_enable_irq(TIM2, TIM_DIER_CC1IE);
}
void tim2_isr(void)
{
if (timer_get_flag(TIM2, TIM_SR_CC1IF)) {
/* Clear compare interrupt flag. */
@ -146,38 +137,31 @@ void tim2_isr(void)
/*
* Get current timer value to calculate next
* compare register value
* compare register value.
*/
compare_time = timer_get_counter(TIM2);
/*
* Calculate and set the next compare value.
*/
/* Calculate and set the next compare value. */
frequency = frequency_sequence[frequency_sel++];
new_time = compare_time + frequency;
timer_set_oc_value(TIM2, TIM_OC1,
new_time);
if (frequency_sel == 18) {
timer_set_oc_value(TIM2, TIM_OC1, new_time);
if (frequency_sel == 18)
frequency_sel = 0;
}
/* Toggle led to indicate compare event */
/* Toggle LED to indicate compare event. */
gpio_toggle(GPIOC, GPIO12);
}
}
int main(void)
{
clock_setup();
gpio_setup();
tim_setup();
while (1) {
while (1)
__asm("nop");
}
return 0;
}

View File

@ -3,8 +3,7 @@ README
------------------------------------------------------------------------------
This experimental program sends some characters on the TRACESWO pin using
the Instrumentation Trace Macrocell (ITM) and Trace Port Interface
Unit (TPIU).
the Instrumentation Trace Macrocell (ITM) and Trace Port Interface Unit (TPIU).
The SWJ-DP port must be in SWD mode and not JTAG mode for the output
to be visible.

View File

@ -35,31 +35,30 @@ void clock_setup(void)
void trace_setup(void)
{
/* Enable trace subsystem (we'll use ITM and TPIU) */
/* Enable trace subsystem (we'll use ITM and TPIU). */
SCS_DEMCR |= SCS_DEMCR_TRCENA;
/* Use Manchester code for asynchronous transmission */
/* Use Manchester code for asynchronous transmission. */
TPIU_SPPR = TPIU_SPPR_ASYNC_MANCHESTER;
TPIU_ACPR = 7;
/* Data width is 1 byte */
/* Data width is 1 byte. */
TPIU_CSPSR = TPIU_CSPSR_BYTE;
/* Formatter and flush control */
/* Formatter and flush control. */
TPIU_FFCR &= ~TPIU_FFCR_ENFCONT;
/* Enable TRACESWO pin for async mode */
/* Enable TRACESWO pin for async mode. */
DBGMCU_CR = DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_ASYNC;
/* Unlock access to ITM registers */
/* Unlock access to ITM registers. */
/* FIXME: Magic numbers... Is this Cortex-M3 generic? */
*((volatile uint32_t*)0xE0000FB0) = 0xC5ACCE55;
*((volatile u32 *)0xE0000FB0) = 0xC5ACCE55;
/* Enable ITM with ID = 1 */
/* Enable ITM with ID = 1. */
ITM_TCR = (1 << 16) | ITM_TCR_ITMENA;
/* Enable stimulus port 1 */
ITM_TER[0] = 1;
/* Enable stimulus port 1. */
ITM_TER[0] = 1;
}
void gpio_setup(void)
@ -71,7 +70,9 @@ void gpio_setup(void)
void trace_send_blocking(char c)
{
while(!(ITM_STIM[0] & ITM_STIM_FIFOREADY));
while (!(ITM_STIM[0] & ITM_STIM_FIFOREADY))
;
ITM_STIM[0] = c;
}
@ -86,14 +87,14 @@ int main(void)
/* Blink the LED (PC12) on the board with every transmitted byte. */
while (1) {
gpio_toggle(GPIOC, GPIO12); /* LED on/off */
trace_send_blocking(c + '0');
trace_send_blocking(c + '0');
c = (c == 9) ? 0 : c + 1; /* Increment c. */
if ((j++ % 80) == 0) { /* Newline after line full. */
trace_send_blocking('\r');
trace_send_blocking('\n');
}
for (i = 0; i < 800000; i++) /* Wait a bit. */
__asm__("NOP");
__asm__("nop");
}
return 0;

View File

@ -26,18 +26,22 @@ void clock_setup(void)
rcc_clock_setup_in_hse_8mhz_out_72mhz();
/* Enable GPIOC clock. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR,
RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN |
RCC_APB2ENR_IOPCEN);
/* Enable clocks for GPIO port B (for GPIO_USART3_TX) and USART3. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_USART1EN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN | RCC_APB1ENR_USART3EN);
rcc_peripheral_enable_clock(&RCC_APB1ENR,
RCC_APB1ENR_USART2EN |
RCC_APB1ENR_USART3EN);
}
void usart_setup(void)
{
/* Setup GPIO pin GPIO_USART1_TX. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
/* Setup UART parameters. */
usart_set_baudrate(USART1, 38400, rcc_ppre2_frequency);
@ -52,7 +56,7 @@ void usart_setup(void)
/* Setup GPIO pin GPIO_USART2_TX. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
/* Setup UART parameters. */
usart_set_baudrate(USART2, 38400, rcc_ppre1_frequency);
@ -67,7 +71,7 @@ void usart_setup(void)
/* Setup GPIO pin GPIO_USART3_TX/GPIO10 on GPIO port B for transmit. */
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART3_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART3_TX);
/* Setup UART parameters. */
usart_set_baudrate(USART3, 38400, rcc_ppre1_frequency);
@ -98,7 +102,7 @@ int main(void)
/* Blink the LED (PC12) on the board with every transmitted byte. */
while (1) {
gpio_toggle(GPIOC, GPIO12); /* LED on/off */
gpio_toggle(GPIOC, GPIO12); /* LED on/off */
usart_send_blocking(USART1, c + '0'); /* USART1: Send byte. */
usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */
usart_send_blocking(USART3, c + '0'); /* USART3: Send byte. */
@ -112,7 +116,7 @@ int main(void)
usart_send_blocking(USART3, '\n');
}
for (i = 0; i < 800000; i++) /* Wait a bit. */
__asm__("NOP");
__asm__("nop");
}
return 0;

View File

@ -31,8 +31,7 @@ void clock_setup(void)
/* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_AFIOEN |
RCC_APB2ENR_USART1EN);
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN);
}
void usart_setup(void)
@ -42,7 +41,7 @@ void usart_setup(void)
/* Setup GPIO pin GPIO_USART1_RE_TX on GPIO port B for transmit. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
/* Setup GPIO pin GPIO_USART1_RE_RX on GPIO port B for receive. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
@ -67,7 +66,7 @@ void gpio_setup(void)
{
gpio_set(GPIOC, GPIO12);
/* Setup GPIO6 and 7 (in GPIO port A) for led use. */
/* Setup GPIO6 and 7 (in GPIO port A) for LED use. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
}
@ -78,7 +77,7 @@ void usart1_isr(void)
/* Check if we were called because of RXNE. */
if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
/* Indicate that we got data. */
gpio_toggle(GPIOC, GPIO12);
@ -92,10 +91,10 @@ void usart1_isr(void)
/* Check if we were called because of TXE. */
if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
((USART_SR(USART1) & USART_SR_TXE) != 0)) {
((USART_SR(USART1) & USART_SR_TXE) != 0)) {
/* Indicate that we are sending out data. */
//gpio_toggle(GPIOA, GPIO7);
// gpio_toggle(GPIOA, GPIO7);
/* Put data into the transmit register. */
usart_send(USART1, data);

View File

@ -2,7 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>,
* 2011 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,7 +23,6 @@
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/nvic.h>
#include <libopencm3/stm32/systick.h>
#include <stdio.h>
#include <errno.h>
@ -31,83 +30,81 @@
* Simple ringbuffer implementation from open-bldc's libgovernor that
* you can find at:
* https://github.com/open-bldc/open-bldc/tree/master/source/libgovernor
******************************************************************************/
*****************************************************************************/
typedef s32 ring_size_t;
struct ring {
u8 *data;
ring_size_t size;
u32 begin;
u32 end;
u8 *data;
ring_size_t size;
u32 begin;
u32 end;
};
#define RING_SIZE(RING) ((RING)->size - 1)
#define RING_DATA(RING) (RING)->data
#define RING_SIZE(RING) ((RING)->size - 1)
#define RING_DATA(RING) (RING)->data
#define RING_EMPTY(RING) ((RING)->begin == (RING)->end)
void ring_init(struct ring *ring, u8 * buf, ring_size_t size)
void ring_init(struct ring *ring, u8 *buf, ring_size_t size)
{
ring->data = buf;
ring->size = size;
ring->begin = 0;
ring->end = 0;
ring->data = buf;
ring->size = size;
ring->begin = 0;
ring->end = 0;
}
s32 ring_write_ch(struct ring *ring, u8 ch)
{
if (((ring->end + 1) % ring->size) != ring->begin) {
ring->data[ring->end++] = ch;
ring->end %= ring->size;
return (u32) ch;
}
if (((ring->end + 1) % ring->size) != ring->begin) {
ring->data[ring->end++] = ch;
ring->end %= ring->size;
return (u32)ch;
}
return -1;
return -1;
}
s32 ring_write(struct ring * ring, u8 * data, ring_size_t size)
s32 ring_write(struct ring *ring, u8 *data, ring_size_t size)
{
s32 i;
s32 i;
for (i = 0; i < size; i++) {
if (ring_write_ch(ring, data[i]) < 0) {
return -i;
}
}
for (i = 0; i < size; i++) {
if (ring_write_ch(ring, data[i]) < 0)
return -i;
}
return i;
return i;
}
s32 ring_read_ch(struct ring * ring, u8 * ch)
s32 ring_read_ch(struct ring *ring, u8 *ch)
{
s32 ret = -1;
s32 ret = -1;
if (ring->begin != ring->end) {
ret = ring->data[ring->begin++];
ring->begin %= ring->size;
if (ch)
*ch = ret;
}
if (ring->begin != ring->end) {
ret = ring->data[ring->begin++];
ring->begin %= ring->size;
if (ch)
*ch = ret;
}
return ret;
return ret;
}
s32 ring_read(struct ring * ring, u8 * data, ring_size_t size)
s32 ring_read(struct ring *ring, u8 *data, ring_size_t size)
{
s32 i;
s32 i;
for (i = 0; i < size; i++) {
if (ring_read_ch(ring, data + i) < 0) {
return i;
}
}
for (i = 0; i < size; i++) {
if (ring_read_ch(ring, data + i) < 0)
return i;
}
return -i;
return -i;
}
/******************************************************************************
* The example implementation
******************************************************************************/
*****************************************************************************/
#define BUFFER_SIZE 1024
@ -123,14 +120,12 @@ void clock_setup(void)
/* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_AFIOEN |
RCC_APB2ENR_USART1EN);
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN);
}
void usart_setup(void)
{
/* Initialize output ring buffer */
/* Initialize output ring buffer. */
ring_init(&output_ring, output_ring_buffer, BUFFER_SIZE);
/* Enable the USART1 interrupt. */
@ -138,7 +133,7 @@ void usart_setup(void)
/* Setup GPIO pin GPIO_USART1_RE_TX on GPIO port B for transmit. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
/* Setup GPIO pin GPIO_USART1_RE_RX on GPIO port B for receive. */
gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
@ -172,7 +167,7 @@ void usart1_isr(void)
{
/* Check if we were called because of RXNE. */
if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
/* Indicate that we got data. */
gpio_toggle(GPIOC, GPIO12);
@ -186,14 +181,14 @@ void usart1_isr(void)
/* Check if we were called because of TXE. */
if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
((USART_SR(USART1) & USART_SR_TXE) != 0)) {
((USART_SR(USART1) & USART_SR_TXE) != 0)) {
s32 data;
data = ring_read_ch(&output_ring, NULL);
if (data == -1) {
/* Disable the TXE interrupt as we don't need it anymore. */
/* Disable the TXE interrupt, it's no longer needed. */
USART_CR1(USART1) &= ~USART_CR1_TXEIE;
} else {
/* Put data into the transmit register. */
@ -202,27 +197,28 @@ void usart1_isr(void)
}
}
int _write (int file, char *ptr, int len)
int _write(int file, char *ptr, int len)
{
int ret;
if (file == 1) {
ret = ring_write(&output_ring, (u8 *)ptr, len);
if (ret < 0) ret = -ret;
if (ret < 0)
ret = -ret;
USART_CR1(USART1) |= USART_CR1_TXEIE;
return ret;
}
errno = EIO;
return -1;
errno = EIO;
return -1;
}
void systick_setup(void) {
/* 72MHz / 8 => 9000000 counts per second */
void systick_setup(void)
{
/* 72MHz / 8 => 9000000 counts per second. */
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
/* 9000000/9000 = 1000 overflows per second - every 1ms one interrupt */
@ -232,7 +228,6 @@ void systick_setup(void) {
/* Start counting. */
systick_counter_enable();
}
void sys_tick_handler(void)
@ -240,17 +235,20 @@ void sys_tick_handler(void)
static int counter = 0;
static float fcounter = 0.0;
static double dcounter = 0.0;
static u32 temp32 = 0;
temp32++;
/* We call this handler every 1ms so we are sending hello world every 10ms / 100Hz. */
/*
* We call this handler every 1ms so we are sending hello world
* every 10ms / 100Hz.
*/
if (temp32 == 10) {
printf("Hello World! %i %f %f\r\n", counter, fcounter, dcounter);
printf("Hello World! %i %f %f\r\n", counter, fcounter,
dcounter);
counter++;
fcounter+=0.01;
dcounter+=0.01;
fcounter += 0.01;
dcounter += 0.01;
temp32 = 0;
}
@ -258,15 +256,13 @@ void sys_tick_handler(void)
int main(void)
{
clock_setup();
gpio_setup();
usart_setup();
systick_setup();
while (1) {
while (1)
__asm__("nop");
}
return 0;
}

View File

@ -2,7 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>,
* 2011 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,6 @@
#include <libopencm3/stm32/f1/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/nvic.h>
#include <stdio.h>
#include <errno.h>
@ -35,15 +34,14 @@ void clock_setup(void)
/* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN |
RCC_APB2ENR_AFIOEN |
RCC_APB2ENR_USART1EN);
RCC_APB2ENR_AFIOEN | RCC_APB2ENR_USART1EN);
}
void usart_setup(void)
{
/* Setup GPIO pin GPIO_USART1_RE_TX on GPIO port B for transmit. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
/* Setup UART parameters. */
usart_set_baudrate(USART1, 230400, rcc_ppre2_frequency);
@ -61,25 +59,23 @@ void gpio_setup(void)
{
gpio_set(GPIOC, GPIO12);
/* Setup GPIO6 and 7 (in GPIO port A) for led use. */
/* Setup GPIO6 and 7 (in GPIO port A) for LED use. */
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
}
int _write (int file, char *ptr, int len)
int _write(int file, char *ptr, int len)
{
int i;
int i;
if (file == 1) {
for (i = 0; i < len; i++){
for (i = 0; i < len; i++)
usart_send_blocking(USART1, ptr[i]);
}
return i;
}
errno = EIO;
return -1;
errno = EIO;
return -1;
}
int main(void)
@ -93,15 +89,16 @@ int main(void)
usart_setup();
/*
* Write Hello World an integer, float and double all over
* Write Hello World, an integer, float and double all over
* again while incrementing the numbers.
*/
while (1) {
gpio_toggle(GPIOC, GPIO12);
printf("Hello World! %i %f %f\r\n", counter, fcounter, dcounter);
printf("Hello World! %i %f %f\r\n", counter, fcounter,
dcounter);
counter++;
fcounter+=0.01;
dcounter+=0.01;
fcounter += 0.01;
dcounter += 0.01;
}
return 0;

View File

@ -24,25 +24,27 @@
#include <libopencm3/usb/cdc.h>
static const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = USB_CLASS_CDC,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0x5740,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = USB_CLASS_CDC,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0x5740,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
/* This notification endpoint isn't implemented. According to CDC spec its
* optional, but its absence causes a NULL pointer dereference in Linux cdc_acm
* driver. */
/*
* This notification endpoint isn't implemented. According to CDC spec its
* optional, but its absence causes a NULL pointer dereference in Linux
* cdc_acm driver.
*/
static const struct usb_endpoint_descriptor comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@ -100,7 +102,7 @@ static const struct {
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = 0,
.bSubordinateInterface0 = 1,
}
},
};
static const struct usb_interface_descriptor comm_iface[] = {{
@ -117,7 +119,7 @@ static const struct usb_interface_descriptor comm_iface[] = {{
.endpoint = comm_endp,
.extra = &cdcacm_functional_descriptors,
.extralen = sizeof(cdcacm_functional_descriptors)
.extralen = sizeof(cdcacm_functional_descriptors),
}};
static const struct usb_interface_descriptor data_iface[] = {{
@ -159,24 +161,26 @@ static const char *usb_strings[] = {
"x",
"Black Sphere Technologies",
"CDC-ACM Demo",
"DEMO"
"DEMO",
};
static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
(void)complete;
(void)buf;
switch(req->bRequest) {
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
/* This Linux cdc_acm driver requires this to be implemented
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor. */
/*
* This Linux cdc_acm driver requires this to be implemented
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor.
*/
char buf[10];
struct usb_cdc_notification *notif = (void*)buf;
struct usb_cdc_notification *notif = (void *)buf;
/* We echo signals back to host as notification */
/* We echo signals back to host as notification. */
notif->bmRequestType = 0xA1;
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
notif->wValue = 0;
@ -184,13 +188,12 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
notif->wLength = 2;
buf[8] = req->wValue & 3;
buf[9] = 0;
//usbd_ep_write_packet(0x83, buf, 10);
// usbd_ep_write_packet(0x83, buf, 10);
return 1;
}
case USB_CDC_REQ_SET_LINE_CODING:
if(*len < sizeof(struct usb_cdc_line_coding))
case USB_CDC_REQ_SET_LINE_CODING:
if (*len < sizeof(struct usb_cdc_line_coding))
return 0;
return 1;
}
return 0;
@ -202,7 +205,8 @@ static void cdcacm_data_rx_cb(u8 ep)
char buf[64];
int len = usbd_ep_read_packet(0x01, buf, 64);
if(len) {
if (len) {
usbd_ep_write_packet(0x82, buf, len);
buf[len] = 0;
}
@ -217,7 +221,7 @@ static void cdcacm_set_config(u16 wValue)
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
}
@ -226,13 +230,13 @@ int main(void)
{
int i;
rcc_clock_setup_in_hsi_out_48mhz();
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
gpio_set(GPIOC, GPIO11);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_register_set_config_callback(cdcacm_set_config);
@ -241,6 +245,6 @@ int main(void)
__asm__("nop");
gpio_clear(GPIOC, GPIO11);
while (1)
while (1)
usbd_poll();
}

View File

@ -111,7 +111,7 @@ static const char *usb_strings[] = {
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */
"@Internal Flash /0x08000000/8*001Ka,56*001Kg"
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
static u8 usbdfu_getstatus(u32 *bwPollTimeout)

View File

@ -28,8 +28,8 @@
#define APP_ADDRESS 0x08002000
/* Commands sent with wBlockNum == 0 as per ST implementation. */
#define CMD_SETADDR 0x21
#define CMD_ERASE 0x41
#define CMD_SETADDR 0x21
#define CMD_ERASE 0x41
/* We need a special large control buffer for this device: */
u8 usbd_control_buffer[1024];
@ -44,20 +44,20 @@ static struct {
} prog;
const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0xDF11,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x0483,
.idProduct = 0xDF11,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
const struct usb_dfu_descriptor dfu_function = {
@ -79,7 +79,7 @@ const struct usb_interface_descriptor iface = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,
/* The ST Microelectronics DfuSe application needs this string.
/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
.iInterface = 4,
@ -110,23 +110,21 @@ static const char *usb_strings[] = {
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility */
"@Internal Flash /0x08000000/8*001Ka,56*001Kg"
/* This string is used by ST Microelectronics' DfuSe utility. */
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
};
static u8 usbdfu_getstatus(u32 *bwPollTimeout)
{
switch(usbdfu_state) {
switch (usbdfu_state) {
case STATE_DFU_DNLOAD_SYNC:
usbdfu_state = STATE_DFU_DNBUSY;
usbdfu_state = STATE_DFU_DNBUSY;
*bwPollTimeout = 100;
return DFU_STATUS_OK;
case STATE_DFU_MANIFEST_SYNC:
/* Device will reset when read is complete */
/* Device will reset when read is complete. */
usbdfu_state = STATE_DFU_MANIFEST;
return DFU_STATUS_OK;
default:
return DFU_STATUS_OK;
}
@ -137,56 +135,50 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
int i;
(void)req;
switch(usbdfu_state) {
switch (usbdfu_state) {
case STATE_DFU_DNBUSY:
flash_unlock();
if(prog.blocknum == 0) {
switch(prog.buf[0]) {
if (prog.blocknum == 0) {
switch (prog.buf[0]) {
case CMD_ERASE:
flash_erase_page(*(u32*)(prog.buf+1));
flash_erase_page(*(u32 *)(prog.buf + 1));
case CMD_SETADDR:
prog.addr = *(u32*)(prog.buf+1);
prog.addr = *(u32 *)(prog.buf + 1);
}
} else {
u32 baseaddr = prog.addr +
((prog.blocknum - 2) *
dfu_function.wTransferSize);
for(i = 0; i < prog.len; i += 2)
flash_program_half_word(baseaddr + i,
*(u16*)(prog.buf+i));
u32 baseaddr = prog.addr + ((prog.blocknum - 2) *
dfu_function.wTransferSize);
for (i = 0; i < prog.len; i += 2)
flash_program_half_word(baseaddr + i,
*(u16 *)(prog.buf + i));
}
flash_lock();
/* We jump straight to dfuDNLOAD-IDLE,
* skipping dfuDNLOAD-SYNC
*/
/* Jump straight to dfuDNLOAD-IDLE, skipping dfuDNLOAD-SYNC. */
usbdfu_state = STATE_DFU_DNLOAD_IDLE;
return;
case STATE_DFU_MANIFEST:
/* USB device must detach, we just reset... */
scb_reset_system();
return; /* Will never return */
return; /* Will never return. */
default:
return;
}
}
static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
if ((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request. */
if((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request */
switch(req->bRequest) {
switch (req->bRequest) {
case DFU_DNLOAD:
if((len == NULL) || (*len == 0)) {
if ((len == NULL) || (*len == 0)) {
usbdfu_state = STATE_DFU_MANIFEST_SYNC;
return 1;
} else {
/* Copy download data for use on GET_STATUS */
/* Copy download data for use on GET_STATUS. */
prog.blocknum = req->wValue;
prog.len = *len;
memcpy(prog.buf, *buf, *len);
@ -194,34 +186,31 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
return 1;
}
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE */
if(usbdfu_state == STATE_DFU_ERROR)
/* Clear error and return to dfuIDLE. */
if (usbdfu_state == STATE_DFU_ERROR)
usbdfu_state = STATE_DFU_IDLE;
return 1;
case DFU_ABORT:
/* Abort returns to dfuIDLE state */
/* Abort returns to dfuIDLE state. */
usbdfu_state = STATE_DFU_IDLE;
return 1;
case DFU_UPLOAD:
/* Upload not supported for now */
/* Upload not supported for now. */
return 0;
case DFU_GETSTATUS: {
u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
(*buf)[0] = usbdfu_getstatus(&bwPollTimeout);
(*buf)[1] = bwPollTimeout & 0xFF;
(*buf)[2] = (bwPollTimeout >> 8) & 0xFF;
(*buf)[3] = (bwPollTimeout >> 16) & 0xFF;
(*buf)[4] = usbdfu_state;
(*buf)[5] = 0; /* iString not used here */
(*buf)[5] = 0; /* iString not used here */
*len = 6;
*complete = usbdfu_getstatus_complete;
return 1;
}
case DFU_GETSTATE:
/* Return state with no state transision */
/* Return state with no state transision. */
*buf[0] = usbdfu_state;
*len = 1;
return 1;
@ -233,20 +222,21 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
if(!gpio_get(GPIOA, GPIO10)) {
/* Boot the application if it's valid */
if((*(volatile u32*)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
/* Set vector table base address */
if (!gpio_get(GPIOA, GPIO10)) {
/* Boot the application if it's valid. */
if ((*(volatile u32 *)APP_ADDRESS & 0x2FFE0000) == 0x20000000) {
/* Set vector table base address. */
SCB_VTOR = APP_ADDRESS & 0xFFFF;
/* Initialise master stack pointer */
asm volatile ("msr msp, %0"::"g"
(*(volatile u32*)APP_ADDRESS));
/* Jump to application */
(*(void(**)())(APP_ADDRESS + 4))();
/* Initialise master stack pointer. */
asm volatile("msr msp, %0"::"g"
(*(volatile u32 *)APP_ADDRESS));
/* Jump to application. */
(*(void (**)())(APP_ADDRESS + 4))();
}
}
rcc_clock_setup_in_hsi_out_48mhz();
rcc_clock_setup_in_hsi_out_48mhz();
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
@ -262,9 +252,9 @@ int main(void)
usbdfu_control_request);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
while (1)
while (1)
usbd_poll();
}