From b83365010e8338a41988426f879243208714c44f Mon Sep 17 00:00:00 2001 From: root Date: Mon, 7 Sep 2015 18:43:44 +0100 Subject: fish --- crypto/Makefile | 12 +- crypto/main.c | 47 ++-- crypto/project.h | 32 +++ crypto/prototypes.h | 7 + crypto/ssd1306.c | 782 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 852 insertions(+), 28 deletions(-) create mode 100644 crypto/project.h create mode 100644 crypto/prototypes.h create mode 100644 crypto/ssd1306.c diff --git a/crypto/Makefile b/crypto/Makefile index 0d73725..5494a9f 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -50,11 +50,16 @@ SDKCSRCS= \ SDKSSRCS = toolchain/gcc/gcc_startup_nrf51.s +PROTOSRCS= \ + ssd1306.c \ + main.c CSRCS = \ bsp/bsp.c \ bsp/bsp_btn_ble.c \ - main.c + ${PROTOSRCS} + + SOFTDEVICE=${SDK}/sdk/softdevice/s110/hex/s110_softdevice.hex @@ -83,6 +88,7 @@ OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy SIZE := $(CROSS)size GDB := $(CROSS)gdb +CPROTO := cproto NRFUTIL := nrfutil CFLAGS += -mcpu=cortex-m0 @@ -185,6 +191,10 @@ flash_softdevice: ${SOFTDEVICE} dfu: ${PROG}.zip nrfdfu -b ${BDADDR} -p ${PROG}.zip +protos: + echo -n > prototypes.h + ${CPROTO} -v -e ${CPPFLAGS} ${PROTOSRCS} > prototypes.h.new + mv -f prototypes.h.new prototypes.h #flash: $(MAKECMDGOALS) # @echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$<.hex diff --git a/crypto/main.c b/crypto/main.c index 2a1c05c..4f15694 100644 --- a/crypto/main.c +++ b/crypto/main.c @@ -26,33 +26,7 @@ * Also it would accept pairing requests from any peer device. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "bsp/bsp.h" -#include -#include "bsp/bsp_btn_ble.h" -#include -#include -#include -#include -#include -#include -#include +#include "project.h" #if BUTTONS_NUMBER <2 #error "Not enough resources on board" @@ -203,6 +177,8 @@ static sensorsim_state_t m_battery_sim_state; static app_timer_id_t m_battery_timer_id; /**< Battery timer. */ +static app_timer_id_t sd_timer_id; + static dm_application_instance_t m_app_handle; /**< Application identifier allocated by device manager. */ static dm_handle_t m_bonded_peer_handle; /**< Device reference handle to the current bonded central. */ static bool m_caps_on = false; /**< Variable to indicate if Caps Lock is turned on. */ @@ -305,6 +281,12 @@ static void battery_level_update(void) } } +static void sd_timeout_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + sd_doodle(); +} + /**@brief Function for handling the Battery measurement timer timeout. * @@ -335,6 +317,11 @@ static void timers_init(void) APP_TIMER_MODE_REPEATED, battery_level_meas_timeout_handler); APP_ERROR_CHECK(err_code); + + err_code = app_timer_create(&sd_timer_id, + APP_TIMER_MODE_REPEATED, + sd_timeout_handler); + APP_ERROR_CHECK(err_code); } @@ -610,6 +597,9 @@ static void timers_start(void) err_code = app_timer_start(m_battery_timer_id, BATTERY_LEVEL_MEAS_INTERVAL, NULL); APP_ERROR_CHECK(err_code); + + err_code = app_timer_start(sd_timer_id, APP_TIMER_TICKS(10,APP_TIMER_PRESCALER),NULL); + APP_ERROR_CHECK(err_code); } @@ -1486,6 +1476,9 @@ int main(void) conn_params_init(); buffer_init(); + sd_init(); + sd_on(); + // Start execution. timers_start(); err_code = ble_advertising_start(BLE_ADV_MODE_FAST); diff --git a/crypto/project.h b/crypto/project.h new file mode 100644 index 0000000..cf6fac0 --- /dev/null +++ b/crypto/project.h @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bsp/bsp.h" +#include +#include "bsp/bsp_btn_ble.h" +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "prototypes.h" diff --git a/crypto/prototypes.h b/crypto/prototypes.h new file mode 100644 index 0000000..35c8abe --- /dev/null +++ b/crypto/prototypes.h @@ -0,0 +1,7 @@ +/* ssd1306.c */ +extern void sd_on(void); +extern void sd_doodle(void); +extern void sd_init(void); +/* main.c */ +extern void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name); +extern int main(void); diff --git a/crypto/ssd1306.c b/crypto/ssd1306.c new file mode 100644 index 0000000..95cab2d --- /dev/null +++ b/crypto/ssd1306.c @@ -0,0 +1,782 @@ +#include "project.h" + +#define BRIGHT 30 + +#define POWER 25 +#define SDA 23 +#define SCL 24 + +#define WRITE 0 +#define READ 1 +#define SAD (0x3C << 1) + + +static void +i2c_delay () +{ + nrf_delay_us (10000); +} + +static void +i2c_set (int c, int d) +{ + uint32_t set = 0; + uint32_t clr = 0; + + if (c) + set |= 1 << SCL; + else + clr |= 1 << SCL; + + if (d) + set |= 1 << SDA; + else + clr |= 1 << SDA; + + + NRF_GPIO->OUTCLR = clr; + NRF_GPIO->OUTSET = set; +} + +static int +i2c_get (void) +{ + return ! !(NRF_GPIO->IN & (1 << SDA)); +} + +static void +i2c_start (void) +{ + i2c_set (1, 1); + i2c_delay (); + i2c_set (1, 0); + i2c_delay (); + i2c_set (0, 0); + i2c_delay (); +} + + +static void +i2c_stop (void) +{ + i2c_set (0, 0); + i2c_delay (); + i2c_set (1, 0); + i2c_delay (); + i2c_set (1, 1); + i2c_delay (); +} + + +static void +i2c_init (void) +{ + NRF_GPIO->PIN_CNF[SDA] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + + NRF_GPIO->PIN_CNF[SCL] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | + (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + + NRF_GPIO->DIRSET = (1 << SDA) | (1 << SCL); + + i2c_set (1, 1); + +} + +static void +i2c_send_byte (uint8_t v) +{ + uint8_t c; + int d; + + for (c = 0x80; c; c >>= 1) + { + d = c & v; + i2c_set (0, d); + i2c_delay (); + i2c_set (1, d); + i2c_delay (); + } + i2c_set (0, d); +} + +static void +i2c_handshake (int ack) +{ + + i2c_set (0, ack); + i2c_delay (); + i2c_set (1, ack); + i2c_delay (); + i2c_set (0, ack); + i2c_delay (); +} + +static void inline +i2c_send_ack (void) +{ + i2c_handshake (0); +} + + +static void inline +i2c_send_nack (void) +{ + i2c_handshake (1); +} + +static int +i2c_recv_ack (void) +{ + int ret; + + i2c_set (0, 1); + i2c_delay (); + i2c_set (1, 1); + i2c_delay (); + ret = i2c_get (); + i2c_set (0, 1); + i2c_delay (); + return ret; +} + + +static void +sd_delay (void) +{ + nrf_delay_ms (1); +} + +static int +sd_write (int dnc, uint8_t v) +{ + int ret = 0; + + i2c_start (); + + i2c_send_byte (SAD | WRITE); + ret |= i2c_recv_ack (); + i2c_send_byte (dnc ? 0xc0 : 0x80); + ret |= i2c_recv_ack (); + i2c_send_byte (v); + i2c_send_nack (); + i2c_stop (); + + return ret; +} + +static int +sd_cmd (uint8_t c) +{ + return sd_write (0, c); +} + + +static int +sd_dat (uint8_t c) +{ + return sd_write (1, c); +} + + + +static int +sd_address_mode (uint8_t m) +{ + int ret = 0; + ret |= sd_cmd (0x20); + ret |= sd_cmd (m); + + return ret; +} + +static int +sd_cols (uint8_t s, uint8_t e) +{ + int ret = 0; + + ret |= sd_cmd (0x21); + ret |= sd_cmd (s); + ret |= sd_cmd (e); + + return ret; +} + + +static int +sd_rows (uint8_t s, uint8_t e) +{ + int ret = 0; + + ret |= sd_cmd (0x22); + ret |= sd_cmd (s); + ret |= sd_cmd (e); + + return ret; +} + + +void +sd_on (void) +{ + NRF_GPIO->OUTSET = (1 << POWER) | (1 << BRIGHT); + + nrf_delay_ms (10); + + // off + sd_cmd (0xae); + sd_delay (); + + // set clock freq + sd_cmd (0xd5); + sd_cmd (0xa0); + sd_delay (); + + // set multiplex ratio + sd_cmd (0xa8); + sd_cmd (0x1f); + sd_delay (); + + // set display offset + sd_cmd (0xd3); + sd_cmd (0x00); + sd_delay (); + + // set display start + sd_cmd (0x40); + sd_delay (); + + // set charge pump using DC/DC + sd_cmd (0x8d); + sd_cmd (0x14); + sd_delay (); + + // set segment remap + sd_cmd (0xa1); + sd_delay (); + + // set com scan direction + sd_cmd (0xc8); + sd_delay (); + + // set com pins hardware config. + sd_cmd (0xda); + sd_cmd (0x02); + sd_delay (); + + // set contrast + sd_cmd (0x81); + sd_cmd (0x8f); + sd_delay (); + + // set precharge period using DC/DC + sd_cmd (0xd9); + sd_cmd (0xf1); + sd_delay (); + + // set deselect voltage + sd_cmd (0xdb); + sd_cmd (0x40); + sd_delay (); + + // set display on/off + sd_cmd (0xa4); + sd_delay (); + + // set display on + sd_cmd (0xaf); + sd_delay (); + + sd_address_mode (0); + + sd_cols (0, 127); + sd_rows (0, 63); +} + +void +sd_doodle (void) +{ + static uint8_t i; + + sd_dat (i++); +} + + +void +sd_init (void) +{ + i2c_init (); + + NRF_GPIO->PIN_CNF[POWER] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | + (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + + NRF_GPIO->PIN_CNF[BRIGHT] = + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | + (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos) | + (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + + NRF_GPIO->DIRSET = (1 << POWER) | (1 << BRIGHT); + NRF_GPIO->OUTCLR = (1 << POWER) | (1 << BRIGHT); + +} + + + + + + + + +// +// +// #!/usr/bin/env perl +// use strict; +// +// use GD::Image; + +// +// use IO::Socket::INET; +// use Data::Dumper; +// +// #use IO::Socket::Timeout; +// # +// # +// +// $SIG{INT} = \&quit; +// my $prompt = '> '; +// +// sub my_readline_worker($) { +// my $sock = shift; +// my $ret = ""; +// my $d = ""; +// +// while (1) { +// return $ret if $sock->read( $d, 1 ) != 1; +// +// next if $d eq "\n"; +// +// $ret .= $d; +// +// return $ret if $d eq "\r"; +// return $ret if $ret =~ /> $/; +// +// } +// +// } +// +// sub my_readline($) { +// my $sock = shift; +// my $ret = my_readline_worker($sock); +// +// #print $ret."\n"; +// return $ret; +// } +// +// sub wait_for_prompt($) { +// my $ocd = shift; +// +// 1 while ( my_readline($ocd) ne $prompt ); +// } +// +// sub open_ocd($) { +// my $addr = shift; +// my $sock = IO::Socket::INET->new($addr); +// wait_for_prompt($sock); +// $sock->printf( "reset halt\n"); +// wait_for_prompt($sock); +// return $sock; +// } +// +// +// sub write_reg($$$) { +// my ( $ocd, $r, $v ) = @_; +// +// $ocd->printf( "mww 0x%08x 0x%08x\n", $r, $v ); +// wait_for_prompt($ocd); +// } +// +// sub read_reg($$) { +// my ( $ocd, $r ) = @_; +// my $ret; +// +// $ocd->printf( "mdw 0x%08x\n", $r ); +// +// $ret = my_readline($ocd); +// $ret = my_readline($ocd); +// +// wait_for_prompt($ocd); +// +// $ret =~ s/[\r\n\s]//g; +// +// if ( $ret =~ /0x[0-9A-Fa-f]+:([0-9a-fA-F]+)/ ) { +// return hex($1); +// } +// +// return undef; +// } +// +// sub dir_set($$) { +// my ( $ocd, $v ) = @_; +// write_reg( $ocd, 0x50000518, $v ); +// } +// +// sub dir_clr($$) { +// my ( $ocd, $v ) = @_; +// write_reg( $ocd, 0x5000051c, $v ); +// } +// +// sub io_set($$) { +// my ( $ocd, $v ) = @_; +// write_reg( $ocd, 0x50000508, $v ); +// } +// +// sub io_clr($$) { +// my ( $ocd, $v ) = @_; +// write_reg( $ocd, 0x5000050c, $v ); +// } +// +// sub io_get($) { +// my $ocd = shift; +// return read_reg( $ocd, 0x50000510 ); +// } +// +// my $SDABIT = 1 << 23; +// my $SCLBIT = 1 << 24; +// +// sub i2c_set($$$) { +// my ( $ocd, $scl, $sda ) = @_; +// my $clr = 0; +// my $set = 0; +// +// if ($scl) { +// $clr |= $SCLBIT; +// } +// else { +// $set |= $SCLBIT; +// } +// +// if ($sda) { +// $clr |= $SDABIT; +// } +// else { +// $set |= $SDABIT; +// } +// +// dir_set( $ocd, $set ); +// dir_clr( $ocd, $clr ); +// } +// +// sub i2c_get($) { +// my $ocd = shift; +// +// return ( io_get($ocd) & $SDABIT ) ? 1 : 0; +// } +// +// sub i2c_start($) { +// my $ocd = shift; +// +// i2c_set( $ocd, 1, 1 ); +// i2c_set( $ocd, 1, 0 ); +// i2c_set( $ocd, 0, 0 ); +// print "S"; +// } +// +// sub i2c_stop($) { +// my $ocd = shift; +// +// i2c_set( $ocd, 0, 0 ); +// i2c_set( $ocd, 1, 0 ); +// i2c_set( $ocd, 1, 1 ); +// print "T\n"; +// } +// +// sub i2c_sendbyte($$) { +// my ( $ocd, $byte ) = @_; +// +// for ( my $c = 0x80 ; $c ; $c >>= 1 ) { +// my $v = ( $c & $byte ) ? 1 : 0; +// +// print $v; +// +// i2c_set( $ocd, 0, $v ); +// i2c_set( $ocd, 1, $v ); +// i2c_set( $ocd, 0, $v ); +// } +// +// } +// +// sub i2c_startaddr($$) { +// my ( $ocd, $addr ) = @_; +// my $ret; +// +// i2c_start($ocd); +// i2c_sendbyte( $ocd, $addr ); +// print " "; +// +// i2c_set( $ocd, 0, 1 ); +// i2c_set( $ocd, 1, 1 ); +// +// $ret = i2c_get($ocd); +// i2c_set( $ocd, 0, 1 ); +// +// print $ret; +// +// return $ret; +// +// } +// +// sub i2c_ping($$) { +// my ( $ocd, $addr ) = @_; +// my $ret; +// $ret = i2c_startaddr( $ocd, $addr ); +// i2c_stop($ocd); +// return $ret; +// } +// +// my $SDADDR = 0x78; +// +// sub sd_write($$$) { +// my ( $ocd, $dnc, $v ) = @_; +// +// my $ack1; +// my $ack2; +// +// i2c_startaddr( $ocd, $SDADDR ); +// i2c_sendbyte( $ocd, 0x80 | ( $dnc ? 0x40 : 0x00 ) ); +// +// i2c_set( $ocd, 0, 1 ); +// i2c_set( $ocd, 1, 1 ); +// $ack1 = i2c_get($ocd); +// i2c_set( $ocd, 0, 1 ); +// +// i2c_sendbyte( $ocd, $v ); +// +// i2c_set( $ocd, 0, 1 ); +// i2c_set( $ocd, 1, 1 ); +// $ack2 = i2c_get($ocd); +// i2c_set( $ocd, 0, 1 ); +// +// i2c_stop($ocd); +// +// return $ack1 | $ack2; +// } +// +// sub sd_cmd($$) { +// my ( $ocd, $c ) = @_; +// +// return sd_write( $ocd, 0, $c ); +// } +// +// sub sd_dat($$) { +// my ( $ocd, $d ) = @_; +// +// return sd_write( $ocd, 1, $d ); +// } +// +// sub sd_address_mode($$) { +// my ( $ocd, $m ) = @_; +// +// sd_cmd( $ocd, 0x20 ); +// sd_cmd( $ocd, $m ); +// } +// +// sub sd_cols($$$) { +// my ( $ocd, $s, $e ) = @_; +// +// sd_cmd( $ocd, 0x21 ); +// sd_cmd( $ocd, $s ); +// sd_cmd( $ocd, $e ); +// } +// +// sub sd_rows($$$) { +// my ( $ocd, $s, $e ) = @_; +// +// sd_cmd( $ocd, 0x22 ); +// sd_cmd( $ocd, $s ); +// sd_cmd( $ocd, $e ); +// } +// +// sub sd_init($) { +// my $ocd = shift; +// +// # off +// sd_cmd( $ocd, 0xae ); +// +// # set clock freq +// sd_cmd( $ocd, 0xd5 ); +// sd_cmd( $ocd, 0xa0 ); +// +// #set multiplex ratio +// sd_cmd( $ocd, 0xa8 ); +// sd_cmd( $ocd, 0x1f ); +// +// #set display offset +// sd_cmd( $ocd, 0xd3 ); +// sd_cmd( $ocd, 0x00 ); +// +// #set display start +// sd_cmd( $ocd, 0x40 ); +// +// #set charge pump using DC/DC +// sd_cmd( $ocd, 0x8d ); +// sd_cmd( $ocd, 0x14 ); +// +// #set segment remap +// sd_cmd( $ocd, 0xa1 ); +// +// #set com scan direction +// sd_cmd( $ocd, 0xc8 ); +// +// # set com pins hardware config. +// sd_cmd( $ocd, 0xda ); +// sd_cmd( $ocd, 0x02 ); +// +// #set contrast +// sd_cmd( $ocd, 0x81 ); +// sd_cmd( $ocd, 0x8f ); +// +// #set precharge period using DC/DC +// sd_cmd( $ocd, 0xd9 ); +// sd_cmd( $ocd, 0xf1 ); +// +// #set deselect voltage +// sd_cmd( $ocd, 0xdb ); +// sd_cmd( $ocd, 0x40 ); +// +// #set display on/off +// sd_cmd( $ocd, 0xa4 ); +// +// #set display on +// sd_cmd( $ocd, 0xaf ); +// } +// +// sub sd_display($$) { +// my ( $ocd, $fn ) = @_; +// +// my $ack; +// +// my $file=GD::Image->new($fn); +// +// my $img=GD::Image->new(128,32,1); +// +// $img->copy($file,0,0,0,0,128,32); +// +// sd_cols($ocd,0,127); +// sd_rows($ocd,0,63); +// +// +// for (my $y=0;$y<32;$y+=8) { +// +// print "y=$y\n"; +// i2c_startaddr( $ocd, $SDADDR ); +// i2c_sendbyte( $ocd, 0x40 ); +// +// i2c_set( $ocd, 0, 1 ); +// i2c_set( $ocd, 1, 1 ); +// +// $ack = i2c_get($ocd); +// i2c_set( $ocd, 0, 1 ); +// print " "; +// +// +// for (my $x=0;$x<128;++$x) { +// +// my $v=0; +// my $c=0x1; +// +// for (my $i=0;$i<8;++$i) { +// my $w=$img->getPixel($x,$i+$y); +// +// # print "r=$r,g=$g,b=$b\n"; +// +// $v|=$c if $w>8388607; +// +// $c<<=1; +// } +// +// +// i2c_sendbyte( $ocd, $v ); +// +// i2c_set( $ocd, 0, 1 ); +// i2c_set( $ocd, 1, 1 ); +// +// $ack = i2c_get($ocd); +// i2c_set( $ocd, 0, 1 ); +// +// print " "; +// +// +// } +// i2c_stop($ocd); +// } +// +// +// +// } +// +// my $ocd = open_ocd('127.0.0.1:4444'); +// +// my $LED = 1 << 22; +// my $SCREEN_PWR = 1 << 25; +// my $SCREEN_BRIGHT = 1 << 30; +// +// sub quit +// { +// io_clr( $ocd, $SCREEN_PWR ); +// io_clr( $ocd, $SCREEN_BRIGHT ); +// io_set( $ocd, $LED ); +// kill 9, $$; +// } +// +// dir_set( $ocd, $LED | $SCREEN_PWR | $SCREEN_BRIGHT ); +// io_clr( $ocd, $SCLBIT | $SDABIT ); +// io_clr( $ocd, $LED ); +// +// i2c_start($ocd); +// i2c_stop($ocd); +// +// #for (my $a=0;$a<0x100;$a++) { +// #printf "a=0x%02x ",$a; +// #i2c_ping($ocd,$a); +// #} +// # +// +// #Power down screen +// io_clr( $ocd, $SCREEN_PWR | $SCREEN_BRIGHT ); +// +// #power up screen +// io_set( $ocd, $SCREEN_PWR | $SCREEN_BRIGHT ); +// sd_init($ocd); +// +// sd_address_mode( $ocd, 0x0 ); +// +// sd_display($ocd,"fish.png"); +// +// while (1) { +// sd_cmd( $ocd, 0xa7 ); +// sleep(1); +// sd_cmd( $ocd, 0xa6 ); +// sleep(1); +// } +// +// +// +// -- cgit v1.2.3