From 35ba45c1d5d9a71b94efed063d22821f8474c791 Mon Sep 17 00:00:00 2001 From: bsongis Date: Fri, 23 Mar 2012 23:46:41 +0000 Subject: [PATCH] Makefile now ok with the ersky9x board --- src/beeper.h | 11 + src/board_ersky9x.cpp | 399 +++++++++++++++++--------- src/eeprom_arm.cpp | 163 ++++++++++- src/ersky9x/sam3s2c_flash.ld | 144 ++++++++++ src/ersky9x/sound.cpp | 24 +- src/ersky9x/sound.h | 26 +- src/ersky9x/vectors_sam3s.c | 6 +- src/{ => gruvin9x}/somo14d.cpp | 0 src/{ => gruvin9x}/somo14d.h | 0 src/open9x.cpp | 501 +++++++++++++++++++-------------- src/open9x.h | 16 +- src/pulses.cpp | 4 + 12 files changed, 900 insertions(+), 394 deletions(-) create mode 100644 src/ersky9x/sam3s2c_flash.ld rename src/{ => gruvin9x}/somo14d.cpp (100%) rename src/{ => gruvin9x}/somo14d.h (100%) diff --git a/src/beeper.h b/src/beeper.h index eff644460..2f4a54716 100644 --- a/src/beeper.h +++ b/src/beeper.h @@ -44,6 +44,17 @@ extern bool warbleC; extern uint8_t hapticTick; #endif +#if defined(PCBARM) +#include "ersky9x/sound.h" +inline void _beep(uint8_t b) { + buzzer_sound(b); +} +#else +inline void _beep(uint8_t b) { + g_beepCnt = b; +} +#endif + extern void beep(uint8_t val); #define AUDIO_KEYPAD_UP() beep(0) diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index a276d1ff9..565350c6e 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -32,6 +32,34 @@ */ #include "open9x.h" +#include "AT91SAM3S2.h" +#include "core_cm3.h" + +uint32_t Master_frequency ; + +/** Console baudrate 9600. */ +#define CONSOLE_BAUDRATE 9600 +/** Usart Hw interface used by the console (UART0). */ +#define CONSOLE_USART UART0 +/** Usart Hw ID used by the console (UART0). */ +#define CONSOLE_ID ID_UART0 +/** Pins description corresponding to Rxd,Txd, (UART pins) */ +#define CONSOLE_PINS {PINS_UART} + +/** Second serial baudrate 9600. */ +#define SECOND_BAUDRATE 9600 +/** Usart Hw interface used by the console (UART0). */ +#define SECOND_USART USART0 +/** Usart Hw ID used by the console (UART0). */ +#define SECOND_ID ID_USART0 +/** Pins description corresponding to Rxd,Txd, (UART pins) */ +#define SECOND_PINS {PINS_USART0} + +#define BT_USART UART1 +#define BT_ID ID_UART1 + +#define CPU_INT int32_t +#define CPU_UINT uint32_t #ifdef REVB inline void init_soft_power() @@ -288,6 +316,36 @@ inline void start_timer0() ptc->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) } +// TODO where used +volatile uint32_t Tenms ; + +extern "C" void TC2_IRQHandler() +{ + register uint32_t dummy; + static uint32_t pre_scale ; // Used to get 10 Hz counter + + /* Clear status bit to acknowledge interrupt */ + dummy = TC0->TC_CHANNEL[2].TC_SR; + (void) dummy ; // Discard value - prevents compiler warning + Tenms |= 1 ; // 10 mS has passed + /* TODO if ( Buzzer_count ) + { + if ( --Buzzer_count == 0 ) + { + buzzer_off() ; + } + } */ + + if ( ++pre_scale >= 10 ) + { + // TODO needed? Timer2_count += 1 ; + pre_scale = 0 ; + } + per10ms(); + +// heartbeat |= HEART_TIMER10ms; +} + // Settings for mode register ADC_MR // USEQ off - silicon problem, doesn't work // TRANSFER = 1 @@ -413,71 +471,6 @@ void init_pwm() #endif } -inline void start_sound() -{ - register Pio *pioptr ; - - start_timer1() ; - init_dac() ; - init_twi() ; - - pioptr = PIOA ; -#ifdef REVB - pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF - pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) - pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output -#else - pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF - pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer) - pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output -#endif -} - -// SPI i/f to EEPROM (4Mb) -// Peripheral ID 21 (0x00200000) -// Connections: -// SS PA11 (peripheral A) -// MISO PA12 (peripheral A) -// MOSI PA13 (peripheral A) -// SCK PA14 (peripheral A) -// Set clock to 3 MHz, AT25 device is rated to 70MHz, 18MHz would be better -inline void init_spi() -{ - register Pio *pioptr ; - register Spi *spiptr ; - register uint32_t timer ; - register uint8_t *p ; - uint8_t spi_buf[4] ; - - PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI - /* Configure PIO */ - pioptr = PIOA ; - pioptr->PIO_ABCDSR[0] &= ~0x00007800 ; // Peripheral A bits 14,13,12,11 - pioptr->PIO_ABCDSR[1] &= ~0x00007800 ; // Peripheral A - pioptr->PIO_PDR = 0x00007800 ; // Assign to peripheral - - spiptr = SPI ; - timer = ( Master_frequency / 3000000 ) << 8 ; // Baud rate 3Mb/s - spiptr->SPI_MR = 0x14000011 ; // 0001 0100 0000 0000 0000 0000 0001 0001 Master - spiptr->SPI_CSR[0] = 0x01180009 | timer ; // 0000 0001 0001 1000 xxxx xxxx 0000 1001 - NVIC_EnableIRQ(SPI_IRQn) ; - - p = spi_buf ; - -// *p = 0x39 ; // Unprotect sector command -// *(p+1) = 0 ; -// *(p+2) = 0 ; -// *(p+3) = 0 ; // 3 bytes address - -// spi_operation( p, spi_buf, 4 ) ; - - eeprom_write_enable() ; - - *p = 1 ; // Write status register command - *(p+1) = 0 ; - spi_operation( p, spi_buf, 2 ) ; -} - // LCD i/o pins // LCD_RES PC27 // LCD_CS1 PC26 @@ -504,72 +497,11 @@ inline void init_spi() #define LCD_CS1 0x04000000L #define LCD_RES 0x08000000L -inline void lcd_init() +extern void start_sound(); // TODO elsewhere + +void board_init() { - register Pio *pioptr ; - // /home/thus/txt/datasheets/lcd/KS0713.pdf - // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= - -#ifdef REVB - pioptr = PIOA ; - pioptr->PIO_PER = LCD_A0 ; // Enable bit 7 (LCD-A0) - pioptr->PIO_CODR = LCD_A0 ; - pioptr->PIO_OER = LCD_A0 ; // Set bit 7 output - pioptr = PIOC ; - pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output - pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR -#else - pioptr = PIOC ; - pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_A0 ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output - pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR -#endif - - pioptr->PIO_CODR = LCD_RES ; // Reset LCD - TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - while ( TC0->TC_CHANNEL[0].TC_CV < 12 ) // 2 uS, Value depends on MCK/2 (used 6MHz) - { - // Wait - } - pioptr->PIO_SODR = LCD_RES ; // Remove LCD reset - TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - while ( TC0->TC_CHANNEL[0].TC_CV < 9000 ) // 1500 uS, Value depends on MCK/2 (used 6MHz) - { - // Wait - } - lcdSendCtl(0xe2); //Initialize the internal functions - lcdSendCtl(0xae); //DON = 0: display OFF - lcdSendCtl(0xa1); //ADC = 1: reverse direction(SEG132->SEG1) - lcdSendCtl(0xA6); //REV = 0: non-reverse display - lcdSendCtl(0xA4); //EON = 0: normal display. non-entire - lcdSendCtl(0xA2); // Select LCD bias=0 - lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64) - lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1 - lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5 - lcdSendCtl(0x81); //Set reference voltage Mode - lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 - lcdSendCtl(0xAF); //DON = 1: display ON - // g_eeGeneral.contrast = 0x22; - -#ifdef REVB - pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups - pioptr->PIO_ODSR = 0 ; // Drive D0 low -#else - pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups - pioptr->PIO_ODSR = 0 ; // Drive D0 low -#endif -} - -inline void board_init() -{ - register uint32_t goto_usb ; + // register uint32_t goto_usb ; register Pio *pioptr ; // Debug variable // uint32_t both_on ; @@ -650,10 +582,166 @@ inline void board_init() start_sound() ; - init_spi() ; + // init_spi() ; // TODO in eeprom_arm } -inline uint8_t keyDown() +/*TODO not here...*/ +void eeDirty(uint8_t msk) { } +void eeCheck(bool immediately) {} +uint16_t eeLoadModelName(uint8_t id, char *name) +{ + memset(name, 0, sizeof(g_model.name)); + return 0; +} +int8_t eeFindEmptyModel(uint8_t id, bool down) { return 0;} +void eeLoadModel(uint8_t id) {} +void eeReadAll() +{ + generalDefault(); + modelDefault(0); +} + +uint16_t getTmr2MHz() +{ + return TC1->TC_CHANNEL[0].TC_CV ; +} + +// keys: +// KEY_EXIT PA31 (PC24) +// KEY_MENU PB6 (PB5) +// KEY_DOWN LCD5 PC3 (PC5) +// KEY_UP LCD6 PC2 (PC1) +// KEY_RIGHT LCD4 PC4 (PC4) +// KEY_LEFT LCD3 PC5 (PC3) +// Reqd. bit 6 LEFT, 5 RIGHT, 4 UP, 3 DOWN 2 EXIT 1 MENU +// LCD pins 5 DOWN, 4 RIGHT, 3 LEFT, 1 UP +uint32_t read_keys() +{ + register uint32_t x ; + register uint32_t y ; + + x = PIOC->PIO_PDSR << 1 ; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () +#ifdef REVB + y = x & 0x00000020 ; // RIGHT + if ( x & 0x00000004 ) + { + y |= 0x00000010 ; // UP + } + if ( x & 0x00000010 ) + { + y |= 0x00000040 ; // LEFT + } + if ( x & 0x00000040 ) + { + y |= 0x00000008 ; // DOWN + } +#else + y = x & 0x00000060 ; + if ( x & 0x00000008 ) + { + y |= 0x00000010 ; + } + if ( x & 0x00000010 ) + { + y |= 0x00000008 ; + } +#endif +#ifdef REVB + if ( PIOC->PIO_PDSR & 0x01000000 ) +#else + if ( PIOA->PIO_PDSR & 0x80000000 ) +#endif + { + y |= 4 ; // EXIT + } +#ifdef REVB + if ( PIOB->PIO_PDSR & 0x000000020 ) +#else + if ( PIOB->PIO_PDSR & 0x000000040 ) +#endif + { + y |= 2 ; // MENU + } + return y ; +} + + + +uint32_t read_trims() +{ + uint32_t trims ; + + trims = 0 ; + +// TRIM_LH_DOWN PA7 (PA23) +#ifdef REVB + if ( ( PIOA->PIO_PDSR & 0x00800000 ) == 0 ) +#else + if ( ( PIOA->PIO_PDSR & 0x0080 ) == 0 ) +#endif + { + trims |= 1 ; + } + +// TRIM_LH_UP PB4 + if ( ( PIOB->PIO_PDSR & 0x10 ) == 0 ) + { + trims |= 2 ; + } + +// TRIM_LV_DOWN PA27 (PA24) +#ifdef REVB + if ( ( PIOA->PIO_PDSR & 0x01000000 ) == 0 ) +#else + if ( ( PIOA->PIO_PDSR & 0x08000000 ) == 0 ) +#endif + { + trims |= 4 ; + } + +// TRIM_LV_UP PC28 + if ( ( PIOC->PIO_PDSR & 0x10000000 ) == 0 ) + { + trims |= 8 ; + } + +// TRIM_RV_DOWN PC10 + if ( ( PIOC->PIO_PDSR & 0x00000400 ) == 0 ) + { + trims |= 0x10 ; + } + +// TRIM_RV_UP PA30 (PA1) +#ifdef REVB + if ( ( PIOA->PIO_PDSR & 0x00000002 ) == 0 ) +#else + if ( ( PIOA->PIO_PDSR & 0x40000000 ) == 0 ) +#endif + { + trims |= 0x20 ; + } + +// TRIM_RH_DOWN PA29 (PA0) +#ifdef REVB + if ( ( PIOA->PIO_PDSR & 0x00000001 ) == 0 ) +#else + if ( ( PIOA->PIO_PDSR & 0x20000000 ) == 0 ) +#endif + { + trims |= 0x40 ; + } + +// TRIM_RH_UP PC9 + if ( ( PIOC->PIO_PDSR & 0x00000200 ) == 0 ) + { + trims |= 0x80 ; + } + + return trims ; +} + + +uint8_t keyDown() { return ~read_keys() & 0x7E ; } @@ -752,3 +840,50 @@ void read_9_adc() // Power save // PMC->PMC_PCER0 &= ~0x20000000L ; // Disable peripheral clock to ADC } + +void readKeysAndTrims() +{ +register uint32_t i ; + +if ( PIOC->PIO_ODSR & 0x00080000 ) +{ + PIOC->PIO_CODR = 0x00200000L ; // Set bit C19 OFF +} +else +{ + PIOC->PIO_SODR = 0x00200000L ; // Set bit C19 ON +} + +uint8_t enuk = KEY_MENU; +uint8_t in = ~read_keys() ; +for( i=1; i<7; i++) +{ +//INP_B_KEY_MEN 1 .. INP_B_KEY_LFT 6 +keys[enuk].input(in & (1<TC_CHANNEL[0].TC_IDR = TC_IDR0_LDRAS ; + NVIC_DisableIRQ(TC3_IRQn) ; +} diff --git a/src/eeprom_arm.cpp b/src/eeprom_arm.cpp index edb687f12..d6e88732d 100644 --- a/src/eeprom_arm.cpp +++ b/src/eeprom_arm.cpp @@ -21,9 +21,7 @@ #include "inttypes.h" #include "string.h" -extern PROGMEM s9xsplash[] ; - - +volatile uint32_t Spi_complete ; // Logic for storing to EERPOM/loading from EEPROM // If main needs to wait for the eeprom, call mainsequence without actioning menus @@ -265,6 +263,105 @@ void ee32_update_name( uint32_t id, uint8_t *source ) } } +uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count ) +{ + register Spi *spiptr ; +// register uint32_t result ; + register uint32_t condition ; + static uint8_t discard_rx_command[4] ; + +// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI + + Spi_complete = 0 ; + if ( comlen > 4 ) + { + Spi_complete = 1 ; + return 0x4FFFF ; + } + condition = SPI_SR_TXEMPTY ; + spiptr = SPI ; + spiptr->SPI_CR = 1 ; // Enable + (void) spiptr->SPI_RDR ; // Dump any rx data + (void) spiptr->SPI_SR ; // Clear error flags + spiptr->SPI_RPR = (uint32_t)discard_rx_command ; + spiptr->SPI_RCR = comlen ; + if ( rx ) + { + spiptr->SPI_RNPR = (uint32_t)rx ; + spiptr->SPI_RNCR = count ; + condition = SPI_SR_RXBUFF ; + } + spiptr->SPI_TPR = (uint32_t)command ; + spiptr->SPI_TCR = comlen ; + if ( tx ) + { + spiptr->SPI_TNPR = (uint32_t)tx ; + } + else + { + spiptr->SPI_TNPR = (uint32_t)rx ; + } + spiptr->SPI_TNCR = count ; + + spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers + + // Wait for things to get started, avoids early interrupt + for ( count = 0 ; count < 1000 ; count += 1 ) + { + if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 ) + { + break ; + } + } + spiptr->SPI_IER = condition ; + + return 0 ; +} + +uint32_t eeprom_write_one( uint8_t byte, uint8_t count ) +{ + register Spi *spiptr ; + register uint32_t result ; + + spiptr = SPI ; + spiptr->SPI_CR = 1 ; // Enable + (void) spiptr->SPI_RDR ; // Dump any rx data + + spiptr->SPI_TDR = byte ; + + result = 0 ; + while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 ) + { + // wait for received + if ( ++result > 10000 ) + { + break ; + } + } + if ( count == 0 ) + { + spiptr->SPI_CR = 2 ; // Disable + return spiptr->SPI_RDR ; + } + (void) spiptr->SPI_RDR ; // Dump the rx data + spiptr->SPI_TDR = 0 ; + result = 0 ; + while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 ) + { + // wait for received + if ( ++result > 10000 ) + { + break ; + } + } + spiptr->SPI_CR = 2 ; // Disable + return spiptr->SPI_RDR ; +} + +void eeprom_write_enable() +{ + eeprom_write_one( 6, 0 ) ; +} // Read eeprom data starting at random address uint32_t read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate ) @@ -435,15 +532,9 @@ bool ee32LoadGeneral() read32_eeprom_data( ( File_system[0].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_eeGeneral, size, 0 ) ; } - for(uint8_t i=0; i eeprom_arm + +// SPI i/f to EEPROM (4Mb) +// Peripheral ID 21 (0x00200000) +// Connections: +// SS PA11 (peripheral A) +// MISO PA12 (peripheral A) +// MOSI PA13 (peripheral A) +// SCK PA14 (peripheral A) +// Set clock to 3 MHz, AT25 device is rated to 70MHz, 18MHz would be better +void init_spi() +{ + register Pio *pioptr ; + register Spi *spiptr ; + register uint32_t timer ; + register uint8_t *p ; + uint8_t spi_buf[4] ; + + PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI + /* Configure PIO */ + pioptr = PIOA ; + pioptr->PIO_ABCDSR[0] &= ~0x00007800 ; // Peripheral A bits 14,13,12,11 + pioptr->PIO_ABCDSR[1] &= ~0x00007800 ; // Peripheral A + pioptr->PIO_PDR = 0x00007800 ; // Assign to peripheral + + spiptr = SPI ; + timer = ( Master_frequency / 3000000 ) << 8 ; // Baud rate 3Mb/s + spiptr->SPI_MR = 0x14000011 ; // 0001 0100 0000 0000 0000 0000 0001 0001 Master + spiptr->SPI_CSR[0] = 0x01180009 | timer ; // 0000 0001 0001 1000 xxxx xxxx 0000 1001 + NVIC_EnableIRQ(SPI_IRQn) ; + + p = spi_buf ; + +// *p = 0x39 ; // Unprotect sector command +// *(p+1) = 0 ; +// *(p+2) = 0 ; +// *(p+3) = 0 ; // 3 bytes address + +// spi_operation( p, spi_buf, 4 ) ; + + eeprom_write_enable() ; + + *p = 1 ; // Write status register command + *(p+1) = 0 ; + spi_operation( p, spi_buf, 2 ) ; +} + void init_ee32() { fill_file_index() ; @@ -1458,5 +1597,5 @@ uint32_t unprotect_eeprom() //} - +} diff --git a/src/ersky9x/sam3s2c_flash.ld b/src/ersky9x/sam3s2c_flash.ld new file mode 100644 index 000000000..f2e1fddc5 --- /dev/null +++ b/src/ersky9x/sam3s2c_flash.ld @@ -0,0 +1,144 @@ +/**************************************************************************** +* Copyright (c) 2011 by Michael Fischer. All rights reserved. +* +* 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. Neither the name of the author nor the names of its contributors may +* be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +* THE COPYRIGHT OWNER OR CONTRIBUTORS 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. +* +***************************************************************************** +* History: +* +* 22.05.2011 mifi First Version +****************************************************************************/ + + +/* + * In this linker script there is no heap available. + * The stack start at the end of the ram segment. + */ + + +/* + * Take a look in the "The GNU linker" manual, here you get + * the following information about the "MEMORY": + * + * "The MEMORY command describes the location and size of + * blocks of memory in the target." + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00400000, LENGTH = 128K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 32K +} + + +/* + * And the "SECTION" is used for: + * + * "The SECTIONS command tells the linker how to map input + * sections into output sections, and how to place the output + * sections in memory. + */ +SECTIONS +{ + + /* + * The ".text" section is used for the code, and + * read only (.rodata) data. Even the vectors (.vectors) + * MUST be saved at the start of this section. + */ + .text : + { + _stext = .; /* Provide the name for the start of this section */ + + CREATE_OBJECT_SYMBOLS + KEEP(*(.vectors)) + + *(.text) + *(.text.*) + + . = ALIGN(4); /* Align the start of the exidx part */ + *(.ARM.exidx) + *(.ARM.exidx.*) + + . = ALIGN(4); /* Align the start of the rodata part */ + *(.rodata) + *(.rodata.*) + + . = ALIGN(4); /* Align the end of the section */ + } > FLASH = 0 + _etext = .; /* Provide the name for the end of this section */ + + + /* + * The ".data" section is used for initialized data + * and for functions (.fastrun) which should be copied + * from flash to ram. This functions will later be + * executed from ram instead of flash. + */ + .data : AT (_etext) + { + . = ALIGN(4); /* Align the start of the section */ + _sdata = .; /* Provide the name for the start of this section */ + + *(.data) + *(.data.*) + + . = ALIGN(4); /* Align the start of the fastrun part */ + *(.fastrun) + *(.fastrun.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _edata = .; /* Provide the name for the end of this section */ + + + /* + * The ".bss" section is used for uninitialized data. + * This section will be cleared by the startup code. + */ + .bss : + { + . = ALIGN(4); /* Align the start of the section */ + _sbss = .; /* Provide the name for the start of this section */ + + *(.bss) + *(.bss.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _ebss = .; /* Provide the name for the end of this section */ + + + /* + * The ".stack" section is our stack. + * Here this section starts at the end of the ram segment. + */ + _estack = ORIGIN(RAM) + LENGTH(RAM); + +} + +/*** EOF **/ + diff --git a/src/ersky9x/sound.cpp b/src/ersky9x/sound.cpp index 32c371fca..4ba0d719c 100644 --- a/src/ersky9x/sound.cpp +++ b/src/ersky9x/sound.cpp @@ -91,6 +91,20 @@ uint16_t Sine_values64[] = 633, 779, 936,1105,1282,1467,1657,1851 } ; +const uint16_t PianoTones[] = +{ + 28, 29, 31, 33, 35, 37, 39, 41, 44, 46, + 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, + 87, 92, 98, 104, 110, 117, 123, 131, 139, 147, + 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, + 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, + 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, + 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, +1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, +2794, 2960, 3136, 3322, 3520 ,3729, 3951, 4186 +} ; + + // Sound routines void start_sound() @@ -244,6 +258,14 @@ void end_sound() PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC } + +void playTone( uint32_t frequency, uint32_t time ) +{ + set_frequency( frequency ) ; + tone_start( time ) ; +} + + // Time is in milliseconds void tone_start( register uint32_t time ) { @@ -340,5 +362,3 @@ void audioDefevent(uint8_t e) } - - diff --git a/src/ersky9x/sound.h b/src/ersky9x/sound.h index 3e6207122..b7b7280d5 100644 --- a/src/ersky9x/sound.h +++ b/src/ersky9x/sound.h @@ -33,31 +33,6 @@ ****************************************************************************/ - - -/* make sure the defines below always go in numeric order */ -#define AUDIO_TADA (0) -#define AUDIO_WARNING1 (1) -#define AUDIO_WARNING2 (2) -#define AUDIO_WARNING3 (3) -#define AUDIO_ERROR (4) -#define AUDIO_KEYPAD_UP (5) -#define AUDIO_KEYPAD_DOWN (6) -#define AUDIO_TRIM_MOVE (7) -#define AUDIO_TRIM_MIDDLE (8) -#define AUDIO_MENUS (9) -#define AUDIO_POT_STICK_MIDDLE (10) -#define AUDIO_MIX_WARNING_1 (11) -#define AUDIO_MIX_WARNING_2 (12) -#define AUDIO_MIX_WARNING_3 (13) -#define AUDIO_TIMER_30 (14) -#define AUDIO_TIMER_20 (15) -#define AUDIO_TIMER_10 (16) -#define AUDIO_TIMER_LT3 (17) -#define AUDIO_INACTIVITY (18) -#define AUDIO_TX_BATTERY_LOW (19) - - #define NUM_VOL_LEVELS 24 extern volatile uint8_t Buzzer_count ; @@ -72,6 +47,7 @@ extern void start_timer1( void ) ; extern void init_dac( void ) ; extern "C" void DAC_IRQHandler( void ) ; extern void end_sound( void ) ; +extern void playTone( uint32_t frequency, uint32_t time ) ; extern void tone_start( register uint32_t time ) ; extern void tone_stop( void ) ; extern void init_twi( void ) ; diff --git a/src/ersky9x/vectors_sam3s.c b/src/ersky9x/vectors_sam3s.c index 56c700acd..99ac1ab6d 100644 --- a/src/ersky9x/vectors_sam3s.c +++ b/src/ersky9x/vectors_sam3s.c @@ -177,18 +177,18 @@ void PIOC_IRQHandler (void) { while(1); } void USART0_IRQHandler (void) { while(1); } void USART1_IRQHandler (void) { while(1); } void MCI_IRQHandler (void) { while(1); } -void TWI0_IRQHandler (void) { while(1); } +// void TWI0_IRQHandler (void) { while(1); } void TWI1_IRQHandler (void) { while(1); } void SPI_IRQHandler (void) { while(1); } void SSC_IRQHandler (void) { while(1); } void TC0_IRQHandler (void) { while(1); } void TC1_IRQHandler (void) { while(1); } -void TC2_IRQHandler (void) { while(1); } +// void TC2_IRQHandler (void) { while(1); } void TC3_IRQHandler (void) { while(1); } void TC4_IRQHandler (void) { while(1); } void TC5_IRQHandler (void) { while(1); } void ADC_IRQHandler (void) { while(1); } -void DAC_IRQHandler (void) { while(1); } +// void DAC_IRQHandler (void) { while(1); } void PWM_IRQHandler (void) { while(1); } void CRCCU_IRQHandler (void) { while(1); } void ACC_IRQHandler (void) { while(1); } diff --git a/src/somo14d.cpp b/src/gruvin9x/somo14d.cpp similarity index 100% rename from src/somo14d.cpp rename to src/gruvin9x/somo14d.cpp diff --git a/src/somo14d.h b/src/gruvin9x/somo14d.h similarity index 100% rename from src/somo14d.h rename to src/gruvin9x/somo14d.h diff --git a/src/open9x.cpp b/src/open9x.cpp index 7c572664c..c13944710 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -50,8 +50,8 @@ gtime_t g_unixTime; // Global date/time register, incremented each second in per EEGeneral g_eeGeneral; ModelData g_model; -uint8_t g_tmr1Latency_max; -uint8_t g_tmr1Latency_min; +uint8_t g_tmr1Latency_max; +uint8_t g_tmr1Latency_min; uint16_t g_timeMain; #ifdef DEBUG uint16_t g_time_per10; @@ -318,13 +318,13 @@ int16_t Expo::expo(int16_t x) #endif -void applyExpos(int16_t *anas, uint8_t phase) +void applyExpos(int16_t *anas, uint8_t phase) { static int16_t anas2[NUM_STICKS]; // values before expo, to ensure same expo base when multiple expo lines are used memcpy(anas2, anas, sizeof(anas2)); - if (phase == 255) - phase = getFlightPhase(); + if (phase == 255) + phase = getFlightPhase(); int8_t cur_chn = -1; for (uint8_t i=0; i=0 && k<8) { // && (event & _MSK_KEY_REPT)) //LH_DWN LH_UP LV_DWN LV_UP RV_DWN RV_UP RH_DWN RH_UP uint8_t idx = CONVERT_MODE(1+k/2) - 1; - uint8_t phase = getTrimFlightPhase(idx, getFlightPhase()); + uint8_t phase = getTrimFlightPhase(idx, getFlightPhase()); int16_t before = getTrimValue(phase, idx); int8_t v = (s==0) ? min(32, abs(before)/4+1) : 1 << (s-1); // 1=>1 2=>2 3=>4 4=>8 bool thro = (idx==THR_STICK && g_model.thrTrim); @@ -896,16 +896,16 @@ void getADC_filt() #else void getADC_filt() { - static uint16_t t_ana[2][8]; - for (uint8_t adc_input=0; adc_input<8; adc_input++) { + static uint16_t t_ana[2][8]; + for (uint8_t adc_input=0; adc_input<8; adc_input++) { ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion ADCSRA|=0x40; - - // Do this while waiting - s_anaFilt[adc_input] = (s_anaFilt[adc_input]/2 + t_ana[1][adc_input]) & 0xFFFE; //gain of 2 on last conversion - clear last bit - t_ana[1][adc_input] = (t_ana[1][adc_input] + t_ana[0][adc_input]) >> 1; - + + // Do this while waiting + s_anaFilt[adc_input] = (s_anaFilt[adc_input]/2 + t_ana[1][adc_input]) & 0xFFFE; //gain of 2 on last conversion - clear last bit + t_ana[1][adc_input] = (t_ana[1][adc_input] + t_ana[0][adc_input]) >> 1; + // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; @@ -942,20 +942,20 @@ void getADC_osmp() #else void getADC_osmp() { - uint16_t temp_ana; - - for (uint8_t adc_input=0; adc_input<8; adc_input++) { - temp_ana = 0; - ADMUX = adc_input|ADC_VREF_TYPE; + uint16_t temp_ana; + + for (uint8_t adc_input=0; adc_input<8; adc_input++) { + temp_ana = 0; + ADMUX = adc_input|ADC_VREF_TYPE; for (uint8_t i=0; i<4;i++) { // Going from 10bits to 11 bits. Addition = n. Loop 4^n times // Start the AD conversion ADCSRA|=0x40; // Wait for the AD conversion to complete while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; - temp_ana += ADCW; + temp_ana += ADCW; } - s_anaFilt[adc_input] = temp_ana / 2; // divide by 2^n to normalize result. + s_anaFilt[adc_input] = temp_ana / 2; // divide by 2^n to normalize result. } } #endif @@ -975,7 +975,7 @@ void getADC_single() #else void getADC_single() { - for (uint8_t adc_input=0; adc_input<8; adc_input++) { + for (uint8_t adc_input=0; adc_input<8; adc_input++) { ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion ADCSRA|=0x40; @@ -987,7 +987,7 @@ void getADC_single() } #endif -#if not defined(PCBARM) +#if not defined(PCBARM) void getADC_bandgap() { #if defined (PCBV4) @@ -1110,17 +1110,17 @@ int32_t act [MAX_MIXERS] = {0}; uint8_t swOn [MAX_MIXERS] = {0}; uint8_t mixWarning; -FORCEINLINE void evalTrims(uint8_t phase) +FORCEINLINE void evalTrims(uint8_t phase) { for (uint8_t i=0; i throttle trim if applicable int32_t vv = 2*RESX; int16_t trim = getTrimValue(getTrimFlightPhase(i, phase), i); if (i==THR_STICK && g_model.thrTrim) { - if (g_eeGeneral.throttleReversed) + if (g_eeGeneral.throttleReversed) trim = -trim; - int16_t v = anas[i]; - vv = ((int32_t)trim-TRIM_MIN)*(RESX-v)/(2*RESX); + int16_t v = anas[i]; + vv = ((int32_t)trim-TRIM_MIN)*(RESX-v)/(2*RESX); } else if (trimsCheckTimer > 0) { trim = 0; @@ -1131,7 +1131,7 @@ FORCEINLINE void evalTrims(uint8_t phase) } bool s_noTrainerInput = false; -uint8_t evalSticks(uint8_t phase) +uint8_t evalSticks(uint8_t phase) { #ifdef HELI uint16_t d = 0; @@ -1162,10 +1162,10 @@ uint8_t evalSticks(uint8_t phase) if(v < -RESX) v = -RESX; if(v > RESX) v = RESX; - - if (g_eeGeneral.throttleReversed && ch==THR_STICK) - v = -v; - + + if (g_eeGeneral.throttleReversed && ch==THR_STICK) + v = -v; + calibratedStick[ch] = v; //for show in expo uint8_t tmp = (uint16_t)abs(v) / 16; if (tmp <= 1) anaCenter |= (tmp==0 ? 1< NUM_POTS) { val = RESX + g_chans512[g_model.thrTraceSrc-NUM_POTS-1]; @@ -1769,27 +1769,27 @@ void perMain() } // Timers end - if (s_fade_flight_phases) { - for (uint8_t p=0; p delta) - fp_act[p] += delta; - else { - fp_act[p] = MAX_ACT; - s_fade_flight_phases -= (1< delta) - fp_act[p] -= delta; - else { - fp_act[p] = 0; - s_fade_flight_phases -= (1< delta) + fp_act[p] += delta; + else { + fp_act[p] = MAX_ACT; + s_fade_flight_phases -= (1< delta) + fp_act[p] -= delta; + else { + fp_act[p] = 0; + s_fade_flight_phases -= (1< 20) - { - for (int xx=0; xx<20; xx++) // scroll one char left - userDataDisplayBuf[xx] = userDataDisplayBuf[xx+1]; - displayBufferIndex = 20; - } - userDataDisplayBuf[displayBufferIndex] = userDataRxBuffer[byt]; - - // Write the raw byte out to log file, if open - if (testLogOpen && (g_oLogFile.fs != 0)) - f_putc(userDataRxBuffer[byt], &g_oLogFile); - - } -#endif - + char userDataRxBuffer[21]; // Temp buffer used to collect fr-sky user data + + // retrieve bytes from user data buffer and insert into display string, + // scrolling at the 21 character mark (edge of screen) + uint8_t numbytes = frskyGetUserData(userDataRxBuffer, 21); // Get as many bytes as we can + + static uint8_t displayBufferIndex; + for (uint8_t byt=0; byt < numbytes; byt++) + { + displayBufferIndex++; + if (displayBufferIndex > 20) + { + for (int xx=0; xx<20; xx++) // scroll one char left + userDataDisplayBuf[xx] = userDataDisplayBuf[xx+1]; + displayBufferIndex = 20; + } + userDataDisplayBuf[displayBufferIndex] = userDataRxBuffer[byt]; + + // Write the raw byte out to log file, if open + if (testLogOpen && (g_oLogFile.fs != 0)) + f_putc(userDataRxBuffer[byt], &g_oLogFile); + + } +#endif + lcd_clear(); uint8_t evt = getEvent(); evt = checkTrim(evt); @@ -1853,23 +1853,23 @@ void perMain() g_menuStack[g_menuStackPtr](evt); refreshDisplay(); -#if defined(PCBV4) - // PPM signal on phono-jack. In or out? ... - if(checkSlaveMode()) { - PORTG |= (1<4000 && val < 16000) // G: Prioritize reset pulse. (Needed when less than 8 incoming pulses) + if (val>4000 && val < 16000) // G: Prioritize reset pulse. (Needed when less than 8 incoming pulses) ppmInState = 1; // triggered else { @@ -2038,7 +2038,7 @@ ISR(TIMER3_CAPT_vect) // G: High frequency noise can cause stack overflo with IS lastCapt = capture; - cli(); // disable other interrupts for stack pops before this function's RETI + cli(); // disable other interrupts for stack pops before this function's RETI #if defined (PCBV4) TIMSK3 |= (1< 0) { + UDR0 = frskyTxBuffer[--frskyTxBufferCount]; + } + else { + UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt + } +} +#endif + +#if defined (DSM2_SERIAL) +FORCEINLINE void DSM2_USART0_vect() { - if (frskyTxBufferCount > 0) { - UDR0 = frskyTxBuffer[--frskyTxBufferCount]; - } - else { - UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt - } -} -#endif - -#if defined (DSM2_SERIAL) -FORCEINLINE void DSM2_USART0_vect() -{ - UDR0 = *((uint16_t*)pulses2MHzRPtr); - - pulses2MHzRPtr += sizeof(uint16_t); - if (pulses2MHzRPtr == pulses2MHzWPtr) { - UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt - } -} -#endif - -#ifndef SIMU -#if defined (FRSKY) or defined(DSM2_SERIAL) -ISR(USART0_UDRE_vect) -{ -#if defined (FRSKY) and defined (DSM2_SERIAL) - if (g_model.protocol == PROTO_DSM2) { - DSM2_USART0_vect(); - } - else { - FRSKY_USART0_vect(); - } -#elif defined (FRSKY) - FRSKY_USART0_vect(); -#else - DSM2_USART0_vect(); -#endif -} -#endif -#endif + UDR0 = *((uint16_t*)pulses2MHzRPtr); + pulses2MHzRPtr += sizeof(uint16_t); + if (pulses2MHzRPtr == pulses2MHzWPtr) { + UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt + } +} +#endif + +#ifndef SIMU +#if defined (FRSKY) or defined(DSM2_SERIAL) +ISR(USART0_UDRE_vect) +{ +#if defined (FRSKY) and defined (DSM2_SERIAL) + if (g_model.protocol == PROTO_DSM2) { + DSM2_USART0_vect(); + } + else { + FRSKY_USART0_vect(); + } +#elif defined (FRSKY) + FRSKY_USART0_vect(); +#else + DSM2_USART0_vect(); +#endif +} +#endif +#endif + #if defined (PCBV4) /*---------------------------------------------------------*/ /* User Provided Date/Time Function for FatFs module */ @@ -2153,14 +2153,14 @@ uint32_t o9x_get_fattime(void) // TODO why not in ff.cpp? void instantTrim() { - uint8_t phase = getFlightPhase(); - + uint8_t phase = getFlightPhase(); + for (uint8_t i=0; iPIO_PER = 0x00020000L ; // Assign A17 to PIO + + sscptr = SSC ; + sscptr->SSC_CR = SSC_CR_TXDIS ; + +} +#endif + int main(void) { board_init(); lcd_init(); -#if not defined(PCBARM) +#if !defined(PCBARM) // Init Stack while interrupts are disabled #define STACKPTR _SFR_IO16(0x3D) { @@ -2250,16 +2270,16 @@ int main(void) lcdSetRefVolt(25); - sei(); // interrupts needed for FRSKY_Init and eeReadAll. + sei(); // interrupts needed for FRSKY_Init and eeReadAll. #if defined (FRSKY) and !defined (DSM2_SERIAL) FRSKY_Init(); #endif -#if defined (DSM2_SERIAL) and !defined (FRSKY) - DSM2_Init(); -#endif - +#if defined (DSM2_SERIAL) and !defined (FRSKY) + DSM2_Init(); +#endif + #ifdef JETI JETI_Init(); #endif @@ -2295,7 +2315,9 @@ int main(void) doSplash(); #endif +#if !defined(PCBARM) checkLowEEPROM(); +#endif getADC_single(); checkTHR(); @@ -2304,7 +2326,7 @@ int main(void) checkAlarm(); } - clearKeyEvents(); //make sure no keys are down before proceeding + clearKeyEvents(); //make sure no keys are down before proceeding lcdSetRefVolt(g_eeGeneral.contrast); g_LightOffCounter = g_eeGeneral.lightAutoOff*500; //turn on light for x seconds - no need to press key Issue 152 @@ -2346,18 +2368,38 @@ int main(void) /***************************************************/ /* - * SOMO set-up (V4 board only) + * SOMO set-up (V4 board only) */ OCR4A = 0x7d; TCCR4B = (1 << WGM42) | (3<PIO_PDSR & 0x02000000 ) { + // Detected USB + // TODO goto_usb = 1 ; + break; + } + + uint16_t t0 = getTmr2MHz(); +#else uint16_t t0 = getTmr16KHz(); +#endif if (g_eeGeneral.filterInput == 1) { getADC_filt() ; @@ -2389,9 +2431,38 @@ int main(void) wdt_reset(); heartbeat = 0; } +#if defined(PCBARM) + t0 = getTmr2MHz() - t0; +#else t0 = getTmr16KHz() - t0; +#endif + g_timeMain = max(g_timeMain,t0); } + +#if defined(PCBARM) + lcd_clear() ; + lcd_putcAtt( 48, 24, 'U', DBLSIZE ) ; + lcd_putcAtt( 60, 24, 'S', DBLSIZE ) ; + lcd_putcAtt( 72, 24, 'B', DBLSIZE ) ; + refreshDisplay() ; + + // This might be replaced by a software reset + // Any interrupts that have been enabled must be disabled here + // BEFORE calling sam_boot() + // TODO needed for REVB soft_power_off() ; + // TODO not started end_ppm_capture() ; + // TODO in eeprom_arm ... end_spi() ; + end_sound() ; + TC0->TC_CHANNEL[2].TC_IDR = TC_IDR0_CPCS ; + NVIC_DisableIRQ(TC2_IRQn) ; + // PWM->PWM_IDR1 = PWM_IDR1_CHID0 ; + // TODO disable_main_ppm() ; + // PWM->PWM_IDR1 = PWM_IDR1_CHID3 ; + // NVIC_DisableIRQ(PWM_IRQn) ; + disable_ssc() ; + sam_boot() ; +#endif } #endif diff --git a/src/open9x.h b/src/open9x.h index 1ce05349b..df972d838 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -49,6 +49,8 @@ #if defined(SIMU) #include "simpgmspace.h" #elif defined(PCBARM) +#include "ersky9x/AT91SAM3S2.h" +#include "ersky9x/core_cm3.h" typedef const unsigned char pm_uchar; typedef const char pm_char; typedef const uint16_t pm_uint16_t; @@ -461,7 +463,11 @@ uint8_t getEvent(); void putEvent(uint8_t evt); uint8_t keyDown(); +#if defined(PCBARM) +uint32_t keyState(EnumKeys enuk); +#else bool keyState(EnumKeys enuk); +#endif void readKeysAndTrims(); uint16_t evalChkSum(); @@ -515,7 +521,12 @@ extern int8_t s_traceCnt; extern int8_t *s_trimPtr[NUM_STICKS]; +#if defined(PCBARM) +uint16_t getTmr2MHz(); +#else uint16_t getTmr16KHz(); +#endif + uint16_t stack_free(); #ifdef SPLASH @@ -698,11 +709,6 @@ extern uint8_t beepAgain; extern uint16_t g_LightOffCounter; extern uint8_t mixWarning; -/// Erzeugt einen beep der laenge b -inline void _beep(uint8_t b) { - g_beepCnt=b; -} - // MM/SD card Disk IO Support #if defined (PCBV4) #include "gruvin9x/rtc.h" diff --git a/src/pulses.cpp b/src/pulses.cpp index d2a79293b..42c88431c 100644 --- a/src/pulses.cpp +++ b/src/pulses.cpp @@ -33,6 +33,9 @@ #include "open9x.h" +#ifndef PCBARM +// TODO!!! + #if defined(DSM2) #define DSM2_CHANS 6 #define BIND_BIT 0x80 @@ -829,3 +832,4 @@ void setupPulsesPPM16() } #endif +#endif