// This file is part of "NPR70 modem firmware" software // (A GMSK data modem for ham radio 430-440MHz, at several hundreds of kbps) // Copyright (c) 2017-2020 Guillaume F. F4HDK (amateur radio callsign) // // "NPR70 modem firmware" is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // "NPR70 modem firmware" is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with "NPR70 modem firmware". If not, see #ifdef EXT_SRAM_USAGE #include "mbed.h" #include "global_variables.h" #include "ext_SRAM2.h" static unsigned char trash[350]; static unsigned short int extSRAM_FIFOs[8][94];// 8 FIFO of pointers to extSRAM static unsigned char extSRAM_filling[374];// 0 : empty frame slot; 1: occupied frame slot static int extSRAM_total_filling = 0; static unsigned char extSRAM_pkt_timer[374];// timer of each frame static unsigned short int extSRAM_pkt_size[374];// size of each frame static unsigned char extSRAM_FIFO_index_read[8];//Read pointers of FIFO static unsigned char extSRAM_FIFO_index_write[8];//write pointers of FIFO static unsigned char extSRAM_FIFO_filling[8]; void ext_SRAM_init(void) { int i; int j; for (i=0; i<8; i++) { extSRAM_FIFO_index_read[i] = 0; extSRAM_FIFO_index_write[i] = 0; extSRAM_FIFO_filling[i] = 0; } extSRAM_total_filling = 0; } void ext_SRAM_set_mode(ext_SRAM_chip* loc_SPI) { static unsigned char command[6] = {0x01, 0x40, 0x00, 0x00}; loc_SPI->cs->write(0); loc_SPI->spi_port->transfer_2 (command, 2, trash, 2); loc_SPI->cs->write(1); } /* void ext_SRAM_read2(ext_SRAM_chip* loc_SPI, unsigned char* loc_data, unsigned int address, int size) { static unsigned char command[6] = {0x03, 0x00, 0x00, 0x00}; loc_SPI->cs->write(0); command[3] = address & 0xFF; command[2] = (address & 0xFF00) >> 8; command[1] = (address & 0xFF0000) >> 16; loc_SPI->spi_port->transfer_2 (command, 4, trash, 4); loc_SPI->spi_port->transfer_2 (trash, size, loc_data, size); loc_SPI->cs->write(1); } */ void ext_SRAM_write(ext_SRAM_chip* loc_SPI, unsigned char* loc_data, unsigned int address, int size) { //static unsigned char trash[350]; static unsigned char command[6] = {0x02, 0x00, 0x00, 0x00}; loc_SPI->cs->write(0); command[3] = address & 0xFF; command[2] = (address & 0xFF00) >> 8; command[1] = (address & 0xFF0000) >> 16; loc_SPI->spi_port->transfer_2 (command, 4, trash, 4); loc_SPI->spi_port->transfer_2 (loc_data, size, trash, size); loc_SPI->cs->write(1); } int extSRAM_testfreespace(int pkt_nb, unsigned char FIFO_index) { int freespace_available = 1; if ( (extSRAM_FIFO_filling[FIFO_index] + pkt_nb) > 94 ) { freespace_available = 0; } if ( (extSRAM_total_filling + pkt_nb) > 374 ) { freespace_available = 0; } return freespace_available; } void extSRAM_push(unsigned char* raw_data, int size, unsigned char FIFO_nb) { unsigned short int i; unsigned short int free_slot = 0xFFFF; for (i=0; i<350; i++) { if (extSRAM_filling[i] == 0) { free_slot = i; } } if (free_slot != 0xFFFF) { extSRAM_filling[free_slot] = 1; extSRAM_FIFOs[FIFO_nb][extSRAM_FIFO_index_write[FIFO_nb]] = free_slot; extSRAM_FIFO_index_write[FIFO_nb] ++; if (extSRAM_FIFO_index_write[FIFO_nb] > 93) { extSRAM_FIFO_index_write[FIFO_nb] = 0; } extSRAM_total_filling ++; extSRAM_FIFO_filling[FIFO_nb]++; extSRAM_pkt_timer[free_slot] = raw_data[0]; extSRAM_pkt_size[free_slot] = size; ext_SRAM_write (SPI_SRAM_p, raw_data, free_slot*350, size); } else { printf("ERROR extSRAM push\r\n"); } } void TXPS_FIFO_fill(unsigned char* loc_data, int size) { int size_to_write; if ( ( (TXPS_FIFO->WR_point & TXPS_FIFO->mask) + size) > TXPS_FIFO->mask) { // to big for 1 step size_to_write = (TXPS_FIFO->mask + 1 - (TXPS_FIFO->WR_point & TXPS_FIFO->mask) ); //G_SI4463->spi->transfer_2 (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), size_to_write, SI_trash, size_to_write); memcpy (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), loc_data, size_to_write); TXPS_FIFO->WR_point = TXPS_FIFO->WR_point + size_to_write; // should become ZERO //second step size_to_write = size - size_to_write; //G_SI4463->spi->transfer_2 (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), size_to_write, SI_trash, size_to_write); memcpy (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), loc_data, size_to_write); TXPS_FIFO->WR_point = TXPS_FIFO->WR_point + size_to_write; TXPS_FIFO->last_ready = TXPS_FIFO->WR_point; } else { //1 step is enough //G_SI4463->spi->transfer_2 (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), size, SI_trash, size); memcpy (TXPS_FIFO->data + (TXPS_FIFO->WR_point & TXPS_FIFO->mask), loc_data, size); TXPS_FIFO->WR_point = TXPS_FIFO->WR_point + size; TXPS_FIFO->last_ready = TXPS_FIFO->WR_point; } } /* void ext_SRAM_periodic_call(void) { int intern_FIFO_filling; int ext_FIFO_filling; intern_FIFO_filling = TX_buff_intern_WR_pointer - TX_buff_intern_RD_pointer; ext_FIFO_filling = TX_buff_ext_WR_pointer - TX_buff_ext_RD_pointer; while ( (ext_FIFO_filling > 0) && (intern_FIFO_filling <= 9) ) { ext_SRAM_read(SPI_SRAM_p, TX_buff_intern_FIFOdata[TX_buff_intern_WR_pointer % 128], TX_buff_ext_RD_pointer*128, 128); TX_buff_ext_RD_pointer++; TX_buff_intern_WR_pointer++; TX_buff_intern_last_ready = TX_buff_intern_WR_pointer; } } */ /* void ext_SRAM_periodic_call() { static unsigned char current_buff; unsigned char radio_pckt[360]; unsigned char nb_buffer_treated = 0; unsigned char frame_datation; unsigned char loc_time_char; unsigned int loc_time_int; unsigned short int extSRAM_pointer; int one_packet_ok = 0; int switch_to_next_buff = 0; int fifo_full; int frame_size; nb_buffer_treated = 0; loc_time_int = GLOBAL_timer.read_us(); loc_time_char = (loc_time_int >> 16) & 0xFF; //condition a rajouter sur buffer interne TXPS if ((TXPS_FIFO->last_ready - TXPS_FIFO->RD_point) < 3740 ) { //16380 - 350 ; 3740 fifo_full = 0; } else { fifo_full = 1; } //printf("FIFO full : %i\r\n", fifo_full); while ( (nb_buffer_treated<8) && (one_packet_ok==0) && (fifo_full == 0) ) {//loop over all buffers switch_to_next_buff = 0; if (extSRAM_FIFO_filling[current_buff] > 0) {//data available in current buffer extSRAM_pointer = extSRAM_FIFOs[current_buff][extSRAM_FIFO_index_read[current_buff]]; frame_datation = extSRAM_pkt_timer[extSRAM_pointer]; //frame_size = extSRAM_pkt_size[extSRAM_pointer] + 2 + SI4463_offset_size; frame_size = extSRAM_pkt_size[extSRAM_pointer]; if ( (loc_time_char - frame_datation) < CONF_Tx_rframe_timeout) {//frame ok //printf("frame OK ext SRAM\r\n"); ext_SRAM_read (SPI_SRAM_p, radio_pckt, extSRAM_pointer*350, frame_size); radio_pckt[1] = frame_size - 2 - SI4463_offset_size;//-2 TXPS_FIFO_fill (radio_pckt, frame_size); switch_to_next_buff = 1; one_packet_ok = 1; } else {//old frame switch_to_next_buff = 0; } extSRAM_filling[extSRAM_pointer] = 0; extSRAM_FIFO_index_read[current_buff]++; if (extSRAM_FIFO_index_read[current_buff] > 93) { extSRAM_FIFO_index_read[current_buff] = 0; } extSRAM_FIFO_filling[current_buff]--; extSRAM_total_filling--; } else {//no data in the current buffer switch_to_next_buff = 1; } if (switch_to_next_buff == 1) { current_buff++; if (current_buff>7) {current_buff = 0;} nb_buffer_treated++; } } } */ void ext_SRAM_test(ext_SRAM_chip* loc_SPI) { unsigned char test_table[400] = "bonjour!!"; unsigned char test_table2[400]; unsigned long int timer1; unsigned long int timer2; unsigned int loc_address; int i, j; printf("\r\nsram test begin\r\n"); //loc_SPI->cs->write(1); for (i=0; i<5000; i++) { loc_address = 16 * i; //wait_ms(1); sprintf ((char*)test_table, "jourbon %i", i); ext_SRAM_write(loc_SPI, test_table, loc_address, 20); printf("write %i\r\n", i); } for (i=0; i<5000; i++) { loc_address = 16 * i; for (j=0; j<30; j++) { test_table2[j] = 0; } //wait_ms(1); ext_SRAM_read2(loc_SPI, test_table2, loc_address, 20); test_table2[12] = 0; printf ("read addr %i content '%s' \r\n", loc_address, test_table2); } timer1 = GLOBAL_timer.read_us(); for (i=0; i<10; i++) { memcpy(test_table2+i, test_table+i, 350); } timer2 = GLOBAL_timer.read_us(); printf("temps memcpy 350 %i\r\n", timer2-timer1); } #endif