This firmware template is designed for development boards based around [STM32 F1 series micro-controller](http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1031).
This firmware implements the Maxim DS2432 1k-Bit Protected 1-Wire EEPROM with SHA-1 Engine using a development board based around [STM32 F1 series micro-controller](http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1031).
project
=======
@ -6,12 +6,20 @@ project
summary
-------
*describe project purpose*
Maxim DS2432 1k-Bit Protected 1-Wire EEPROM with SHA-1 Engine based on the datasheet
technology
----------
*described electronic details*
This is a example application using the 1-Wire slave library
Following DS2432 features are not implemented:
- PF flag
- Load First Secret function command
- Compute Next Secret function command
- Copy Scratchpad function command
- prevent reading secret memory by returning 0xaa or 0x55
board
=====
@ -45,17 +53,18 @@ dependencies
The source code uses the [libopencm3](http://libopencm3.org/) library.
The projects is already a git submodules.
To initialize and it you just need to run once: `git submodule init` and `git submodule update`.
It will be initialized when compiling the firmware.
Alternatively you can run once: `git submodule init` and `git submodule update`.
firmware
--------
To compile the firmware run `make`.
To compile the firmware run `rake`.
documentation
-------------
To generate doxygen documentation run `make doc`.
To generate doxygen documentation run `rake doc`.
flash
-----
@ -63,23 +72,23 @@ flash
There are two firmware images: `bootloader` and `application`.
The `bootloader` image allows to flash the `application` over USB using the DFU protocol.
The `bootloader` is started first and immediately jumps to the `application` if it is valid and the DFU mode is not forced (i.e. by pressing the user button on the board or requesting a DFU detach in the `application`).
The main application should be implemented in `application.c`.
The `application` image is the main application and is implemented in `application.c`.
It is up to the application to advertise USB DFU support (i.e. as does the provided USB CDC ACM example).
The `bootlaoder` image will be flashed using SWD (Serial Wire Debug).
For that you need an SWD adapter.
The `Makefile` uses a Black Magic Probe (per default), or a ST-Link V2 along OpenOCD software.
To flash the `booltoader` using SWD run `make flash_booloader`.
To flash the `booltoader` using SWD run `rake flash_booloader`.
Once the `bootloader` flashed it is possible to flash the `application` over USB using the DFU protocol by running `make flash`.
Once the `bootloader`is flashed it is possible to flash the `application` over USB using the DFU protocol by running `rake flash`.
To force the bootloader to start the DFU mode press the user button or short a pin, depending on the board.
It is also possible to flash the `application`using SWD by running `make flash_application`.
It is also possible to flash the `application`image using SWD by running `rake flash_application`.
debug
-----
SWD also allows to debug the code running on the micro-controller using GDB.
To start the debugging session run `make debug`.
To start the debugging session run `rake debug`.
USB
---
@ -87,5 +96,5 @@ USB
The firmware offers serial communication over USART1 and USB (using the CDC ACM device class).
You can also reset the board by setting the serial width to 5 bits over USB.
To reset the board run `make reset`.
To reset the board run `rake reset`.
This only works if provided USB CDC ACM is running correctly and the micro-controller isn't stuck.
uint8_tds2432_scratchpad[8];/**< scratchpad data */
uint8_tds2432_address[2+1]={0,0,0x5f};/**< address registers: target address and E/S */
uint8_tds2432_buffer[2+1+8+2];/**< buffer to save command code target address, data status, scratchpad, and CRC */
constuint8_tds2432_padding=0xff;/**< padding byte used in Read Authenticated Page command */
uint16_tds2432_crc=0;// CRC-16 used in 1-Wire DS2432 communication
uint8_tds2432_mac[20]={0};// buffer for the MAC
enum{
DS2432_STATE_IDLE,
DS2432_STATE_WRITE_SCRATCHPAD_DATA,
DS2432_STATE_WRITE_SCRATCHPAD_CRC,
DS2432_STATE_READ_SCRATCHPAD_ADDRESS,
DS2432_STATE_READ_SCRATCHPAD_DATA,
DS2432_STATE_READ_SCRATCHPAD_CRC,
DS2432_STATE_READ_AUTHENTICATED_PAGE_ADDRESS,
DS2432_STATE_READ_AUTHENTICATED_PAGE_DATA,
DS2432_STATE_READ_AUTHENTICATED_PAGE_PADDING,
DS2432_STATE_READ_AUTHENTICATED_PAGE_CRC,
DS2432_STATE_READ_AUTHENTICATED_PAGE_MAC,
DS2432_STATE_READ_AUTHENTICATED_PAGE_MACCRC,
DS2432_STATE_READ_MEMORY_ADDRESS,
DS2432_STATE_READ_MEMORY_DATA,
}ds2432_state=DS2432_STATE_IDLE;/**< current state */
printf("setup 1-Wire bus: ");
onewire_slave_setup(ds2432_eeprom[0x90],((uint64_t)ds2432_eeprom[0x91]<<0)+((uint64_t)ds2432_eeprom[0x91]<<0)+((uint64_t)ds2432_eeprom[0x92]<<8)+((uint64_t)ds2432_eeprom[0x93]<<16)+((uint64_t)ds2432_eeprom[0x94]<<24)+((uint64_t)ds2432_eeprom[0x95]<<32)+((uint64_t)ds2432_eeprom[0x96]<<40));// setup 1-Wire peripheral to act as slave
printf("OK\n");
// main loop
printf("command input: ready\n");
boolaction=false;// if an action has been performed don't go to sleep
button_flag=false;// reset button flag
charc='\0';// to store received character
charch='\0';// to store received character
boolchar_flag=false;// a new character has been received
while(true){// infinite loop
iwdg_reset();// kick the dog
while(usart_received){// data received over UART
action=true;// action has been performed
led_toggle();// toggle LED
c=usart_getchar();// store receive character
ch=usart_getchar();// store receive character
char_flag=true;// notify character has been received
}
while(usb_cdcacm_received){// data received over USB
action=true;// action has been performed
led_toggle();// toggle LED
c=usb_cdcacm_getchar();// store receive character
ch=usb_cdcacm_getchar();// store receive character
char_flag=true;// notify character has been received
}
while(char_flag){// user data received
char_flag=false;// reset flag
action=true;// action has been performed
printf("%c",c);// echo receive character
if(c=='\r'||c=='\n'){// end of command received
printf("%c",ch);// echo receive character
if(ch=='\r'||ch=='\n'){// end of command received
if(command_i>0){// there is a command to process
command[command_i]=0;// end string
command_i=0;// prepare for next command
process_command(command);// process user command
}
}else{// user command input
command[command_i]=c;// save command input
command[command_i]=ch;// save command input
if(command_i<LENGTH(command)-2){// verify if there is place to save next character
command_i++;// save next character
}
@ -255,18 +415,15 @@ void main(void)
}
while(button_flag){// user pressed button
action=true;// action has been performed
printf("button pressed\n");
led_toggle();// toggle LED
for(uint32_ti=0;i<1000000;i++){// wait a bit to remove noise and double trigger
__asm__("nop");
}
printf("button pressed\n");
button_flag=false;// reset flag
}
while(rtc_internal_tick_flag){// the internal RTC ticked
rtc_internal_tick_flag=false;// reset flag
action=true;// action has been performed
#if !defined(BLUE_PILL) // on the blue pill the LED is close to the 32.768 kHz oscillator and heavily influences it
led_toggle(); // toggle LED (good to indicate if main function is stuck)
//led_toggle(); // toggle LED (good to indicate if main function is stuck)
#endif
time_rtc=rtc_get_counter_val();// get time from internal RTC (seconds since Unix Epoch)
time_tm=localtime(&time_rtc);// get time in tm format from Epoch (time zones are not handled for non-POSIX environments)
if(!dfu_force&&(((*application)&0xFFFE0000)==0x20000000)){// application at address seems valid
SCB_VTOR=(volatileuint32_t)(application);// set vector table to application vector table (store at the beginning of the application)
__asm__volatile("MSR msp,%0"::"r"(*application));// set stack pointer to address provided in the beginning of the application (loaded into a register first)
(*(void(**)())(application+1))();// start application (by jumping to the reset function which address is stored as second entry of the vector table)
(*(void(**)(void))(application+1))();// start application (by jumping to the reset function which address is stored as second entry of the vector table)
}
rcc_clock_setup_in_hse_8mhz_out_72mhz();// start main clock