diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 80b4aeb50..7de329e48 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -140,11 +140,13 @@ jobs: - name: ArduinoBLE - name: ArduinoGraphics - name: Arduino_GigaDisplayTouch + - name: arducam_dvp additional-sketch-paths: | - libraries/PDM - libraries/MCUboot - libraries/Camera/examples/CameraCaptureRawBytes - libraries/Camera/examples/CameraMotionDetect + - libraries/Camera/examples/GigaCameraDisplay - libraries/Portenta_SDCARD - libraries/Portenta_SDRAM - libraries/Arduino_H7_Video diff --git a/boards.txt b/boards.txt index 112e3f502..6a067f06c 100644 --- a/boards.txt +++ b/boards.txt @@ -581,6 +581,9 @@ opta.menu.split.100_0=2MB M7 opta.menu.split.75_25=1.5MB M7 + 0.5MB M4 opta.menu.split.50_50=1MB M7 + 1MB M4 +opta.menu.security.none=None +opta.menu.security.sien=Signature + Encryption + opta.menu.target_core.cm7.build.variant=OPTA opta.menu.target_core.cm7.build.mcu=cortex-m7 opta.menu.target_core.cm7.build.fpu=-mfpu=fpv5-d16 @@ -593,15 +596,23 @@ opta.menu.target_core.cm4.build.fpu=-mfpu=fpv4-sp-d16 opta.menu.target_core.cm4.build.architecture=cortex-m4 opta.menu.target_core.cm4.compiler.mbed.arch.define=-DOPTA_PINS +opta.build.float-abi=-mfloat-abi=softfp +opta.build.extra_flags= opta.menu.split.50_50.build.extra_ldflags=-DCM4_BINARY_START=0x08100000 -DCM4_BINARY_END=0x08200000 opta.menu.split.75_25.build.extra_ldflags=-DCM4_BINARY_START=0x08180000 -DCM4_BINARY_END=0x08200000 opta.menu.split.100_0.build.extra_ldflags=-DCM4_BINARY_START=0x60000000 -DCM4_BINARY_END=0x60040000 -DCM4_RAM_END=0x60080000 -opta.build.board={build.variant} -opta.build.extra_flags= -opta.build.float-abi=-mfloat-abi=softfp +opta.build.board={build.variant} opta.build.ldscript=linker_script.ld opta.compiler.mbed.arch.define= +opta.build.slot_size=0x1E0000 +opta.build.header_size=0x20000 +opta.build.alignment=32 +opta.build.version=1.2.3+4 +opta.menu.security.sien.recipe.hooks.objcopy.postobjcopy.1.pattern="{tools.imgtool.path}/{tools.imgtool.cmd}" {tools.imgtool.flags} +opta.menu.security.sien.build.keys.keychain={runtime.platform.path}/libraries/MCUboot/default_keys +opta.menu.security.sien.build.keys.sign_key=ecdsa-p256-signing-priv-key.pem +opta.menu.security.sien.build.keys.encrypt_key=ecdsa-p256-encrypt-pub-key.pem opta.compiler.mbed.defines={build.variant.path}/defines.txt opta.compiler.mbed.ldflags={build.variant.path}/ldflags.txt opta.compiler.mbed.cflags={build.variant.path}/cflags.txt @@ -653,10 +664,15 @@ opta.upload.interface=0 opta.upload.use_1200bps_touch=true opta.upload.wait_for_upload_port=true opta.upload.native_usb=true -opta.upload.maximum_size=786432 +opta.upload.maximum_size=1966080 opta.upload.maximum_data_size=523624 -opta.menu.target_core.cm7.upload.address=0x08040000 +opta.menu.security.none.upload.interface=0 +opta.menu.security.sien.upload.interface=2 + +opta.menu.security.none.upload.address_m7=0x08040000 +opta.menu.security.sien.upload.address_m7=0xA0000000 +opta.menu.target_core.cm7.upload.address={upload.address_m7} opta.menu.target_core.cm7.menu.split.50_50.upload.maximum_size=786432 opta.menu.target_core.cm7.menu.split.75_25.upload.maximum_size=1441792 diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h new file mode 100644 index 000000000..2850a8e95 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/m460_eth.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 Nuvoton Technology Corp. + * Copyright (c) 2022 ARM Limited + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Description: M460 EMAC driver header file + */ + +#include "numaker_emac_config.h" +#include "M460.h" +#ifndef _M460_ETH_ +#define _M460_ETH_ + +/* Generic MII registers. */ + +#define MII_BMCR 0x00 /* Basic mode control register */ +#define MII_BMSR 0x01 /* Basic mode status register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control reg */ +#define MII_LPA 0x05 /* Link partner ability reg */ +#define MII_EXPANSION 0x06 /* Expansion register */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control register. */ +#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status register. */ +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x07c0 /* Unused... */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +/* Advertisement control register. */ +#define ADVERTISE_SLCT 0x001f /* Selector bits */ +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ +#define ADVERTISE_RESV 0x1c00 /* Unused... */ +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */ +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */ + +#define PACKET_BUFFER_SIZE ( NU_ETH_MAX_FLEN + ((NU_ETH_MAX_FLEN%4) ? (4 - (NU_ETH_MAX_FLEN%4)) : 0) ) //For DMA 4 bytes alignment + +#define CONFIG_PHY_ADDR 1 + + +#endif /* _M460_ETH_ */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h new file mode 100644 index 000000000..4410ea744 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_Dev.h @@ -0,0 +1,1500 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/**\file + * This file defines the function prototypes for the Synopsys GMAC device and the + * Marvell 88E1011/88E1011S integrated 10/100/1000 Gigabit Ethernet Transceiver. + * Since the phy register mapping are standardised, the phy register map and the + * bit definitions remain the same for other phy as well. + * This also defines some of the Ethernet related parmeters. + * \internal + * -----------------------------REVISION HISTORY------------------------------------ + * Synopsys 01/Aug/2007 Created + */ + + +#ifndef SYNOP_GMAC_DEV_H +#define SYNOP_GMAC_DEV_H 1 + +#include "synopGMAC_plat.h" + +#define GMAC_CNT 1 + +/*SynopGMAC can support up to 32 phys*/ + +enum GMACPhyBase { + PHY0 = 0, //The device can support 32 phys, but we use first phy only + PHY1 = 1, + PHY31 = 31, +}; + +#define DEFAULT_PHY_BASE PHY1 //We use First Phy + +#define GMAC0MappedAddr EMAC_BASE //0x40012000 +#define GMAC1MappedAddr EMAC_BASE +#define MACBASE 0x0000 // The Mac Base address offset is 0x0000 +#define DMABASE 0x1000 // Dma base address starts with an offset 0x1000 + + +#define TRANSMIT_DESC_SIZE 8//256 //Tx Descriptors needed in the Descriptor pool/queue +#define RECEIVE_DESC_SIZE 16//256 //Rx Descriptors needed in the Descriptor pool/queue + +#define ETHERNET_HEADER 14 //6 byte Dest addr, 6 byte Src addr, 2 byte length/type +#define ETHERNET_CRC 4 //Ethernet CRC +#define ETHERNET_EXTRA 2 //Only God knows about this????? +#define ETHERNET_PACKET_COPY 250 // Maximum length when received data is copied on to a new skb +#define ETHERNET_PACKET_EXTRA 18 // Preallocated length for the rx packets is MTU + ETHERNET_PACKET_EXTRA +#define VLAN_TAG 4 //optional 802.1q VLAN Tag +#define MIN_ETHERNET_PAYLOAD 46 //Minimum Ethernet payload size +#define MAX_ETHERNET_PAYLOAD 1500 //Maximum Ethernet payload size +#define JUMBO_FRAME_PAYLOAD 9000 //Jumbo frame payload size + +#define TX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG + + +// This is the IP's phy address. This is unique address for every MAC in the universe +#define DEFAULT_MAC0_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7} +#define DEFAULT_MAC1_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF8} +/* +DMA Descriptor Structure +The structure is common for both receive and transmit descriptors +The descriptor is of 4 words, but our structrue contains 6 words where +last two words are to hold the virtual address of the network buffer pointers +for driver's use +From the GMAC core release 3.50a onwards, the Enhanced Descriptor structure got changed. +The descriptor (both transmit and receive) are of 8 words each rather the 4 words of normal +descriptor structure. +Whenever IEEE 1588 Timestamping is enabled TX/RX DESC6 provides the lower 32 bits of Timestamp value and + TX/RX DESC7 provides the upper 32 bits of Timestamp value +In addition to this whenever extended status bit is set (RX DESC0 bit 0), RX DESC4 contains the extended status information +*/ + +#define MODULO_INTERRUPT 1 // if it is set to 1, interrupt is available for all the descriptors or else interrupt is available only for +// descriptor whose index%MODULO_INTERRUPT is zero +typedef struct DmaDescStruct { + u32 status; /* Status */ + u32 length; /* Buffer 1 and Buffer 2 length */ + u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */ + u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */ + /* This data below is used only by driver */ + u32 extstatus; /* Extended status of a Rx Descriptor */ + u32 reserved1; /* Reserved word */ + u32 timestamplow; /* Lower 32 bits of the 64 bit timestamp value */ + u32 timestamphigh; /* Higher 32 bits of the 64 bit timestamp value */ + //u32 data1; /* This holds virtual address of buffer1, not used by DMA */ + //u32 data2; /* This holds virtual address of buffer2, not used by DMA */ +} DmaDesc; + +enum DescMode { + RINGMODE = 0x00000001, + CHAINMODE = 0x00000002, +}; + +enum BufferMode { + SINGLEBUF = 0x00000001, + DUALBUF = 0x00000002, +}; + +typedef u32 * dma_addr_t; + +/* synopGMAC device data */ + +struct sk_buff { + unsigned char data[2048]; + unsigned int len; + unsigned int volatile rdy; +}; + +struct net_device_stats { + u32 tx_bytes; + u32 tx_packets; + u32 tx_errors; + u32 tx_aborted_errors; + u32 tx_carrier_errors; + u32 tx_ip_header_errors; + u32 tx_ip_payload_errors; + u32 collisions; + u32 rx_bytes; + u32 rx_packets; + u32 rx_errors; + u32 rx_crc_errors; + u32 rx_frame_errors; + u32 rx_length_errors; + u32 rx_dropped; + u32 rx_over_errors; + u32 rx_ip_header_errors; + u32 rx_ip_payload_errors; + volatile u32 ts_int; +}; + +typedef struct synopGMACDeviceStruct { + u64 MacBase; /* base address of MAC registers */ + u64 DmaBase; /* base address of DMA registers */ + u64 PhyBase; /* PHY device address on MII interface */ + u64 Version; /* Gmac Revision version */ + + + /*dma_addr_t*/ DmaDesc *TxDescDma; /* Dma-able address of first tx descriptor either in ring or chain mode, this is used by the GMAC device*/ + /*dma_addr_t*/ DmaDesc *RxDescDma; /* Dma-albe address of first rx descriptor either in ring or chain mode, this is used by the GMAC device*/ + DmaDesc *TxDesc; /* start address of TX descriptors ring or chain, this is used by the driver */ + DmaDesc *RxDesc; /* start address of RX descriptors ring or chain, this is used by the driver */ + + u32 BusyTxDesc; /* Number of Tx Descriptors owned by DMA at any given time*/ + u32 BusyRxDesc; /* Number of Rx Descriptors owned by DMA at any given time*/ + + u32 RxDescCount; /* number of rx descriptors in the tx descriptor queue/pool */ + u32 TxDescCount; /* number of tx descriptors in the rx descriptor queue/pool */ + + u32 TxBusy; /* index of the tx descriptor owned by DMA, is obtained by synopGMAC_get_tx_qptr() */ + u32 TxNext; /* index of the tx descriptor next available with driver, given to DMA by synopGMAC_set_tx_qptr() */ + u32 RxBusy; /* index of the rx descriptor owned by DMA, obtained by synopGMAC_get_rx_qptr() */ + u32 RxNext; /* index of the rx descriptor next available with driver, given to DMA by synopGMAC_set_rx_qptr() */ + + DmaDesc * TxBusyDesc; /* Tx Descriptor address corresponding to the index TxBusy */ + DmaDesc * TxNextDesc; /* Tx Descriptor address corresponding to the index TxNext */ + DmaDesc * RxBusyDesc; /* Rx Descriptor address corresponding to the index TxBusy */ + DmaDesc * RxNextDesc; /* Rx Descriptor address corresponding to the index RxNext */ + + + /*Phy related stuff*/ + u32 ClockDivMdc; /* Clock divider value programmed in the hardware */ + /* The status of the link */ + u32 LinkState; /* Link status as reported by the Marvel Phy */ + u32 DuplexMode; /* Duplex mode of the Phy */ + u32 Speed; /* Speed of the Phy */ + u32 LoopBackMode; /* Loopback status of the Phy */ + u32 Intf; + struct net_device_stats synopGMACNetStats; + + u32 tx_sec; + u32 tx_subsec; + u32 rx_sec; + u32 rx_subsec; + + u32 GMAC_Power_down; + +} synopGMACdevice; + + +/* Below is "88E1011/88E1011S Integrated 10/100/1000 Gigabit Ethernet Transceiver" + * Register and their layouts. This Phy has been used in the Dot Aster GMAC Phy daughter. + * Since the Phy register map is standard, this map hardly changes to a different Ppy + */ + +enum MiiRegisters { + PHY_CONTROL_REG = 0x0000, /*Control Register*/ + PHY_STATUS_REG = 0x0001, /*Status Register */ + PHY_ID_HI_REG = 0x0002, /*PHY Identifier High Register*/ + PHY_ID_LOW_REG = 0x0003, /*PHY Identifier High Register*/ + PHY_AN_ADV_REG = 0x0004, /*Auto-Negotiation Advertisement Register*/ + PHY_LNK_PART_ABl_REG = 0x0005, /*Link Partner Ability Register (Base Page)*/ + PHY_AN_EXP_REG = 0x0006, /*Auto-Negotiation Expansion Register*/ + PHY_AN_NXT_PAGE_TX_REG = 0x0007, /*Next Page Transmit Register*/ + PHY_LNK_PART_NXT_PAGE_REG = 0x0008, /*Link Partner Next Page Register*/ + PHY_1000BT_CTRL_REG = 0x0009, /*1000BASE-T Control Register*/ + PHY_1000BT_STATUS_REG = 0x000a, /*1000BASE-T Status Register*/ + PHY_SPECIFIC_CTRL_REG = 0x0010, /*Phy specific control register*/ + PHY_SPECIFIC_STATUS_REG = 0x0011, /*Phy specific status register*/ + PHY_INTERRUPT_ENABLE_REG = 0x0012, /*Phy interrupt enable register*/ + PHY_INTERRUPT_STATUS_REG = 0x0013, /*Phy interrupt status register*/ + PHY_EXT_PHY_SPC_CTRL = 0x0014, /*Extended Phy specific control*/ + PHY_RX_ERR_COUNTER = 0x0015, /*Receive Error Counter*/ + PHY_EXT_ADDR_CBL_DIAG = 0x0016, /*Extended address for cable diagnostic register*/ + PHY_LED_CONTROL = 0x0018, /*LED Control*/ + PHY_MAN_LED_OVERIDE = 0x0019, /*Manual LED override register*/ + PHY_EXT_PHY_SPC_CTRL2 = 0x001a, /*Extended Phy specific control 2*/ + PHY_EXT_PHY_SPC_STATUS = 0x001b, /*Extended Phy specific status*/ + PHY_CBL_DIAG_REG = 0x001c, /*Cable diagnostic registers*/ +}; + + +/* This is Control register layout. Control register is of 16 bit wide. +*/ + +enum Mii_GEN_CTRL { + /* Description bits R/W default value */ + Mii_reset = 0x8000, + Mii_Speed_10 = 0x0000, /* 10 Mbps 6:13 RW */ + Mii_Speed_100 = 0x2000, /* 100 Mbps 6:13 RW */ + Mii_Speed_1000 = 0x0040, /* 1000 Mbit/s 6:13 RW */ + + Mii_Duplex = 0x0100, /* Full Duplex mode 8 RW */ + + Mii_Manual_Master_Config = 0x0800, /* Manual Master Config 11 RW */ + + Mii_Loopback = 0x4000, /* Enable Loop back 14 RW */ + Mii_NoLoopback = 0x0000, /* Enable Loop back 14 RW */ +}; + +enum Mii_Phy_Status { + Mii_phy_status_speed_10 = 0x0000, + Mii_phy_status_speed_100 = 0x4000, + Mii_phy_status_speed_1000 = 0x8000, + + Mii_phy_status_full_duplex = 0x2000, + Mii_phy_status_half_duplex = 0x0000, + + Mii_phy_status_link_up = 0x0400, +}; +/* This is Status register layout. Status register is of 16 bit wide. +*/ +enum Mii_GEN_STATUS { + Mii_AutoNegCmplt = 0x0020, /* Autonegotiation completed 5 RW */ + Mii_Link = 0x0004, /* Link status 2 RW */ +}; + +enum Mii_Link_Status { + LINKDOWN = 0, + LINKUP = 1, +}; + +enum Mii_Duplex_Mode { + HALFDUPLEX = 1, + FULLDUPLEX = 2, +}; +enum Mii_Link_Speed { + SPEED10 = 1, + SPEED100 = 2, + SPEED1000 = 3, +}; + +enum Mii_Loop_Back { + NOLOOPBACK = 0, + LOOPBACK = 1, +}; + + + +/********************************************************** + * GMAC registers Map + * For Pci based system address is BARx + GmacRegisterBase + * For any other system translation is done accordingly + **********************************************************/ +enum GmacRegisters { + GmacConfig = 0x0000, /* Mac config Register */ + GmacFrameFilter = 0x0004, /* Mac frame filtering controls */ + GmacHashHigh = 0x0008, /* Multi-cast hash table high */ + GmacHashLow = 0x000C, /* Multi-cast hash table low */ + GmacGmiiAddr = 0x0010, /* GMII address Register(ext. Phy) */ + GmacGmiiData = 0x0014, /* GMII data Register(ext. Phy) */ + GmacFlowControl = 0x0018, /* Flow control Register */ + GmacVlan = 0x001C, /* VLAN tag Register (IEEE 802.1Q) */ + + GmacVersion = 0x0020, /* GMAC Core Version Register */ + GmacDebug = 0x0024, /* GMAC Debug Register */ + GmacWakeupAddr = 0x0028, /* GMAC wake-up frame filter adrress reg */ + GmacPmtCtrlStatus = 0x002C, /* PMT control and status register */ + + + GmacLPICtrlSts = 0x0030, /* LPI (low power idle) Control and Status Register */ + GmacLPITimerCtrl = 0x0034, /* LPI timer control register */ + + + GmacInterruptStatus = 0x0038, /* Mac Interrupt ststus register */ + GmacInterruptMask = 0x003C, /* Mac Interrupt Mask register */ + + GmacAddr0High = 0x0040, /* Mac address0 high Register */ + GmacAddr0Low = 0x0044, /* Mac address0 low Register */ + GmacAddr1High = 0x0048, /* Mac address1 high Register */ + GmacAddr1Low = 0x004C, /* Mac address1 low Register */ + GmacAddr2High = 0x0050, /* Mac address2 high Register */ + GmacAddr2Low = 0x0054, /* Mac address2 low Register */ + GmacAddr3High = 0x0058, /* Mac address3 high Register */ + GmacAddr3Low = 0x005C, /* Mac address3 low Register */ + GmacAddr4High = 0x0060, /* Mac address4 high Register */ + GmacAddr4Low = 0x0064, /* Mac address4 low Register */ + GmacAddr5High = 0x0068, /* Mac address5 high Register */ + GmacAddr5Low = 0x006C, /* Mac address5 low Register */ + GmacAddr6High = 0x0070, /* Mac address6 high Register */ + GmacAddr6Low = 0x0074, /* Mac address6 low Register */ + GmacAddr7High = 0x0078, /* Mac address7 high Register */ + GmacAddr7Low = 0x007C, /* Mac address7 low Register */ + GmacAddr8High = 0x0080, /* Mac address8 high Register */ + GmacAddr8Low = 0x0084, /* Mac address8 low Register */ + GmacAddr9High = 0x0088, /* Mac address9 high Register */ + GmacAddr9Low = 0x008C, /* Mac address9 low Register */ + GmacAddr10High = 0x0090, /* Mac address10 high Register */ + GmacAddr10Low = 0x0094, /* Mac address10 low Register */ + GmacAddr11High = 0x0098, /* Mac address11 high Register */ + GmacAddr11Low = 0x009C, /* Mac address11 low Register */ + GmacAddr12High = 0x00A0, /* Mac address12 high Register */ + GmacAddr12Low = 0x00A4, /* Mac address12 low Register */ + GmacAddr13High = 0x00A8, /* Mac address13 high Register */ + GmacAddr13Low = 0x00AC, /* Mac address13 low Register */ + GmacAddr14High = 0x00B0, /* Mac address14 high Register */ + GmacAddr14Low = 0x00B4, /* Mac address14 low Register */ + GmacAddr15High = 0x00B8, /* Mac address15 high Register */ + GmacAddr15Low = 0x00BC, /* Mac address15 low Register */ + GmacRgmiiCtrlSts = 0x00D8, /*SGMII_RGMII_SMII_Control_Status Register */ + GmacVLANIncRep = 0x0584, + /*Time Stamp Register Map*/ + GmacTSControl = 0x0700, /* Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ + + GmacTSSubSecIncr = 0x0704, /* 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHigh = 0x0708, /* 32 bit seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLow = 0x070C, /* 32 bit nano seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighUpdate = 0x0710, /* 32 bit seconds(MS) to be written/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSLowUpdate = 0x0714, /* 32 bit nano seconds(MS) to be writeen/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSAddend = 0x0718, /* Used by Software to readjust the clock frequency linearly : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSTargetTimeHigh = 0x071C, /* 32 bit seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + GmacTSTargetTimeLow = 0x0720, /* 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ + + GmacTSHighWord = 0x0724, /* Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ + //GmacTSHighWordUpdate = 0x072C, /* Time Stamp Higher Word Update Register (Version 2 only); only lower 16 bits are valid */ + + GmacTSStatus = 0x0728, /* Time Stamp Status Register */ + GmacPPSCtrl = 0x072C, /* PPS Control Register */ + GmacPPSInt = 0x0760, /* PPS0 Interval Register */ + GmacPPSWidth = 0x0764, /* PPS0 Width Register */ +}; + +/********************************************************** + * GMAC Network interface registers + * This explains the Register's Layout + + * FES is Read only by default and is enabled only when Tx + * Config Parameter is enabled for RGMII/SGMII interface + * during CoreKit Config. + + * DM is Read only with value 1'b1 in Full duplex only Config + **********************************************************/ + +/* GmacConfig = 0x0000, Mac config Register Layout */ +enum GmacConfigReg { + /* Bit description Bits R/W Reset value */ + + GmacSrcAddrInsRpl = 0x70000000, + GmacSrcAddrIns = 0x20000000, + GmacSrcAddrRpl = 0x30000000, + GmacWatchdog = 0x00800000, + GmacWatchdogDisable = 0x00800000, /* (WD)Disable watchdog timer on Rx 23 RW */ + GmacWatchdogEnable = 0x00000000, /* Enable watchdog timer 0 */ + + GmacJabber = 0x00400000, + GmacJabberDisable = 0x00400000, /* (JD)Disable jabber timer on Tx 22 RW */ + GmacJabberEnable = 0x00000000, /* Enable jabber timer 0 */ + + GmacFrameBurst = 0x00200000, + GmacFrameBurstEnable = 0x00200000, /* (BE)Enable frame bursting during Tx 21 RW */ + GmacFrameBurstDisable = 0x00000000, /* Disable frame bursting 0 */ + + GmacJumboFrame = 0x00100000, + GmacJumboFrameEnable = 0x00100000, /* (JE)Enable jumbo frame for Tx 20 RW */ + GmacJumboFrameDisable = 0x00000000, /* Disable jumbo frame 0 */ + + GmacInterFrameGap7 = 0x000E0000, /* (IFG) Config7 - 40 bit times 19:17 RW */ + GmacInterFrameGap6 = 0x000C0000, /* (IFG) Config6 - 48 bit times */ + GmacInterFrameGap5 = 0x000A0000, /* (IFG) Config5 - 56 bit times */ + GmacInterFrameGap4 = 0x00080000, /* (IFG) Config4 - 64 bit times */ + GmacInterFrameGap3 = 0x00040000, /* (IFG) Config3 - 72 bit times */ + GmacInterFrameGap2 = 0x00020000, /* (IFG) Config2 - 80 bit times */ + GmacInterFrameGap1 = 0x00010000, /* (IFG) Config1 - 88 bit times */ + GmacInterFrameGap0 = 0x00000000, /* (IFG) Config0 - 96 bit times 000 */ + + GmacDisableCrs = 0x00010000, + GmacMiiGmii = 0x00008000, + GmacSelectMii = 0x00008000, /* (PS)Port Select-MII mode 15 RW */ + GmacSelectGmii = 0x00000000, /* GMII mode 0 */ + + GmacFESpeed100 = 0x00004000, /*(FES)Fast Ethernet speed 100Mbps 14 RW */ + GmacFESpeed10 = 0x00000000, /* 10Mbps 0 */ + + GmacRxOwn = 0x00002000, + GmacDisableRxOwn = 0x00002000, /* (DO)Disable receive own packets 13 RW */ + GmacEnableRxOwn = 0x00000000, /* Enable receive own packets 0 */ + + GmacLoopback = 0x00001000, + GmacLoopbackOn = 0x00001000, /* (LM)Loopback mode for GMII/MII 12 RW */ + GmacLoopbackOff = 0x00000000, /* Normal mode 0 */ + + GmacDuplex = 0x00000800, + GmacFullDuplex = 0x00000800, /* (DM)Full duplex mode 11 RW */ + GmacHalfDuplex = 0x00000000, /* Half duplex mode 0 */ + + GmacRxIpcOffload = 0x00000400, /*IPC checksum offload 10 RW 0 */ + + GmacRetry = 0x00000200, + GmacRetryDisable = 0x00000200, /* (DR)Disable Retry 9 RW */ + GmacRetryEnable = 0x00000000, /* Enable retransmission as per BL 0 */ + + GmacLinkUp = 0x00000100, /* (LUD)Link UP 8 RW */ + GmacLinkDown = 0x00000100, /* Link Down 0 */ + + GmacPadCrcStrip = 0x00000080, + GmacPadCrcStripEnable = 0x00000080, /* (ACS) Automatic Pad/Crc strip enable 7 RW */ + GmacPadCrcStripDisable = 0x00000000, /* Automatic Pad/Crc stripping disable 0 */ + + GmacBackoffLimit = 0x00000060, + GmacBackoffLimit3 = 0x00000060, /* (BL)Back-off limit in HD mode 6:5 RW */ + GmacBackoffLimit2 = 0x00000040, /* */ + GmacBackoffLimit1 = 0x00000020, /* */ + GmacBackoffLimit0 = 0x00000000, /* 00 */ + + GmacDeferralCheck = 0x00000010, + GmacDeferralCheckEnable = 0x00000010, /* (DC)Deferral check enable in HD mode 4 RW */ + GmacDeferralCheckDisable = 0x00000000, /* Deferral check disable 0 */ + + GmacTx = 0x00000008, + GmacTxEnable = 0x00000008, /* (TE)Transmitter enable 3 RW */ + GmacTxDisable = 0x00000000, /* Transmitter disable 0 */ + + GmacRx = 0x00000004, + GmacRxEnable = 0x00000004, /* (RE)Receiver enable 2 RW */ + GmacRxDisable = 0x00000000, /* Receiver disable 0 */ +}; + +/* GmacFrameFilter = 0x0004, Mac frame filtering controls Register Layout*/ +enum GmacFrameFilterReg { + GmacFilter = 0x80000000, + GmacFilterOff = 0x80000000, /* (RA)Receive all incoming packets 31 RW */ + GmacFilterOn = 0x00000000, /* Receive filtered packets only 0 */ + GmacVlanTagFilter = 0x00010000, /*VLAN tag filter enable 16 RW 0 */ + GmacHashPerfectFilter = 0x00000400, /*Hash or Perfect Filter enable 10 RW 0 */ + + GmacSrcAddrFilter = 0x00000200, + GmacSrcAddrFilterEnable = 0x00000200, /* (SAF)Source Address Filter enable 9 RW */ + GmacSrcAddrFilterDisable = 0x00000000, /* 0 */ + + GmacSrcInvaAddrFilter = 0x00000100, + GmacSrcInvAddrFilterEn = 0x00000100, /* (SAIF)Inv Src Addr Filter enable 8 RW */ + GmacSrcInvAddrFilterDis = 0x00000000, /* 0 */ + + GmacPassControl = 0x000000C0, + GmacPassControl3 = 0x000000C0, /* (PCS)Forwards ctrl frms that pass AF 7:6 RW */ + GmacPassControl2 = 0x00000080, /* Forwards all control frames */ + GmacPassControl1 = 0x00000040, /* Does not pass control frames */ + GmacPassControl0 = 0x00000000, /* Does not pass control frames 00 */ + + GmacBroadcast = 0x00000020, + GmacBroadcastDisable = 0x00000020, /* (DBF)Disable Rx of broadcast frames 5 RW */ + GmacBroadcastEnable = 0x00000000, /* Enable broadcast frames 0 */ + + GmacMulticastFilter = 0x00000010, + GmacMulticastFilterOff = 0x00000010, /* (PM) Pass all multicast packets 4 RW */ + GmacMulticastFilterOn = 0x00000000, /* Pass filtered multicast packets 0 */ + + GmacDestAddrFilter = 0x00000008, + GmacDestAddrFilterInv = 0x00000008, /* (DAIF)Inverse filtering for DA 3 RW */ + GmacDestAddrFilterNor = 0x00000000, /* Normal filtering for DA 0 */ + + GmacMcastHashFilter = 0x00000004, + GmacMcastHashFilterOn = 0x00000004, /* (HMC)perfom multicast hash filtering 2 RW */ + GmacMcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacUcastHashFilter = 0x00000002, + GmacUcastHashFilterOn = 0x00000002, /* (HUC)Unicast Hash filtering only 1 RW */ + GmacUcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */ + + GmacPromiscuousMode = 0x00000001, + GmacPromiscuousModeOn = 0x00000001, /* Receive all frames 0 RW */ + GmacPromiscuousModeOff = 0x00000000, /* Receive filtered packets only 0 */ +}; + + +/*GmacGmiiAddr = 0x0010, GMII address Register(ext. Phy) Layout */ +enum GmacGmiiAddrReg { + GmiiDevMask = 0x0000F800, /* (PA)GMII device address 15:11 RW 0x00 */ + GmiiDevShift = 11, + + GmiiRegMask = 0x000007C0, /* (GR)GMII register in selected Phy 10:6 RW 0x00 */ + GmiiRegShift = 6, + + GmiiCsrClkMask = 0x0000001C, /*CSR Clock bit Mask 4:2 */ + GmiiCsrClk5 = 0x00000014, /* (CR)CSR Clock Range 250-300 MHz 4:2 RW 000 */ + GmiiCsrClk4 = 0x00000010, /* 150-250 MHz */ + GmiiCsrClk3 = 0x0000000C, /* 35-60 MHz */ + GmiiCsrClk2 = 0x00000008, /* 20-35 MHz */ + GmiiCsrClk1 = 0x00000004, /* 100-150 MHz */ + GmiiCsrClk0 = 0x00000000, /* 60-100 MHz */ + + GmiiWrite = 0x00000002, /* (GW)Write to register 1 RW */ + GmiiRead = 0x00000000, /* Read from register 0 */ + + GmiiBusy = 0x00000001, /* (GB)GMII interface is busy 0 RW 0 */ +}; + +enum GmacVlanTagReg { + GmacEnableSVlan = 0x00040000, /* (ESVL) Enabe S-Vlan */ + GmacVlanInvMatch = 0x00020000, /* (VTIM) VLAN tag inverse match enable */ + GmacEnable12BitComp = 0x00010000, /* (ETV) Enable 12-bit VLAN tag comparision */ + GmacVlanTagMsk = 0x0000FFFF /* (VL) VLAN tag */ + +}; + + +enum GmacLPICtrlStsReg { + GmacLPITxAuto = 0x00080000, + GmacLPIPhyStsEn = 0x00040000, + GmacLPIPhySts = 0x00020000, + GmacLPIEn = 0x00010000, + GmacRxLPISts = 0x00000200, + GmacTxLPISts = 0x00000100, + GmacRxLPIExit = 0x00000008, + GmacRxLPIEnter = 0x00000004, + GmacTxLPIExit = 0x00000002, + GmacTxLPIEnter = 0x00000001, +}; + +enum GmacLPITimerCtrlReg { + GmacLPILinkStableTimerMsk = 0x03FF0000, + GmacLPITxWaitTimerMsk = 0x0000FFFF, +}; + + +/* GmacGmiiData = 0x0014, GMII data Register(ext. Phy) Layout */ +enum GmacGmiiDataReg { + GmiiDataMask = 0x0000FFFF, /* (GD)GMII Data 15:0 RW 0x0000 */ +}; + + +/*GmacFlowControl = 0x0018, Flow control Register Layout */ +enum GmacFlowControlReg { + GmacPauseTimeMask = 0xFFFF0000, /* (PT) PAUSE TIME field in the control frame 31:16 RW 0x0000 */ + GmacPauseTimeShift = 16, + + GmacPauseLowThresh = 0x00000030, + GmacPauseLowThresh3 = 0x00000030, /* (PLT)thresh for pause tmr 256 slot time 5:4 RW */ + GmacPauseLowThresh2 = 0x00000020, /* 144 slot time */ + GmacPauseLowThresh1 = 0x00000010, /* 28 slot time */ + GmacPauseLowThresh0 = 0x00000000, /* 4 slot time 000 */ + + GmacUnicastPauseFrame = 0x00000008, + GmacUnicastPauseFrameOn = 0x00000008, /* (UP)Detect pause frame with unicast addr. 3 RW */ + GmacUnicastPauseFrameOff = 0x00000000, /* Detect only pause frame with multicast addr. 0 */ + + GmacRxFlowControl = 0x00000004, + GmacRxFlowControlEnable = 0x00000004, /* (RFE)Enable Rx flow control 2 RW */ + GmacRxFlowControlDisable = 0x00000000, /* Disable Rx flow control 0 */ + + GmacTxFlowControl = 0x00000002, + GmacTxFlowControlEnable = 0x00000002, /* (TFE)Enable Tx flow control 1 RW */ + GmacTxFlowControlDisable = 0x00000000, /* Disable flow control 0 */ + + GmacFlowControlBackPressure= 0x00000001, + GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */ +}; + + +enum GmacVLANIncRepReg { + GmacSVLAN = 0x00080000, + GmacCVLAN = 0x00000000, + GmacVLP = 0x00040000, + GmacVLANNoACT = 0x00000000, + GmacVLANDel = 0x00010000, + GmacVLANIns = 0x00020000, + GmacVLANRep = 0x00030000, + GmacVLANMsk = 0x0000FFFF + +}; + +/* GmacInterruptStatus = 0x0038, Mac Interrupt ststus register */ +enum GmacInterruptStatusBitDefinition { + GmacLPIIntSts = 0x00000400, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/ + GmacTSIntSts = 0x00000200, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/ + GmacMmcRxChksumOffload = 0x00000080, /* set if int generated in MMC RX CHECKSUM OFFLOAD int register */ + GmacMmcTxIntSts = 0x00000040, /* set if int generated in MMC TX Int register */ + GmacMmcRxIntSts = 0x00000020, /* set if int generated in MMC RX Int register */ + GmacMmcIntSts = 0x00000010, /* set if any of the above bit [7:5] is set */ + GmacPmtIntSts = 0x00000008, /* set whenver magic pkt/wake-on-lan frame is received */ + GmacPcsAnComplete = 0x00000004, /* set when AN is complete in TBI/RTBI/SGMIII phy interface */ + GmacPcsLnkStsChange = 0x00000002, /* set if any lnk status change in TBI/RTBI/SGMII interface */ + GmacRgmiiIntSts = 0x00000001, /* set if any change in lnk status of RGMII interface */ + +}; + +/* GmacInterruptMask = 0x003C, Mac Interrupt Mask register */ +enum GmacInterruptMaskBitDefinition { + GmacTSIntMask = 0x00000200, /* when set disables the time stamp interrupt generation */ + GmacPmtIntMask = 0x00000008, /* when set Disables the assertion of PMT interrupt */ + GmacPcsAnIntMask = 0x00000004, /* When set disables the assertion of PCS AN complete interrupt */ + GmacPcsLnkStsIntMask = 0x00000002, /* when set disables the assertion of PCS lnk status change interrupt */ + GmacRgmiiIntMask = 0x00000001, /* when set disables the assertion of RGMII int */ +}; + +/********************************************************** + * GMAC DMA registers + * For Pci based system address is BARx + GmaDmaBase + * For any other system translation is done accordingly + **********************************************************/ + +enum DmaRegisters { + DmaBusMode = 0x0000, /* CSR0 - Bus Mode Register */ + DmaTxPollDemand = 0x0004, /* CSR1 - Transmit Poll Demand Register */ + DmaRxPollDemand = 0x0008, /* CSR2 - Receive Poll Demand Register */ + DmaRxBaseAddr = 0x000C, /* CSR3 - Receive Descriptor list base address */ + DmaTxBaseAddr = 0x0010, /* CSR4 - Transmit Descriptor list base address */ + DmaStatus = 0x0014, /* CSR5 - Dma status Register */ + DmaControl = 0x0018, /* CSR6 - Dma Operation Mode Register */ + DmaInterrupt = 0x001C, /* CSR7 - Interrupt enable */ + DmaMissedFr = 0x0020, /* CSR8 - Missed Frame & Buffer overflow Counter */ + DmaTxCurrDesc = 0x0048, /* - Current host Tx Desc Register */ + DmaRxCurrDesc = 0x004C, /* - Current host Rx Desc Register */ + DmaTxCurrAddr = 0x0050, /* CSR20 - Current host transmit buffer address */ + DmaRxCurrAddr = 0x0054, /* CSR21 - Current host receive buffer address */ + + +}; + +/********************************************************** + * DMA Engine registers Layout + **********************************************************/ + +/*DmaBusMode = 0x0000, CSR0 - Bus Mode */ +enum DmaBusModeReg { + /* Bit description Bits R/W Reset value */ + + DmaFixedBurstEnable = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, INCR8 or INCR16 16 RW */ + DmaFixedBurstDisable = 0x00000000, /* SINGLE, INCR 0 */ + + DmaTxPriorityRatio11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 15:14 RW 00 */ + DmaTxPriorityRatio21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */ + DmaTxPriorityRatio31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */ + DmaTxPriorityRatio41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */ + + DmaBurstLengthx8 = 0x01000000, /* When set mutiplies the PBL by 8 24 RW 0 */ + + DmaBurstLength256 = 0x01002000, /*(DmaBurstLengthx8 | DmaBurstLength32) = 256 [24]:13:8 */ + DmaBurstLength128 = 0x01001000, /*(DmaBurstLengthx8 | DmaBurstLength16) = 128 [24]:13:8 */ + DmaBurstLength64 = 0x01000800, /*(DmaBurstLengthx8 | DmaBurstLength8) = 64 [24]:13:8 */ + DmaBurstLength32 = 0x00002000, /* (PBL) programmable Dma burst length = 32 13:8 RW */ + DmaBurstLength16 = 0x00001000, /* Dma burst length = 16 */ + DmaBurstLength8 = 0x00000800, /* Dma burst length = 8 */ + DmaBurstLength4 = 0x00000400, /* Dma burst length = 4 */ + DmaBurstLength2 = 0x00000200, /* Dma burst length = 2 */ + DmaBurstLength1 = 0x00000100, /* Dma burst length = 1 */ + DmaBurstLength0 = 0x00000000, /* Dma burst length = 0 0x00 */ + + DmaDescriptor8Words = 0x00000080, /* Enh Descriptor works 1=> 8 word descriptor 7 0 */ + DmaDescriptor4Words = 0x00000000, /* Enh Descriptor works 0=> 4 word descriptor 7 0 */ + + DmaDescriptorSkip16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) 6:2 RW */ + DmaDescriptorSkip8 = 0x00000020, /* between two unchained descriptors */ + DmaDescriptorSkip4 = 0x00000010, /* */ + DmaDescriptorSkip2 = 0x00000008, /* */ + DmaDescriptorSkip1 = 0x00000004, /* */ + DmaDescriptorSkip0 = 0x00000000, /* 0x00 */ + + DmaArbitRr = 0x00000000, /* (DA) DMA RR arbitration 1 RW 0 */ + DmaArbitPr = 0x00000002, /* Rx has priority over Tx */ + + DmaResetOn = 0x00000001, /* (SWR)Software Reset DMA engine 0 RW */ + DmaResetOff = 0x00000000, /* 0 */ +}; + + +/*DmaStatus = 0x0014, CSR5 - Dma status Register */ +enum DmaStatusReg { + /*Bit 28 27 and 26 indicate whether the interrupt due to PMT GMACMMC or GMAC LINE Remaining bits are DMA interrupts*/ + + + GmacLPIIntr = 0x40000000, /* GMC LPI interrupt 31 RO 0 */ + + + GmacPmtIntr = 0x10000000, /* (GPI)Gmac subsystem interrupt 28 RO 0 */ + GmacMmcIntr = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt 27 RO 0 */ + GmacLineIntfIntr = 0x04000000, /* Line interface interrupt 26 RO 0 */ + + DmaErrorBit2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc. access 25 RO 0 */ + DmaErrorBit1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfr 24 RO 0 */ + DmaErrorBit0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA 23 RO 0 */ + + DmaTxState = 0x00700000, /* (TS)Transmit process state 22:20 RO */ + DmaTxStopped = 0x00000000, /* Stopped - Reset or Stop Tx Command issued 000 */ + DmaTxFetching = 0x00100000, /* Running - fetching the Tx descriptor */ + DmaTxWaiting = 0x00200000, /* Running - waiting for status */ + DmaTxReading = 0x00300000, /* Running - reading the data from host memory */ + DmaTxSuspended = 0x00600000, /* Suspended - Tx Descriptor unavailabe */ + DmaTxClosing = 0x00700000, /* Running - closing Rx descriptor */ + + DmaRxState = 0x000E0000, /* (RS)Receive process state 19:17 RO */ + DmaRxStopped = 0x00000000, /* Stopped - Reset or Stop Rx Command issued 000 */ + DmaRxFetching = 0x00020000, /* Running - fetching the Rx descriptor */ + DmaRxWaiting = 0x00060000, /* Running - waiting for packet */ + DmaRxSuspended = 0x00080000, /* Suspended - Rx Descriptor unavailable */ + DmaRxClosing = 0x000A0000, /* Running - closing descriptor */ + DmaRxQueuing = 0x000E0000, /* Running - queuing the recieve frame into host memory */ + + DmaIntNormal = 0x00010000, /* (NIS)Normal interrupt summary 16 RW 0 */ + DmaIntAbnormal = 0x00008000, /* (AIS)Abnormal interrupt summary 15 RW 0 */ + + DmaIntEarlyRx = 0x00004000, /* Early receive interrupt (Normal) RW 0 */ + DmaIntBusError = 0x00002000, /* Fatal bus error (Abnormal) RW 0 */ + DmaIntEarlyTx = 0x00000400, /* Early transmit interrupt (Abnormal) RW 0 */ + DmaIntRxWdogTO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) RW 0 */ + DmaIntRxStopped = 0x00000100, /* Receive process stopped (Abnormal) RW 0 */ + DmaIntRxNoBuffer = 0x00000080, /* Receive buffer unavailable (Abnormal) RW 0 */ + DmaIntRxCompleted = 0x00000040, /* Completion of frame reception (Normal) RW 0 */ + DmaIntTxUnderflow = 0x00000020, /* Transmit underflow (Abnormal) RW 0 */ + DmaIntRcvOverflow = 0x00000010, /* Receive Buffer overflow interrupt RW 0 */ + DmaIntTxJabberTO = 0x00000008, /* Transmit Jabber Timeout (Abnormal) RW 0 */ + DmaIntTxNoBuffer = 0x00000004, /* Transmit buffer unavailable (Normal) RW 0 */ + DmaIntTxStopped = 0x00000002, /* Transmit process stopped (Abnormal) RW 0 */ + DmaIntTxCompleted = 0x00000001, /* Transmit completed (Normal) RW 0 */ +}; + +/*DmaControl = 0x0018, CSR6 - Dma Operation Mode Register */ +enum DmaControlReg { + DmaDisableDropTcpCs = 0x04000000, /* (DT) Dis. drop. of tcp/ip CS error frames 26 RW 0 */ + + DmaStoreAndForward = 0x00200000, /* (SF)Store and forward 21 RW 0 */ + DmaFlushTxFifo = 0x00100000, /* (FTF)Tx FIFO controller is reset to default 20 RW 0 */ + + DmaTxThreshCtrl = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16:14 RW */ + DmaTxThreshCtrl16 = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16 16:14 RW */ + DmaTxThreshCtrl24 = 0x00018000, /* (TTC)Controls thre Threh of MTL tx Fifo 24 16:14 RW */ + DmaTxThreshCtrl32 = 0x00014000, /* (TTC)Controls thre Threh of MTL tx Fifo 32 16:14 RW */ + DmaTxThreshCtrl40 = 0x00010000, /* (TTC)Controls thre Threh of MTL tx Fifo 40 16:14 RW */ + DmaTxThreshCtrl256 = 0x0000c000, /* (TTC)Controls thre Threh of MTL tx Fifo 256 16:14 RW */ + DmaTxThreshCtrl192 = 0x00008000, /* (TTC)Controls thre Threh of MTL tx Fifo 192 16:14 RW */ + DmaTxThreshCtrl128 = 0x00004000, /* (TTC)Controls thre Threh of MTL tx Fifo 128 16:14 RW */ + DmaTxThreshCtrl64 = 0x00000000, /* (TTC)Controls thre Threh of MTL tx Fifo 64 16:14 RW 000 */ + + DmaTxStart = 0x00002000, /* (ST)Start/Stop transmission 13 RW 0 */ + + DmaRxFlowCtrlDeact = 0x00401800, /* (RFD)Rx flow control deact. threhold [22]:12:11 RW */ + DmaRxFlowCtrlDeact1K = 0x00000000, /* (RFD)Rx flow control deact. threhold (1kbytes) [22]:12:11 RW 00 */ + DmaRxFlowCtrlDeact2K = 0x00000800, /* (RFD)Rx flow control deact. threhold (2kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact3K = 0x00001000, /* (RFD)Rx flow control deact. threhold (3kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact4K = 0x00001800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact5K = 0x00400000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact6K = 0x00400800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + DmaRxFlowCtrlDeact7K = 0x00401000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */ + + DmaRxFlowCtrlAct = 0x00800600, /* (RFA)Rx flow control Act. threhold [23]:10:09 RW */ + DmaRxFlowCtrlAct1K = 0x00000000, /* (RFA)Rx flow control Act. threhold (1kbytes) [23]:10:09 RW 00 */ + DmaRxFlowCtrlAct2K = 0x00000200, /* (RFA)Rx flow control Act. threhold (2kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct3K = 0x00000400, /* (RFA)Rx flow control Act. threhold (3kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct4K = 0x00000300, /* (RFA)Rx flow control Act. threhold (4kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct5K = 0x00800000, /* (RFA)Rx flow control Act. threhold (5kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct6K = 0x00800200, /* (RFA)Rx flow control Act. threhold (6kbytes) [23]:10:09 RW */ + DmaRxFlowCtrlAct7K = 0x00800400, /* (RFA)Rx flow control Act. threhold (7kbytes) [23]:10:09 RW */ + + DmaRxThreshCtrl = 0x00000018, /* (RTC)Controls thre Threh of MTL rx Fifo 4:3 RW */ + DmaRxThreshCtrl64 = 0x00000000, /* (RTC)Controls thre Threh of MTL tx Fifo 64 4:3 RW */ + DmaRxThreshCtrl32 = 0x00000008, /* (RTC)Controls thre Threh of MTL tx Fifo 32 4:3 RW */ + DmaRxThreshCtrl96 = 0x00000010, /* (RTC)Controls thre Threh of MTL tx Fifo 96 4:3 RW */ + DmaRxThreshCtrl128 = 0x00000018, /* (RTC)Controls thre Threh of MTL tx Fifo 128 4:3 RW */ + + DmaEnHwFlowCtrl = 0x00000100, /* (EFC)Enable HW flow control 8 RW */ + DmaDisHwFlowCtrl = 0x00000000, /* Disable HW flow control 0 */ + + DmaFwdErrorFrames = 0x00000080, /* (FEF)Forward error frames 7 RW 0 */ + DmaFwdUnderSzFrames = 0x00000040, /* (FUF)Forward undersize frames 6 RW 0 */ + DmaTxSecondFrame = 0x00000004, /* (OSF)Operate on second frame 4 RW 0 */ + DmaRxStart = 0x00000002, /* (SR)Start/Stop reception 1 RW 0 */ +}; + + +/*DmaInterrupt = 0x001C, CSR7 - Interrupt enable Register Layout */ +enum DmaInterruptReg { + DmaIeNormal = DmaIntNormal , /* Normal interrupt enable RW 0 */ + DmaIeAbnormal = DmaIntAbnormal , /* Abnormal interrupt enable RW 0 */ + + DmaIeEarlyRx = DmaIntEarlyRx , /* Early receive interrupt enable RW 0 */ + DmaIeBusError = DmaIntBusError , /* Fatal bus error enable RW 0 */ + DmaIeEarlyTx = DmaIntEarlyTx , /* Early transmit interrupt enable RW 0 */ + DmaIeRxWdogTO = DmaIntRxWdogTO , /* Receive Watchdog Timeout enable RW 0 */ + DmaIeRxStopped = DmaIntRxStopped , /* Receive process stopped enable RW 0 */ + DmaIeRxNoBuffer = DmaIntRxNoBuffer , /* Receive buffer unavailable enable RW 0 */ + DmaIeRxCompleted = DmaIntRxCompleted, /* Completion of frame reception enable RW 0 */ + DmaIeTxUnderflow = DmaIntTxUnderflow, /* Transmit underflow enable RW 0 */ + + DmaIeRxOverflow = DmaIntRcvOverflow, /* Receive Buffer overflow interrupt RW 0 */ + DmaIeTxJabberTO = DmaIntTxJabberTO , /* Transmit Jabber Timeout enable RW 0 */ + DmaIeTxNoBuffer = DmaIntTxNoBuffer , /* Transmit buffer unavailable enable RW 0 */ + DmaIeTxStopped = DmaIntTxStopped , /* Transmit process stopped enable RW 0 */ + DmaIeTxCompleted = DmaIntTxCompleted, /* Transmit completed enable RW 0 */ +}; + + +/********************************************************** + * DMA Engine descriptors + **********************************************************/ + +/* +**********Enhanced Descritpor structure to support 8K buffer per buffer **************************** + +DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address +DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + +Similarly +DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address +DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a +32 bit Data bus is as shown below + -------------------------------------------------------------------------- + RDES0 |OWN (31)| Status | + -------------------------------------------------------------------------- + RDES1 | Ctrl | Res | Byte Count Buffer 2 | Ctrl | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + RDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + RDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + + -------------------------------------------------------------------------- + TDES0 |OWN (31)| Ctrl | Res | Ctrl | Res | Status | + -------------------------------------------------------------------------- + TDES1 | Res | Byte Count Buffer 2 | Res | Byte Count Buffer 1 | + -------------------------------------------------------------------------- + TDES2 | Buffer 1 Address | + -------------------------------------------------------------------------- + TDES3 | Buffer 2 Address / Next Descriptor Address | + -------------------------------------------------------------------------- + +*/ + +enum DmaDescriptorStatus /* status word of DMA descriptor */ +{ + + DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */ + + DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */ + + DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */ + DescFrameLengthShift = 16, + + DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */ + /* DE || OE || IPC || LC || RWT || RE || CE */ + DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */ + DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */ + DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */ + DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */ + DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */ + DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */ + DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */ + DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */ + DescRxTSAvailable = 0x00000080, /* Share bit with (Giant Frame)Rx 7 */ + DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */ + DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */ + DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */ + DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */ + DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */ +// DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */ + + DescRxEXTsts = 0x00000001, /* Extended Status Available (RDES4) 0 */ + + DescTxIntEnable = 0x40000000, /* (IC)Tx - interrupt on completion 30 */ + DescTxLast = 0x20000000, /* (LS)Tx - Last segment of the frame 29 */ + DescTxFirst = 0x10000000, /* (FS)Tx - First segment of the frame 28 */ + DescTxDisableCrc = 0x08000000, /* (DC)Tx - Add CRC disabled (first segment only) 27 */ + DescTxDisablePadd = 0x04000000, /* (DP)disable padding, added by - reyaz 26 */ + DescTxTSEnable = 0x02000000, /* (TTSE) Transmit Timestamp Enable 25 */ + DescTxCrcReplacement = 0x01000000, /* (CRCR) CRC Replacement Control 24 */ + DescTxCisMask = 0x00c00000, /* Tx checksum offloading control mask 23:22 */ + DescTxCisBypass = 0x00000000, /* Checksum bypass */ + DescTxCisIpv4HdrCs = 0x00400000, /* IPv4 header checksum */ + DescTxCisTcpOnlyCs = 0x00800000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */ + DescTxCisTcpPseudoCs = 0x00c00000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */ + + TxDescEndOfRing = 0x00200000, /* (TER)End of descriptors ring 21 */ + TxDescChain = 0x00100000, /* (TCH)Second buffer address is chain address 20 */ + + DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */ + DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */ + DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + + DescRxTSavail = 0x00000080, /* Time stamp available 7 */ + DescRxFrameType = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */ + DescTxTSStatus = 0x00020000, /* (TTSS) Transmit Timestamp Status 17 */ + DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */ + DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */ + DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */ + DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */ + DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */ + DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */ + DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */ + DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */ + DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */ + + DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */ + DescTxCollShift = 3, + + DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */ + DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */ + DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */ + + /* + This explains the RDES1/TDES1 bits layout + -------------------------------------------------------------------- + RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 | + -------------------------------------------------------------------- + + */ +// DmaDescriptorLength length word of DMA descriptor + + + RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */ + RxDescEndOfRing = 0x00008000, /* (TER)End of descriptors ring 15 */ + RxDescChain = 0x00004000, /* (TCH)Second buffer address is chain address 14 */ + + + DescSize2Mask = 0x1FFF0000, /* (TBS2) Buffer 2 size 28:16 */ + DescSize2Shift = 16, + DescSize1Mask = 0x00001FFF, /* (TBS1) Buffer 1 size 12:0 */ + DescSize1Shift = 0, + + + /* + This explains the RDES4 Extended Status bits layout + -------------------------------------------------------------------- + RDES4 | Extended Status | + -------------------------------------------------------------------- + */ + + DescRxPtpAvail = 0x00004000, /* PTP snapshot available 14 */ + DescRxPtpVer = 0x00002000, /* When set indicates IEEE1584 Version 2 (else Ver1) 13 */ + DescRxPtpFrameType = 0x00001000, /* PTP frame type Indicates PTP sent over ethernet 12 */ + DescRxPtpMessageType = 0x00000F00, /* Message Type 11:8 */ + DescRxPtpNo = 0x00000000, /* 0000 => No PTP message received */ + DescRxPtpSync = 0x00000100, /* 0001 => Sync (all clock types) received */ + DescRxPtpFollowUp = 0x00000200, /* 0010 => Follow_Up (all clock types) received */ + DescRxPtpDelayReq = 0x00000300, /* 0011 => Delay_Req (all clock types) received */ + DescRxPtpDelayResp = 0x00000400, /* 0100 => Delay_Resp (all clock types) received */ + DescRxPtpPdelayReq = 0x00000500, /* 0101 => Pdelay_Req (in P to P tras clk) or Announce in Ord and Bound clk */ + DescRxPtpPdelayResp = 0x00000600, /* 0110 => Pdealy_Resp(in P to P trans clk) or Management in Ord and Bound clk */ + DescRxPtpPdelayRespFP = 0x00000700, /* 0111 => Pdealy_Resp_Follow_Up (in P to P trans clk) or Signaling in Ord and Bound clk */ + DescRxPtpIPV6 = 0x00000080, /* Received Packet is in IPV6 Packet 7 */ + DescRxPtpIPV4 = 0x00000040, /* Received Packet is in IPV4 Packet 6 */ + + DescRxChkSumBypass = 0x00000020, /* When set indicates checksum offload engine 5 + is bypassed */ + DescRxIpPayloadError = 0x00000010, /* When set indicates 16bit IP payload CS is in error 4 */ + DescRxIpHeaderError = 0x00000008, /* When set indicates 16bit IPV4 header CS is in 3 + error or IP datagram version is not consistent + with Ethernet type value */ + DescRxIpPayloadType = 0x00000007, /* Indicate the type of payload encapsulated 2:0 + in IPdatagram processed by COE (Rx) */ + DescRxIpPayloadUnknown= 0x00000000, /* Unknown or didnot process IP payload */ + DescRxIpPayloadUDP = 0x00000001, /* UDP */ + DescRxIpPayloadTCP = 0x00000002, /* TCP */ + DescRxIpPayloadICMP = 0x00000003, /* ICMP */ + +}; + + +// Rx Descriptor COE type2 encoding +enum RxDescCOEEncode { + RxLenLT600 = 0, /* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600 */ + RxIpHdrPayLoadChkBypass = 1, /* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) */ + RxIpHdrPayLoadRes = 2, /* Bit(5:7:0)=>2 Reserved */ + RxChkBypass = 3, /* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed */ + RxNoChkError = 4, /* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected */ + RxPayLoadChkError = 5, /* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames */ + RxIpHdrChkError = 6, /* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames */ + RxIpHdrPayLoadChkError = 7, /* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames */ +}; + +/********************************************************** + * DMA engine interrupt handling functions + **********************************************************/ + +enum synopGMACDmaIntEnum /* Intrerrupt types */ +{ + synopGMACDmaRxNormal = 0x01, /* normal receiver interrupt */ + synopGMACDmaRxAbnormal = 0x02, /* abnormal receiver interrupt */ + synopGMACDmaRxStopped = 0x04, /* receiver stopped */ + synopGMACDmaTxNormal = 0x08, /* normal transmitter interrupt */ + synopGMACDmaTxAbnormal = 0x10, /* abnormal transmitter interrupt */ + synopGMACDmaTxStopped = 0x20, /* transmitter stopped */ + synopGMACDmaError = 0x80, /* Dma engine error */ + +}; + + +/********************************************************** + * Initial register values + **********************************************************/ +enum InitialRegisters { + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode with perfect filter on */ + GmacConfigInitFdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacEnableRxOwn | GmacLoopbackOff + | GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Full-duplex mode */ + // CHANGED: Pass control config, dest addr filter normal, added source address filter, multicast & unicast + // Hash filter. + /* = GmacFilterOff | GmacPassControlOff | GmacBroadcastEnable */ + GmacFrameFilterInitFdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacPromiscuousModeOff | GmacUcastHashFilterOff, + + /* Full-duplex mode */ + GmacFlowControlInitFdx = GmacUnicastPauseFrameOff | GmacRxFlowControlEnable | GmacTxFlowControlEnable, + + /* Full-duplex mode */ + GmacGmiiAddrInitFdx = GmiiCsrClk2, + + + /* Half-duplex mode with perfect filter on */ + // CHANGED: Removed Endian configuration, added single bit config for PAD/CRC strip, + /*| GmacSelectMii | GmacLittleEndian | GmacDisableRxOwn | GmacLoopbackOff*/ + GmacConfigInitHdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectGmii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode with perfect filter on */ + GmacConfigInitHdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable + | GmacSelectMii | GmacDisableRxOwn | GmacLoopbackOff + | GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable + | GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable, + + /* Half-duplex mode */ + GmacFrameFilterInitHdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable + | GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff + | GmacUcastHashFilterOff| GmacPromiscuousModeOff, + + /* Half-duplex mode */ + GmacFlowControlInitHdx = GmacUnicastPauseFrameOff | GmacRxFlowControlDisable | GmacTxFlowControlDisable, + + /* Half-duplex mode */ + GmacGmiiAddrInitHdx = GmiiCsrClk2, + + + + /********************************************** + *DMA configurations + **********************************************/ + + DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip2 | DmaResetOff, +// DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip4 | DmaResetOff, + + /* 1000 Mb/s mode */ + DmaControlInit1000 = DmaStoreAndForward,// | DmaTxSecondFrame , + + /* 100 Mb/s mode */ + DmaControlInit100 = DmaStoreAndForward, + + /* 10 Mb/s mode */ + DmaControlInit10 = DmaStoreAndForward, + + /* Interrupt groups */ + DmaIntErrorMask = DmaIntBusError, /* Error */ + DmaIntRxAbnMask = DmaIntRxNoBuffer, /* receiver abnormal interrupt */ + DmaIntRxNormMask = DmaIntRxCompleted, /* receiver normal interrupt */ + DmaIntRxStoppedMask = DmaIntRxStopped, /* receiver stopped */ + DmaIntTxAbnMask = DmaIntTxUnderflow, /* transmitter abnormal interrupt */ + DmaIntTxNormMask = DmaIntTxCompleted, /* transmitter normal interrupt */ + DmaIntTxStoppedMask = DmaIntTxStopped, /* transmitter stopped */ + + DmaIntEnable = DmaIeNormal | DmaIeAbnormal | DmaIntErrorMask + | DmaIntRxAbnMask | DmaIntRxNormMask | DmaIntRxStoppedMask + | DmaIntTxAbnMask | DmaIntTxNormMask | DmaIntTxStoppedMask, + DmaIntDisable = 0, +}; + + + + +/********************************************************** + * Power Management (PMT) Block + **********************************************************/ + +/** + * PMT supports the reception of network (remote) wake-up frames and Magic packet frames. + * It generates interrupts for wake-up frames and Magic packets received by GMAC. + * PMT sits in Rx path and is enabled with remote wake-up frame enable and Magic packet enable. + * These enable are in PMT control and Status register and are programmed by apllication. + * + * When power down mode is enabled in PMT, all rx frames are dropped by the core. Core comes + * out of power down mode only when either Magic packe tor a Remote wake-up frame is received + * and the corresponding detection is enabled. + * + * Driver need not be modified to support this feature. Only Api to put the device in to power + * down mode is sufficient + */ + +#define WAKEUP_REG_LENGTH 8 /*This is the reg length for wake up register configuration*/ + +enum GmacPmtCtrlStatusBitDefinition { + GmacPmtFrmFilterPtrReset = 0x80000000, /* when set remote wake-up frame filter register pointer to 3'b000 */ + GmacPmtGlobalUnicast = 0x00000200, /* When set enables any unicast packet to be a wake-up frame */ + GmacPmtWakeupFrameReceived = 0x00000040, /* Wake up frame received */ + GmacPmtMagicPktReceived = 0x00000020, /* Magic Packet received */ + GmacPmtWakeupFrameEnable = 0x00000004, /* Wake-up frame enable */ + GmacPmtMagicPktEnable = 0x00000002, /* Magic packet enable */ + GmacPmtPowerDown = 0x00000001, /* Power Down */ +}; + + + + +/********************************************************** + * IEEE 1588-2008 Precision Time Protocol (PTP) Support + **********************************************************/ +enum PTPMessageType { + SYNC = 0x0, + Delay_Req = 0x1, + Pdelay_Req = 0x2, + Pdelay_Resp = 0x3, + Follow_up = 0x8, + Delay_Resp = 0x9, + Pdelay_Resp_Follow_Up = 0xA, + Announce = 0xB, + Signaling = 0xC, + Management = 0xD, +}; + + + +typedef struct TimeStampStruct { + u32 TSversion; /* PTP Version 1 or PTP version2 */ + u32 TSmessagetype; /* Message type associated with this time stamp */ + + u16 TShighest16; /* Highest 16 bit time stamp value, Valid onley when ADV_TIME_HIGH_WORD configured in corekit */ + u32 TSupper32; /* Most significant 32 bit time stamp value */ + u32 TSlower32; /* Least Significat 32 bit time stamp value */ + +} TimeStamp; + + +/** + * IEEE 1588-2008 is the optional module to support Ethernet frame time stamping. + * Sixty four (+16) bit time stamps are given in each frames transmit and receive status. + * The driver assumes the following + * 1. "IEEE 1588 Time Stamping" "TIME_STAMPING"is ENABLED in corekit + * 2. "IEEE 1588 External Time Stamp Input Enable" "EXT_TIME_STAMPING" is DISABLED in corekit + * 3. "IEEE 1588 Advanced Time Stamp support" "ADV_TIME_STAMPING" is ENABLED in corekit + * 4. "IEEE 1588 Higher Word Register Enable" "ADV_TIME_HIGH_WORD" is ENABLED in corekit + */ + +/* GmacTSControl = 0x0700, Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */ +enum GmacTSControlReg { + GmacTSENMACADDR = 0x00040000, /* Enable Mac Addr for PTP filtering 18 RW 0 */ + + GmacTSCLKTYPE = 0x00030000, /* Select the type of clock node 17:16 RW 00 */ + /* + TSCLKTYPE TSMSTRENA TSEVNTENA Messages for wihich TS snapshot is taken + 00/01 X 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 00/01 1 0 DELAY_REQ + 00/01 0 1 SYNC + 10 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP + 10 NA 1 SYNC, FOLLOW_UP + 11 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP, PDELAY_REQ, PDELAY_RESP + 11 NA 1 SYNC, PDELAY_REQ, PDELAY_RESP + */ + GmacTSOrdClk = 0x00000000, /* 00=> Ordinary clock*/ + GmacTSBouClk = 0x00010000, /* 01=> Boundary clock*/ + GmacTSEtoEClk = 0x00020000, /* 10=> End-to-End transparent clock*/ + GmacTSPtoPClk = 0x00030000, /* 11=> P-to-P transparent clock*/ + + GmacTSMSTRENA = 0x00008000, /* Ena TS Snapshot for Master Messages 15 RW 0 */ + GmacTSEVNTENA = 0x00004000, /* Ena TS Snapshot for Event Messages 14 RW 0 */ + GmacTSIPV4ENA = 0x00002000, /* Ena TS snapshot for IPv4 13 RW 1 */ + GmacTSIPV6ENA = 0x00001000, /* Ena TS snapshot for IPv6 12 RW 0 */ + GmacTSIPENA = 0x00000800, /* Ena TS snapshot for PTP over E'net 11 RW 0 */ + GmacTSVER2ENA = 0x00000400, /* Ena PTP snooping for version 2 10 RW 0 */ + + GmacTSCTRLSSR = 0x00000200, /* Digital or Binary Rollover 9 RW 0 */ + + GmacTSENALL = 0x00000100, /* Enable TS fro all frames (Ver2 only) 8 RW 0 */ + + GmacTSADDREG = 0x00000020, /* Addend Register Update 5 RW_SC 0 */ + GmacTSUPDT = 0x00000008, /* Time Stamp Update 3 RW_SC 0 */ + GmacTSINT = 0x00000004, /* Time Atamp Initialize 2 RW_SC 0 */ + + GmacTSTRIG = 0x00000010, /* Time stamp interrupt Trigger Enable 4 RW_SC 0 */ + + GmacTSCFUPDT = 0x00000002, /* Time Stamp Fine/Coarse 1 RW 0 */ + GmacTSCUPDTCoarse = 0x00000000, /* 0=> Time Stamp update method is coarse */ + GmacTSCUPDTFine = 0x00000002, /* 1=> Time Stamp update method is fine */ + + GmacTSENA = 0x00000001, /* Time Stamp Enable 0 RW 0 */ +}; + + +/* GmacTSSubSecIncr = 0x0704, 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSSubSecIncrReg { + GmacSSINCMsk = 0x000000FF, /* Only Lower 8 bits are valid bits 7:0 RW 00 */ +}; + +/* GmacTSLow = 0x070C, Indicates whether the timestamp low count is positive or negative; for Adv timestamp it is always zero */ +enum GmacTSSign { + GmacTSSign = 0x80000000, /* PSNT 31 RW 0 */ + GmacTSPositive = 0x00000000, + GmacTSNegative = 0x80000000, +}; + +/*GmacTargetTimeLow = 0x0718, 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */ +enum GmacTSLowReg { + GmacTSDecThr = 0x3B9AC9FF, /*when TSCTRLSSR is set the max value for GmacTargetTimeLowReg and GmacTimeStampLow register is 0x3B9AC9FF at 1ns precision */ +}; + +/* GmacTSHighWord = 0x0724, Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */ +enum GmacTSHighWordReg { + GmacTSHighWordMask = 0x0000FFFF, /* Time Stamp Higher work register has only lower 16 bits valid */ +}; +/*GmacTSStatus = 0x0728, Time Stamp Status Register */ +enum GmacTSStatusReg { + GmacTSTargTimeReached = 0x00000002, /* Time Stamp Target Time Reached 1 RO 0 */ + GmacTSSecondsOverflow = 0x00000001, /* Time Stamp Seconds Overflow 0 RO 0 */ +}; + + +/********************************************************** + * Time stamp related functions + **********************************************************/ +void synopGMAC_TS_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev); + +void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev); +void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type); +void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp" +void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev); +void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" +void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp" + +s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value); +s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); +s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value); + +void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled +void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled + +void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_val); // Update should happen making use of subsecond mask +void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val, + u32 * sec_val, u32 * sub_sec_val); // Reads the timestamp low,high and higher(Ver2) registers in the the struct pointer; readonly contents +void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val); //Loads the timestamp target register with the values provided + +void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val); +void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val); +void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val); //Read the target time stamp register contents + + +/********************************************************** + * Common functions + **********************************************************/ +s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val); +u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev); +s32 synopGMAC_read_phy_reg(u32 *RegBase,u32 PhyBase, u32 RegOffset, u16 * data); +s32 synopGMAC_write_phy_reg(u32 *RegBase, u32 PhyBase, u32 RegOffset, u16 data); +s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback); +s32 synopGMAC_read_version (synopGMACdevice * gmacdev) ; +s32 synopGMAC_reset (synopGMACdevice * gmacdev ); +s32 synopGMAC_reset_nocheck (synopGMACdevice * gmacdev ); +s32 synopGMAC_dma_bus_mode_init(synopGMACdevice * gmacdev, u32 init_value ); +s32 synopGMAC_dma_control_init(synopGMACdevice * gmacdev, u32 init_value); +void synopGMAC_wd_enable(synopGMACdevice * gmacdev); +void synopGMAC_wd_disable(synopGMACdevice * gmacdev); +void synopGMAC_jab_enable(synopGMACdevice * gmacdev); +void synopGMAC_jab_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_burst_disable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_enable(synopGMACdevice * gmacdev); +void synopGMAC_jumbo_frame_disable(synopGMACdevice * gmacdev); +void synopGMAC_select_gmii(synopGMACdevice * gmacdev); +void synopGMAC_select_mii(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_own_disable(synopGMACdevice * gmacdev); +void synopGMAC_loopback_on(synopGMACdevice * gmacdev); +void synopGMAC_loopback_off(synopGMACdevice * gmacdev); +void synopGMAC_set_full_duplex(synopGMACdevice * gmacdev); +void synopGMAC_set_half_duplex(synopGMACdevice * gmacdev); +void synopGMAC_retry_enable(synopGMACdevice * gmacdev); +void synopGMAC_retry_disable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_enable(synopGMACdevice * gmacdev); +void synopGMAC_pad_crc_strip_disable(synopGMACdevice * gmacdev); +void synopGMAC_back_off_limit(synopGMACdevice * gmacdev, u32 value); +void synopGMAC_deferral_check_enable(synopGMACdevice * gmacdev); +void synopGMAC_deferral_check_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_disable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_frame_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_write_hash_table_high(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_write_hash_table_low(synopGMACdevice * gmacdev, u32 data); +void synopGMAC_hash_perfect_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_Hash_filter_only_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_inverse(synopGMACdevice * gmacdev); +void synopGMAC_dst_addr_filter_normal(synopGMACdevice * gmacdev); +void synopGMAC_set_pass_control(synopGMACdevice * gmacdev,u32 passcontrol); +void synopGMAC_broadcast_enable(synopGMACdevice * gmacdev); +void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_disable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_multicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_enable(synopGMACdevice * gmacdev); +void synopGMAC_promisc_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_hash_filter_disable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice * gmacdev); +void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_rx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_enable(synopGMACdevice * gmacdev); +void synopGMAC_tx_flow_control_disable(synopGMACdevice * gmacdev); +void synopGMAC_tx_activate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_tx_deactivate_flow_control(synopGMACdevice * gmacdev); +void synopGMAC_pause_control(synopGMACdevice *gmacdev); +s32 synopGMAC_mac_init(synopGMACdevice * gmacdev); +s32 synopGMAC_check_phy_init (synopGMACdevice * gmacdev); +s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr); +s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr); +s32 synopGMAC_attach (synopGMACdevice * gmacdev, u32 macBase, u32 dmaBase, u32 phyBase); +void synopGMAC_rx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc); +void synopGMAC_rx_desc_init_chain(DmaDesc * desc); +void synopGMAC_tx_desc_init_chain(DmaDesc * desc); +s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev); +void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev); +void synopGMAC_set_owner_dma(DmaDesc *desc); +void synopGMAC_set_desc_sof(DmaDesc *desc); +void synopGMAC_set_desc_eof(DmaDesc *desc); +bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc); +bool synopGMAC_is_da_filter_failed(DmaDesc *desc); +bool synopGMAC_is_sa_filter_failed(DmaDesc *desc); +bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc); +u32 synopGMAC_get_rx_desc_frame_length(u32 status); +bool synopGMAC_is_desc_valid(u32 status); +bool synopGMAC_is_desc_empty(DmaDesc *desc); +bool synopGMAC_is_rx_desc_valid(u32 status); +bool synopGMAC_is_tx_aborted(u32 status); +bool synopGMAC_is_tx_carrier_error(u32 status); +u32 synopGMAC_get_tx_collision_count(u32 status); +u32 synopGMAC_is_exc_tx_collisions(u32 status); +bool synopGMAC_is_rx_frame_damaged(u32 status); +bool synopGMAC_is_rx_frame_collision(u32 status); +bool synopGMAC_is_rx_crc(u32 status); +bool synopGMAC_is_frame_dribbling_errors(u32 status); +bool synopGMAC_is_rx_frame_length_errors(u32 status); +bool synopGMAC_is_last_rx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_last_tx_desc(synopGMACdevice * gmacdev,DmaDesc *desc); +bool synopGMAC_is_rx_desc_chained(DmaDesc * desc); +bool synopGMAC_is_tx_desc_chained(DmaDesc * desc); +void synopGMAC_get_desc_data(DmaDesc * desc, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1); + +s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); + +s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1, u32 offload_needed, u32 ts); +s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u32 Data1); + +s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u32 * Data1, u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low); + +void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev); +u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev); +void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev); +void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts); +void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership(DmaDesc * desc); +void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev); +void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev); +void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev); +/******Following APIs are valid only for Enhanced Descriptor from 3.50a release onwards*******/ +bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status); +bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status); +bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status); +/*******************PMT APIs***************************************/ +void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_enable(synopGMACdevice *gmacdev); +void synopGMAC_power_down_disable(synopGMACdevice *gmacdev); +void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev); +void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev); +void synopGMAC_magic_packet_disable(synopGMACdevice *gmacdev); +void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev); +void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev); +bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev); +bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev); +void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents); + +/*******************Ip checksum offloading APIs***************************************/ +void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_disable_rx_chksum_offload(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev); +void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev); +u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status); +bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status); +void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc); +void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc); + + +// For testing --ya +void synopGMAC_src_addr_insert_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_insert_disable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_replace_enable(synopGMACdevice * gmacdev); +void synopGMAC_src_addr_replace_disable(synopGMACdevice * gmacdev); + +void synopGMAC_svlan_insertion_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_cvlan_insertion_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_svlan_replace_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_cvlan_replace_enable(synopGMACdevice * gmacdev, u16 vlantag); +void synopGMAC_vlan_deletion_enable(synopGMACdevice * gmacdev); +void synopGMAC_vlan_no_act_enable(synopGMACdevice * gmacdev); + +void synopGMAC_set_crc_replacement(synopGMACdevice * gmacdev); +void synopGMAC_clr_crc_replacement(synopGMACdevice * gmacdev); + +void synopGMAC_enable_under_size_pkt(synopGMACdevice * gmacdev); +void synopGMAC_disable_under_size_pkt(synopGMACdevice * gmacdev); + +void synopGMAC_enable_crc_err_pkt(synopGMACdevice * gmacdev); +void synopGMAC_disable_crc_err_pkt(synopGMACdevice * gmacdev); + +#endif /* End of file */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h new file mode 100644 index 000000000..0c95eee55 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_network_interface.h @@ -0,0 +1,63 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/** \file + * Header file for the nework dependent functionality. + * The function prototype listed here are linux dependent. + * + * \internal + * ---------------------------REVISION HISTORY------------------- + * Synopsys 01/Aug/2007 Created + */ +#include "synopGMAC_Dev.h" + + +#ifndef SYNOP_GMAC_NETWORK_INTERFACE_H +#define SYNOP_GMAC_NETWORK_INTERFACE_H 1 + +//#define EMULATION + +//#define TEST_RGMII +#define TEST_RMII + +//#define CACHE_ON + + +s32 synopGMAC_open(int intf); +s32 synopGMAC_open_selftest(int intf); +s32 synopGMAC_close(int intf); +s32 synopGMAC_xmit_frames(struct sk_buff *, int intf, u32 offload_needed, u32 ts); +void synopGMAC_set_multicast_list(int intf); +s32 synopGMAC_set_mac_address(int intf, u8*); +s32 synopGMAC_change_mtu(int intf,s32); +void synop_handle_transmit_over(int intf); +//void synop_handle_received_data(int intf); +s32 synop_handle_received_data(int intf, u8 **buf); // Chris, to get RX buffer pointer +void synopGMAC_set_mode(int intf, int mode); + +void synopGMAC_powerup_mac(synopGMACdevice *gmacdev); +void synopGMAC_powerdown_mac(synopGMACdevice *gmacdev); +s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode); +s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice * gmacdev,u32 no_of_desc, u32 desc_mode); + + +#endif /* End of file */ diff --git a/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h new file mode 100644 index 000000000..b3daf4a1e --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/emac/TARGET_NUVOTON_EMAC/TARGET_M460/synopGMAC_plat.h @@ -0,0 +1,183 @@ +/* =================================================================================== + * Copyright (c) <2009> Synopsys, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software annotated with this license and associated documentation files + * (the "Software"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * =================================================================================== */ + +/**\file + * This file serves as the wrapper for the platform/OS dependent functions + * It is needed to modify these functions accordingly based on the platform and the + * OS. Whenever the synopsys GMAC driver ported on to different platform, this file + * should be handled at most care. + * The corresponding function definitions for non-inline functions are available in + * synopGMAC_plat.c file. + * \internal + * -------------------------------------REVISION HISTORY--------------------------- + * Synopsys 01/Aug/2007 Created + */ + + +#ifndef SYNOP_GMAC_PLAT_H +#define SYNOP_GMAC_PLAT_H 1 + +#include +#include "NuMicro.h" + +#define TR0(fmt, args...) printf("SynopGMAC: " fmt, ##args) + +//#define DEBUG +#ifdef DEBUG +#undef TR +# define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args) +#else +# define TR(fmt, args...) /* not debugging: nothing */ +#endif + +typedef unsigned char u8; ///< Define 8-bit unsigned data type +typedef unsigned short u16; ///< Define 16-bit unsigned data type +typedef unsigned int u32; ///< Define 32-bit unsigned data type +typedef signed int s32; ///< Define 32-bit signed data type +//typedef unsigned long long u64; +typedef unsigned int u64; + + +typedef int bool; +enum synopGMAC_boolean { + false = 0, + true = 1 +}; + +#define DEFAULT_DELAY_VARIABLE 10 +#define DEFAULT_LOOP_VARIABLE 10000 + +/* There are platform related endian conversions + * + */ + +#define LE32_TO_CPU __le32_to_cpu +#define BE32_TO_CPU __be32_to_cpu +#define CPU_TO_LE32 __cpu_to_le32 + +/* Error Codes */ +#define ESYNOPGMACNOERR 0 +#define ESYNOPGMACNOMEM 1 +#define ESYNOPGMACPHYERR 2 +#define ESYNOPGMACBUSY 3 + + +/** + * These are the wrapper function prototypes for OS/platform related routines + */ + +extern void plat_delay(uint32_t ticks); + + +/** + * The Low level function to read register contents from Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * \return Returns the register contents + */ +static u32 __INLINE synopGMACReadReg(u32 *RegBase, u32 RegOffset) +{ + + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + return data; + +} + +/** + * The Low level function to write to a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Data to be written + * \return void + */ +static void __INLINE synopGMACWriteReg(u32 *RegBase, u32 RegOffset, u32 RegData) +{ + + u64 addr = (u64)RegBase + RegOffset; + if(RegOffset == 0) + plat_delay(1); + outp32((void *)addr, RegData); + return; +} + +/** + * The Low level function to set bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return void + */ +static void __INLINE synopGMACSetBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data |= BitPos; + + outp32((void *)addr, data); + + return; +} + + +/** + * The Low level function to clear bits of a register in Hardware. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to clear bits to logical 0 + * \return void + */ +static void __INLINE synopGMACClearBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data &= (~BitPos); + + outp32((void *)addr, data); + return; +} + +/** + * The Low level function to Check the setting of the bits. + * + * @param[in] pointer to the base of register map + * @param[in] Offset from the base + * @param[in] Bit mask to set bits to logical 1 + * \return returns TRUE if set to '1' returns FALSE if set to '0'. Result undefined there are no bit set in the BitPos argument. + * + */ +static bool __INLINE synopGMACCheckBits(u32 *RegBase, u32 RegOffset, u32 BitPos) +{ + u64 addr = (u64)RegBase + RegOffset; + u32 data = inp32((void *)addr); + data &= BitPos; + if(data) return true; + else return false; + +} + + +#endif diff --git a/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h b/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h index afcc82d87..fa8d61ee1 100644 --- a/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h +++ b/cores/arduino/mbed/connectivity/drivers/lora/TARGET_STM32WL/STM32WL_radio_driver.h @@ -17,9 +17,18 @@ #define RFO_HP 2 /* STM32WL Nucleo antenna switch defines */ -#define RBI_CONF_RFO_LP_HP 0 -#define RBI_CONF_RFO_LP 1 -#define RBI_CONF_RFO_HP 2 +#define RBI_CONF_RFO_LP_HP 0 +#define RBI_CONF_RFO_LP 1 +#define RBI_CONF_RFO_HP 2 +// Some boards such as LoRa-E5 and RAK3172 have only RFO_HP path wired +// thus, in EU868 mode, TX peak is 80mA (over consumption) +// We made a fix that decrease consumption according datasheet but +// since fix breaks HW machting network, transmit range may be lowered so +// it's depending on what you want to achieve, hi range or low consumption +// Setting RBI_CONF_RFO_HP_LPFIX decrease power according datasheet but can +// reduce range (long ones) due to bad HW macthing network on the both modules +// See https://github.com/ARMmbed/mbed-os/pull/15017#issuecomment-1173455762 +#define RBI_CONF_RFO_HP_LPFIX 3 typedef enum { RBI_SWITCH_OFF = 0, diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h new file mode 100644 index 000000000..23625b5b6 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/aes/aes_alt.h @@ -0,0 +1,262 @@ +/** + * \file aes_alt.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_AES_ALT_H +#define MBEDTLS_AES_ALT_H + +#include "mbedtls/aes.h" + +#if defined(MBEDTLS_AES_ALT) +// Regular implementation +// +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES context structure + */ +typedef struct { + uint32_t keySize; /* Key size: AES_KEY_SIZE_128/192/256 */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ + uint32_t iv[4]; /* IV for next block cipher */ + uint32_t keys[8]; /* Cipher key */ +} +mbedtls_aes_context; + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_DECRYPT_ALT) + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + + +#endif /* MBEDTLS_AES_ALT */ + +#endif /* aes_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h new file mode 100644 index 000000000..1c1345e4b --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ccm/ccm_alt.h @@ -0,0 +1,318 @@ +/** + * \file ccm.h + * + * \brief This file provides an API for the CCM authenticated encryption + * mode for block ciphers. + * + * CCM combines Counter mode encryption with CBC-MAC authentication + * for 128-bit block ciphers. + * + * Input to CCM includes the following elements: + * + * + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + * + * Definition of CCM*: + * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks + * Integer representation is fixed most-significant-octet-first order and + * the representation of octets is most-significant-bit-first order. This is + * consistent with RFC 3610. + */ +/* + * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved + * Copyright (c) 2022, Nuvoton Technology Corporation + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CCM_ALT_H +#define MBEDTLS_CCM_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbed_toolchain.h" +#include "mbedtls/cipher.h" +#include "NuMicro.h" + +#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ +#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ +#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +// Regular implementation +// + +#define MAX_CCM_BUF 256 +#define CCM_PBLOCK_SIZE MAX_CCM_BUF + +/** + * \brief The CCM context-type definition. The CCM context is passed + * to the APIs called. + */ +typedef struct mbedtls_ccm_context +{ + MBED_ALIGN(4) uint8_t ccm_buf[MAX_CCM_BUF + 16]; /* 16 bytes for ctr0 in packer */ + MBED_ALIGN(4) uint8_t out_buf[MAX_CCM_BUF + 16]; /* 16 bytes for tag */ + MBED_ALIGN(4) uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */ + uint32_t keySize; + uint32_t keys[8]; /* Cipher key */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE CCM */ + +} +mbedtls_ccm_context; + +/** + * \brief This function initializes the specified CCM context, + * to make references valid, and prepare the context + * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). + * + * \param ctx The CCM context to initialize. This must not be \c NULL. + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); + +/** + * \brief This function initializes the CCM context set in the + * \p ctx parameter and sets the encryption key. + * + * \param ctx The CCM context to initialize. This must be an initialized + * context. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must not be \c NULL. + * \param keybits The key size in bits. This must be acceptable by the cipher. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function releases and clears the specified CCM context + * and underlying cipher sub-context. + * + * \param ctx The CCM context to clear. If this is \c NULL, the function + * has no effect. Otherwise, this must be initialized. + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); + +/** + * \brief This function encrypts a buffer using CCM. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. + * \param add_len The length of additional data in Bytes. + * This must be less than `2^16 - 2^8`. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function encrypts a buffer using CCM*. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \note When using this function in a variable tag length context, + * the tag length has to be encoded into the \p iv passed to + * this function. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer of + * at least \p add_len Bytes. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief This function performs a CCM authenticated decryption of a + * buffer. + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer + * of at least that \p add_len Bytes.. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. This indicates that the message is authentic. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +/** + * \brief This function performs a CCM* authenticated decryption of a + * buffer. + * + * \note When using this function in a variable tag length context, + * the tag length has to be decoded from \p iv and passed to + * this function as \p tag_len. (\p tag needs to be adjusted + * accordingly.) + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. This must be a readable buffer of + * at least that \p add_len Bytes. + * \param add_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field in Bytes. + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is nos + * longer authenticated. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief The CCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ccm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CCM_ALT_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h new file mode 100644 index 000000000..3bcb43c9d --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/crypto_ecc_hw.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CRYPTO_ECC_HW_H +#define CRYPTO_ECC_HW_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECP_ALT) || defined(MBEDTLS_ECP_INTERNAL_ALT) + +#include "mbedtls/ecp.h" +#include + +/* Crypto ECC H/W point operations */ +#define ECCOP_POINT_MUL (0x0UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_MODULE (0x1UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_POINT_ADD (0x2UL << CRPT_ECC_CTL_ECCOP_Pos) +#define ECCOP_POINT_DOUBLE (0x3UL << CRPT_ECC_CTL_ECCOP_Pos) + +/* Crypto ECC H/W modulus operations */ +#define MODOP_DIV (0x0UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_MUL (0x1UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_ADD (0x2UL << CRPT_ECC_CTL_MODOP_Pos) +#define MODOP_SUB (0x3UL << CRPT_ECC_CTL_MODOP_Pos) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This function checks whether a given group can be used + * for Crypto ECC H/W. + * + * \param grp ECP group + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int crypto_ecc_capable(const mbedtls_ecp_group *grp); + +/** + * \brief Initialize/Free Crypto ECC H/W + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + * \note crypto_ecp_init()/crypto_ecp_free() are like pre-op/post-op calls + * and they guarantee: + * + * 1. Paired + * 2. No overlapping + * 3. Upper public function cannot return when ECP alter. is still activated. + */ +int crypto_ecc_init(const mbedtls_ecp_group *grp); +void crypto_ecc_free(const mbedtls_ecp_group *grp); +/** + * \brief Configure ECCOP operation, start it, and wait for its completion + * + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply P + * \param P Point to multiply by m + * \param n Integer by which to multiply Q + * \param Q Point to be multiplied by n + * \param eccop ECCOP code. Could be ECCOP_POINT_MUL/ADD/DOUBLE + * \param blinding Blinding (SCAP) or not. + * Dependent on passed-in eccop, only partial parameters among m/P/n/Q are needed and checked. + * ECCOP_POINT_MUL R = m*P + * ECCOP_POINT_ADD R = P + Q + * ECCOP_POINT_DOUBLE R = 2*P + * + * \return 0 if successful + * + * \note P/Q must be normalized (= affine). R would be normalized. + * + * \note m/n could be negative. + * + * \note ECC accelerator doesn't support R = 0, and we need to detect it additionally. + * For R = P + Q or R = 2*P, we can detect all R = 0 cases. + * For R = m*P, we can detect all R = 0 cases only if grp->N (order) is a prime. + * + * \note According to ECCOP operation, n is unnecessary. But to be consistent with R = m*P + n*Q, + * n is kept with unused modifier. + * + * \note Blinding (SCAP) is applicable only for point multiplication. But for future extension, + * blinding is kept with all point operations. + * + */ +int crypto_ecc_run_eccop_add(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q, + bool blinding); +int crypto_ecc_run_eccop_double(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, + bool blinding); +int crypto_ecc_run_eccop_mul(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P, + bool blinding); +int crypto_ecc_run_eccop(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P, + const mbedtls_mpi *n, + const mbedtls_ecp_point *Q, + uint32_t eccop, + bool blinding); + +/** + * \brief Configure MODOP operation and wait for its completion + * + * \param r Destination MPI + * \param o1 Input MPI for first operand of MODOP + * \param o2 Input MPI for second operand of MODOP + * \param p Prime modulus + * \param pbits Bit number of p + * \param modop ECCOP code. Could be MODOP_ADD/SUB/MUL/DIV + * MODOP_ADD r = o1 + o2 mod p + * MODOP_SUB r = o1 - o2 mod p + * MODOP_MUL r = o1 * o2 mod p + * MODOP_DIV r = o1 / o2 mod p + * + * \return 0 if successful + * + * \note o1/o2 must be normalized (within [0, p - 1]). r would be normalized. + */ +int crypto_ecc_run_modop(mbedtls_mpi *r, + const mbedtls_mpi *o1, + const mbedtls_mpi *o2, + const mbedtls_mpi *p, + uint32_t pbits, + uint32_t modop); + +/** + * \brief Import X from ECC registers, little endian + * + * \param X Destination MPI + * \param eccreg Start of input ECC register + * \param eccreg_num Number of input ECC register + * + * \return 0 if successful + * + * \note Destination MPI is always non-negative. + */ +int crypto_ecc_mpi_read_eccreg( mbedtls_mpi *X, const volatile uint32_t *eccreg, size_t eccreg_num ); + +/** + * \brief Export X into ECC registers, little endian + * + * \param X Source MPI + * \param eccreg Start of ECC output registers + * \param eccreg_num Number of ECC output registers + * + * \return 0 if successful + * + * \note Source MPI cannot be negative. + * \note Fills the remaining MSB ECC registers with zeros if X doesn't cover all. + */ +int crypto_ecc_mpi_write_eccreg( const mbedtls_mpi *X, volatile uint32_t *eccreg, size_t eccreg_num ); + +/** + * \brief Abort Crypto ECC H/W + * + * \param timeout_us Timeout in microseconds. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int crypto_ecc_abort(uint32_t timeout_us); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_ECP_ALT || MBEDTLS_ECP_INTERNAL_ALT */ +#endif /* CRYPTO_ECC_HW_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h new file mode 100644 index 000000000..8c7c8d127 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_alt.h @@ -0,0 +1,187 @@ +/** + * \file ecp_alt.h + * + * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). + * + * The use of ECP in cryptography and TLS is defined in + * Standards for Efficient Cryptography Group (SECG): SEC1 + * Elliptic Curve Cryptography and + * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites + * for Transport Layer Security (TLS). + * + * RFC-2409: The Internet Key Exchange (IKE) defines ECP + * group types. + * + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_ECP_ALT_H +#define MBEDTLS_ECP_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_ECP_ALT) + +/* Enable Nuvoton's Crypto ECC H/W */ +#define NU_CRYPTO_ECC_ENABLE + +/* + * default mbed TLS elliptic curve arithmetic implementation + * + * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an + * alternative implementation for the whole module and it will replace this + * one.) + */ + +/** + * \brief The ECP group structure. + * + * We consider two types of curve equations: + * + * In both cases, the generator (\p G) for a prime-order subgroup is fixed. + * + * For Short Weierstrass, this subgroup is the whole curve, and its + * cardinality is denoted by \p N. Our code requires that \p N is an + * odd prime as mbedtls_ecp_mul() requires an odd number, and + * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. + * + * For Montgomery curves, we do not store \p A, but (A + 2) / 4, + * which is the quantity used in the formulas. Additionally, \p nbits is + * not the size of \p N but the required size for private keys. + * + * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. + * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the + * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer + * which is congruent mod \p P to the given MPI, and is close enough to \p pbits + * in size, so that it may be efficiently brought in the 0..P-1 range by a few + * additions or subtractions. Therefore, it is only an approximative modular + * reduction. It must return 0 on success and non-zero on failure. + * + * \note Alternative implementations must keep the group IDs distinct. If + * two group structures have the same ID, then they must be + * identical. + * + */ +typedef struct mbedtls_ecp_group +{ + mbedtls_ecp_group_id id; /*!< An internal group identifier. */ + mbedtls_mpi P; /*!< The prime modulus of the base field. */ + mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For + Montgomery curves: (A + 2) / 4. */ + mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. + For Montgomery curves: unused. */ + mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ + mbedtls_mpi N; /*!< The order of \p G. */ + size_t pbits; /*!< The number of bits in \p P.*/ + size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. + For Montgomery curves: the number of bits in the + private keys. */ + unsigned int h; /*!< \internal 1 if the constants are static. */ + int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction + mod \p P (see above).*/ + int (*t_pre)(mbedtls_ecp_point *, void *); /*!< Unused. */ + int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */ + void *t_data; /*!< Unused. */ + mbedtls_ecp_point *T; /*!< Pre-computed points for ecp_mul_comb(). */ + size_t T_size; /*!< The number of pre-computed points. */ + +#if defined(NU_CRYPTO_ECC_ENABLE) + int hw_init; /*!< Initialized Crypto ECC H/W or not. */ +#endif +} +mbedtls_ecp_group; + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h, or define them using the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_ECP_MAX_BITS) +/** + * The maximum size of the groups, that is, of \c N and \c P. + */ +#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ +#endif + +#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) +#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) + +#if !defined(MBEDTLS_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: 6. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ +#endif /* MBEDTLS_ECP_WINDOW_SIZE */ + +#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ + +/* \} name SECTION: Module settings */ + +#endif /* MBEDTLS_ECP_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecp.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h new file mode 100644 index 000000000..6903af4d5 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/ecp/ecp_helper.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECP_HELPER_H +#define ECP_HELPER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" + +/** + * \brief Check if MPI has been normalized + * + * \param N Input MPI which is to check + * \param P Prime modulus + * + * \return 0 if not normalized, + * 1 if normalized + */ +#define ECP_HELPER_MPI_IS_NORM(N, P) \ + ((mbedtls_mpi_cmp_int(&N, 0) >= 0) && (mbedtls_mpi_cmp_mpi(&N, &P) < 0)) + +/** + * \brief Normalize MPI if it is not normalized yet + * + * \param R Holds pointer to normalized MPI (N1 or N2) + * \param N1 Input MPI which is to normalize + * \param N2 Output MPI which holds normalized N1 if N1 is not normalized yet + * \param P Prime modulus + */ +#define ECP_HELPER_MPI_NORM(R, N1, N2, P) \ + do { \ + if (ECP_HELPER_MPI_IS_NORM(N1, P)) { \ + *R = &N1; \ + } else { \ + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&N2, &N1, &P)); \ + *R = &N2; \ + } \ + } while(0) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This function deduces y coordinate from x coordinate + * for a ECP point expressed in compact representation. + * + * \param grp The ECP group to be exported. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param y Deduced y coordinate which is smaller. The other would be + * \p grp->P - \p y. \p y must point to an initialized MPI. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a Curve25519 or Curve448 curve. + * \return Another negative error code on other kinds of failure. + */ +int ecp_helper_deduce_y(const mbedtls_ecp_group *grp, + mbedtls_mpi *y, + const mbedtls_mpi *x); + +#ifdef __cplusplus +} +#endif + +#endif /* ECP_HELPER_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h new file mode 100644 index 000000000..a680e897d --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/gcm/gcm_alt.h @@ -0,0 +1,72 @@ +/** + * \file gcm.h + * + * \brief This file contains GCM definitions and functions. + * + * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. + * + * For more information on GCM, see NIST SP 800-38D: Recommendation for + * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_GCM_ALT_H +#define MBEDTLS_GCM_ALT_H + +#if defined(MBEDTLS_GCM_ALT) +#include "mbed_toolchain.h" +#define MAX_GCM_BUF 256 +#define GCM_PBLOCK_SIZE (MAX_GCM_BUF) /* NOTE: This value must be 16 bytes alignment. This value must > size of A */ + + +/** + * \brief The GCM context structure. + */ +typedef struct mbedtls_gcm_context +{ + uint32_t len; /*!< The total length of the encrypted data. */ + int mode; /*!< The operation to perform: + #MBEDTLS_GCM_ENCRYPT or + #MBEDTLS_GCM_DECRYPT. */ + + uint32_t keySize; /* Key size unit is bytes: 16(128 bits)/24(192 bits)/32(256 bits) */ + uint32_t encDec; /* 0: decrypt, 1: encrypt */ + uint32_t opMode; /* AES_MODE_ECB/CBC/CFB */ + uint32_t iv[4]; /* IV for next block cipher */ + uint32_t keys[8]; /* Cipher key */ + uint32_t basicOpt; /* Basic option of AES controller */ + MBED_ALIGN(4) uint8_t gcm_buf[MAX_GCM_BUF]; /* buffer for GCM DMA input */ + MBED_ALIGN(4) uint8_t out_buf[MAX_GCM_BUF+16]; /* buffer for GCM DMA output */ + MBED_ALIGN(4) uint8_t fb_buf[72]; /* feedback buffer for GCM DMA */ + MBED_ALIGN(4) uint8_t fb_buf2[72]; /* feedback buffer 2 for GCM DMA */ + uint8_t tag[16]; /* Tag */ + uint32_t gcm_buf_bytes; /* Bytes in gcm_buf */ + uint32_t firstFlag; /* A flag for the first data block */ + uint32_t endFlag; /* final block is done */ + uint32_t pcntLen; /* PCNT length*/ +// uint8_t *add; +// size_t addlen; +} +mbedtls_gcm_context; + +#endif /* MBEDTLS_GCM_ALT */ + +#endif /* gcm.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h new file mode 100644 index 000000000..71ed198f0 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/mbedtls_device.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_DEVICE_H +#define MBEDTLS_DEVICE_H + +#define MBEDTLS_SHA1_ALT +#define MBEDTLS_SHA256_ALT +#define MBEDTLS_SHA512_ALT + +#define MBEDTLS_AES_ALT +#define MBEDTLS_GCM_ALT +#define MBEDTLS_CCM_ALT + +#define MBEDTLS_ECP_ALT + +#if !defined(MBEDTLS_ECP_ALT) + +#define MBEDTLS_ECP_INTERNAL_ALT + +/* Support for Weierstrass curves with Jacobi representation */ +#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +#define MBEDTLS_ECP_ADD_MIXED_ALT +#define MBEDTLS_ECP_DOUBLE_JAC_ALT +#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT + +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +#endif /* !MBEDTLS_ECP_ALT */ + +#define MBEDTLS_RSA_ALT + +#endif /* MBEDTLS_DEVICE_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h new file mode 100644 index 000000000..b3bd67a07 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/crypto_rsa_hw.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CRYPTO_RSA_HW_H +#define CRYPTO_RSA_HW_H + +#include "mbedtls/rsa.h" + +#if defined(MBEDTLS_RSA_ALT) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize/Free Crypto RSA H/W + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + * \note crypto_rsa_init()/crypto_rsa_free() are like pre-op/post-op calls + * and they guarantee: + * + * 1. Paired + * 2. No overlapping + * 3. Upper public function cannot return when RSA alter. is still activated. + */ +int crypto_rsa_init(mbedtls_rsa_context *ctx); +void crypto_rsa_free(mbedtls_rsa_context *ctx); + +/** + * \brief Query whether or not RSA H/W supports encrypt/decrypt operation in this context + * in normal/CRT algorithm + * + * \param ctx The initialized RSA context to use. + * \param decrypt true for decrypt, or encrypt. + * \param crt true for CRT algorithm, or normal. + * \param blinding Blinding (SCAP) or not. + * + * \return \c 1 on capable, or 0 on incapable. + * + * \note Blinding is applicable only for decrypt operation. + * \note CRT is applicable only for decrypt operation. + */ +int crypto_rsa_encrypt_norm_capable(const mbedtls_rsa_context *ctx); +int crypto_rsa_decrypt_norm_capable(const mbedtls_rsa_context *ctx, bool blinding); +int crypto_rsa_decrypt_crt_capable(const mbedtls_rsa_context *ctx, bool blinding); +int crypto_rsa_crypt_capable(const mbedtls_rsa_context *ctx, + bool decrypt, + bool crt, + bool blinding); +/** + * \brief Run RSA encrypt/decrypt operation in normal/CRT algorithm + * + * \param ctx The initialized RSA context to use. + * \param decrypt true for decrypt, or encrypt. + * \param crt true for CRT algorithm, or normal. + * \param blinding Blinding (SCAP) or not. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int crypto_rsa_encrypt_norm(mbedtls_rsa_context *ctx, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_decrypt_norm(mbedtls_rsa_context *ctx, + bool blinding, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_decrypt_crt(mbedtls_rsa_context *ctx, + bool blinding, + const unsigned char *input, + unsigned char *output); +int crypto_rsa_crypt(mbedtls_rsa_context *ctx, + bool decrypt, + bool crt, + bool blinding, + const unsigned char *input, + unsigned char *output); + +/** + * \brief Abort Crypto RSA H/W + * + * \param ctx The initialized RSA context to use. + * \param timeout_us Timeout in microseconds. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int crypto_rsa_abort(mbedtls_rsa_context *ctx, + uint32_t timeout_us); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_RSA_ALT */ + +#endif /* CRYPTO_RSA_HW_H */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h new file mode 100644 index 000000000..86201c520 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/rsa/rsa_alt.h @@ -0,0 +1,109 @@ +/** + * \file rsa_alt.h + * + * \brief This file provides an API for the RSA public-key cryptosystem. + * + * The RSA public-key cryptosystem is defined in Public-Key + * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption + * and Public-Key Cryptography Standards (PKCS) #1 v2.1: + * RSA Cryptography Specifications. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_RSA_ALT_H +#define MBEDTLS_RSA_ALT_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/bignum.h" +#include "mbedtls/md.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_RSA_ALT) +// Regular implementation +// + +/* Enable Nuvoton's Crypto RSA H/W */ +#define NU_CRYPTO_RSA_ENABLE + +/** + * \brief The RSA context structure. + * + * \note Direct manipulation of the members of this structure + * is deprecated. All manipulation should instead be done through + * the public interface functions. + */ +typedef struct mbedtls_rsa_context +{ + int ver; /*!< Always 0.*/ + size_t len; /*!< The size of \p N in Bytes. */ + + mbedtls_mpi N; /*!< The public modulus. */ + mbedtls_mpi E; /*!< The public exponent. */ + + mbedtls_mpi D; /*!< The private exponent. */ + mbedtls_mpi P; /*!< The first prime factor. */ + mbedtls_mpi Q; /*!< The second prime factor. */ + + mbedtls_mpi DP; /*!< D % (P - 1). */ + mbedtls_mpi DQ; /*!< D % (Q - 1). */ + mbedtls_mpi QP; /*!< 1 / (Q % P). */ + + mbedtls_mpi RN; /*!< cached R^2 mod N. */ + + mbedtls_mpi RP; /*!< cached R^2 mod P. */ + mbedtls_mpi RQ; /*!< cached R^2 mod Q. */ + + mbedtls_mpi Vi; /*!< The cached blinding value. */ + mbedtls_mpi Vf; /*!< The cached un-blinding value. */ + + int padding; /*!< Selects padding mode: + #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and + #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ + int hash_id; /*!< Hash identifier of mbedtls_md_type_t type, + as specified in md.h for use in the MGF + mask generating function used in the + EME-OAEP and EMSA-PSS encodings. */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */ +#endif + +#if defined(NU_CRYPTO_RSA_ENABLE) + int hw_init; /*!< Initialized Crypto RSA H/W or not. */ +#endif +} +mbedtls_rsa_context; + +#endif /* MBEDTLS_RSA_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* rsa_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h new file mode 100644 index 000000000..3c4efdac8 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha1_alt.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA1_ALT_H +#define MBEDTLS_SHA1_ALT_H + +#include "mbedtls/sha1.h" + +#if defined(MBEDTLS_SHA1_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha1_context_s; + +/** + * \brief SHA-1 context structure + */ +typedef struct mbedtls_sha1_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha1_context; + +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void mbedtls_sha1_init( mbedtls_sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void mbedtls_sha1_free( mbedtls_sha1_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-1 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha1_clone( mbedtls_sha1_context *dst, + const mbedtls_sha1_context *src ); + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + * + * \returns error code + */ +int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + * + * \returns error code + */ +int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ); + +/* Internal use */ +int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief SHA-1 context setup + * + * \deprecated Superseded by mbedtls_sha1_starts_ret() in 2.7.0 + * + * \param ctx The SHA-1 context to be initialized. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \deprecated Superseded by mbedtls_sha1_update_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \deprecated Superseded by mbedtls_sha1_finish_ret() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param output The SHA-1 checksum result. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, + unsigned char output[20] ); + +/** + * \brief SHA-1 process data block (internal use only) + * + * \deprecated Superseded by mbedtls_internal_sha1_process() in 2.7.0 + * + * \param ctx The SHA-1 context. + * \param data The data block being processed. + * + * \warning SHA-1 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx, + const unsigned char data[64] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA1_ALT */ + +#endif /* sha1_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h new file mode 100644 index 000000000..bd8669a43 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha256_alt.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA256_ALT_H +#define MBEDTLS_SHA256_ALT_H + +#include "mbedtls/sha256.h" + +#if defined(MBEDTLS_SHA256_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha256_context_s; + +/** + * \brief SHA-256 context structure + */ +typedef struct mbedtls_sha256_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha256_context; + +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void mbedtls_sha256_init( mbedtls_sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void mbedtls_sha256_free( mbedtls_sha256_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-256 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha256_clone( mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src ); + +/** + * \brief SHA-256 context setup + * + * \param ctx context to be initialized + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \returns error code + */ +int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 ); + +/** + * \brief SHA-256 process buffer + * + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-224/256 checksum result + * + * \returns error code + */ +int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ); + +/* Internal use */ +int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_starts_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param is224 Determines which function to use. + *
  • 0: Use SHA-256.
  • + *
  • 1: Use SHA-224.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, + int is224 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-256 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha256_update_ret() in 2.7.0. + * + * \param ctx The SHA-256 context to initialize. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-256 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha256_finish_ret() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param output The SHA-224or SHA-256 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, + unsigned char output[32] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-256 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha256_process() in 2.7.0. + * + * \param ctx The SHA-256 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx, + const unsigned char data[64] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA256_ALT */ + +#endif /* sha256_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h new file mode 100644 index 000000000..b6decc2f4 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha512_alt.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA512_ALT_H +#define MBEDTLS_SHA512_ALT_H + +#include "mbedtls/sha512.h" + +#if defined(MBEDTLS_SHA512_ALT) + +#include "sha_alt_hw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbedtls_sha512_context_s; + +/** + * \brief SHA-512 context structure + */ +typedef struct mbedtls_sha512_context_s { + crypto_sha_context hw_ctx; +} +mbedtls_sha512_context; + +/** + * \brief Initialize SHA-512 context + * + * \param ctx SHA-512 context to be initialized + */ +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ); + +/** + * \brief Clear SHA-512 context + * + * \param ctx SHA-512 context to be cleared + */ +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ); + +/** + * \brief Clone (the state of) a SHA-512 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ); + +/** + * \brief SHA-512 context setup + * + * \param ctx context to be initialized + * \param is384 0 = use SHA512, 1 = use SHA384 + * + * \returns error code + */ +int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 ); + +/** + * \brief SHA-512 process buffer + * + * \param ctx SHA-512 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns error code + */ +int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-512 final digest + * + * \param ctx SHA-512 context + * \param output SHA-384/512 checksum result + * + * \returns error code + */ +int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ); + +/* Internal use */ +int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function starts a SHA-384 or SHA-512 checksum + * calculation. + * + * \deprecated Superseded by mbedtls_sha512_starts_ret() in 2.7.0 + * + * \param ctx The SHA-512 context to initialize. + * \param is384 Determines which function to use. + *
  • 0: Use SHA-512.
  • + *
  • 1: Use SHA-384.
+ */ +MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, + int is384 ); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-512 checksum calculation. + * + * \deprecated Superseded by mbedtls_sha512_update_ret() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function finishes the SHA-512 operation, and writes + * the result to the output buffer. + * + * \deprecated Superseded by mbedtls_sha512_finish_ret() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param output The SHA-384 or SHA-512 checksum result. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, + unsigned char output[64] ); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-512 computation. This function is for + * internal use only. + * + * \deprecated Superseded by mbedtls_internal_sha512_process() in 2.7.0 + * + * \param ctx The SHA-512 context. + * \param data The buffer holding one block of data. + */ +MBEDTLS_DEPRECATED void mbedtls_sha512_process( mbedtls_sha512_context *ctx, + const unsigned char data[128] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA512_ALT */ + +#endif /* sha512_alt.h */ diff --git a/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h new file mode 100644 index 000000000..43219d701 --- /dev/null +++ b/cores/arduino/mbed/connectivity/drivers/mbedtls/TARGET_NUVOTON/TARGET_M460/sha/sha_alt_hw.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2022, Nuvoton Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA_ALT_HW_H +#define MBEDTLS_SHA_ALT_HW_H + +#if defined(MBEDTLS_SHA1_ALT) || defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA512_ALT) + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Max size of SHA block in bytes + * + * SHA-160/224/256: 64 bytes + * SHA-384/512: 128 bytes + * + * \note Support SHA1/2 only, no SHA3 + */ +#define NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES 128 + +/** + * \brief Max size of SHA DMA block run in bytes + * + * \note DMA cascade mode requires block-aligned except for the last block. + * \note This also defines DMA intermediary buffer size. + */ +#define NU_CRYPTO_SHA_MAXSIZE_DMABLOCKRUN_BYTES \ + (NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES * 4) + +/** + * \brief Max size of SHA feedback information in words, used in DMA cascade mode + * + * SHA1/2: 54 words + * SHA3: 88 words + * + * \note Support SHA1/2 only, no SHA3 + * \note According to spec, reserve 54 words for SHA1/2. But per real + * test, SHA H/W will overwrite beyond 54 words. Workaround by + * reserving 88 words anyway. + */ +#define NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS 88 + +/** + * \brief SHA context structure + * + * \note SHA type/opmode + * 1. For type, borrow from opmode defines and can only be SHA_MODE_SHA1/SHA256/SHA512. + * 2. Initialize opmode/digestsize dependent on type + * 3. For SHA_MODE_SHA256/512, opmode will change to SHA_MODE_SHA224/384 + * when is224_384 is non-zero in the call to crypto_sha_starts(). + * 4. Following above, for opmode being SHA_MODE_SHA224/384, change digestsize to 28/48 + */ +typedef struct { + /* These fields will initialize at crypto_sha_init() */ + uint32_t type; /*!< SHA type */ + uint32_t opmode; /*!< SHA operation mode */ + uint32_t digestsize; /*!< SHA digest size */ + int err_hw_accel; /*!< Mbed TLS error code for the SHA type */ + int err_bad_input; /*!< Mbed TLS error code for the SHA type */ + + /* These fields will initialize at crypto_sha_starts() */ + uint32_t total; /*!< number of bytes processed */ + union { + uint8_t buffer[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES]; /*!< data block being processed. Max of SHA-1/SHA-256/SHA-512 */ + uint32_t buffer_u32[NU_CRYPTO_SHA_MAXSIZE_BLOCK_BYTES/4]; /*!< make buffer word aligned */ + }; + uint16_t buffer_left; + uint16_t blocksize; /*!< block size */ + uint32_t blocksize_mask; /*!< block size mask */ + int is224_384; /*!< 0 => SHA-256/SHA-512, else SHA-224/384 */ + uint32_t fbinfo[NU_CRYPTO_SHA_MAXSIZE_FBINFO_WORDS]; /*!< feedback information in DMA cascade mode */ +} +crypto_sha_context; + +void crypto_sha_init(crypto_sha_context *ctx, uint32_t type); +void crypto_sha_free(crypto_sha_context *ctx); +int crypto_sha_starts(crypto_sha_context *ctx, int is224_384); +int crypto_sha_update(crypto_sha_context *ctx, const unsigned char *input, size_t ilen); +int crypto_sha_update_nobuf(crypto_sha_context *ctx, const unsigned char *input, size_t ilen, int isfirst, int islast); +int crypto_sha_finish(crypto_sha_context *ctx, unsigned char output[], size_t olen); +int crypto_sha_getdigest(unsigned char output[], size_t olen); + +#if defined(MBEDTLS_SHA1_ALT) + +void mbedtls_sha1_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha1_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha1_hw_starts( crypto_sha_context *ctx ); +int mbedtls_sha1_hw_update( crypto_sha_context *ctx, const unsigned char *input, size_t ilen ); +int mbedtls_sha1_hw_finish( crypto_sha_context *ctx, unsigned char output[20] ); +int mbedtls_sha1_hw_process( crypto_sha_context *ctx, const unsigned char data[64] ); + +#endif /* MBEDTLS_SHA1_ALT */ + +#if defined(MBEDTLS_SHA256_ALT) + +void mbedtls_sha256_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha256_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha256_hw_starts( crypto_sha_context *ctx, int is224 ); +int mbedtls_sha256_hw_update( crypto_sha_context *ctx, const unsigned char *input, + size_t ilen ); +int mbedtls_sha256_hw_finish( crypto_sha_context *ctx, unsigned char output[32] ); +int mbedtls_sha256_hw_process( crypto_sha_context *ctx, const unsigned char data[64] ); + +#endif /* MBEDTLS_SHA256_ALT */ + +#if defined(MBEDTLS_SHA512_ALT) + +void mbedtls_sha512_hw_init( crypto_sha_context *ctx ); +void mbedtls_sha512_hw_free( crypto_sha_context *ctx ); +int mbedtls_sha512_hw_starts( crypto_sha_context *ctx, int is384 ); +int mbedtls_sha512_hw_update( crypto_sha_context *ctx, const unsigned char *input, + size_t ilen ); +int mbedtls_sha512_hw_finish( crypto_sha_context *ctx, unsigned char output[64] ); +int mbedtls_sha512_hw_process( crypto_sha_context *ctx, const unsigned char data[128] ); + +#endif /* MBEDTLS_SHA512_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_SHA1_ALT || MBEDTLS_SHA256_ALT || MBEDTLS_SHA512_ALT */ + +#endif /* sha_alt.h */ diff --git a/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h b/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h index b4c83706b..4fb9103d3 100644 --- a/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h +++ b/cores/arduino/mbed/connectivity/nanostack/include/nanostack-interface/Nanostack.h @@ -122,7 +122,7 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyabletop = wrap; } +static inline void pwm_set_chan_level(uint slice_num, uint chan, uint16_t level); + /** \brief Initialise a PWM with settings from a configuration object * \ingroup hardware_pwm * @@ -188,12 +190,12 @@ static inline void pwm_config_set_wrap(pwm_config *c, uint16_t wrap) { * \param start If true the PWM will be started running once configured. If false you will need to start * manually using \ref pwm_set_enabled() or \ref pwm_set_mask_enabled() */ -static inline void pwm_init(uint slice_num, pwm_config *c, bool start) { +static inline void pwm_init(uint slice_num, uint chan, pwm_config *c, bool start) { check_slice_num_param(slice_num); pwm_hw->slice[slice_num].csr = 0; pwm_hw->slice[slice_num].ctr = PWM_CH0_CTR_RESET; - pwm_hw->slice[slice_num].cc = PWM_CH0_CC_RESET; + pwm_set_chan_level(slice_num, chan, PWM_CH0_CC_A_RESET); pwm_hw->slice[slice_num].top = c->top; pwm_hw->slice[slice_num].div = c->div; pwm_hw->slice[slice_num].csr = c->csr | (bool_to_bit(start) << PWM_CH0_CSR_EN_LSB); diff --git a/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h b/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h index 61d480678..9ca283c8f 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h +++ b/cores/arduino/mbed/targets/TARGET_STM/PeripheralPins.h @@ -52,6 +52,11 @@ #define AFIO_REMAP_TIM2_PARTIAL_1 14 #define AFIO_REMAP_TIM2_PARTIAL_2 15 #define AFIO_REMAP_TIM4_ENABLE 16 +#define AFIO_REMAP_TIM9_ENABLE 17 +#define AFIO_REMAP_TIM10_ENABLE 18 +#define AFIO_REMAP_TIM11_ENABLE 19 +#define AFIO_REMAP_TIM13_ENABLE 20 +#define AFIO_REMAP_TIM14_ENABLE 21 #endif diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h index dbdadf962..c8188eb4e 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F0/objects.h @@ -77,39 +77,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct analogin_s { ADC_HandleTypeDef handle; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h index 660403eb5..793badc15 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F1/pin_device.h @@ -109,6 +109,31 @@ static inline void stm_pin_SetAFPin(GPIO_TypeDef *gpio, PinName pin, uint32_t af case AFIO_REMAP_TIM4_ENABLE: __HAL_AFIO_REMAP_TIM4_ENABLE(); break; +#if defined(AFIO_MAPR2_TIM9_REMAP) + case AFIO_REMAP_TIM9_ENABLE: + __HAL_AFIO_REMAP_TIM9_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM10_REMAP) + case AFIO_REMAP_TIM10_ENABLE: + __HAL_AFIO_REMAP_TIM10_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM11_REMAP) + case AFIO_REMAP_TIM11_ENABLE: + __HAL_AFIO_REMAP_TIM11_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM13_REMAP) + case AFIO_REMAP_TIM13_ENABLE: + __HAL_AFIO_REMAP_TIM13_ENABLE(); + break; +#endif +#if defined(AFIO_MAPR2_TIM14_REMAP) + case AFIO_REMAP_TIM14_ENABLE: + __HAL_AFIO_REMAP_TIM14_ENABLE(); + break; +#endif default: break; } diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h index d69e9e7b6..c95c440c8 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F3/objects.h @@ -90,41 +90,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct dac_s { DACName dac; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h index ef8dc2919..ed253af45 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32F7/objects.h @@ -108,39 +108,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct analogin_s { ADC_HandleTypeDef handle; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h index 55dea741c..062116229 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G0/objects.h @@ -89,41 +89,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h index 647c45253..183cf5416 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32G4/objects.h @@ -88,41 +88,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct dac_s { DACName dac; PinName pin; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h index e981df8aa..655995565 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/cmsis_nvic.h @@ -25,20 +25,28 @@ #define MBED_ROM_SIZE 0x100000 // 1 MB #endif +// 0x20000000 - 0x2001FFFF 128K DTCM +// 0x24000000 - 0x2404FFFF 320K AXI SRAM +// 0x30000000 - 0x30003FFF 16K SRAM1 +// 0x30004000 - 0x30007FFF 16K SRAM2 +// 0x38000000 - 0x38003FFF 16K SRAM4 + #if !defined(MBED_RAM_START) -#define MBED_RAM_START 0x24000000 +#define MBED_RAM_START 0x20000000 #endif #if !defined(MBED_RAM_SIZE) -// 0x38000000 - 0x38003FFF 16K SRAM4 -// 0x30004000 - 0x30007FFF 16K SRAM2 -// 0x30000000 - 0x30003FFF 16K SRAM1 -// 0x24000000 - 0x2404FFFF 320K AXI SRAM -// 0x20000000 - 0x2001FFFF 128K DTCM -#define MBED_RAM_SIZE 0x50000 // 320 KB +#define MBED_RAM_SIZE 0x20000 // 128 KB +#endif + +#if !defined(MBED_RAM1_START) +#define MBED_RAM_1START 0x24000000 +#endif + +#if !defined(MBED_RAM1_SIZE) +#define MBED1_RAM_SIZE 0x50000 // 320 KB #endif #define NVIC_NUM_VECTORS 180 #define NVIC_RAM_VECTOR_ADDRESS MBED_RAM_START - #endif diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h index 628ffa747..02ed6ea8c 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -103,39 +103,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - #if DEVICE_ANALOGIN struct analogin_s { ADC_HandleTypeDef handle; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h index 8ed217b88..4becf27ff 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L0/objects.h @@ -91,41 +91,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - #if DEVICE_FLASH struct flash_s { /* nothing to be stored for now */ diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h index 136a582b3..d41e92738 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L4/objects.h @@ -87,41 +87,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - int sda_func; - int scl_func; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h index c06bdd717..ed7d2a8db 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32L5/objects.h @@ -97,39 +97,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h index a5e3d328e..69e9c5bc2 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32U5/objects.h @@ -97,39 +97,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h index 515846edc..a3b501e89 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WB/objects.h @@ -80,39 +80,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h index a8fd7b93d..d3c601b35 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h +++ b/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32WL/objects.h @@ -83,39 +83,6 @@ struct serial_s { #endif }; -struct i2c_s { - /* The 1st 2 members I2CName i2c - * and I2C_HandleTypeDef handle should - * be kept as the first members of this struct - * to ensure i2c_get_obj to work as expected - */ - I2CName i2c; - I2C_HandleTypeDef handle; - uint8_t index; - int hz; - PinName sda; - PinName scl; - IRQn_Type event_i2cIRQ; - IRQn_Type error_i2cIRQ; - uint32_t XferOperation; - volatile uint8_t event; - volatile int pending_start; - int current_hz; -#if DEVICE_I2CSLAVE - uint8_t slave; - volatile uint8_t pending_slave_tx_master_rx; - volatile uint8_t pending_slave_rx_maxter_tx; - uint8_t *slave_rx_buffer; - volatile uint16_t slave_rx_buffer_size; - volatile uint16_t slave_rx_count; -#endif -#if DEVICE_I2C_ASYNCH - uint32_t address; - uint8_t stop; - uint8_t available_events; -#endif -}; - struct flash_s { /* nothing to be stored for now */ uint32_t dummy; diff --git a/cores/arduino/mbed/targets/TARGET_STM/device.h b/cores/arduino/mbed/targets/TARGET_STM/device.h index a2fd83c54..b30041afd 100644 --- a/cores/arduino/mbed/targets/TARGET_STM/device.h +++ b/cores/arduino/mbed/targets/TARGET_STM/device.h @@ -36,6 +36,7 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" +#include "stm_i2c_api.h" #if DEVICE_USTICKER #include "us_ticker_defines.h" diff --git a/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h b/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h new file mode 100644 index 000000000..7ae17f4b8 --- /dev/null +++ b/cores/arduino/mbed/targets/TARGET_STM/stm_i2c_api.h @@ -0,0 +1,102 @@ +/* mbed Microcontroller Library + * Copyright (c) 2016-2022 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef MBED_STM_I2C_API_H +#define MBED_STM_I2C_API_H + +#include "i2c_device.h" + +#include + +/** + * State of the I2C peripheral. + * Note: SB stands for Single Byte, TR stands for Transaction + */ +typedef enum stm_i2c_state +{ + STM_I2C_IDLE, + STM_I2C_PENDING_START, // This state is created either by calling start(), or by completing a transaction with the repeated start flag + STM_I2C_SB_READ_IN_PROGRESS, + STM_I2C_SB_WRITE_IN_PROGRESS, + STM_I2C_TR_READ_IN_PROGRESS, + STM_I2C_TR_WRITE_IN_PROGRESS, + STM_I2C_ASYNC_READ_IN_PROGRESS, + STM_I2C_ASYNC_WRITE_IN_PROGRESS +} stm_i2c_state; + +#ifdef I2C_IP_VERSION_V2 + +/** + * Extended I2C structure containing STM-specific data + */ +struct i2c_s { + /* The 1st 2 members I2CName i2c + * and I2C_HandleTypeDef handle should + * be kept as the first members of this struct + * to ensure i2c_get_obj to work as expected + */ + I2CName i2c; + I2C_HandleTypeDef handle; + uint8_t index; + int hz; + PinName sda; + PinName scl; + IRQn_Type event_i2cIRQ; + IRQn_Type error_i2cIRQ; + volatile stm_i2c_state state; + + /// Used to pass events (the I2C_EVENT_xxx defines) from ISRs to the main thread + volatile uint8_t event; + + int current_hz; +#if DEVICE_I2CSLAVE + uint8_t slave; + volatile uint8_t pending_slave_tx_master_rx; + volatile uint8_t pending_slave_rx_maxter_tx; + uint8_t *slave_rx_buffer; + volatile uint16_t slave_rx_buffer_size; + volatile uint16_t slave_rx_count; +#endif +#if DEVICE_I2C_ASYNCH + /// Address that the current asynchronous transaction is talking to + uint32_t address; + + /// If true, send a stop at the end of the current asynchronous transaction + bool stop; + + /// Specifies which events (the I2C_EVENT_xxx defines) can be passed up to the application from the IRQ handler + uint8_t available_events; +#endif + +#if STATIC_PINMAP_READY + int sda_func; + int scl_func; +#endif +}; + +#endif + +// Macro that can be used to set the state of an I2C object. +// Compiles to nothing for IP v1 +#ifdef I2C_IP_VERSION_V2 +#define STM_I2C_SET_STATE(i2c_s, new_state) i2c_s->state = new_state +#else +#define STM_I2C_SET_STATE(i2c_s, new_state) (void)i2c_s +#endif + +#endif //MBED_STM_I2C_API_H diff --git a/giga.variables b/giga.variables index c3d7ea373..83045721f 100644 --- a/giga.variables +++ b/giga.variables @@ -1,5 +1,5 @@ export FLAVOUR="giga" export VARIANTS=("GIGA PORTENTA_H7_M4") export FQBNS=("giga") -export LIBRARIES=("MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 PDM Portenta_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib OV7670 mbed-memory-status Scheduler USBMSD SocketWrapper MCUboot") +export LIBRARIES=("MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 PDM Arduino_H7_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib OV7670 mbed-memory-status Scheduler USBMSD USBMIDI SocketWrapper MCUboot Arduino_CAN") export BOOTLOADERS=("GIGA") diff --git a/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino index 522f6c345..78d1c68a3 100644 --- a/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino +++ b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino @@ -35,7 +35,7 @@ void loop() */ uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0}; memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt)); - CanMsg msg(CAN_ID, sizeof(msg_data), msg_data); + CanMsg msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data); /* Transmit the CAN message, capture and display an * error core in case of failure. diff --git a/libraries/Arduino_CAN/src/Arduino_CAN.cpp b/libraries/Arduino_CAN/src/Arduino_CAN.cpp index fce0ce3a2..de74c22c5 100644 --- a/libraries/Arduino_CAN/src/Arduino_CAN.cpp +++ b/libraries/Arduino_CAN/src/Arduino_CAN.cpp @@ -48,12 +48,14 @@ void Arduino_CAN::end() int Arduino_CAN::write(CanMsg const & msg) { + bool const is_standard_id = msg.isStandardId(); + mbed::CANMessage const can_msg( - msg.id, + is_standard_id ? msg.getStandardId() : msg.getExtendedId(), msg.data, msg.data_length, CANData, - CANStandard); + is_standard_id ? CANStandard : CANExtended); return _can.write(can_msg); } @@ -65,8 +67,10 @@ size_t Arduino_CAN::available() if (msg_read) { + bool const is_standard_id = (can_msg.format == CANStandard); + CanMsg const msg( - can_msg.id, + is_standard_id ? CanStandardId(can_msg.id) : CanExtendedId(can_msg.id), can_msg.len, can_msg.data); diff --git a/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino b/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino index d9218000d..4c1328d21 100644 --- a/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino +++ b/libraries/Camera/examples/GigaCameraDisplay/GigaCameraDisplay.ino @@ -1,28 +1,40 @@ -#include "camera.h" -#include "Portenta_lvgl.h" -#include "Portenta_Video.h" +#include "arducam_dvp.h" +#include "Arduino_H7_Video.h" +#include "dsi.h" +#include "SDRAM.h" -#if 0 -#include "gc2145.h" -GC2145 galaxyCore; -Camera cam(galaxyCore); -#define IMAGE_MODE CAMERA_RGB565 -#else -#include "himax.h" +// This example only works with Greyscale cameras (due to the palette + resize&rotate algo) +#define ARDUCAM_CAMERA_HM01B0 + +#ifdef ARDUCAM_CAMERA_HM01B0 +#include "Himax_HM01B0/himax.h" HM01B0 himax; Camera cam(himax); #define IMAGE_MODE CAMERA_GRAYSCALE +#elif defined(ARDUCAM_CAMERA_HM0360) +#include "Himax_HM0360/hm0360.h" +HM0360 himax; +Camera cam(himax); +#define IMAGE_MODE CAMERA_GRAYSCALE +#elif defined(ARDUCAM_CAMERA_OV767X) +#include "OV7670/ov767x.h" +// OV7670 ov767x; +OV7675 ov767x; +Camera cam(ov767x); +#define IMAGE_MODE CAMERA_RGB565 +#elif defined(ARDUCAM_CAMERA_GC2145) +#include "GC2145/gc2145.h" +GC2145 galaxyCore; +Camera cam(galaxyCore); +#define IMAGE_MODE CAMERA_RGB565 #endif -/* - Other buffer instantiation options: - FrameBuffer fb(0x30000000); - FrameBuffer fb(320,240,2); -*/ +// The buffer used to capture the frame FrameBuffer fb; - -unsigned long lastUpdate = 0; - +// The buffer used to rotate and resize the frame +FrameBuffer outfb; +// The buffer used to rotate and resize the frame +Arduino_H7_Video Display(800, 480, GigaDisplayShield); void blinkLED(uint32_t count = 0xFFFFFFFF) { @@ -34,68 +46,61 @@ void blinkLED(uint32_t count = 0xFFFFFFFF) delay(50); // wait for a second } } -void LCD_ST7701_Init(); uint32_t palette[256]; void setup() { - pinMode(PA_1, OUTPUT); - digitalWrite(PA_1, HIGH); - - pinMode(PD_4, OUTPUT); - digitalWrite(PD_4, LOW); - // Init the cam QVGA, 30FPS if (!cam.begin(CAMERA_R320x240, IMAGE_MODE, 30)) { blinkLED(); } + // Setup the palette to convert 8 bit greyscale to 32bit greyscale for (int i = 0; i < 256; i++) { palette[i] = 0xFF000000 | (i << 16) | (i << 8) | i; } - giga_init_video(); - LCD_ST7701_Init(); + Display.begin(); - blinkLED(5); + if (IMAGE_MODE == CAMERA_GRAYSCALE) { + dsi_configueCLUT((uint32_t*)palette); + } + outfb.setBuffer((uint8_t*)SDRAM.malloc(1024 * 1024)); - stm32_configue_CLUT((uint32_t*)palette); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); - stm32_LCD_Clear(0); + // clear the display (gives a nice black background) + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); + dsi_lcdClear(0); + dsi_drawCurrentFrameBuffer(); } -#include "avir.h" +#define HTONS(x) (((x >> 8) & 0x00FF) | ((x << 8) & 0xFF00)) void loop() { - lastUpdate = millis(); - - // Grab frame and write to serial + // Grab frame and write to another framebuffer if (cam.grabFrame(fb, 3000) == 0) { - //avir :: CImageResizer<> ImageResizer( 8 ); - //ImageResizer.resizeImage( (uint8_t*)fb.getBuffer(), 320, 240, 0, (uint8_t*)outfb.getBuffer(), 480, 320, 1, 0 ); - static FrameBuffer outfb(0x30000000); - //static FrameBuffer outfb(getFramebufferEnd()); - for (int i = 0; i < 300; i++) { + + // double the resolution and transpose (rotate by 90 degrees) in the same step + // this only works if the camera feed is 320x240 and the area where we want to display is 640x480 + for (int i = 0; i < 320; i++) { for (int j = 0; j < 240; j++) { - //((uint8_t*)outfb.getBuffer())[j * 240 + (320 - i)] = ((uint8_t*)fb.getBuffer())[i * 320 + j]; -#if 1 - ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i*2+1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; - ((uint8_t*)outfb.getBuffer())[j * 2 + (i*2+1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; -#endif -#if 0 - ((uint8_t*)outfb.getBuffer())[j + i * 240] = ((uint8_t*)fb.getBuffer())[i + j * 320]; -#endif + if (IMAGE_MODE == CAMERA_GRAYSCALE) { + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + ((uint8_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = ((uint8_t*)fb.getBuffer())[i + j * 320]; + } else { + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + ((uint16_t*)outfb.getBuffer())[j * 2 + (i * 2 + 1) * 480 + 1] = HTONS(((uint16_t*)fb.getBuffer())[i + j * 320]); + } } } - //stm32_LCD_DrawImage((void*)outfb.getBuffer(), (void*)getNextFrameBuffer(), 240, 320, DMA2D_INPUT_L8); - stm32_LCD_DrawImage((void*)outfb.getBuffer(), (void*)getNextFrameBuffer(), 480, 640, DMA2D_INPUT_L8); - //stm32_LCD_DrawImage((void*)fb.getBuffer(), (void*)getNextFrameBuffer(), 320, 240, DMA2D_INPUT_L8); + dsi_lcdDrawImage((void*)outfb.getBuffer(), (void*)dsi_getCurrentFrameBuffer(), 480, 640, IMAGE_MODE == CAMERA_GRAYSCALE ? DMA2D_INPUT_L8 : DMA2D_INPUT_RGB565); + dsi_drawCurrentFrameBuffer(); } else { blinkLED(20); } -} +} \ No newline at end of file diff --git a/libraries/Camera/examples/GigaCameraDisplay/avir.h b/libraries/Camera/examples/GigaCameraDisplay/avir.h deleted file mode 100644 index ce4cec87a..000000000 --- a/libraries/Camera/examples/GigaCameraDisplay/avir.h +++ /dev/null @@ -1,6644 +0,0 @@ -//$ nobt -//$ nocpp - -/** - * @file avir.h - * - * @brief The "main" inclusion file with all required classes and functions. - * - * This is the "main" inclusion file for the "AVIR" image resizer. This - * inclusion file contains implementation of the AVIR image resizing algorithm - * in its entirety. Also includes several classes and functions that can be - * useful elsewhere. - * - * AVIR Copyright (c) 2015-2021 Aleksey Vaneev - * - * @mainpage - * - * @section intro_sec Introduction - * - * Description is available at https://github.com/avaneev/avir - * - * AVIR is devoted to women. Your digital photos can look good at any size! - * - * Please credit the author of this library in your documentation in the - * following way: "AVIR image resizing algorithm designed by Aleksey Vaneev". - * - * @section license License - * - * MIT License - * - * Copyright (c) 2015-2021 Aleksey Vaneev - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * @version 3.0 - */ - -#ifndef AVIR_CIMAGERESIZER_INCLUDED -#define AVIR_CIMAGERESIZER_INCLUDED - -#include -#include -#include -#include - -namespace avir { - -/** - * The macro defines AVIR version string. - */ - -#define AVIR_VERSION "3.0" - -/** - * The macro equals to "pi" constant, fills 53-bit floating point mantissa. - * Undefined at the end of file. - */ - -#define AVIR_PI 3.1415926535897932 - -/** - * The macro equals to "pi divided by 2" constant, fills 53-bit floating - * point mantissa. Undefined at the end of file. - */ - -#define AVIR_PId2 1.5707963267948966 - -/** - * A special macro that defines empty copy-constructor and copy operator with - * the "private:" prefix. This macro should be used in classes that cannot be - * copied in a standard C++ way. - */ - -#define AVIR_NOCTOR( ClassName ) \ - private: \ - ClassName( const ClassName& ) { } \ - ClassName& operator = ( const ClassName& ) { return( *this ); } - -/** - * Rounding function, based on the (int) typecast. Biased result. Not suitable - * for numbers >= 2^31. - * - * @param d Value to round. - * @return Rounded value. Some bias may be introduced. - */ - -template< class T > -inline T round( const T d ) -{ - return( d < (T) 0 ? -(T) (int) ( (T) 0.5 - d ) : - (T) (int) ( d + (T) 0.5 )); -} - -/** - * Template function "clamps" (clips) the specified value so that it is not - * lesser than "minv", and not greater than "maxv". - * - * @param Value Value to clamp. - * @param minv Minimal allowed value. - * @param maxv Maximal allowed value. - * @return The clamped value. - */ - -template< class T > -inline T clamp( const T& Value, const T minv, const T maxv ) -{ - if( Value < minv ) - { - return( minv ); - } - else - if( Value > maxv ) - { - return( maxv ); - } - else - { - return( Value ); - } -} - -/** - * Power 2.4 approximation function, designed for sRGB gamma correction. - * - * @param x Argument, in the range 0.09 to 1. - * @return Value raised into power 2.4, approximate. - */ - -template< class T > -inline T pow24_sRGB( const T x ) -{ - const double x2 = (double) x * x; - const double x3 = x2 * x; - const double x4 = x2 * x2; - - return( (T) ( 0.0985766365536824 + 0.839474952656502 * x2 + - 0.363287814061725 * x3 - 0.0125559718896615 / - ( 0.12758338921578 + 0.290283465468235 * x ) - - 0.231757513261358 * x - 0.0395365717969074 * x4 )); -} - -/** - * Power 1/2.4 approximation function, designed for sRGB gamma correction. - * - * @param x Argument, in the range 0.003 to 1. - * @return Value raised into power 1/2.4, approximate. - */ - -template< class T > -inline T pow24i_sRGB( const T x ) -{ - const double sx = sqrt( (double) x ); - const double ssx = sqrt( sx ); - const double sssx = sqrt( ssx ); - - return( (T) ( 0.000213364515060263 + 0.0149409239419218 * x + - 0.433973412731747 * sx + ssx * ( 0.659628181609715 * sssx - - 0.0380957908841466 - 0.0706476137208521 * sx ))); -} - -/** - * Function approximately linearizes the sRGB gamma value. - * - * @param s sRGB gamma value, in the range 0 to 1. - * @return Linearized sRGB gamma value, approximated. - */ - -template< class T > -inline T convertSRGB2Lin( const T s ) -{ - const T a = (T) 0.055; - - if( s <= (T) 0.04045 ) - { - return( s / (T) 12.92 ); - } - - return( pow24_sRGB(( s + a ) / ( (T) 1 + a ))); -} - -/** - * Function approximately de-linearizes the linear gamma value. - * - * @param s Linear gamma value, in the range 0 to 1. - * @return sRGB gamma value, approximated. - */ - -template< class T > -inline T convertLin2SRGB( const T s ) -{ - const T a = (T) 0.055; - - if( s <= (T) 0.0031308 ) - { - return( (T) 12.92 * s ); - } - - return(( (T) 1 + a ) * pow24i_sRGB( s ) - a ); -} - -/** - * Function converts (via typecast) specified array of type T1 values of - * length l into array of type T2 values. If T1 is the same as T2, copy - * operation is performed. When copying data at overlapping address spaces, - * "op" should be lower than "ip". - * - * @param ip Input buffer. - * @param[out] op Output buffer. - * @param l The number of elements to copy. - * @param ip Input buffer pointer increment. - * @param op Output buffer pointer increment. - */ - -template< class T1, class T2 > -inline void copyArray( const T1* ip, T2* op, int l, - const int ipinc = 1, const int opinc = 1 ) -{ - while( l > 0 ) - { - *op = (T2) *ip; - op += opinc; - ip += ipinc; - l--; - } -} - -/** - * Function adds values located in array "ip" to array "op". - * - * @param ip Input buffer. - * @param[out] op Output buffer. - * @param l The number of elements to add. - * @param ip Input buffer pointer increment. - * @param op Output buffer pointer increment. - */ - -template< class T1, class T2 > -inline void addArray( const T1* ip, T2* op, int l, - const int ipinc = 1, const int opinc = 1 ) -{ - while( l > 0 ) - { - *op += *ip; - op += opinc; - ip += ipinc; - l--; - } -} - -/** - * Function that replicates a set of adjacent elements several times in a row. - * This operation is usually used to replicate pixels at the start or end of - * image's scanline. - * - * @param ip Source array. - * @param ipl Source array length (usually 1..4, but can be any number). - * @param[out] op Destination buffer. - * @param l Number of times the source array should be replicated (the - * destination buffer should be able to hold ipl * l number of elements). - * @param opinc Destination buffer position increment after replicating the - * source array. This value should be equal to at least ipl. - */ - -template< class T1, class T2 > -inline void replicateArray( const T1* const ip, const int ipl, T2* op, int l, - const int opinc ) -{ - if( ipl == 1 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op += opinc; - l--; - } - } - else - if( ipl == 4 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op[ 2 ] = (T2) ip[ 2 ]; - op[ 3 ] = (T2) ip[ 3 ]; - op += opinc; - l--; - } - } - else - if( ipl == 3 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op[ 2 ] = (T2) ip[ 2 ]; - op += opinc; - l--; - } - } - else - if( ipl == 2 ) - { - while( l > 0 ) - { - op[ 0 ] = (T2) ip[ 0 ]; - op[ 1 ] = (T2) ip[ 1 ]; - op += opinc; - l--; - } - } - else - { - while( l > 0 ) - { - int i; - - for( i = 0; i < ipl; i++ ) - { - op[ i ] = (T2) ip[ i ]; - } - - op += opinc; - l--; - } - } -} - -/** - * Function calculates frequency response of the specified FIR filter at the - * specified circular frequency. Phase can be calculated as atan2( im, re ). - * Function uses computationally-efficient oscillators instead of "cos" and - * "sin" functions. - * - * @param flt FIR filter's coefficients. - * @param fltlen Number of coefficients (taps) in the filter. - * @param th Circular frequency [0; pi]. - * @param[out] re0 Resulting real part of the complex frequency response. - * @param[out] im0 Resulting imaginary part of the complex frequency response. - * @param fltlat Filter's latency in samples (taps). - */ - -template< class T > -inline void calcFIRFilterResponse( const T* flt, int fltlen, - const double th, double& re0, double& im0, const int fltlat = 0 ) -{ - const double sincr = 2.0 * cos( th ); - double cvalue1; - double svalue1; - - if( fltlat == 0 ) - { - cvalue1 = 1.0; - svalue1 = 0.0; - } - else - { - cvalue1 = cos( -fltlat * th ); - svalue1 = sin( -fltlat * th ); - } - - double cvalue2 = cos( -( fltlat + 1 ) * th ); - double svalue2 = sin( -( fltlat + 1 ) * th ); - - double re = 0.0; - double im = 0.0; - - while( fltlen > 0 ) - { - re += cvalue1 * flt[ 0 ]; - im += svalue1 * flt[ 0 ]; - flt++; - fltlen--; - - double tmp = cvalue1; - cvalue1 = sincr * cvalue1 - cvalue2; - cvalue2 = tmp; - - tmp = svalue1; - svalue1 = sincr * svalue1 - svalue2; - svalue2 = tmp; - } - - re0 = re; - im0 = im; -} - -/** - * Function normalizes FIR filter so that its frequency response at DC is - * equal to DCGain. - * - * @param[in,out] p Filter coefficients. - * @param l Filter length. - * @param DCGain Filter's gain at DC. - * @param pstep "p" array step. - */ - -template< class T > -inline void normalizeFIRFilter( T* const p, const int l, const double DCGain, - const int pstep = 1 ) -{ - double s = 0.0; - T* pp = p; - int i = l; - - while( i > 0 ) - { - s += *pp; - pp += pstep; - i--; - } - - s = DCGain / s; - pp = p; - i = l; - - while( i > 0 ) - { - *pp = (T) ( *pp * s ); - pp += pstep; - i--; - } -} - -/** - * @brief Memory buffer class for element array storage, with capacity - * tracking. - * - * Allows easier handling of memory blocks allocation and automatic - * deallocation for arrays (buffers) consisting of elements of specified - * class. Tracks buffer's capacity in "int" variable; unsuitable for - * allocation of very large memory blocks (with more than 2 billion elements). - * - * This class manages memory space only - it does not perform element class - * construction (initialization) operations. Buffer's required memory address - * alignment specification is supported. - * - * Uses standard library to allocate and deallocate memory. - * - * @tparam T Buffer element's type. - * @tparam capint Buffer capacity's type to use. Use size_t for large buffers. - */ - -template< class T, typename capint = int > -class CBuffer -{ -public: - CBuffer() - : Data( NULL ) - , DataAligned( NULL ) - , Capacity( 0 ) - , Alignment( 0 ) - { - } - - /** - * Constructor creates the buffer with the specified capacity. - * - * @param aCapacity Buffer's capacity. - * @param aAlignment Buffer's required memory address alignment. 0 - use - * stdlib's default alignment. - */ - - CBuffer( const capint aCapacity, const int aAlignment = 0 ) - { - allocinit( aCapacity, aAlignment ); - } - - CBuffer( const CBuffer& Source ) - { - allocinit( Source.Capacity, Source.Alignment ); - - if( Capacity > 0 ) - { - memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); - } - } - - ~CBuffer() - { - freeData(); - } - - CBuffer& operator = ( const CBuffer& Source ) - { - alloc( Source.Capacity, Source.Alignment ); - - if( Capacity > 0 ) - { - memcpy( DataAligned, Source.DataAligned, Capacity * sizeof( T )); - } - - return( *this ); - } - - /** - * Function allocates memory so that the specified number of elements - * can be stored in *this buffer object. - * - * @param aCapacity Storage for this number of elements to allocate. - * @param aAlignment Buffer's required memory address alignment, - * power-of-2 values only. 0 - use stdlib's default alignment. - */ - - void alloc( const capint aCapacity, const int aAlignment = 0 ) - { - freeData(); - allocinit( aCapacity, aAlignment ); - } - - /** - * Function deallocates any previously allocated buffer. - */ - - void free() - { - freeData(); - Data = NULL; - DataAligned = NULL; - Capacity = 0; - Alignment = 0; - } - - /** - * @return The capacity of the element buffer. - */ - - capint getCapacity() const - { - return( Capacity ); - } - - /** - * Function "forces" *this buffer to have an arbitary capacity. Calling - * this function invalidates all further operations except deleting *this - * object. This function should not be usually used at all. Function can - * be used to "model" certain buffer capacity without calling a costly - * memory allocation function. - * - * @param NewCapacity A new "forced" capacity. - */ - - void forceCapacity( const capint NewCapacity ) - { - Capacity = NewCapacity; - } - - /** - * Function reallocates *this buffer to a larger size so that it will be - * able to hold the specified number of elements. Downsizing is not - * performed. Alignment is not changed. - * - * @param NewCapacity New (increased) capacity. - * @param DoDataCopy "True" if data in the buffer should be retained. - */ - - void increaseCapacity( const capint NewCapacity, - const bool DoDataCopy = true ) - { - if( NewCapacity < Capacity ) - { - return; - } - - if( DoDataCopy ) - { - const capint PrevCapacity = Capacity; - T* const PrevData = Data; - T* const PrevDataAligned = DataAligned; - - allocinit( NewCapacity, Alignment ); - - if( PrevCapacity > 0 ) - { - memcpy( DataAligned, PrevDataAligned, - PrevCapacity * sizeof( T )); - } - - :: free( PrevData ); - } - else - { - :: free( Data ); - allocinit( NewCapacity, Alignment ); - } - } - - /** - * Function "truncates" (reduces) capacity of the buffer without - * reallocating it. Alignment is not changed. - * - * @param NewCapacity New required capacity. - */ - - void truncateCapacity( const capint NewCapacity ) - { - if( NewCapacity >= Capacity ) - { - return; - } - - Capacity = NewCapacity; - } - - /** - * Function increases capacity so that the specified number of - * elements can be stored. This function increases the previous capacity - * value by third the current capacity value until space for the required - * number of elements is available. Alignment is not changed. - * - * @param ReqCapacity Required capacity. - */ - - void updateCapacity( const capint ReqCapacity ) - { - if( ReqCapacity <= Capacity ) - { - return; - } - - capint NewCapacity = Capacity; - - while( NewCapacity < ReqCapacity ) - { - NewCapacity += NewCapacity / 3 + 1; - } - - increaseCapacity( NewCapacity ); - } - - operator T* () const - { - return( DataAligned ); - } - -private: - T* Data; ///< Element buffer pointer. - ///< - T* DataAligned; ///< Memory address-aligned element buffer pointer. - ///< - capint Capacity; ///< Element buffer capacity. - ///< - int Alignment; ///< Memory address alignment in use. 0 - use stdlib's - ///< default alignment. - ///< - - /** - * Internal element buffer allocation function used during object - * construction. - * - * @param aCapacity Storage for this number of elements to allocate. - * @param aAlignment Buffer's required memory address alignment. 0 - use - * stdlib's default alignment. - */ - - void allocinit( const capint aCapacity, const int aAlignment ) - { - if( aAlignment == 0 ) - { - Data = (T*) :: malloc( aCapacity * sizeof( T )); - DataAligned = Data; - Alignment = 0; - } - else - { - Data = (T*) :: malloc( aCapacity * sizeof( T ) + aAlignment ); - DataAligned = alignptr( Data, aAlignment ); - Alignment = aAlignment; - } - - Capacity = aCapacity; - } - - /** - * Function frees a previously allocated Data buffer. - */ - - void freeData() - { - :: free( Data ); - } - - /** - * Function modifies the specified pointer so that it becomes memory - * address-aligned. - * - * @param ptr Pointer to align. - * @param align Alignment in bytes to apply. - * @return Pointer aligned to align bytes. Works with power-of-2 - * alignments only. If no alignment is necessary, "align" bytes will be - * added to the pointer value. - */ - - template< class Tp > - inline Tp alignptr( const Tp ptr, const uintptr_t align ) - { - return( (Tp) ( (uintptr_t) ptr + align - - ( (uintptr_t) ptr & ( align - 1 ))) ); - } -}; - -/** - * @brief Array of structured objects. - * - * Implements allocation of a linear array of objects of class T (which are - * initialized), addressable via operator[]. Each object is created via the - * "operator new". New object insertions are quick since implementation uses - * prior space allocation (capacity), thus not requiring frequent memory block - * reallocations. - * - * @tparam T Array element's type. - */ - -template< class T > -class CStructArray -{ -public: - CStructArray() - : ItemCount( 0 ) - { - } - - CStructArray( const CStructArray& Source ) - : ItemCount( 0 ) - , Items( Source.getItemCount() ) - { - while( ItemCount < Source.getItemCount() ) - { - Items[ ItemCount ] = new T( Source[ ItemCount ]); - ItemCount++; - } - } - - ~CStructArray() - { - clear(); - } - - CStructArray& operator = ( const CStructArray& Source ) - { - clear(); - - const int NewCount = Source.ItemCount; - Items.updateCapacity( NewCount ); - - while( ItemCount < NewCount ) - { - Items[ ItemCount ] = new T( Source[ ItemCount ]); - ItemCount++; - } - - return( *this ); - } - - T& operator []( const int Index ) - { - return( *Items[ Index ]); - } - - const T& operator []( const int Index ) const - { - return( *Items[ Index ]); - } - - /** - * Function creates a new object of type T with the default constructor - * and adds this object to the array. - * - * @return Reference to a newly added object. - */ - - T& add() - { - if( ItemCount == Items.getCapacity() ) - { - Items.increaseCapacity( ItemCount * 3 / 2 + 1 ); - } - - Items[ ItemCount ] = new T(); - ItemCount++; - - return( (*this)[ ItemCount - 1 ]); - } - - /** - * Function changes number of allocated items. New items are created with - * the default constructor. If NewCount is below the current item count, - * items that are above NewCount range will be destructed. - * - * @param NewCount New requested item count. - */ - - void setItemCount( const int NewCount ) - { - if( NewCount > ItemCount ) - { - Items.increaseCapacity( NewCount ); - - while( ItemCount < NewCount ) - { - Items[ ItemCount ] = new T(); - ItemCount++; - } - } - else - { - while( ItemCount > NewCount ) - { - ItemCount--; - delete Items[ ItemCount ]; - } - } - } - - /** - * Function erases all items of *this array. - */ - - void clear() - { - while( ItemCount > 0 ) - { - ItemCount--; - delete Items[ ItemCount ]; - } - } - - /** - * @return The number of allocated items. - */ - - int getItemCount() const - { - return( ItemCount ); - } - -private: - int ItemCount; ///< The number of items available in the array. - ///< - CBuffer< T* > Items; ///< Element buffer. - ///< -}; - -/** - * @brief Sine signal generator class. - * - * Class implements sine signal generator without biasing, with - * constructor-based initalization only. This generator uses oscillator - * instead of "sin" function. - */ - -class CSineGen -{ -public: - /** - * Constructor initializes *this sine signal generator. - * - * @param si Sine function increment, in radians. - * @param ph Starting phase, in radians. Add 0.5 * AVIR_PI for cosine - * function. - */ - - CSineGen( const double si, const double ph ) - : svalue1( sin( ph )) - , svalue2( sin( ph - si )) - , sincr( 2.0 * cos( si )) - { - } - - /** - * @return The next value of the sine function, without biasing. - */ - - double generate() - { - const double res = svalue1; - - svalue1 = sincr * res - svalue2; - svalue2 = res; - - return( res ); - } - -private: - double svalue1; ///< Current sine value. - ///< - double svalue2; ///< Previous sine value. - ///< - double sincr; ///< Sine value increment. - ///< -}; - -/** - * @brief Peaked Cosine window function generator class. - * - * Class implements Peaked Cosine window function generator. Generates the - * right-handed half of the window function. The Alpha parameter of this - * window function offers the control of the balance between the early and - * later taps of the filter. E.g. at Alpha=1 both early and later taps are - * attenuated, but at Alpha=4 mostly later taps are attenuated. This offers a - * great control over ringing artifacts produced by a low-pass filter in image - * processing, without compromising achieved image sharpness. - */ - -class CDSPWindowGenPeakedCosine -{ -public: - /** - * Constructor initializes *this window function generator. - * - * @param aAlpha Alpha parameter, affects the peak shape (peak - * augmentation) of the window function. Any positive value can be used. - * @param aLen2 Half filter's length (non-truncated). - */ - - CDSPWindowGenPeakedCosine( const double aAlpha, const double aLen2 ) - : Alpha( aAlpha ) - , Len2( aLen2 ) - , Len2i( 1.0 / aLen2 ) - , wn( 0.0 ) - , w1( AVIR_PId2 / Len2, AVIR_PI * 0.5 ) - { - } - - /** - * @return The next Peaked Cosine window function coefficient. - */ - - double generate() - { - const double h = pow( wn * Len2i, Alpha ); - wn += 1.0; - - return( w1.generate() * ( 1.0 - h )); - } - -private: - double Alpha; ///< Alpha parameter, affects the peak shape of window. - ///< - double Len2; ///< Half length of the window function. - ///< - double Len2i; ///< = 1 / Len2. - ///< - double wn; ///< Window function integer position. 0 - center of the - ///< window function. - ///< - CSineGen w1; ///< Sine-wave generator. - ///< -}; - -/** - * @brief FIR filter-based equalizer generator. - * - * Class implements an object used to generate symmetric-odd FIR filters with - * the specified frequency response (aka paragraphic equalizer). The - * calculated filter is windowed by the Peaked Cosine window function. - * - * In image processing, due to short length of filters being used (6-8 taps) - * the resulting frequency response of the filter is approximate and may be - * mathematically imperfect, but still adequate to the visual requirements. - * - * On a side note, this equalizer generator can be successfully used for audio - * signal equalization as well: for example, it is used in almost the same - * form in Voxengo Marvel GEQ equalizer plug-in. - * - * Filter generation is based on decomposition of frequency range into - * spectral bands, with each band represented by linear and ramp "kernels". - * When the filter is built, these kernels are combined together with - * different weights that approximate the required frequency response. - */ - -class CDSPFIREQ -{ -public: - /** - * Function initializes *this object with the required parameters. The - * gain of frequencies beyond the MinFreq..MaxFreq range are controlled by - * the first and the last band's gain. - * - * @param SampleRate Processing sample rate (use 2 for image processing). - * @param aFilterLength Required filter length in samples (taps). The - * actual filter length is truncated to an integer value. - * @param aBandCount Number of band crossover points required to control, - * including bands at MinFreq and MaxFreq. - * @param MinFreq Minimal frequency that should be controlled. - * @param MaxFreq Maximal frequency that should be controlled. - * @param IsLogBands "True" if the bands should be spaced logarithmically. - * @param WFAlpha Peaked Cosine window function's Alpha parameter. - */ - - void init( const double SampleRate, const double aFilterLength, - const int aBandCount, const double MinFreq, const double MaxFreq, - const bool IsLogBands, const double WFAlpha ) - { - FilterLength = aFilterLength; - BandCount = aBandCount; - - CenterFreqs.alloc( BandCount ); - - z = (int) ceil( FilterLength * 0.5 ); - zi = z + ( z & 1 ); - z2 = z * 2; - - CBuffer< double > oscbuf( z2 ); - initOscBuf( oscbuf ); - - CBuffer< double > winbuf( z ); - initWinBuf( winbuf, WFAlpha ); - - UseFirstVirtBand = ( MinFreq > 0.0 ); - const int k = zi * ( BandCount + ( UseFirstVirtBand ? 1 : 0 )); - Kernels1.alloc( k ); - Kernels2.alloc( k ); - - double m; // Frequency step multiplier. - double mo; // Frequency step offset (addition). - - if( IsLogBands ) - { - m = exp( log( MaxFreq / MinFreq ) / ( BandCount - 1 )); - mo = 0.0; - } - else - { - m = 1.0; - mo = ( MaxFreq - MinFreq ) / ( BandCount - 1 ); - } - - double f = MinFreq; - double x1 = 0.0; - double x2; - int si; - - if( UseFirstVirtBand ) - { - si = 0; - } - else - { - si = 1; - CenterFreqs[ 0 ] = 0.0; - f = f * m + mo; - } - - double* kernbuf1 = &Kernels1[ 0 ]; - double* kernbuf2 = &Kernels2[ 0 ]; - int i; - - for( i = si; i < BandCount; i++ ) - { - x2 = f * 2.0 / SampleRate; - CenterFreqs[ i ] = x2; - - fillBandKernel( x1, x2, kernbuf1, kernbuf2, oscbuf, winbuf ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - f = f * m + mo; - } - - if( x1 < 1.0 ) - { - UseLastVirtBand = true; - fillBandKernel( x1, 1.0, kernbuf1, kernbuf2, oscbuf, winbuf ); - } - else - { - UseLastVirtBand = false; - } - } - - /** - * @return Filter's length, in samples (taps). - */ - - int getFilterLength() const - { - return( z2 - 1 ); - } - - /** - * @return Filter's latency (group delay), in samples (taps). - */ - - int getFilterLatency() const - { - return( z - 1 ); - } - - /** - * Function creates symmetric-odd FIR filter with the specified gain - * levels at band crossover points. - * - * @param BandGains Array of linear gain levels, count=BandCount specified - * in the init() function. - * @param[out] Filter Output filter buffer, length = getFilterLength(). - */ - - void buildFilter( const double* const BandGains, double* const Filter ) - { - const double* kernbuf1 = &Kernels1[ 0 ]; - const double* kernbuf2 = &Kernels2[ 0 ]; - double x1 = 0.0; - double y1 = BandGains[ 0 ]; - double x2; - double y2; - - int i; - int si; - - if( UseFirstVirtBand ) - { - si = 1; - x2 = CenterFreqs[ 0 ]; - y2 = y1; - } - else - { - si = 2; - x2 = CenterFreqs[ 1 ]; - y2 = BandGains[ 1 ]; - } - - copyBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - x2 * y1 ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - y1 = y2; - - for( i = si; i < BandCount; i++ ) - { - x2 = CenterFreqs[ i ]; - y2 = BandGains[ i ]; - - addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - x2 * y1 ); - - kernbuf1 += zi; - kernbuf2 += zi; - x1 = x2; - y1 = y2; - } - - if( UseLastVirtBand ) - { - addBandKernel( Filter, kernbuf1, kernbuf2, y1 - y2, - x1 * y2 - y1 ); - } - - for( i = 0; i < z - 1; i++ ) - { - Filter[ z + i ] = Filter[ z - 2 - i ]; - } - } - - /** - * Function calculates filter's length (in samples) and latency depending - * on the required non-truncated filter length. - * - * @param aFilterLength Required filter length in samples (non-truncated). - * @param[out] Latency Resulting latency (group delay) of the filter, - * in samples (taps). - * @return Filter length in samples (taps). - */ - - static int calcFilterLength( const double aFilterLength, int& Latency ) - { - const int l = (int) ceil( aFilterLength * 0.5 ); - Latency = l - 1; - - return( l * 2 - 1 ); - } - -private: - double FilterLength; ///< Length of filter. - ///< - int z; ///< Equals (int) ceil( FilterLength * 0.5 ). - ///< - int zi; ///< Equals "z" if z is even, or z + 1 if z is odd. Used as a - ///< Kernels1 and Kernels2 size multiplier and kernel buffer increment - ///< to make sure each kernel buffer is 16-byte aligned. - ///< - int z2; ///< Equals z * 2. - ///< - int BandCount; ///< Number of controllable bands. - ///< - CBuffer< double > CenterFreqs; ///< Center frequencies for all bands, - ///< normalized to 0.0-1.0 range. - ///< - CBuffer< double > Kernels1; ///< Half-length kernel buffers for each - ///< spectral band (linear part). - ///< - CBuffer< double > Kernels2; ///< Half-length kernel buffers for each - ///< spectral band (ramp part). - ///< - bool UseFirstVirtBand; ///< "True" if the first virtual band - ///< (between 0.0 and MinFreq) should be used. The first virtual band - ///< won't be used if MinFreq equals 0.0. - ///< - bool UseLastVirtBand; ///< "True" if the last virtual band (between - ///< MaxFreq and SampleRate * 0.5) should be used. The last virtual - ///< band won't be used if MaxFreq * 2.0 equals SampleRate. - ///< - - /** - * Function initializes the "oscbuf" used in the fillBandKernel() - * function. - * - * @param oscbuf Oscillator buffer, length = z * 2. - */ - - void initOscBuf( double* oscbuf ) const - { - int i = z; - - while( i > 0 ) - { - oscbuf[ 0 ] = 0.0; - oscbuf[ 1 ] = 1.0; - oscbuf += 2; - i--; - } - } - - /** - * Function initializes window function buffer. This function generates - * Peaked Cosine window function. - * - * @param winbuf Windowing buffer. - * @param Alpha Peaked Cosine alpha parameter. - */ - - void initWinBuf( double* winbuf, const double Alpha ) const - { - CDSPWindowGenPeakedCosine wf( Alpha, FilterLength * 0.5 ); - int i; - - for( i = 1; i <= z; i++ ) - { - winbuf[ z - i ] = wf.generate(); - } - } - - /** - * Function fills first half of symmetric-odd FIR kernel for the band. - * This function should be called successively for adjacent bands. - * Previous band's x2 should be equal to current band's x1. A band kernel - * consists of 2 elements: linear kernel and ramp kernel. - * - * @param x1 Band's left corner frequency (0..1). - * @param x2 Band's right corner frequency (0..1). - * @param kernbuf1 Band kernel buffer 1 (linear part), length = z. - * @param kernbuf2 Band kernel buffer 2 (ramp part), length = z. - * @param oscbuf Oscillation buffer. Before the first call of the - * fillBandKernel() should be initialized with the call of the - * initOscBuf() function. - * @param winbuf Buffer that contains windowing function. - */ - - void fillBandKernel( const double x1, const double x2, double* kernbuf1, - double* kernbuf2, double* oscbuf, const double* const winbuf ) - { - const double s2_incr = AVIR_PI * x2; - const double s2_coeff = 2.0 * cos( s2_incr ); - - double s2_value1 = sin( s2_incr * ( -z + 1 )); - double c2_value1 = sin( s2_incr * ( -z + 1 ) + AVIR_PI * 0.5 ); - oscbuf[ 0 ] = sin( s2_incr * -z ); - oscbuf[ 1 ] = sin( s2_incr * -z + AVIR_PI * 0.5 ); - - int ks; - - for( ks = 1; ks < z; ks++ ) - { - const int ks2 = ks * 2; - const double s1_value1 = oscbuf[ ks2 ]; - const double c1_value1 = oscbuf[ ks2 + 1 ]; - oscbuf[ ks2 ] = s2_value1; - oscbuf[ ks2 + 1 ] = c2_value1; - - const double x = AVIR_PI * ( ks - z ); - const double v0 = winbuf[ ks - 1 ] / (( x1 - x2 ) * x ); - - kernbuf1[ ks - 1 ] = ( x2 * s2_value1 - x1 * s1_value1 + - ( c2_value1 - c1_value1 ) / x ) * v0; - - kernbuf2[ ks - 1 ] = ( s2_value1 - s1_value1 ) * v0; - - s2_value1 = s2_coeff * s2_value1 - oscbuf[ ks2 - 2 ]; - c2_value1 = s2_coeff * c2_value1 - oscbuf[ ks2 - 1 ]; - } - - kernbuf1[ z - 1 ] = ( x2 * x2 - x1 * x1 ) / ( x1 - x2 ) * 0.5; - kernbuf2[ z - 1 ] = -1.0; - } - - /** - * Function copies band kernel's elements to the output buffer. - * - * @param outbuf Output buffer. - * @param kernbuf1 Kernel buffer 1 (linear part). - * @param kernbuf2 Kernel buffer 2 (ramp part). - * @param c Multiplier for linear kernel element. - * @param d Multiplier for ramp kernel element. - */ - - void copyBandKernel( double* outbuf, const double* const kernbuf1, - const double* const kernbuf2, const double c, const double d ) const - { - int ks; - - for( ks = 0; ks < z; ks++ ) - { - outbuf[ ks ] = c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; - } - } - - /** - * Function adds band kernel's elements to the output buffer. - * - * @param outbuf Output buffer. - * @param kernbuf1 Kernel buffer 1 (linear part). - * @param kernbuf2 Kernel buffer 2 (ramp part). - * @param c Multiplier for linear kernel element. - * @param d Multiplier for ramp kernel element. - */ - - void addBandKernel( double* outbuf, const double* const kernbuf1, - const double* const kernbuf2, const double c, const double d ) const - { - int ks; - - for( ks = 0; ks < z; ks++ ) - { - outbuf[ ks ] += c * kernbuf1[ ks ] + d * kernbuf2[ ks ]; - } - } -}; - -/** - * @brief Low-pass filter windowed by Peaked Cosine window function. - * - * This class implements calculation of linear-phase symmetric-odd FIR - * low-pass filter windowed by the Peaked Cosine window function, for image - * processing applications. - */ - -class CDSPPeakedCosineLPF -{ -public: - int fl2; ///< Half filter's length, excluding the peak value. This value - ///< can be also used as filter's latency in samples (taps). - ///< - int FilterLen; ///< Filter's length in samples (taps). - ///< - - /** - * Constructor initalizes *this object. - * - * @param aLen2 Half-length (non-truncated) of low-pass filter, in samples - * (taps). - * @param aFreq2 Low-pass filter's corner frequency [0; pi]. - * @param aAlpha Peaked Cosine window function Alpha parameter. - */ - - CDSPPeakedCosineLPF( const double aLen2, const double aFreq2, - const double aAlpha ) - : fl2( (int) ceil( aLen2 ) - 1 ) - , FilterLen( fl2 + fl2 + 1 ) - , Len2( aLen2 ) - , Freq2( aFreq2 ) - , Alpha( aAlpha ) - { - } - - /** - * Function generates a linear-phase low-pass filter windowed by Peaked - * Cosine window function. - * - * @param[out] op Output buffer, length = FilterLen (fl2 * 2 + 1). - * @param DCGain Required gain at DC. The resulting filter will be - * normalized to achieve this DC gain. If non-positive, no automatic - * normalization will be performed. - */ - - template< class T > - void generateLPF( T* op, const double DCGain ) - { - CDSPWindowGenPeakedCosine wf( Alpha, Len2 ); - CSineGen f2( Freq2, 0.0 ); - - op += fl2; - T* op2 = op; - f2.generate(); - - if( DCGain > 0.0 ) - { - int t = 1; - - *op = (T) ( Freq2 * wf.generate() ); - double s = *op; - - while( t <= fl2 ) - { - const T v = (T) ( f2.generate() * wf.generate() / t ); - op++; - op2--; - *op = v; - *op2 = v; - s += v + v; - t++; - } - - t = FilterLen; - s = DCGain / s; - - while( t > 0 ) - { - *op2 = (T) ( *op2 * s ); - op2++; - t--; - } - } - else - { - int t = 1; - - *op = (T) ( Freq2 * wf.generate() ); - - while( t <= fl2 ) - { - const T v = (T) ( f2.generate() * wf.generate() / t ); - op++; - op2--; - *op = v; - *op2 = v; - t++; - } - } - } - -private: - double Len2; ///< Half-length (non-truncated) of low-pass filter, in - ///< samples (taps). - ///< - double Freq2; ///< Low-pass filter's corner frequency. - ///< - double Alpha; ///< Peaked Cosine window function Alpha parameter. - ///< -}; - -/** - * @brief Buffer class for parametrized low-pass filter. - * - * This class extends the CBuffer< double > class by adding several variables - * that define a symmetric-odd FIR low-pass filter windowed by Peaked Cosine - * window function. This class can be used to compare filters without - * comparing their buffer contents. - */ - -class CFltBuffer : public CBuffer< double > -{ -public: - double Len2; ///< Half-length (non-truncated) of low-pass filters, in - ///< samples (taps). - ///< - double Freq; ///< Low-pass filter's corner frequency. - ///< - double Alpha; ///< Peaked Cosine window function Alpha parameter. - ///< - double DCGain; ///< DC gain applied to the filter. - ///< - - CFltBuffer() - : CBuffer< double >() - , Len2( 0.0 ) - , Freq( 0.0 ) - , Alpha( 0.0 ) - , DCGain( 0.0 ) - { - } - - /** - * @param b2 Filter buffer to compare *this object to. - * @return Operator returns "true" if both filters have same parameters. - */ - - bool operator == ( const CFltBuffer& b2 ) const - { - return( Len2 == b2.Len2 && Freq == b2.Freq && Alpha == b2.Alpha && - DCGain == b2.DCGain ); - } -}; - -/** - * @brief Sinc function-based fractional delay filter bank. - * - * Class implements storage and initialization of a bank of sinc - * function-based fractional delay filters, expressed as 1st order polynomial - * interpolation coefficients. The filters are produced from a single "long" - * windowed low-pass filter. Also supports 0th-order ("nearest neighbor") - * interpolation. - * - * This class also supports multiplication of each fractional delay filter by - * an external filter (usually a low-pass filter). - * - * @tparam fptype Specifies storage type of the filter coefficients bank. The - * filters are initially calculated using the "double" precision. - */ - -template< class fptype > -class CDSPFracFilterBankLin -{ - AVIR_NOCTOR( CDSPFracFilterBankLin ); - -public: - CDSPFracFilterBankLin() - : Order( -1 ) - { - } - - /** - * Copy constructor copies a limited set of parameters of the source - * filter bank. The actual filters are not copied. Such copying is used - * during filtering steps "modeling" stage. A further init() function - * call is required. - * - * @param s Source filter bank. - */ - - void copyInitParams( const CDSPFracFilterBankLin& s ) - { - WFLen2 = s.WFLen2; - WFFreq = s.WFFreq; - WFAlpha = s.WFAlpha; - FracCount = s.FracCount; - Order = s.Order; - Alignment = s.Alignment; - SrcFilterLen = s.SrcFilterLen; - FilterLen = s.FilterLen; - FilterSize = s.FilterSize; - IsSrcTableBuilt = false; - ExtFilter = s.ExtFilter; - TableFillFlags.alloc( s.TableFillFlags.getCapacity() ); - int i; - - // Copy table fill flags, but shifted so that further initialization - // is still possible (such feature should not be used, though). - - for( i = 0; i < TableFillFlags.getCapacity(); i++ ) - { - TableFillFlags[ i ] = (uint8_t) ( s.TableFillFlags[ i ] << 2 ); - } - } - - /** - * Operator compares *this filter bank and another filter bank and returns - * "true" if their parameters are equal. Alignment is not taken into - * account. - * - * @param s Filter bank to compare to. - * @return "True" if compared banks have equal parameters. - */ - - bool operator == ( const CDSPFracFilterBankLin& s ) const - { - return( Order == s.Order && WFLen2 == s.WFLen2 && - WFFreq == s.WFFreq && WFAlpha == s.WFAlpha && - FracCount == s.FracCount && ExtFilter == s.ExtFilter ); - } - - /** - * Function initializes (builds) the filter bank based on the supplied - * parameters. If the supplied parameters are equal to previously defined - * parameters, function does nothing (alignment is assumed to be never - * changing between the init() function calls). - * - * @param ReqFracCount Required number of fractional delays in the filter - * bank. The minimal value is 2. - * @param ReqOrder Required order of the interpolation polynomial - * (0 or 1). - * @param BaseLen Low-pass filter's base length, in samples (taps). - * Affects the actual length of the filter and its overall steepness. - * @param Cutoff Low-pass filter's normalized cutoff frequency [0; 1]. - * @param aWFAlpha Peaked Cosine window function's Alpha parameter. - * @param aExtFilter External filter to apply to each fractional delay - * filter. - * @param aAlignment Memory alignment of the filter bank, power-of-2 - * value. 0 - use default stdlib alignment. - * @param FltLenAlign Filter's length alignment, power-of-2 value. - */ - - void init( const int ReqFracCount, const int ReqOrder, - const double BaseLen, const double Cutoff, const double aWFAlpha, - const CFltBuffer& aExtFilter, const int aAlignment = 0, - const int FltLenAlign = 1 ) - { - double NewWFLen2 = 0.5 * BaseLen * ReqFracCount; - double NewWFFreq = AVIR_PI * Cutoff / ReqFracCount; - double NewWFAlpha = aWFAlpha; - - if( ReqOrder == Order && NewWFLen2 == WFLen2 && NewWFFreq == WFFreq && - NewWFAlpha == WFAlpha && ReqFracCount == FracCount && - aExtFilter == ExtFilter ) - { - IsInitRequired = false; - return; - } - - WFLen2 = NewWFLen2; - WFFreq = NewWFFreq; - WFAlpha = NewWFAlpha; - FracCount = ReqFracCount; - Order = ReqOrder; - Alignment = aAlignment; - ExtFilter = aExtFilter; - - CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); - SrcFilterLen = ( p.fl2 / ReqFracCount + 1 ) * 2; - - const int ElementSize = ReqOrder + 1; - FilterLen = SrcFilterLen; - - if( ExtFilter.getCapacity() > 0 ) - { - FilterLen += ExtFilter.getCapacity() - 1; - } - - FilterLen = ( FilterLen + FltLenAlign - 1 ) & ~( FltLenAlign - 1 ); - FilterSize = FilterLen * ElementSize; - IsSrcTableBuilt = false; - IsInitRequired = true; - } - - /** - * @return The length of each fractional delay filter, in samples (taps). - * Always an even value. - */ - - int getFilterLen() const - { - return( FilterLen ); - } - - /** - * @return The number of fractional filters in use by *this bank. - */ - - int getFracCount() const - { - return( FracCount ); - } - - /** - * @return The order of the interpolation polynomial. - */ - - int getOrder() const - { - return( Order ); - } - - /** - * Function returns the pointer to the specified interpolation table - * filter. - * - * @param i Filter (fractional delay) index, in the range 0 to - * ReqFracCount - 1, inclusive. - * @return Pointer to filter. Higher order polynomial coefficients are - * stored after after previous order coefficients, separated by FilterLen - * elements. - */ - - const fptype* getFilter( const int i ) - { - if( !IsSrcTableBuilt ) - { - buildSrcTable(); - } - - fptype* const Res = &Table[ i * FilterSize ]; - - if(( TableFillFlags[ i ] & 2 ) == 0 ) - { - createFilter( i ); - TableFillFlags[ i ] |= 2; - - if( Order > 0 ) - { - createFilter( i + 1 ); - const fptype* const Res2 = Res + FilterSize; - fptype* const op = Res + FilterLen; - int j; - - // Create higher-order interpolation coefficients (linear - // interpolation). - - for( j = 0; j < FilterLen; j++ ) - { - op[ j ] = Res2[ j ] - Res[ j ]; - } - } - } - - return( Res ); - } - - /** - * Function makes sure all fractional delay filters were created. - */ - - void createAllFilters() - { - int i; - - for( i = 0; i < FracCount; i++ ) - { - getFilter( i ); - } - } - - /** - * Function returns an approximate initialization complexity, expressed in - * the number of multiply-add operations. This includes fractional delay - * filters calculation and multiplication by an external filter. This - * function can only be called after the init() function. - * - * @param FracUseMap Fractional delays use map, each element corresponds - * to a single fractional delay, will be compared to the internal table - * fill flags. This map should include 0 and 1 values only. - * @return The complexity of the initialization, expressed in the number - * of multiply-add operations. - */ - - int calcInitComplexity( const CBuffer< uint8_t >& FracUseMap ) const - { - const int FltInitCost = 65; // Cost to initialize a single sample - // of the fractional delay filter. - const int FltUseCost = FilterLen * Order + - SrcFilterLen * ExtFilter.getCapacity(); // Cost to use a single - // fractional delay filter. - const int ucb[ 2 ] = { 0, FltUseCost }; - int ic; - int i; - - if( IsInitRequired ) - { - ic = FracCount * SrcFilterLen * FltInitCost; - - for( i = 0; i < FracCount; i++ ) - { - ic += ucb[ FracUseMap[ i ]]; - } - } - else - { - ic = 0; - - for( i = 0; i < FracCount; i++ ) - { - if( FracUseMap[ i ] != 0 ) - { - ic += ucb[ TableFillFlags[ i ] == 0 ? 1 : 0 ]; - } - } - } - - return( ic ); - } - -private: - static const int InterpPoints = 2; ///< The maximal number of points the - ///< interpolation is based on. - ///< - double WFLen2; ///< Window function's Len2 parameter. - ///< - double WFFreq; ///< Window function's Freq parameter. - ///< - double WFAlpha; ///< Window function's Alpha parameter. - ///< - int FracCount; ///< The required number of fractional delay filters. - ///< - int Order; ///< The order of the interpolation polynomial. - ///< - int Alignment; ///< The required filter table alignment. - ///< - int SrcFilterLen; ///< Length of the "source" filters. This is always an - ///< even value. - ///< - int FilterLen; ///< Specifies the number of samples (taps) each fractional - ///< delay filter has. This is always an even value, adjusted by the - ///< FltLenAlign. - ///< - int FilterSize; ///< The size of a single filter element, equals - ///< FilterLen * ElementSize. - ///< - bool IsInitRequired; ///< "True" if SrcTable filter table initialization - ///< is required. This value is available only after the call to the - ///< init() function. - ///< - CBuffer< fptype > Table; ///< Interpolation table, size equals to - ///< ReqFracCount * FilterLen * ElementSize. - ///< - CBuffer< uint8_t > TableFillFlags; ///< Contains ReqFracCount + 1 - ///< elements. Bit 0 of every element is 1 if Table already contains - ///< the filter from SrcTable filtered by ExtFilter. Bit 1 of every - ///< element means higher order coefficients were filled for the - ///< filter. - ///< - CFltBuffer ExtFilter; ///< External filter that should be applied to every - ///< fractional delay filter. Can be empty. Half of this filter's - ///< capacity is used as latency (group delay) value of the filter. - ///< - CBuffer< double > SrcTable; ///< Source table of delay filters, contains - ///< ReqFracCount + 1 elements. This table is used to fill the Table - ///< with the actual filters, filtered by an external filter. - ///< - bool IsSrcTableBuilt; ///< "True" if the SrcTable was built already. This - ///< variable is set to "false" in the init() function. - ///< - - /** - * Function builds source table used in the createFilter() function. - */ - - void buildSrcTable() - { - IsSrcTableBuilt = true; - IsInitRequired = false; - - CDSPPeakedCosineLPF p( WFLen2, WFFreq, WFAlpha ); - - const int BufLen = SrcFilterLen * FracCount + InterpPoints - 1; - const int BufOffs = InterpPoints / 2 - 1; - const int BufCenter = SrcFilterLen * FracCount / 2 + BufOffs; - - CBuffer< double > Buf( BufLen ); - memset( Buf, 0, ( BufCenter - p.fl2 ) * sizeof( double )); - int i = BufLen - BufCenter - p.fl2 - 1; - memset( &Buf[ BufLen - i ], 0, i * sizeof( double )); - - p.generateLPF( &Buf[ BufCenter - p.fl2 ], 0.0 ); - - SrcTable.alloc(( FracCount + 1 ) * SrcFilterLen ); - TableFillFlags.alloc( FracCount + 1 ); - int j; - double* op0 = SrcTable; - - for( i = FracCount; i >= 0; i-- ) - { - TableFillFlags[ i ] = 0; - double* p = Buf + BufOffs + i; - - for( j = 0; j < SrcFilterLen; j++ ) - { - op0[ 0 ] = p[ 0 ]; - op0++; - p += FracCount; - } - - normalizeFIRFilter( op0 - SrcFilterLen, SrcFilterLen, 1.0 ); - } - - Table.alloc(( FracCount + 1 ) * FilterSize, Alignment ); - } - - /** - * Function creates the specified filter in the Table by copying it from - * the SrcTable and filtering by ExtFilter. Function does nothing if - * filter was already created. - * - * @param k Filter index to create, in the range 0 to FracCount, - * inclusive. - */ - - void createFilter( const int k ) - { - if( TableFillFlags[ k ] != 0 ) - { - return; - } - - TableFillFlags[ k ] |= 1; - const int ExtFilterLatency = ExtFilter.getCapacity() / 2; - const int ResLatency = ExtFilterLatency + SrcFilterLen / 2; - int ResLen = SrcFilterLen; - - if( ExtFilter.getCapacity() > 0 ) - { - ResLen += ExtFilter.getCapacity() - 1; - } - - const int ResOffs = FilterLen / 2 - ResLatency; - fptype* op = &Table[ k * FilterSize ]; - int i; - - for( i = 0; i < ResOffs; i++ ) - { - op[ i ] = (fptype) 0; - } - - for( i = ResOffs + ResLen; i < FilterLen; i++ ) - { - op[ i ] = (fptype) 0; - } - - op += ResOffs; - const double* const srcflt = &SrcTable[ k * SrcFilterLen ]; - - if( ExtFilter.getCapacity() == 0 ) - { - for( i = 0; i < ResLen; i++ ) - { - op[ i ] = (fptype) srcflt[ i ]; - } - - return; - } - - // Perform convolution of extflt and srcflt. - - const double* const extflt = &ExtFilter[ 0 ]; - int j; - - for( j = 0; j < ResLen; j++ ) - { - int k = 0; - int l = j - ExtFilter.getCapacity() + 1; - int r = l + ExtFilter.getCapacity(); - - if( l < 0 ) - { - k -= l; - l = 0; - } - - if( r > SrcFilterLen ) - { - r = SrcFilterLen; - } - - const double* const extfltb = extflt + k; - const double* const srcfltb = srcflt + l; - double s = 0.0; - l = r - l; - - for( i = 0; i < l; i++ ) - { - s += extfltb[ i ] * srcfltb[ i ]; - } - - op[ j ] = (fptype) s; - } - } -}; - -/** - * @brief Thread pool for multi-threaded image resizing operation. - * - * This base class is used to organize a multi-threaded image resizing - * operation. The thread pool should consist of threads that initially wait - * for a signal. Upon receiving a signal (via the startAllWorkloads() - * function) each previously added thread should execute its workload's - * process() function once, and return to the wait signal state again. The - * thread pool should be also able to efficiently wait for all workloads to - * finish via the waitAllWorkloadsToFinish() function. - * - * The image resizing algorithm makes calls to functions of this class. - */ - -class CImageResizerThreadPool -{ -public: - CImageResizerThreadPool() - { - } - - virtual ~CImageResizerThreadPool() - { - } - - /** - * @brief Thread pool's workload object class. - * - * This class should be used as a base class for objects that perform the - * actual work spread over several threads. - */ - - class CWorkload - { - public: - virtual ~CWorkload() - { - } - - /** - * Function that gets called from the thread when thread pool's - * startAllWorkloads() function is called. - */ - - virtual void process() = 0; - }; - - /** - * @return The suggested number of workloads (and their associated - * threads) to add. The minimal value this function can return is 1. The - * usual value may depend on the number of physical and virtual cores - * present in the system, and on other considerations. - */ - - virtual int getSuggestedWorkloadCount() const - { - return( 1 ); - } - - /** - * Function adds a new workload (and possibly thread) to the thread pool. - * The caller decides how many parallel workloads (and threads) it - * requires, but this number will not exceed the value returned by the - * getSuggestedWorkloadCount() function. It is implementation-specific how - * many workloads to associate with a single thread. But for efficiency - * reasons each workload should be associated with its own thread. - * - * Note that the same set of workload objects will be processed each time - * the startAllWorkloads() function is called. This means that workload - * objects are added only once. The caller changes the state of the - * workload objects and then calls the startAllWorkloads() function to - * process them. - * - * @param Workload Workload object whose process() function will be called - * from within the thread when the startAllWorkloads() function is called. - */ - - virtual void addWorkload( CWorkload* const Workload ) - { - } - - /** - * Function starts all workloads associated with threads previously added - * via the addWorkload() function. It is assumed that this function - * performs the necessary "memory barrier" (or "cache sync") kind of - * operation so that all threads catch up the prior changes made to the - * workload objects during their wait state. - */ - - virtual void startAllWorkloads() - { - } - - /** - * Function waits for all workloads to finish. - */ - - virtual void waitAllWorkloadsToFinish() - { - } - - /** - * Function removes all workloads previously added via the addWorkload() - * function. This function gets called only after the - * waitAllWorkloadsToFinish() function call. - */ - - virtual void removeAllWorkloads() - { - } -}; - -/** - * @brief Resizing algorithm parameters structure. - * - * This structure holds all selectable parameters used by the resizing - * algorithm at various stages, for both downsizing and upsizing. There are no - * other parameters exist that can optimize the performance of the resizing - * algorithm. Filter length parameters can take fractional values. - * - * Beside quality, these parameters (except Alpha parameters) directly affect - * the computative cost of the resizing algorithm. It is possible to trade - * the visual quality for computative cost. - * - * Anti-alias filtering during downsizing can be defined as a considerable - * reduction of contrast of smallest features of an image. Unfortunately, such - * de-contrasting partially affects features of all sizes thus producing a - * non-linearity of frequency response. All pre-defined parameter sets are - * described by 3 values separated by slashes. The first value is the - * de-contrasting factor of small features (which are being removed) while - * the second value is the de-contrasting factor of large features (which - * should remain intact), with value of 1 equating to "no contrast change". - * The third value is the optimization score (see below), with value of 0 - * equating to the "perfect" linearity of frequency response. - * - * The pre-defined parameter sets offered by this library were auto-optimized - * for the given LPFltBaseLen, IntFltLen and CorrFltAlpha values. The - * optimization goal was to minimize the score: the sum of squares of the - * difference between original and processed images (which was not actually - * resized, k=1). The original image was a 0.5 megapixel uniformly-distributed - * white-noise image with pixel intensities in the 0-1 range. Such goal - * converges very well and produces filtering system with the flattest - * frequency response possible for the given constraints. With this goal, - * increasing the LPFltBaseLen value reduces the general amount of aliasing - * artifacts. - */ - -struct CImageResizerParams -{ - double CorrFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the correction filter. The "usable" values are - ///< in the narrow range 1.0 to 1.5. - ///< - double CorrFltLen; ///< Correction filter's length in samples (taps). The - ///< "usable" range is narrow, 5.5 to 8, as to minimize the - ///< "overcorrection" which is mathematically precise, but visually - ///< unacceptable. - ///< - double IntFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the interpolation low-pass filter. The "usable" - ///< values are in the range 1.5 to 2.5. - ///< - double IntFltCutoff; ///< Interpolation low-pass filter's cutoff frequency - ///< (normalized, [0; 1]). The "usable" range is 0.6 to 0.8. - ///< - double IntFltLen; ///< Interpolation low-pass filter's length in samples - ///< (taps). The length value should be at least 18 or otherwise a - ///< "dark grid" artifact will be introduced if a further sharpening - ///< is applied. IntFltLen together with other IntFlt parameters - ///< should be tuned in a way that produces the flattest frequency - ///< response in 0-0.5 normalized frequency range (this range is due - ///< to 2X upsampling). - ///< - double LPFltAlpha; ///< Alpha parameter of the Peaked Cosine window - ///< function used on the low-pass filter. The "usable" values are - ///< in the range 1.5 to 6.5. - ///< - double LPFltBaseLen; ///< Base length of the low-pass (aka anti-aliasing - ///< or reconstruction) filter, in samples (taps), further adjusted by - ///< the actual cutoff frequency, upsampling and downsampling factors. - ///< The "usable" range is between 6 and 9. - ///< - double LPFltCutoffMult; ///< Low-pass filter's cutoff frequency - ///< multiplier. This value can be both below and above 1.0 as - ///< low-pass filters are inserted on downsampling and upsampling - ///< steps and always have corner frequency equal to or below 0.5pi. - ///< This multiplier shifts low-pass filter's corner frequency towards - ///< lower (if below 1.0) or higher (if above 1.0) frequencies. This - ///< multiplier can be way below 1.0 since any additional - ///< high-frequency damping will be partially corrected by the - ///< correction filter. The "usable" range is 0.3 to 1.0. - ///< - - CImageResizerParams() - : HBFltAlpha( 1.94609 ) - , HBFltCutoff( 0.46437 ) - , HBFltLen( 24 ) - { - } - - double HBFltAlpha; ///< Half-band filter's Alpha. Assigned internally. - ///< - double HBFltCutoff; ///< Half-band filter's cutoff point [0; 1]. Assigned - ///< internally. - ///< - double HBFltLen; ///< Length of the half-band low-pass filter. Assigned - ///< internally. Internally used to perform 2X or higher downsampling. - ///< These filter parameters should be treated as "technical" and do - ///< not require adjustment as they were tuned to suit all - ///< combinations of other parameters. This half-band filter provides - ///< a wide transition band (for minimal ringing artifacts) and a high - ///< stop-band attenuation (for minimal aliasing). - ///< -}; - -/** - * @brief The default set of resizing algorithm parameters - * (10.06/1.88/1.029(256064.90)/0.000039). - * - * This is the default set of resizing parameters that was designed to deliver - * a sharp image while still providing a low amount of ringing artifacts, and - * having a reasonable computational cost. - */ - -struct CImageResizerParamsDef : public CImageResizerParams -{ - CImageResizerParamsDef() - { - CorrFltAlpha = 0.97946;//10.06/1.88/1.029(256064.90)/0.000039:258649,447179 - CorrFltLen = 6.4262; - IntFltAlpha = 6.41341; - IntFltCutoff = 0.7372; - IntFltLen = 18; - LPFltAlpha = 4.76449; - LPFltBaseLen = 7.55999999999998; - LPFltCutoffMult = 0.79285; - } -}; - -/** - * @brief Set of resizing algorithm parameters for ultra-low-ringing - * performance (7.50/2.01/1.083(11568559.86)/0.000001). - * - * This set of resizing algorithm parameters offers the lowest amount of - * ringing this library is capable of providing while still offering a decent - * quality. Low ringing is attained at the expense of higher aliasing - * artifacts and a slightly reduced contrast. - */ - -struct CImageResizerParamsULR : public CImageResizerParams -{ - CImageResizerParamsULR() - { - CorrFltAlpha = 0.95521;//7.50/2.01/1.083(11568559.86)/0.000001:258649,434609 - CorrFltLen = 5.70774; - IntFltAlpha = 1.00766; - IntFltCutoff = 0.74202; - IntFltLen = 18; - LPFltAlpha = 1.6801; - LPFltBaseLen = 6.62; - LPFltCutoffMult = 0.67821; - } -}; - -/** - * @brief Set of resizing algorithm parameters for low-ringing performance - * (7.91/1.96/1.065(1980857.66)/0.000004). - * - * This set of resizing algorithm parameters offers a very low-ringing - * performance at the expense of higher aliasing artifacts and a slightly - * reduced contrast. - */ - -struct CImageResizerParamsLR : public CImageResizerParams -{ - CImageResizerParamsLR() - { - CorrFltAlpha = 1;//7.91/1.96/1.065(1980857.66)/0.000004:258649,437578 - CorrFltLen = 5.865; - IntFltAlpha = 1.79529; - IntFltCutoff = 0.74325; - IntFltLen = 18; - LPFltAlpha = 1.87597; - LPFltBaseLen = 6.89999999999999; - LPFltCutoffMult = 0.69326; - } -}; - -/** - * @brief Set of resizing algorithm parameters for lower-ringing performance - * (9.21/1.91/1.040(391960.71)/0.000023). - * - * This set of resizing algorithm parameters offers a lower-ringing - * performance in comparison to the default setting, at the expense of higher - * aliasing artifacts and a slightly reduced contrast. - */ - -struct CImageResizerParamsLow : public CImageResizerParams -{ - CImageResizerParamsLow() - { - CorrFltAlpha = 0.99739;//9.21/1.91/1.040(391960.71)/0.000023:258649,444105 - CorrFltLen = 6.20326; - IntFltAlpha = 4.6836; - IntFltCutoff = 0.73879; - IntFltLen = 18; - LPFltAlpha = 7.86565; - LPFltBaseLen = 6.91999999999999; - LPFltCutoffMult = 0.78379; - } -}; - -/** - * @brief Set of resizing algorithm parameters for low-aliasing - * resizing (11.59/1.84/1.015(73054.59)/0.000159). - * - * This set of resizing algorithm parameters offers a considerable - * anti-aliasing performance with a good frequency response linearity (and - * contrast). This is an intermediate setting between the default and Ultra - * parameters. - */ - -struct CImageResizerParamsHigh : public CImageResizerParams -{ - CImageResizerParamsHigh() - { - CorrFltAlpha = 0.97433;//11.59/1.84/1.015(73054.59)/0.000159:258649,451830 - CorrFltLen = 6.87893; - IntFltAlpha = 7.74731; - IntFltCutoff = 0.73844; - IntFltLen = 18; - LPFltAlpha = 4.8149; - LPFltBaseLen = 8.07999999999996; - LPFltCutoffMult = 0.79335; - } -}; - -/** - * @brief Set of resizing algorithm parameters for ultra low-aliasing - * resizing (13.68/1.79/1.000(521792.07)/0.000026). - * - * This set of resizing algorithm parameters offers a very considerable - * anti-aliasing performance with a good frequency response linearity (and - * contrast). This set of parameters is computationally expensive and may - * produce ringing artifacts on sharp features. - */ - -struct CImageResizerParamsUltra : public CImageResizerParams -{ - CImageResizerParamsUltra() - { - CorrFltAlpha = 0.99705;//13.68/1.79/1.000(521792.07)/0.000026:258649,457973 - CorrFltLen = 7.42695; - IntFltAlpha = 1.71985; - IntFltCutoff = 0.7571; - IntFltLen = 18; - LPFltAlpha = 6.71313; - LPFltBaseLen = 8.27999999999996; - LPFltCutoffMult = 0.78413; - } -}; - -/** - * @brief Image resizing variables class. - * - * This is an utility "catch all" class that defines various variables used - * during image resizing. Several variables that are explicitly initialized in - * this class' constructor are also used as additional "input" variables to - * the image resizing function. These variables will not be changed by the - * avir::CImageResizer<>::resizeImage() function. - */ - -class CImageResizerVars -{ -public: - int ElCount; ///< The number of "fptype" elements used to store 1 pixel. - ///< - int ElCountIO; ///< The number of source and destination image's elements - ///< used to store 1 pixel. - ///< - int fppack; ///< The number of atomic types stored in a single "fptype" - ///< element. - ///< - int fpalign; ///< Suggested alignment size in bytes. This is not a - ///< required alignment, because image resizing algorithm cannot be - ///< made to have a strictly aligned data access in all cases (e.g. - ///< de-interleaved interpolation cannot perform aligned accesses). - ///< - int elalign; ///< Length alignment of arrays of elements. This applies to - ///< filters and intermediate buffers: this constant forces filters - ///< and scanlines to have a length which is a multiple of this value, - ///< for more efficient SIMD implementation. - ///< - int packmode; ///< 0 if interleaved packing, 1 if de-interleaved. - ///< - int BufLen[ 2 ]; ///< Intermediate buffers' lengths in "fptype" elements. - int BufOffs[ 2 ]; ///< Offsets into the intermediate buffers, used to - ///< provide prefix elements required during processing so that no - ///< "out of range" access happens. This offset is a multiple of - ///< ElCount if pixels are stored in interleaved form. - ///< - double k; ///< Resizing step coefficient, updated to reflect the actually - ///< used coefficient during resizing. - ///< - double o; ///< Starting pixel offset inside the source image, updated to - ///< reflect the actually used offset during resizing. - ///< - int ResizeStep; ///< Index of the resizing step in the latest filtering - ///< steps array. - ///< - bool IsResize2; ///< Use optimized "doResize2" function. - ///< - double InGammaMult; ///< Input gamma multiplier, used to convert input - ///< data to 0 to 1 range. 0.0 if no gamma is in use. - ///< - double OutGammaMult; ///< Output gamma multiplier, used to convert data to - ///< 0 to 255/65535 range. 0.0 if no gamma is in use. - ///< - - double ox; ///< Start X pixel offset within source image (can be - ///< negative). Positive offset moves image to the left. - ///< - double oy; ///< Start Y pixel offset within source image (can be - ///< negative). Positive offset moves image to the top. - ///< - CImageResizerThreadPool* ThreadPool; ///< Thread pool to be used by the - ///< image resizing function. Set to NULL to use single-threaded - ///< processing. - ///< - bool UseSRGBGamma; ///< Perform sRGB gamma linearization (correction). - ///< - int BuildMode; ///< The build mode to use, for debugging purposes. Set to - ///< -1 to select a minimal-complexity mode automatically. All build - ///< modes deliver similar results with minor deviations. - ///< - int RndSeed; ///< Random seed parameter. This parameter may be incremented - ///< after each random generator initialization. The use of this - ///< variable depends on the ditherer implementation. - ///< - - CImageResizerVars() - : ox( 0.0 ) - , oy( 0.0 ) - , ThreadPool( NULL ) - , UseSRGBGamma( false ) - , BuildMode( -1 ) - , RndSeed( 0 ) - { - } -}; - -/** - * @brief Image resizer's filtering step class. - * - * Class defines data to perform a single filtering step over a whole - * horizontal or vertical scanline. Resizing consists of 1 or more steps that - * may be performed before the actual resizing takes place. Filtering may also - * follow a resizing step. Each step must ensure that scanline data contains - * enough pixels to perform the next step (which may be resizing) without - * exceeding scanline's bounds. - * - * A derived class must implement several "const" and "static" functions that - * are used to perform the actual filtering in interleaved or de-interleaved - * mode. - * - * @tparam fptype Floating point type to use for storing pixel elements. SIMD - * types can be used: in this case each element may hold a whole pixel. - * @tparam fptypeatom The atomic type the "fptype" consists of. - */ - -template< class fptype, class fptypeatom > -class CImageResizerFilterStep -{ - AVIR_NOCTOR( CImageResizerFilterStep ); - -public: - bool IsUpsample; ///< "True" if this step is an upsampling step, "false" - ///< if downsampling step. Should be set to "false" if ResampleFactor - ///< equals 0. - ///< - int ResampleFactor; ///< Resample factor (>=1). If 0, this is a resizing - ///< step. This value should be >1 if IsUpsample equals "true". - ///< - CBuffer< fptype > Flt; ///< Filter to use at this step. - ///< - CFltBuffer FltOrig; ///< Originally-designed filter. This buffer may not - ///< be assigned. Assigned by filters that precede the resizing step - ///< if such filter is planned to be embedded into the interpolation - ///< filter as "external" filter. If IsUpsample=true and this filter - ///< buffer is not empty, the upsampling step will not itself apply - ///< any filtering over upsampled input scanline. - ///< - double DCGain; ///< DC gain which was applied to the filter. Not defined - ///< if ResampleFactor = 0. - ///< - int FltLatency; ///< Filter's latency (group delay, shift) in pixels. - ///< - const CImageResizerVars* Vars; ///< Image resizing-related variables. - ///< - int InLen; ///< Input scanline's length in pixels. - ///< - int InBuf; ///< Input buffer index, 0 or 1. - ///< - int InPrefix; ///< Required input prefix pixels. These prefix pixels will - ///< be filled with source scanline's first pixel value. If IsUpsample - ///< is "true", this is the additional number of times the first pixel - ///< will be filtered before processing scanline, this number is also - ///< reflected in the OutPrefix. - ///< - int InSuffix; ///< Required input suffix pixels. These suffix pixels will - ///< be filled with source scanline's last pixel value. If IsUpsample - ///< is "true", this is the additional number of times the last pixel - ///< will be filtered before processing scanline, this number is also - ///< reflected in the OutSuffix. - ///< - int InElIncr; ///< Pixel element increment within the input buffer, used - ///< during de-interleaved processing: in this case each image's - ///< channel is stored independently, InElIncr elements apart. - ///< - int OutLen; ///< Length of the resulting scanline. - ///< - int OutBuf; ///< Output buffer index. 0 or 1; 2 for the last step. - ///< - int OutPrefix; ///< Required output prefix pixels. These prefix pixels - ///< will not be pre-filled with any values. Value is valid only if - ///< IsUpsample equals "true". - ///< - int OutSuffix; ///< Required input suffix pixels. These suffix pixels will - ///< not be pre-filled with any values. Value is valid only if - ///< IsUpsample equals "true". - ///< - int OutElIncr; ///< Pixel element increment within the output buffer, used - ///< during de-interleaved processing. Equals to the InBufElIncr of - ///< the next step. - ///< - CBuffer< fptype > PrefixDC; ///< DC component fluctuations added at the - ///< start of the resulting scanline, used when IsUpsample equals - ///< "true". - ///< - CBuffer< fptype > SuffixDC; ///< DC component fluctuations added at the - ///< end of the resulting scanline, used when IsUpsample equals - ///< "true". - ///< - int EdgePixelCount; ///< The number of edge pixels added. Affects the - ///< initial position within the input scanline, used to produce edge - ///< pixels. This variable is used and should be defined when - ///< IsUpsample=false and ResampleFactor>0. When assigning this - ///< variable it is also necessary to update InPrefix, OutLen and - ///< Vars.o variables. - ///< - static const int EdgePixelCountDef = 3; ///< The default number of pixels - ///< additionally produced at scanline edges during filtering. This is - ///< required to reduce edge artifacts. - ///< - - /** - * @brief Resizing position structure. - * - * Structure holds resizing position and pointer to fractional delay - * filter. - */ - - struct CResizePos - { - int SrcPosInt; ///< Source scanline position. - ///< - int fti; ///< Fractional delay filter index. - ///< - const fptype* ftp; ///< Fractional delay filter pointer. - ///< - fptypeatom x; ///< Interpolation coefficient between delay filters. - ///< - int SrcOffs; ///< Source scanline offset. - ///< - int fl; ///< Filter length to use, applies to doResize2() only. - ///< - }; - - /** - * @brief Resizing positions buffer class. - * - * This class combines buffer together with variables that define resizing - * stepping. - */ - - class CRPosBuf : public CBuffer< CResizePos > - { - public: - double k; ///< Resizing step. - ///< - double o; ///< Resizing offset. - ///< - int FracCount; ///< The number of fractional delay filters in a filter - ///< bank used together with this buffer. - ///< - }; - - /** - * @brief Resizing positions buffer array class. - * - * This class combines structure array of the CRPosBuf class objects with - * the function that locates or creates buffer with the required resizing - * stepping. - */ - - class CRPosBufArray : public CStructArray< CRPosBuf > - { - public: - using CStructArray< CRPosBuf > :: add; - using CStructArray< CRPosBuf > :: getItemCount; - - /** - * Function returns the resizing positions buffer with the required - * stepping. If no such buffer exists, it is created. - * - * @param k Resizing step. - * @param o Resizing offset. - * @param FracCount The number of fractional delay filters in a filter - * bank used together with this buffer. - * @return Reference to the CRPosBuf object. - */ - - CRPosBuf& getRPosBuf( const double k, const double o, - const int FracCount ) - { - int i; - - for( i = 0; i < getItemCount(); i++ ) - { - CRPosBuf& Buf = (*this)[ i ]; - - if( Buf.k == k && Buf.o == o && Buf.FracCount == FracCount ) - { - return( Buf ); - } - } - - CRPosBuf& NewBuf = add(); - NewBuf.k = k; - NewBuf.o = o; - NewBuf.FracCount = FracCount; - - return( NewBuf ); - } - }; - - CRPosBuf* RPosBuf; ///< Resizing positions buffer. Used when - ///< ResampleFactor equals 0 (resizing step). - ///< - CDSPFracFilterBankLin< fptype >* FltBank; ///< Filter bank in use by *this - ///< resizing step. - ///< - - CImageResizerFilterStep() - { - } -}; - -/** - * @brief Interleaved filtering steps implementation class. - * - * This class implements scanline filtering functions in interleaved mode. - * This means that each pixel is processed independently, not in groups. - * - * @tparam fptype Floating point type to use for storing pixel elements. SIMD - * types can be used: in this case each element may hold a whole pixel. - * @tparam fptypeatom The atomic type the "fptype" consists of. - */ - -template< class fptype, class fptypeatom > -class CImageResizerFilterStepINL : - public CImageResizerFilterStep< fptype, fptypeatom > -{ -public: - using CImageResizerFilterStep< fptype, fptypeatom > :: IsUpsample; - using CImageResizerFilterStep< fptype, fptypeatom > :: ResampleFactor; - using CImageResizerFilterStep< fptype, fptypeatom > :: Flt; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltOrig; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltLatency; - using CImageResizerFilterStep< fptype, fptypeatom > :: Vars; - using CImageResizerFilterStep< fptype, fptypeatom > :: InLen; - using CImageResizerFilterStep< fptype, fptypeatom > :: InPrefix; - using CImageResizerFilterStep< fptype, fptypeatom > :: InSuffix; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutLen; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutPrefix; - using CImageResizerFilterStep< fptype, fptypeatom > :: OutSuffix; - using CImageResizerFilterStep< fptype, fptypeatom > :: PrefixDC; - using CImageResizerFilterStep< fptype, fptypeatom > :: SuffixDC; - using CImageResizerFilterStep< fptype, fptypeatom > :: RPosBuf; - using CImageResizerFilterStep< fptype, fptypeatom > :: FltBank; - using CImageResizerFilterStep< fptype, fptypeatom > :: EdgePixelCount; - - /** - * Function performs "packing" of a scanline, and type conversion. - * Scanline, depending on the "fptype" can be potentially stored as a - * packed SIMD values having a certain atomic type. If required, the sRGB - * gamma correction is applied. - * - * @param ip Input scanline. - * @param op0 Output scanline. - * @param l0 The number of pixels to "pack". - */ - - template< class Tin > - void packScanline( const Tin* ip, fptype* const op0, const int l0 ) const - { - const int ElCount = Vars -> ElCount; - const int ElCountIO = Vars -> ElCountIO; - fptype* op = op0; - int l = l0; - - if( !Vars -> UseSRGBGamma ) - { - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - op += ElCount; - ip++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - v[ 2 ] = (fptypeatom) ip[ 2 ]; - v[ 3 ] = (fptypeatom) ip[ 3 ]; - op += ElCount; - ip += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - v[ 2 ] = (fptypeatom) ip[ 2 ]; - op += ElCount; - ip += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) ip[ 0 ]; - v[ 1 ] = (fptypeatom) ip[ 1 ]; - op += ElCount; - ip += 2; - l--; - } - } - } - else - { - const fptypeatom gm = (fptypeatom) Vars -> InGammaMult; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - op += ElCount; - ip++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); - v[ 3 ] = convertSRGB2Lin( (fptypeatom) ip[ 3 ] * gm ); - op += ElCount; - ip += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - v[ 2 ] = convertSRGB2Lin( (fptypeatom) ip[ 2 ] * gm ); - op += ElCount; - ip += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = convertSRGB2Lin( (fptypeatom) ip[ 0 ] * gm ); - v[ 1 ] = convertSRGB2Lin( (fptypeatom) ip[ 1 ] * gm ); - op += ElCount; - ip += 2; - l--; - } - } - } - - const int ZeroCount = ElCount * Vars -> fppack - ElCountIO; - op = (fptype*) ( (fptypeatom*) op0 + ElCountIO ); - l = l0; - - if( ZeroCount == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - else - if( ZeroCount == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - v[ 1 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - else - if( ZeroCount == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) op; - v[ 0 ] = (fptypeatom) 0; - v[ 1 ] = (fptypeatom) 0; - v[ 2 ] = (fptypeatom) 0; - op += ElCount; - l--; - } - } - } - - /** - * Function applies Linear to sRGB gamma correction to the specified - * scanline. - * - * @param p Scanline. - * @param l The number of pixels to de-linearize. - * @param Vars0 Image resizing-related variables. - */ - - static void applySRGBGamma( fptype* p, int l, - const CImageResizerVars& Vars0 ) - { - const int ElCount = Vars0.ElCount; - const int ElCountIO = Vars0.ElCountIO; - const fptypeatom gm = (fptypeatom) Vars0.OutGammaMult; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; - v[ 3 ] = convertLin2SRGB( v[ 3 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - v[ 2 ] = convertLin2SRGB( v[ 2 ]) * gm; - p += ElCount; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - fptypeatom* v = (fptypeatom*) p; - v[ 0 ] = convertLin2SRGB( v[ 0 ]) * gm; - v[ 1 ] = convertLin2SRGB( v[ 1 ]) * gm; - p += ElCount; - l--; - } - } - } - - /** - * Function converts vertical scanline to horizontal scanline. This - * function is called by the image resizer when image is resized - * vertically. This means that the vertical scanline is stored in the - * same format produced by the packScanline() and maintained by other - * filtering functions. - * - * @param ip Input vertical scanline. - * @param op Output buffer (temporary buffer used during resizing). - * @param SrcLen The number of pixels in the input scanline, also used to - * calculate input buffer increment. - * @param SrcIncr Input buffer increment to the next vertical pixel. - */ - - void convertVtoH( const fptype* ip, fptype* op, const int SrcLen, - const int SrcIncr ) const - { - const int ElCount = Vars -> ElCount; - int j; - - if( ElCount == 1 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - ip += SrcIncr; - op++; - } - } - else - if( ElCount == 4 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - op[ 2 ] = ip[ 2 ]; - op[ 3 ] = ip[ 3 ]; - ip += SrcIncr; - op += 4; - } - } - else - if( ElCount == 3 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - op[ 2 ] = ip[ 2 ]; - ip += SrcIncr; - op += 3; - } - } - else - if( ElCount == 2 ) - { - for( j = 0; j < SrcLen; j++ ) - { - op[ 0 ] = ip[ 0 ]; - op[ 1 ] = ip[ 1 ]; - ip += SrcIncr; - op += 2; - } - } - } - - /** - * Function performs "unpacking" of a scanline and type conversion - * (truncation is used when floating point is converted to integer). - * Scanline, depending on the "fptype" can be potentially stored as a - * packed SIMD values having a certain atomic type. The unpacking function - * assumes that scanline is stored in the style produced by the - * packScanline() function. - * - * @param ip Input scanline. - * @param op Output scanline. - * @param l The number of pixels to "unpack". - * @param Vars0 Image resizing-related variables. - */ - - template< class Tout > - static void unpackScanline( const fptype* ip, Tout* op, int l, - const CImageResizerVars& Vars0 ) - { - const int ElCount = Vars0.ElCount; - const int ElCountIO = Vars0.ElCountIO; - - if( ElCountIO == 1 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - ip += ElCount; - op++; - l--; - } - } - else - if( ElCountIO == 4 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - op[ 2 ] = (Tout) v[ 2 ]; - op[ 3 ] = (Tout) v[ 3 ]; - ip += ElCount; - op += 4; - l--; - } - } - else - if( ElCountIO == 3 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - op[ 2 ] = (Tout) v[ 2 ]; - ip += ElCount; - op += 3; - l--; - } - } - else - if( ElCountIO == 2 ) - { - while( l > 0 ) - { - const fptypeatom* v = (const fptypeatom*) ip; - op[ 0 ] = (Tout) v[ 0 ]; - op[ 1 ] = (Tout) v[ 1 ]; - ip += ElCount; - op += 2; - l--; - } - } - } - - /** - * Function calculates scanline's DC gain for each channel, further used - * to "unbias" the scanline. - * - * @param p Source scanline. - * @param SrcLen Source scanline's length. - * @param[out] ElBiases Resuling biases. - */ - - void calcScanlineBias( const fptype* p, const int SrcLen, - fptype* const ElBiases ) const - { - const int ElCount = Vars -> ElCount; - int l = SrcLen; - - if( ElCount == 1 ) - { - fptype b0 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - p++; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - } - else - if( ElCount == 4 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - fptype b2 = (fptype) 0; - fptype b3 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - b2 += p[ 2 ]; - b3 += p[ 3 ]; - p += 4; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - ElBiases[ 2 ] = b2 / (fptype) SrcLen; - ElBiases[ 3 ] = b3 / (fptype) SrcLen; - } - else - if( ElCount == 3 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - fptype b2 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - b2 += p[ 2 ]; - p += 3; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - ElBiases[ 2 ] = b2 / (fptype) SrcLen; - } - else - if( ElCount == 2 ) - { - fptype b0 = (fptype) 0; - fptype b1 = (fptype) 0; - - while( l > 0 ) - { - b0 += p[ 0 ]; - b1 += p[ 1 ]; - p += 2; - l--; - } - - ElBiases[ 0 ] = b0 / (fptype) SrcLen; - ElBiases[ 1 ] = b1 / (fptype) SrcLen; - } - } - - /** - * Function applies "unbiasing" to the scanline, by subtracting the - * previously calculated bias (DC gain) values. - * - * @param p Scanline. - * @param l Scanline's length. - * @param ElBiases Biases to subtract, for each channel. - */ - - void unbiasScanline( fptype* p, int l, - const fptype* const ElBiases ) const - { - const int ElCount = Vars -> ElCount; - - if( ElCount == 1 ) - { - const fptype b0 = ElBiases[ 0 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p++; - l--; - } - } - else - if( ElCount == 4 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - const fptype b2 = ElBiases[ 2 ]; - const fptype b3 = ElBiases[ 3 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p[ 2 ] -= b2; - p[ 3 ] -= b3; - p += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - const fptype b2 = ElBiases[ 2 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p[ 2 ] -= b2; - p += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - const fptype b0 = ElBiases[ 0 ]; - const fptype b1 = ElBiases[ 1 ]; - - while( l > 0 ) - { - p[ 0 ] -= b0; - p[ 1 ] -= b1; - p += 2; - l--; - } - } - } - - /** - * Function prepares input scanline buffer for *this filtering step. - * Left- and right-most pixels are replicated to make sure no buffer - * overrun happens. Such approach also allows to bypass any pointer - * range checks. - * - * @param Src Source buffer. - */ - - void prepareInBuf( fptype* Src ) const - { - if( IsUpsample || InPrefix + InSuffix == 0 ) - { - return; - } - - const int ElCount = Vars -> ElCount; - replicateArray( Src, ElCount, Src - ElCount, InPrefix, -ElCount ); - - Src += ( InLen - 1 ) * ElCount; - replicateArray( Src, ElCount, Src + ElCount, InSuffix, ElCount ); - } - - /** - * Function peforms scanline upsampling with filtering. - * - * @param Src Source scanline buffer (length = this -> InLen). Source - * scanline increment will be equal to ElCount. - * @param Dst Destination scanline buffer. - */ - - void doUpsample( const fptype* const Src, fptype* const Dst ) const - { - const int ElCount = Vars -> ElCount; - fptype* op0 = &Dst[ -OutPrefix * ElCount ]; - memset( op0, 0, ( OutPrefix + OutLen + OutSuffix ) * ElCount * - sizeof( fptype )); - - const fptype* ip = Src; - const int opstep = ElCount * ResampleFactor; - int l; - - if( FltOrig.getCapacity() > 0 ) - { - // Do not perform filtering, only upsample. - - op0 += ( OutPrefix % ResampleFactor ) * ElCount; - l = OutPrefix / ResampleFactor; - - if( ElCount == 1 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0[ 3 ] = ip[ 3 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0[ 2 ] = ip[ 2 ]; - op0 += opstep; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - ip += ElCount; - l--; - } - - l = OutSuffix / ResampleFactor; - - while( l >= 0 ) - { - op0[ 0 ] = ip[ 0 ]; - op0[ 1 ] = ip[ 1 ]; - op0 += opstep; - l--; - } - } - - return; - } - - const fptype* const f = Flt; - const int flen = Flt.getCapacity(); - fptype* op; - int i; - - if( ElCount == 1 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ i ] += f[ i ] * ip[ 0 ]; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 4 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op[ 3 ] += f[ i ] * ip[ 3 ]; - op += 4; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 3 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op[ 2 ] += f[ i ] * ip[ 2 ]; - op += 3; - } - - op0 += opstep; - l--; - } - } - else - if( ElCount == 2 ) - { - l = InPrefix; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - op0 += opstep; - l--; - } - - l = InLen - 1; - - while( l > 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - ip += ElCount; - op0 += opstep; - l--; - } - - l = InSuffix; - - while( l >= 0 ) - { - op = op0; - - for( i = 0; i < flen; i++ ) - { - op[ 0 ] += f[ i ] * ip[ 0 ]; - op[ 1 ] += f[ i ] * ip[ 1 ]; - op += 2; - } - - op0 += opstep; - l--; - } - } - - op = op0; - const fptype* dc = SuffixDC; - l = SuffixDC.getCapacity(); - - if( ElCount == 1 ) - { - for( i = 0; i < l; i++ ) - { - op[ i ] += ip[ 0 ] * dc[ i ]; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - op[ 3 ] += ip[ 3 ] * dc[ 0 ]; - dc++; - op += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - dc++; - op += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - dc++; - op += 2; - l--; - } - } - - ip = Src; - op = Dst - InPrefix * opstep; - dc = PrefixDC; - l = PrefixDC.getCapacity(); - - if( ElCount == 1 ) - { - for( i = 0; i < l; i++ ) - { - op[ i ] += ip[ 0 ] * dc[ i ]; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - op[ 3 ] += ip[ 3 ] * dc[ 0 ]; - dc++; - op += 4; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - op[ 2 ] += ip[ 2 ] * dc[ 0 ]; - dc++; - op += 3; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - op[ 0 ] += ip[ 0 ] * dc[ 0 ]; - op[ 1 ] += ip[ 1 ] * dc[ 0 ]; - dc++; - op += 2; - l--; - } - } - } - - /** - * Function peforms scanline filtering with optional downsampling. - * Function makes use of the symmetry of the filter. - * - * @param Src Source scanline buffer (length = this -> InLen). Source - * scanline increment will be equal to ElCount. - * @param Dst Destination scanline buffer. - * @param DstIncr Destination scanline buffer increment, used for - * horizontal or vertical scanline stepping. - */ - - void doFilter( const fptype* const Src, fptype* Dst, - const int DstIncr ) const - { - const int ElCount = Vars -> ElCount; - const fptype* const f = &Flt[ FltLatency ]; - const int flen = FltLatency + 1; - const int ipstep = ElCount * ResampleFactor; - const fptype* ip = Src - EdgePixelCount * ipstep; - const fptype* ip1; - const fptype* ip2; - int l = OutLen; - int i; - - if( ElCount == 1 ) - { - while( l > 0 ) - { - fptype s = f[ 0 ] * ip[ 0 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1++; - ip2--; - s += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - } - - Dst[ 0 ] = s; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 4 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - fptype s3 = f[ 0 ] * ip[ 2 ]; - fptype s4 = f[ 0 ] * ip[ 3 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 4; - ip2 -= 4; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); - s4 += f[ i ] * ( ip1[ 3 ] + ip2[ 3 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst[ 2 ] = s3; - Dst[ 3 ] = s4; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 3 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - fptype s3 = f[ 0 ] * ip[ 2 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 3; - ip2 -= 3; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - s3 += f[ i ] * ( ip1[ 2 ] + ip2[ 2 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst[ 2 ] = s3; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - else - if( ElCount == 2 ) - { - while( l > 0 ) - { - fptype s1 = f[ 0 ] * ip[ 0 ]; - fptype s2 = f[ 0 ] * ip[ 1 ]; - ip1 = ip; - ip2 = ip; - - for( i = 1; i < flen; i++ ) - { - ip1 += 2; - ip2 -= 2; - s1 += f[ i ] * ( ip1[ 0 ] + ip2[ 0 ]); - s2 += f[ i ] * ( ip1[ 1 ] + ip2[ 1 ]); - } - - Dst[ 0 ] = s1; - Dst[ 1 ] = s2; - Dst += DstIncr; - ip += ipstep; - l--; - } - } - } - - /** - * Function performs resizing of a single scanline. This function does - * not "know" about the length of the source scanline buffer. This buffer - * should be padded with enough pixels so that ( SrcPos - FilterLenD2 ) is - * always >= 0 and ( SrcPos + ( DstLineLen - 1 ) * k + FilterLenD2 + 1 ) - * does not exceed source scanline's buffer length. SrcLine's increment is - * assumed to be equal to ElCount. - * - * @param SrcLine Source scanline buffer. - * @param DstLine Destination (resized) scanline buffer. - * @param DstLineIncr Destination scanline position increment, used for - * horizontal or vertical scanline stepping. - * @param ElBiases Bias values to add to the resulting scanline. - * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be - * aligned by fpclass :: fpalign. - */ - - void doResize( const fptype* SrcLine, fptype* DstLine, - const int DstLineIncr, const fptype* const ElBiases, - fptype* const ) const - { - const int IntFltLen = FltBank -> getFilterLen(); - const int ElCount = Vars -> ElCount; - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* rpos = &(*RPosBuf)[ 0 ]; - - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* const rpose = rpos + OutLen; - -#define AVIR_RESIZE_PART1 \ - while( rpos < rpose ) \ - { \ - const fptype x = (fptype) rpos -> x; \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* const ftp2 = ftp + IntFltLen; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - int i; - -#define AVIR_RESIZE_PART1nx \ - while( rpos < rpose ) \ - { \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - int i; - -#define AVIR_RESIZE_PART2 \ - DstLine += DstLineIncr; \ - rpos++; \ - } - - if( FltBank -> getOrder() == 1 ) - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - sum0 += ( ftp[ i ] + ftp2[ i ] * x ) * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - else - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - sum0 += ftp[ i ] * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i++ ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - } -#undef AVIR_RESIZE_PART2 -#undef AVIR_RESIZE_PART1nx -#undef AVIR_RESIZE_PART1 - - /** - * Function performs resizing of a single scanline assuming that the input - * buffer consists of zero-padded elements (2X upsampling without - * filtering). Similar to the doResize() function otherwise. - * - * @param SrcLine Source scanline buffer. - * @param DstLine Destination (resized) scanline buffer. - * @param DstLineIncr Destination scanline position increment, used for - * horizontal or vertical scanline stepping. - * @param ElBiases Bias values to add to the resulting scanline. - * @param xx Temporary buffer, of size FltBank -> getFilterLen(), must be - * aligned by fpclass :: fpalign. - */ - - void doResize2( const fptype* SrcLine, fptype* DstLine, - const int DstLineIncr, const fptype* const ElBiases, - fptype* const ) const - { - const int IntFltLen0 = FltBank -> getFilterLen(); - const int ElCount = Vars -> ElCount; - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* rpos = &(*RPosBuf)[ 0 ]; - - const typename CImageResizerFilterStep< fptype, fptypeatom > :: - CResizePos* const rpose = rpos + OutLen; - -#define AVIR_RESIZE_PART1 \ - while( rpos < rpose ) \ - { \ - const fptype x = (fptype) rpos -> x; \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* const ftp2 = ftp + IntFltLen0; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - const int IntFltLen = rpos -> fl; \ - int i; - -#define AVIR_RESIZE_PART1nx \ - while( rpos < rpose ) \ - { \ - const fptype* const ftp = rpos -> ftp; \ - const fptype* Src = SrcLine + rpos -> SrcOffs; \ - const int IntFltLen = rpos -> fl; \ - int i; - -#define AVIR_RESIZE_PART2 \ - DstLine += DstLineIncr; \ - rpos++; \ - } - - if( FltBank -> getOrder() == 1 ) - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - sum0 += ( ftp[ i ] + ftp2[ i ] * x ) * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1 - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ] + ftp2[ i ] * x; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - else - { - if( ElCount == 1 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - sum0 += ftp[ i ] * Src[ i ]; - } - - DstLine[ 0 ] = sum0; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 4 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - fptype sum3 = ElBiases[ 3 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - sum3 += xx * Src[ 3 ]; - Src += 4 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - DstLine[ 3 ] = sum3; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 3 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - fptype sum2 = ElBiases[ 2 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - sum2 += xx * Src[ 2 ]; - Src += 3 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - DstLine[ 2 ] = sum2; - - AVIR_RESIZE_PART2 - } - else - if( ElCount == 2 ) - { - AVIR_RESIZE_PART1nx - - fptype sum0 = ElBiases[ 0 ]; - fptype sum1 = ElBiases[ 1 ]; - - for( i = 0; i < IntFltLen; i += 2 ) - { - const fptype xx = ftp[ i ]; - sum0 += xx * Src[ 0 ]; - sum1 += xx * Src[ 1 ]; - Src += 2 * 2; - } - - DstLine[ 0 ] = sum0; - DstLine[ 1 ] = sum1; - - AVIR_RESIZE_PART2 - } - } - } -#undef AVIR_RESIZE_PART2 -#undef AVIR_RESIZE_PART1nx -#undef AVIR_RESIZE_PART1 -}; - -/** - * @brief Image resizer's default dithering class. - * - * This class defines an object that performs rounding, clipping and dithering - * operations over horizontal scanline pixels before scanline is stored in the - * output buffer. - * - * The ditherer should expect the same storage order of the pixels in a - * scanline as used in the "filtering step" class. So, a separate ditherer - * class should be defined for each scanline pixel storage style. The default - * ditherer implements a simple rounding without dithering: it can be used for - * an efficient dithering method which can be multi-threaded. - * - * @tparam fptype Floating point type to use for storing pixel data. SIMD - * types can be used. - */ - -template< class fptype > -class CImageResizerDithererDefINL -{ -public: - /** - * Function initializes the ditherer object. - * - * @param aLen Scanline length in pixels to process. - * @param aVars Image resizing-related variables. - * @param aTrMul Bit-depth truncation multiplier. 1 - no additional - * truncation. - * @param aPkOut Peak output value allowed. - */ - - void init( const int aLen, const CImageResizerVars& aVars, - const double aTrMul, const double aPkOut ) - { - Len = aLen; - Vars = &aVars; - LenE = aLen * Vars -> ElCount; - TrMul0 = aTrMul; - PkOut0 = aPkOut; - } - - /** - * @return "True" if dithering is recursive relative to scanlines meaning - * multi-threaded execution is not supported by this dithering method. - */ - - static bool isRecursive() - { - return( false ); - } - - /** - * Function performs rounding and clipping operations. - * - * @param ResScanline The buffer containing the final scanline. - */ - - void dither( fptype* const ResScanline ) const - { - const fptype c0 = (fptype) 0; - const fptype PkOut = (fptype) PkOut0; - int j; - - if( TrMul0 == 1.0 ) - { - // Optimization - do not perform bit depth truncation. - - for( j = 0; j < LenE; j++ ) - { - ResScanline[ j ] = clamp( round( ResScanline[ j ]), c0, - PkOut ); - } - } - else - { - const fptype TrMul = (fptype) TrMul0; - - for( j = 0; j < LenE; j++ ) - { - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - } - } - } - -protected: - int Len; ///< Scanline's length in pixels. - ///< - const CImageResizerVars* Vars; ///< Image resizing-related variables. - ///< - int LenE; ///< = LenE * ElCount. - ///< - double TrMul0; ///< Bit-depth truncation multiplier. - ///< - double PkOut0; ///< Peak output value allowed. - ///< -}; - -/** - * @brief Image resizer's error-diffusion dithering class, interleaved mode. - * - * This ditherer implements error-diffusion dithering which looks good, and - * whose results are compressed by PNG well. This implementation uses - * weighting coefficients obtained via machine optimization and visual - * evaluation. - * - * @tparam fptype Floating point type to use for storing pixel data. SIMD - * types can be used. - */ - -template< class fptype > -class CImageResizerDithererErrdINL : - public CImageResizerDithererDefINL< fptype > -{ -public: - /** - * Function initializes the ditherer object. - * - * @param aLen Scanline length in pixels to process. - * @param aVars Image resizing-related variables. - * @param aTrMul Bit-depth truncation multiplier. 1 - no additional - * truncation. - * @param aPkOut Peak output value allowed. - */ - - void init( const int aLen, const CImageResizerVars& aVars, - const double aTrMul, const double aPkOut ) - { - CImageResizerDithererDefINL< fptype > :: init( aLen, aVars, aTrMul, - aPkOut ); - - ResScanlineDith0.alloc( LenE + Vars -> ElCount, sizeof( fptype )); - ResScanlineDith = ResScanlineDith0 + Vars -> ElCount; - int i; - - for( i = 0; i < LenE + Vars -> ElCount; i++ ) - { - ResScanlineDith0[ i ] = (fptype) 0; - } - } - - static bool isRecursive() - { - return( true ); - } - - void dither( fptype* const ResScanline ) - { - const int ElCount = Vars -> ElCount; - const fptype c0 = (fptype) 0; - const fptype TrMul = (fptype) TrMul0; - const fptype PkOut = (fptype) PkOut0; - int j; - - for( j = 0; j < LenE; j++ ) - { - ResScanline[ j ] += ResScanlineDith[ j ]; - ResScanlineDith[ j ] = (fptype) 0; - } - - for( j = 0; j < LenE - ElCount; j++ ) - { - // Perform rounding, noise estimation and saturation. - - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - const fptype Noise = ResScanline[ j ] - z0; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - - ResScanline[ j + ElCount ] += Noise * (fptype) 0.364842; - ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; - ResScanlineDith[ j ] += Noise * (fptype) 0.364842; - ResScanlineDith[ j + ElCount ] += Noise * (fptype) 0.063011; - } - - while( j < LenE ) - { - const fptype z0 = round( ResScanline[ j ] / TrMul ) * TrMul; - const fptype Noise = ResScanline[ j ] - z0; - ResScanline[ j ] = clamp( z0, c0, PkOut ); - - ResScanlineDith[ j - ElCount ] += Noise * (fptype) 0.207305; - ResScanlineDith[ j ] += Noise * (fptype) 0.364842; - j++; - } - } - -protected: - using CImageResizerDithererDefINL< fptype > :: Len; - using CImageResizerDithererDefINL< fptype > :: Vars; - using CImageResizerDithererDefINL< fptype > :: LenE; - using CImageResizerDithererDefINL< fptype > :: TrMul0; - using CImageResizerDithererDefINL< fptype > :: PkOut0; - - CBuffer< fptype > ResScanlineDith0; ///< Error diffusion buffer. - ///< - fptype* ResScanlineDith; ///< Error diffusion buffer pointer which skips - ///< the first ElCount elements. - ///< -}; - -/** - * @brief Floating-point processing definition and abstraction class. - * - * This class defines several constants and typedefs that point to classes - * that should be used by the image resizing algorithm. Such "definition - * class" can be used to define alternative scanline processing algorithms - * (e.g. SIMD) and image scanline packing styles used during processing. This - * class also offers an abstraction layer for dithering, rounding and - * clamping (saturation) operation. - * - * The fpclass_def class can be used to define processing using both SIMD and - * non-SIMD types, but using algorithms that operate on interleaved pixels, - * and which are non-SIMD optimized themselves. - * - * @tparam afptype Floating point type to use for storing intermediate data - * and variables. For variables that are not used in intensive calculations - * the "double" type is always used. On the latest Intel processors (like - * i7-4770K) there is almost no performance difference between "double" and - * "float". Image quality differences between "double" and "float" are not - * apparent on 8-bit images. At the same time the "float" uses half amount of - * working memory the "double" type uses. SIMD types can be used. The - * functions round() and clamp() in the "avir" or other visible namespace - * should be available for the specified type. SIMD types allow to perform - * resizing of images with more than 4 channels, to be exact 4 * SIMD element - * number (e.g. 16 for float4), without modification of the image resizing - * algorithm required. - * @tparam afptypeatom The atomic type the "afptype" consists of. - * @tparam adith Ditherer class to use during processing. - */ - -template< class afptype, class afptypeatom = afptype, - class adith = CImageResizerDithererDefINL< afptype > > -class fpclass_def -{ -public: - typedef afptype fptype; ///< Floating-point type to use during processing. - ///< - typedef afptypeatom fptypeatom; ///< Atomic type "fptype" consists of. - ///< - static const int fppack = sizeof( fptype ) / sizeof( fptypeatom ); ///< - ///< The number of atomic types stored in a single "fptype" element. - ///< - static const int fpalign = sizeof( fptype ); ///< Suggested alignment size - ///< in bytes. This is not a required alignment, because image - ///< resizing algorithm cannot be made to have a strictly aligned data - ///< access at all steps (e.g. interpolation cannot perform aligned - ///< accesses). - ///< - static const int elalign = 1; ///< Length alignment of arrays of elements. - ///< This applies to filters and intermediate buffers: this constant - ///< forces filters and scanlines to have a length which is a multiple - ///< of this value, for more efficient SIMD implementation. - ///< - static const int packmode = 0; ///< 0 if interleaved packing, 1 if - ///< de-interleaved. - ///< - typedef CImageResizerFilterStepINL< fptype, fptypeatom > CFilterStep; ///< - ///< Filtering step class to use during processing. - ///< - typedef adith CDitherer; ///< Ditherer class to use during processing. - ///< -}; - -/** - * @brief Image resizer class. - * - * The object of this class can be used to resize 1-4 channel images to any - * required size. Resizing is performed by utilizing interpolated sinc - * fractional delay filters plus (if necessary) a cascade of built-in - * sinc function-based 2X upsampling or 2X downsampling stages, followed by a - * correction filtering. - * - * Object of this class can be allocated on stack. - * - * @tparam fpclass Floating-point processing definition class to use. See - * avir::fpclass_def for more details. - */ - -template< class fpclass = fpclass_def< float > > -class CImageResizer -{ - AVIR_NOCTOR( CImageResizer ); - -public: - /** - * Constructor initializes the resizer. - * - * @param aResBitDepth Required bit depth of resulting image (1-16). If - * integer value output is used (e.g. uint8_t), the bit depth also affects - * rounding: for example, if aResBitDepth=6 and "Tout" is uint8_t, the - * result will be rounded to 6 most significant bits (2 least significant - * bits truncated, with dithering applied). - * @param aSrcBitDepth Source image's real bit-depth. Set to 0 to use - * aResBitDepth. - * @param aParams Resizing algorithm's parameters to use. Leave out for - * default values. Can be useful when performing automatic optimization of - * parameters. - */ - - CImageResizer( const int aResBitDepth = 8, const int aSrcBitDepth = 0, - const CImageResizerParams& aParams = CImageResizerParamsDef() ) - : Params( aParams ) - , ResBitDepth( aResBitDepth ) - { - SrcBitDepth = ( aSrcBitDepth == 0 ? ResBitDepth : aSrcBitDepth ); - - initFilterBank( FixedFilterBank, 1.0, false, CFltBuffer() ); - FixedFilterBank.createAllFilters(); - } - - /** - * Function resizes image. - * - * @param SrcBuf Source image buffer. - * @param SrcWidth Source image width. - * @param SrcHeight Source image height. - * @param SrcScanlineSize Physical size of source scanline in elements - * (not bytes). If this value is below 1, SrcWidth * ElCountIO will be - * used as the physical source scanline size. - * @param[out] NewBuf Buffer to accept the resized image. Can be equal to - * SrcBuf if the size of the resized image is smaller or equal to source - * image in size. - * @param NewWidth New image width. - * @param NewHeight New image height. - * @param ElCountIO The number of elements (channels) used to store each - * source and destination pixel (1-4). - * @param k Resizing step (one output pixel corresponds to "k" input - * pixels). A downsizing factor if > 1.0; upsizing factor if <= 1.0. - * Multiply by -1 if you would like to bypass "ox" and "oy" adjustment - * which is done by default to produce a centered image. If step value - * equals 0, the step value will be chosen automatically and independently - * for horizontal and vertical resizing. - * @param[in,out] aVars Pointer to variables structure to be passed to the - * image resizing function. Can be NULL. Only variables that are - * initialized in default constructor of this structure are accepted by - * this function. These variables will not be changed by this function. - * All other variables can be modified by this function. The access to - * this object is not thread-safe, each concurrent instance of this - * function should use a separate aVars object. - * @tparam Tin Input buffer element's type. Can be uint8_t (0-255 value - * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), - * double (0.0-1.0 value range). Larger integer types are treated as - * uint16_t. Signed integer types are unsupported. - * @tparam Tout Output buffer element's type. Can be uint8_t (0-255 value - * range), uint16_t (0-65535 value range), float (0.0-1.0 value range), - * double (0.0-1.0 value range). Larger integer types are treated as - * uint16_t. Signed integer types are unsupported. - */ - - template< class Tin, class Tout > - void resizeImage( const Tin* const SrcBuf, const int SrcWidth, - const int SrcHeight, int SrcScanlineSize, Tout* const NewBuf, - const int NewWidth, const int NewHeight, const int ElCountIO, - const double k, CImageResizerVars* const aVars = NULL ) const - { - if( SrcWidth == 0 || SrcHeight == 0 ) - { - memset( NewBuf, 0, (size_t) NewWidth * NewHeight * - sizeof( Tout )); - - return; - } - else - if( NewWidth == 0 || NewHeight == 0 ) - { - return; - } - - CImageResizerVars DefVars; - CImageResizerVars& Vars = ( aVars == NULL ? DefVars : *aVars ); - - CImageResizerThreadPool DefThreadPool; - CImageResizerThreadPool& ThreadPool = ( Vars.ThreadPool == NULL ? - DefThreadPool : *Vars.ThreadPool ); - - // Define resizing steps, also optionally modify offsets so that - // resizing produces a "centered" image. - - double kx; - double ky; - double ox = Vars.ox; - double oy = Vars.oy; - - if( k == 0.0 ) - { - kx = (double) SrcWidth / NewWidth; - ox += ( kx - 1.0 ) * 0.5; - - ky = (double) SrcHeight / NewHeight; - oy += ( ky - 1.0 ) * 0.5; - } - else - if( k > 0.0 ) - { - kx = k; - ky = k; - - const double ko = ( k - 1.0 ) * 0.5; - ox += ko; - oy += ko; - } - else - { - kx = -k; - ky = -k; - } - - // Evaluate pre-multipliers used on the output stage. - - const bool IsInFloat = ( (Tin) 0.25 != 0 ); - const bool IsOutFloat = ( (Tout) 0.25 != 0 ); - double OutMul; // Output multiplier. - - if( Vars.UseSRGBGamma ) - { - if( IsInFloat ) - { - Vars.InGammaMult = 1.0; - } - else - { - Vars.InGammaMult = - 1.0 / ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); - } - - if( IsOutFloat ) - { - Vars.OutGammaMult = 1.0; - } - else - { - Vars.OutGammaMult = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); - } - - OutMul = 1.0; - } - else - { - if( IsOutFloat ) - { - OutMul = 1.0; - } - else - { - OutMul = ( sizeof( Tout ) == 1 ? 255.0 : 65535.0 ); - } - - if( !IsInFloat ) - { - OutMul /= ( sizeof( Tin ) == 1 ? 255.0 : 65535.0 ); - } - } - - // Fill widely-used variables. - - const int ElCount = ( ElCountIO + fpclass :: fppack - 1 ) / - fpclass :: fppack; - - const int NewWidthE = NewWidth * ElCount; - - if( SrcScanlineSize < 1 ) - { - SrcScanlineSize = SrcWidth * ElCountIO; - } - - Vars.ElCount = ElCount; - Vars.ElCountIO = ElCountIO; - Vars.fppack = fpclass :: fppack; - Vars.fpalign = fpclass :: fpalign; - Vars.elalign = fpclass :: elalign; - Vars.packmode = fpclass :: packmode; - - // Horizontal scanline filtering and resizing. - - CDSPFracFilterBankLin< fptype > FltBank; - CFilterSteps FltSteps; - typename CFilterStep :: CRPosBufArray RPosBufArray; - CBuffer< uint8_t > UsedFracMap; - - // Perform the filtering steps modeling at various modes, find the - // most efficient mode for both horizontal and vertical resizing. - - int UseBuildMode = 1; - const int BuildModeCount = - ( FixedFilterBank.getOrder() == 0 ? 4 : 2 ); - - int m; - - if( Vars.BuildMode >= 0 ) - { - UseBuildMode = Vars.BuildMode; - } - else - { - int BestScore = 0x7FFFFFFF; - - for( m = 0; m < BuildModeCount; m++ ) - { - CDSPFracFilterBankLin< fptype > TmpBank; - CFilterSteps TmpSteps; - Vars.k = kx; - Vars.o = ox; - buildFilterSteps( TmpSteps, Vars, TmpBank, OutMul, m, true ); - updateFilterStepBuffers( TmpSteps, Vars, RPosBufArray, - SrcWidth, NewWidth ); - - fillUsedFracMap( TmpSteps[ Vars.ResizeStep ], UsedFracMap ); - const int c = calcComplexity( TmpSteps, Vars, UsedFracMap, - SrcHeight ); - - if( c < BestScore ) - { - UseBuildMode = m; - BestScore = c; - } - } - } - - // Perform the actual filtering steps building. - - Vars.k = kx; - Vars.o = ox; - buildFilterSteps( FltSteps, Vars, FltBank, OutMul, UseBuildMode, - false ); - - updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcWidth, - NewWidth ); - - updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); - - const int ThreadCount = ThreadPool.getSuggestedWorkloadCount(); - // Includes the current thread. - - CStructArray< CThreadData< Tin, Tout > > td; - td.setItemCount( ThreadCount ); - int i; - - for( i = 0; i < ThreadCount; i++ ) - { - if( i > 0 ) - { - ThreadPool.addWorkload( &td[ i ]); - } - - td[ i ].init( i, ThreadCount, FltSteps, Vars ); - - td[ i ].initScanlineQueue( td[ i ].sopResizeH, SrcHeight, - SrcWidth ); - } - - CBuffer< fptype, size_t > FltBuf( (size_t) NewWidthE * SrcHeight, - fpclass :: fpalign ); // Temporary buffer that receives - // horizontally-filtered and resized image. - - for( i = 0; i < SrcHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - (void*) &SrcBuf[ (size_t) i * SrcScanlineSize ], - &FltBuf[ (size_t) i * NewWidthE ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - - // Vertical scanline filtering and resizing, reuse previously defined - // filtering steps if possible. - - const int PrevUseBuildMode = UseBuildMode; - - if( Vars.BuildMode >= 0 ) - { - UseBuildMode = Vars.BuildMode; - } - else - { - CImageResizerVars TmpVars( Vars ); - int BestScore = 0x7FFFFFFF; - - for( m = 0; m < BuildModeCount; m++ ) - { - CDSPFracFilterBankLin< fptype > TmpBank; - TmpBank.copyInitParams( FltBank ); - CFilterSteps TmpSteps; - TmpVars.k = ky; - TmpVars.o = oy; - buildFilterSteps( TmpSteps, TmpVars, TmpBank, 1.0, m, true ); - updateFilterStepBuffers( TmpSteps, TmpVars, RPosBufArray, - SrcHeight, NewHeight ); - - fillUsedFracMap( TmpSteps[ TmpVars.ResizeStep ], - UsedFracMap ); - - const int c = calcComplexity( TmpSteps, TmpVars, UsedFracMap, - NewWidth ); - - if( c < BestScore ) - { - UseBuildMode = m; - BestScore = c; - } - } - } - - Vars.k = ky; - Vars.o = oy; - - if( UseBuildMode == PrevUseBuildMode && ky == kx ) - { - if( OutMul != 1.0 ) - { - modifyCorrFilterDCGain( FltSteps, 1.0 / OutMul ); - } - } - else - { - buildFilterSteps( FltSteps, Vars, FltBank, 1.0, UseBuildMode, - false ); - } - - updateFilterStepBuffers( FltSteps, Vars, RPosBufArray, SrcHeight, - NewHeight ); - - updateBufLenAndRPosPtrs( FltSteps, Vars, NewWidth ); - - if( IsOutFloat && sizeof( FltBuf[ 0 ]) == sizeof( Tout ) && - fpclass :: packmode == 0 ) - { - // In-place output. - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, - SrcHeight, NewWidthE, NewWidthE ); - } - - for( i = 0; i < NewWidth; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &FltBuf[ (size_t) i * ElCount ], - (fptype*) &NewBuf[ (size_t) i * ElCount ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - ThreadPool.removeAllWorkloads(); - - return; - } - - CBuffer< fptype, size_t > ResBuf( (size_t) NewWidthE * NewHeight, - fpclass :: fpalign ); - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopResizeV, NewWidth, - SrcHeight, NewWidthE, NewWidthE ); - } - - const int im = ( fpclass :: packmode == 0 ? ElCount : 1 ); - - for( i = 0; i < NewWidth; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &FltBuf[ (size_t) i * im ], &ResBuf[ (size_t) i * im ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - - if( IsOutFloat ) - { - // Perform output, but skip dithering. - - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopUnpackH, - NewHeight, NewWidth ); - } - - for( i = 0; i < NewHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &ResBuf[ (size_t) i * NewWidthE ], - &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - ThreadPool.removeAllWorkloads(); - - return; - } - - // Perform output with dithering (for integer output only). - - int TruncBits; // The number of lower bits to truncate and dither. - int OutRange; // Output range. - - if( sizeof( Tout ) == 1 ) - { - TruncBits = 8 - ResBitDepth; - OutRange = 255; - } - else - { - TruncBits = 16 - ResBitDepth; - OutRange = 65535; - } - - const double PkOut = OutRange; - const double TrMul = ( TruncBits > 0 ? - PkOut / ( OutRange >> TruncBits ) : 1.0 ); - - if( CDitherer :: isRecursive() ) - { - td[ 0 ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); - - if( Vars.UseSRGBGamma ) - { - for( i = 0; i < NewHeight; i++ ) - { - fptype* const ResScanline = - &ResBuf[ (size_t) i * NewWidthE ]; - - CFilterStep :: applySRGBGamma( ResScanline, NewWidth, - Vars ); - - td[ 0 ].getDitherer().dither( ResScanline ); - - CFilterStep :: unpackScanline( ResScanline, - &NewBuf[ (size_t) i * NewWidth * ElCountIO ], - NewWidth, Vars ); - } - } - else - { - for( i = 0; i < NewHeight; i++ ) - { - fptype* const ResScanline = - &ResBuf[ (size_t) i * NewWidthE ]; - - td[ 0 ].getDitherer().dither( ResScanline ); - - CFilterStep :: unpackScanline( ResScanline, - &NewBuf[ (size_t) i * NewWidth * ElCountIO ], - NewWidth, Vars ); - } - } - } - else - { - for( i = 0; i < ThreadCount; i++ ) - { - td[ i ].initScanlineQueue( td[ i ].sopDitherAndUnpackH, - NewHeight, NewWidth ); - - td[ i ].getDitherer().init( NewWidth, Vars, TrMul, PkOut ); - } - - for( i = 0; i < NewHeight; i++ ) - { - td[ i % ThreadCount ].addScanlineToQueue( - &ResBuf[ (size_t) i * NewWidthE ], - &NewBuf[ (size_t) i * NewWidth * ElCountIO ]); - } - - ThreadPool.startAllWorkloads(); - td[ 0 ].processScanlineQueue(); - ThreadPool.waitAllWorkloadsToFinish(); - } - - ThreadPool.removeAllWorkloads(); - } - -private: - typedef typename fpclass :: fptype fptype; ///< Floating-point type to use - ///< during processing. - ///< - typedef typename fpclass :: CFilterStep CFilterStep; ///< Filtering step - ///< class to use during processing. - ///< - typedef typename fpclass :: CDitherer CDitherer; ///< Ditherer class to - ///< use during processing. - ///< - CImageResizerParams Params; ///< Algorithm's parameters currently in use. - ///< - int SrcBitDepth; ///< Bit resolution of the source image. - ///< - int ResBitDepth; ///< Bit resolution of the resulting image. - ///< - CDSPFracFilterBankLin< fptype > FixedFilterBank; ///< Fractional delay - ///< filter bank with fixed characteristics, mainly for upsizing - ///< cases. - ///< - - /** - * @brief Filtering steps array. - * - * The object of this class stores filtering steps together. - */ - - typedef CStructArray< CFilterStep > CFilterSteps; - - /** - * Function initializes the filter bank in the specified resizing step - * according to the source and resulting image bit depths. - * - * @param FltBank Filter bank to initialize. - * @param CutoffMult Cutoff multiplier, 0 to 1. 1 corresponds to 0.5pi - * cutoff point. - * @param ForceHiOrder "True" if a high-order interpolation should be - * forced which requires considerably less resources for initialization. - * @param ExtFilter External filter to apply to interpolation filter. - */ - - void initFilterBank( CDSPFracFilterBankLin< fptype >& FltBank, - const double CutoffMult, const bool ForceHiOrder, - const CFltBuffer& ExtFilter ) const - { - const int IntBitDepth = ( ResBitDepth > SrcBitDepth ? ResBitDepth : - SrcBitDepth ); - - const double SNR = -6.02 * ( IntBitDepth + 3 ); - int UseOrder; - int FracCount; // The number of fractional delay filters sampled by - // the filter bank. This variable affects the signal-to-noise - // ratio at interpolation stage. Theoretically, at UseOrder==1, - // 8-bit image resizing requires 66.2 dB SNR or 11. 16-bit - // resizing requires 114.4 dB SNR or 150. At UseOrder=0 the - // required number of filters is exponentially higher. - - if( ForceHiOrder || IntBitDepth > 8 ) - { - UseOrder = 1; // -146 dB max - FracCount = (int) ceil( 0.23134052 * exp( -0.058062929 * SNR )); - } - else - { - UseOrder = 0; // -72 dB max - FracCount = (int) ceil( 0.33287686 * exp( -0.11334583 * SNR )); - } - - if( FracCount < 2 ) - { - FracCount = 2; - } - - FltBank.init( FracCount, UseOrder, Params.IntFltLen / CutoffMult, - Params.IntFltCutoff * CutoffMult, Params.IntFltAlpha, ExtFilter, - fpclass :: fpalign, fpclass :: elalign ); - } - - /** - * Function allocates filter buffer taking "fpclass" alignments into - * account. The allocated buffer may be larger than the requested size: in - * this case the additional elements will be zeroed by this function. - * - * @param Flt Filter buffer. - * @param ReqCapacity The required filter buffer's capacity. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter allocation. - * @param FltExt If non-NULL this variable will receive the number of - * elements the filter was extended by. - */ - - static void allocFilter( CBuffer< fptype >& Flt, const int ReqCapacity, - const bool IsModel = false, int* const FltExt = NULL ) - { - int UseCapacity = ( ReqCapacity + fpclass :: elalign - 1 ) & - ~( fpclass :: elalign - 1 ); - - int Ext = UseCapacity - ReqCapacity; - - if( FltExt != NULL ) - { - *FltExt = Ext; - } - - if( IsModel ) - { - Flt.forceCapacity( UseCapacity ); - return; - } - - Flt.alloc( UseCapacity, fpclass :: fpalign ); - - while( Ext > 0 ) - { - Ext--; - Flt[ ReqCapacity + Ext ] = (fptype) 0; - } - } - - /** - * Function assigns filter parameters to the specified filtering step - * object. - * - * @param fs Filtering step to assign parameter to. This step cannot be - * the last step if ResampleFactor greater than 1 was specified. - * @param IsUpsample "True" if upsampling step. Should be set to "false" - * if FltCutoff is negative. - * @param ResampleFactor Resampling factor of this filter (>=1). - * @param FltCutoff Filter cutoff point. This value will be divided by the - * ResampleFactor if IsUpsample equals "true". If zero value was - * specified, the "half-band" predefined filter will be created. In this - * case the ResampleFactor will modify the filter cutoff point. - * @param DCGain DC gain to apply to the filter. Assigned to filtering - * step's DCGain variable. - * @param UseFltOrig "True" if the originally-designed filter should be - * left in filtering step's FltOrig buffer. Otherwise it will be freed. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - void assignFilterParams( CFilterStep& fs, const bool IsUpsample, - const int ResampleFactor, const double FltCutoff, const double DCGain, - const bool UseFltOrig, const bool IsModel ) const - { - double FltAlpha; - double Len2; - double Freq; - - if( FltCutoff == 0.0 ) - { - const double m = 2.0 / ResampleFactor; - FltAlpha = Params.HBFltAlpha; - Len2 = 0.5 * Params.HBFltLen / m; - Freq = AVIR_PI * Params.HBFltCutoff * m; - } - else - { - FltAlpha = Params.LPFltAlpha; - Len2 = 0.25 * Params.LPFltBaseLen / FltCutoff; - Freq = AVIR_PI * Params.LPFltCutoffMult * FltCutoff; - } - - if( IsUpsample ) - { - Len2 *= ResampleFactor; - Freq /= ResampleFactor; - fs.DCGain = DCGain * ResampleFactor; - } - else - { - fs.DCGain = DCGain; - } - - fs.FltOrig.Len2 = Len2; - fs.FltOrig.Freq = Freq; - fs.FltOrig.Alpha = FltAlpha; - fs.FltOrig.DCGain = fs.DCGain; - - CDSPPeakedCosineLPF w( Len2, Freq, FltAlpha ); - - fs.IsUpsample = IsUpsample; - fs.ResampleFactor = ResampleFactor; - fs.FltLatency = w.fl2; - - int FltExt; // Filter's extension due to fpclass :: elalign. - - if( IsModel ) - { - allocFilter( fs.Flt, w.FilterLen, true, &FltExt ); - - if( UseFltOrig ) - { - // Allocate a real buffer even in modeling mode since this - // filter may be copied by the filter bank. - - fs.FltOrig.alloc( w.FilterLen ); - memset( &fs.FltOrig[ 0 ], 0, - w.FilterLen * sizeof( fs.FltOrig[ 0 ])); - } - } - else - { - fs.FltOrig.alloc( w.FilterLen ); - - w.generateLPF( &fs.FltOrig[ 0 ], fs.DCGain ); - - allocFilter( fs.Flt, fs.FltOrig.getCapacity(), false, &FltExt ); - copyArray( &fs.FltOrig[ 0 ], &fs.Flt[ 0 ], - fs.FltOrig.getCapacity() ); - - if( !UseFltOrig ) - { - fs.FltOrig.free(); - } - } - - if( IsUpsample ) - { - int l = fs.Flt.getCapacity() - fs.FltLatency - ResampleFactor - - FltExt; - - allocFilter( fs.PrefixDC, l, IsModel ); - allocFilter( fs.SuffixDC, fs.FltLatency, IsModel ); - - if( IsModel ) - { - return; - } - - // Create prefix and suffix "tails" used during upsampling. - - const fptype* ip = &fs.Flt[ fs.FltLatency + ResampleFactor ]; - copyArray( ip, &fs.PrefixDC[ 0 ], l ); - - while( true ) - { - ip += ResampleFactor; - l -= ResampleFactor; - - if( l <= 0 ) - { - break; - } - - addArray( ip, &fs.PrefixDC[ 0 ], l ); - } - - l = fs.FltLatency; - fptype* op = &fs.SuffixDC[ 0 ]; - copyArray( &fs.Flt[ 0 ], op, l ); - - while( true ) - { - op += ResampleFactor; - l -= ResampleFactor; - - if( l <= 0 ) - { - break; - } - - addArray( &fs.Flt[ 0 ], op, l ); - } - } - else - if( !UseFltOrig ) - { - fs.EdgePixelCount = fs.EdgePixelCountDef; - } - } - - /** - * Function adds a correction filter that tries to achieve a linear - * frequency response at all frequencies. The actual resulting response - * may feature a slight damping of the highest frequencies since a - * suitably short correction filter cannot fix steep high-frequency - * damping. - * - * This function assumes that the resizing step is currently the last - * step, even if it was not inserted yet: this allows placement of the - * correction filter both before and after the resizing step. - * - * @param Steps Filtering steps. - * @param bw Resulting bandwidth relative to the original bandwidth (which - * is 1.0), usually 1/k. Should be <= 1.0. - * @param IsPreCorrection "True" if the filtering step was already created - * and it is first in the Steps array. "True" also adds edge pixels to - * reduce edge artifacts. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - void addCorrectionFilter( CFilterSteps& Steps, const double bw, - const bool IsPreCorrection, const bool IsModel ) const - { - CFilterStep& fs = ( IsPreCorrection ? Steps[ 0 ] : Steps.add() ); - fs.IsUpsample = false; - fs.ResampleFactor = 1; - fs.DCGain = 1.0; - fs.EdgePixelCount = ( IsPreCorrection ? fs.EdgePixelCountDef : 0 ); - - if( IsModel ) - { - allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( - Params.CorrFltLen, fs.FltLatency ), true ); - - return; - } - - const int BinCount = 65; // Frequency response bins to control. - const int BinCount1 = BinCount - 1; - double curbw = 1.0; // Bandwidth of the filter at the current step. - int i; - int j; - double re; - double im; - - CBuffer< double > Bins( BinCount ); // Adjustment introduced by all - // steps at all frequencies of interest. - - for( j = 0; j < BinCount; j++ ) - { - Bins[ j ] = 1.0; - } - - const int si = ( IsPreCorrection ? 1 : 0 ); - - for( i = si; i < Steps.getItemCount() - ( si ^ 1 ); i++ ) - { - const CFilterStep& fs = Steps[ i ]; - - if( fs.IsUpsample ) - { - curbw *= fs.ResampleFactor; - - if( fs.FltOrig.getCapacity() > 0 ) - { - continue; - } - } - - const fptype* Flt; - int FltLen; - - if( fs.ResampleFactor == 0 ) - { - Flt = fs.FltBank -> getFilter( 0 ); - FltLen = fs.FltBank -> getFilterLen(); - } - else - { - Flt = &fs.Flt[ 0 ]; - FltLen = fs.Flt.getCapacity(); - } - - // Calculate frequency response adjustment introduced by the - // filter at this step, within the bounds of bandwidth of - // interest. - - const double thm = AVIR_PI * bw / ( curbw * BinCount1 ); - - for( j = 0; j < BinCount; j++ ) - { - calcFIRFilterResponse( Flt, FltLen, j * thm, re, im ); - - Bins[ j ] *= fs.DCGain / sqrt( re * re + im * im ); - } - - if( !fs.IsUpsample && fs.ResampleFactor > 1 ) - { - curbw /= fs.ResampleFactor; - } - } - - // Calculate filter. - - CDSPFIREQ EQ; - EQ.init( bw * 2.0, Params.CorrFltLen, BinCount, 0.0, bw, false, - Params.CorrFltAlpha ); - - fs.FltLatency = EQ.getFilterLatency(); - - CBuffer< double > Filter( EQ.getFilterLength() ); - EQ.buildFilter( Bins, &Filter[ 0 ]); - normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); - - allocFilter( fs.Flt, Filter.getCapacity() ); - copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); - - // Print a theoretically achieved final frequency response at various - // feature sizes (from DC to 1 pixel). Values above 255 means features - // become brighter, values below 255 means features become dimmer. - -/* const double sbw = ( bw > 1.0 ? 1.0 / bw : 1.0 ); - - for( j = 0; j < BinCount; j++ ) - { - const double th = AVIR_PI * sbw * j / BinCount1; - - calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), - th, re, im ); - - printf( "%f\n", sqrt( re * re + im * im ) / Bins[ j ] * 255 ); - } - - printf( "***\n" );*/ - } - - /** - * Function adds a sharpening filter if image is being upsized. Such - * sharpening allows to spot interpolation filter's stop-band attenuation: - * if attenuation is too weak, a "dark grid" and other artifacts may - * become visible. - * - * It is assumed that 40 decibel stop-band attenuation should be - * considered a required minimum: this allows application of (deliberately - * strong) 64X sharpening without spotting any artifacts. - * - * @param Steps Filtering steps. - * @param bw Resulting bandwidth relative to the original bandwidth (which - * is 1.0), usually 1/k. - * @param IsModel "True" if filtering steps modeling is performed without - * actual filter building. - */ - - static void addSharpenTest( CFilterSteps& Steps, const double bw, - const bool IsModel ) - { - if( bw <= 1.0 ) - { - return; - } - - const double FltLen = 10.0 * bw; - - CFilterStep& fs = Steps.add(); - fs.IsUpsample = false; - fs.ResampleFactor = 1; - fs.DCGain = 1.0; - fs.EdgePixelCount = 0; - - if( IsModel ) - { - allocFilter( fs.Flt, CDSPFIREQ :: calcFilterLength( FltLen, - fs.FltLatency ), true ); - - return; - } - - const int BinCount = 200; - CBuffer< double > Bins( BinCount ); - int Thresh = (int) round( BinCount / bw * 1.75 ); - - if( Thresh > BinCount ) - { - Thresh = BinCount; - } - - int j; - - for( j = 0; j < Thresh; j++ ) - { - Bins[ j ] = 1.0; - } - - for( j = Thresh; j < BinCount; j++ ) - { - Bins[ j ] = 256.0; - } - - CDSPFIREQ EQ; - EQ.init( bw * 2.0, FltLen, BinCount, 0.0, bw, false, 1.7 ); - - fs.FltLatency = EQ.getFilterLatency(); - - CBuffer< double > Filter( EQ.getFilterLength() ); - EQ.buildFilter( Bins, &Filter[ 0 ]); - normalizeFIRFilter( &Filter[ 0 ], Filter.getCapacity(), 1.0 ); - - allocFilter( fs.Flt, Filter.getCapacity() ); - copyArray( &Filter[ 0 ], &fs.Flt[ 0 ], Filter.getCapacity() ); - -/* for( j = 0; j < BinCount; j++ ) - { - const double th = AVIR_PI * j / ( BinCount - 1 ); - double re; - double im; - - calcFIRFilterResponse( &fs.Flt[ 0 ], fs.Flt.getCapacity(), - th, re, im ); - - printf( "%f\n", sqrt( re * re + im * im )); - } - - printf( "***\n" );*/ - } - - /** - * Function builds sequence of filtering steps depending on the specified - * resizing coefficient. The last steps included are always the resizing - * step then (possibly) the correction step. - * - * @param Steps Array that receives filtering steps. - * @param[out] Vars Variables object. - * @param FltBank Filter bank to initialize and use. - * @param DCGain The overall DC gain to apply. This DC gain is applied to - * the first filtering step only (upsampling or filtering step). - * @param ModeFlags Build mode flags to use. This is a bitmap of switches - * that enable or disable certain algorithm features. - * @param IsModel "True" if filtering steps modeling is performed without - * the actual filter allocation and building. - */ - - void buildFilterSteps( CFilterSteps& Steps, CImageResizerVars& Vars, - CDSPFracFilterBankLin< fptype >& FltBank, const double DCGain, - const int ModeFlags, const bool IsModel ) const - { - Steps.clear(); - - const bool DoFltAndIntCombo = (( ModeFlags & 1 ) != 0 ); // Do filter - // and interpolator combining. - const bool ForceHiOrderInt = (( ModeFlags & 2 ) != 0 ); // Force use - // of a higher-order interpolation. - const bool UseHalfband = (( ModeFlags & 4 ) != 0 ); // Use half-band - // filter. - - const double bw = 1.0 / Vars.k; // Resulting bandwidth. - const int UpsampleFactor = ( (int) floor( Vars.k ) < 2 ? 2 : 1 ); - double IntCutoffMult; // Interpolation filter cutoff multiplier. - CFilterStep* ReuseStep; // If not NULL, resizing step should use - // this step object instead of creating a new one. - CFilterStep* ExtFltStep; // Use FltOrig of this step as the external - // filter to applied to the interpolator. - bool IsPreCorrection; // "True" if the correction filter is applied - // first. - double FltCutoff; // Cutoff frequency of the first filtering step. - double corrbw; ///< Bandwidth at the correction step. - - if( Vars.k <= 1.0 ) - { - IsPreCorrection = true; - FltCutoff = 1.0; - corrbw = 1.0; - Steps.add(); - } - else - { - IsPreCorrection = false; - FltCutoff = bw; - corrbw = bw; - } - - // Add 1 upsampling or several downsampling filters. - - if( UpsampleFactor > 1 ) - { - CFilterStep& fs = Steps.add(); - assignFilterParams( fs, true, UpsampleFactor, FltCutoff, DCGain, - DoFltAndIntCombo, IsModel ); - - IntCutoffMult = FltCutoff * 2.0 / UpsampleFactor; - ReuseStep = NULL; - ExtFltStep = ( DoFltAndIntCombo ? &fs : NULL ); - } - else - { - int DownsampleFactor; - - while( true ) - { - DownsampleFactor = (int) floor( 0.5 / FltCutoff ); - bool DoHBFltAdd = ( UseHalfband && DownsampleFactor > 1 ); - - if( DoHBFltAdd ) - { - assignFilterParams( Steps.add(), false, DownsampleFactor, - 0.0, 1.0, false, IsModel ); - - FltCutoff *= DownsampleFactor; - } - else - { - if( DownsampleFactor < 1 ) - { - DownsampleFactor = 1; - } - - break; - } - } - - CFilterStep& fs = Steps.add(); - assignFilterParams( fs, false, DownsampleFactor, FltCutoff, - DCGain, DoFltAndIntCombo, IsModel ); - - IntCutoffMult = FltCutoff / 0.5; - - if( DoFltAndIntCombo ) - { - ReuseStep = &fs; - ExtFltStep = &fs; - } - else - { - IntCutoffMult *= DownsampleFactor; - ReuseStep = NULL; - ExtFltStep = NULL; - } - } - - // Insert resizing and correction steps. - - CFilterStep& fs = ( ReuseStep == NULL ? Steps.add() : *ReuseStep ); - - Vars.ResizeStep = Steps.getItemCount() - 1; - fs.IsUpsample = false; - fs.ResampleFactor = 0; - fs.DCGain = ( ExtFltStep == NULL ? 1.0 : ExtFltStep -> DCGain ); - - initFilterBank( FltBank, IntCutoffMult, ForceHiOrderInt, - ( ExtFltStep == NULL ? fs.FltOrig : ExtFltStep -> FltOrig )); - - if( FltBank == FixedFilterBank ) - { - fs.FltBank = (CDSPFracFilterBankLin< fptype >*) &FixedFilterBank; - } - else - { - fs.FltBank = &FltBank; - } - - addCorrectionFilter( Steps, corrbw, IsPreCorrection, IsModel ); - - //addSharpenTest( Steps, bw, IsModel ); - } - - /** - * Function extends *this upsampling step so that it produces more - * upsampled pixels that cover the prefix and suffix needs of the next - * step. After the call to this function the InPrefix and InSuffix - * variables of the next step will be set to zero. - * - * @param fs Upsampling filtering step. - * @param NextStep The next step structure. - */ - - static void extendUpsample( CFilterStep& fs, CFilterStep& NextStep ) - { - fs.InPrefix = ( NextStep.InPrefix + fs.ResampleFactor - 1 ) / - fs.ResampleFactor; - - fs.OutPrefix += fs.InPrefix * fs.ResampleFactor; - NextStep.InPrefix = 0; - - fs.InSuffix = ( NextStep.InSuffix + fs.ResampleFactor - 1 ) / - fs.ResampleFactor; - - fs.OutSuffix += fs.InSuffix * fs.ResampleFactor; - NextStep.InSuffix = 0; - } - - /** - * Function fills resizing step's RPosBuf array, excluding the actual - * "ftp" pointers and "SrcOffs" offsets. - * - * This array should be cleared if the resizing step or offset were - * changed. Otherwise this function only fills the elements required to - * cover resizing step's OutLen. - * - * This function is called by the updateFilterStepBuffers() function. - * - * @param fs Resizing step. - * @param Vars Variables object. - */ - - static void fillRPosBuf( CFilterStep& fs, const CImageResizerVars& Vars ) - { - const int PrevLen = fs.RPosBuf -> getCapacity(); - - if( fs.OutLen > PrevLen ) - { - fs.RPosBuf -> increaseCapacity( fs.OutLen ); - } - - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ PrevLen ]; - const int FracCount = fs.FltBank -> getFracCount(); - const double o = Vars.o; - const double k = Vars.k; - int i; - - for( i = PrevLen; i < fs.OutLen; i++ ) - { - const double SrcPos = o + k * i; - const int SrcPosInt = (int) floor( SrcPos ); - const double x = ( SrcPos - SrcPosInt ) * FracCount; - const int fti = (int) x; - rpos -> x = (typename fpclass :: fptypeatom) ( x - fti ); - rpos -> fti = fti; - rpos -> SrcPosInt = SrcPosInt; - rpos++; - } - } - - /** - * Function updates filtering step buffer lengths depending on the - * specified source and new scanline lengths. This function should be - * called after the buildFilterSteps() function. - * - * @param Steps Array that receives filtering steps. - * @param[out] Vars Variables object, will receive buffer size and length. - * This function expects "k" and "o" variable values that will be - * adjusted by this function. - * @param RPosBufArray Resizing position buffers array, used to obtain - * buffer to initialize and use (will be reused if it is already fully or - * partially filled). - * @param SrcLen Source scanline's length in pixels. - * @param NewLen New scanline's length in pixels. - */ - - static void updateFilterStepBuffers( CFilterSteps& Steps, - CImageResizerVars& Vars, - typename CFilterStep :: CRPosBufArray& RPosBufArray, int SrcLen, - const int NewLen ) - { - int upstep = -1; - int InBuf = 0; - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - - fs.Vars = &Vars; - fs.InLen = SrcLen; - fs.InBuf = InBuf; - fs.OutBuf = ( InBuf + 1 ) & 1; - - if( fs.IsUpsample ) - { - upstep = i; - Vars.k *= fs.ResampleFactor; - Vars.o *= fs.ResampleFactor; - fs.InPrefix = 0; - fs.InSuffix = 0; - fs.OutLen = fs.InLen * fs.ResampleFactor; - fs.OutPrefix = fs.FltLatency; - fs.OutSuffix = fs.Flt.getCapacity() - fs.FltLatency - - fs.ResampleFactor; - - int l0 = fs.OutPrefix + fs.OutLen + fs.OutSuffix; - int l = fs.InLen * fs.ResampleFactor + - fs.SuffixDC.getCapacity(); - - if( l > l0 ) - { - fs.OutSuffix += l - l0; - } - - l0 = fs.OutLen + fs.OutSuffix; - - if( fs.PrefixDC.getCapacity() > l0 ) - { - fs.OutSuffix += fs.PrefixDC.getCapacity() - l0; - } - } - else - if( fs.ResampleFactor == 0 ) - { - const int FilterLenD2 = fs.FltBank -> getFilterLen() / 2; - const int FilterLenD21 = FilterLenD2 - 1; - - const int ResizeLPix = (int) floor( Vars.o ) - FilterLenD21; - fs.InPrefix = ( ResizeLPix < 0 ? -ResizeLPix : 0 ); - const int ResizeRPix = (int) floor( Vars.o + - ( NewLen - 1 ) * Vars.k ) + FilterLenD2 + 1; - - fs.InSuffix = ( ResizeRPix > fs.InLen ? - ResizeRPix - fs.InLen : 0 ); - - fs.OutLen = NewLen; - fs.RPosBuf = &RPosBufArray.getRPosBuf( Vars.k, Vars.o, - fs.FltBank -> getFracCount() ); - - fillRPosBuf( fs, Vars ); - } - else - { - Vars.k /= fs.ResampleFactor; - Vars.o /= fs.ResampleFactor; - Vars.o += fs.EdgePixelCount; - - fs.InPrefix = fs.FltLatency; - fs.InSuffix = fs.Flt.getCapacity() - fs.FltLatency - 1; - - // Additionally extend OutLen to produce more precise edge - // pixels. - - fs.OutLen = ( fs.InLen + fs.ResampleFactor - 1 ) / - fs.ResampleFactor + fs.EdgePixelCount; - - fs.InSuffix += ( fs.OutLen - 1 ) * fs.ResampleFactor + 1 - - fs.InLen; - - fs.InPrefix += fs.EdgePixelCount * fs.ResampleFactor; - fs.OutLen += fs.EdgePixelCount; - } - - InBuf = fs.OutBuf; - SrcLen = fs.OutLen; - } - - Steps[ Steps.getItemCount() - 1 ].OutBuf = 2; - Vars.IsResize2 = false; - - if( upstep != -1 ) - { - extendUpsample( Steps[ upstep ], Steps[ upstep + 1 ]); - - if( Steps[ upstep ].ResampleFactor == 2 && - Vars.ResizeStep == upstep + 1 && - fpclass :: packmode == 0 && - Steps[ upstep ].FltOrig.getCapacity() > 0 ) - { - // Interpolation with preceeding 2x filterless upsample, - // interleaved resizing only. - - Vars.IsResize2 = true; - } - } - } - - /** - * Function calculates an optimal intermediate buffer length that will - * cover all needs of the specified filtering steps. This function should - * be called after the updateFilterStepBuffers() function. - * - * Function also updates resizing step's RPosBuf pointers to the filter - * bank and SrcOffs values. - * - * @param Steps Filtering steps. - * @param[out] Vars Variables object, will receive buffer size and length. - * @param ResElIncr Resulting (final) element increment, used to produce - * de-interleaved result. For horizontal processing this value is equal - * to last step's OutLen, for vertical processing this value is equal to - * resulting image's width. - */ - - static void updateBufLenAndRPosPtrs( CFilterSteps& Steps, - CImageResizerVars& Vars, const int ResElIncr ) - { - int MaxPrefix[ 2 ] = { 0, 0 }; - int MaxLen[ 2 ] = { 0, 0 }; - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - const int ib = fs.InBuf; - - if( fs.InPrefix > MaxPrefix[ ib ]) - { - MaxPrefix[ ib ] = fs.InPrefix; - } - - int l = fs.InLen + fs.InSuffix; - - if( l > MaxLen[ ib ]) - { - MaxLen[ ib ] = l; - } - - fs.InElIncr = fs.InPrefix + l; - - if( fs.OutBuf == 2 ) - { - break; - } - - const int ob = fs.OutBuf; - - if( fs.IsUpsample ) - { - if( fs.OutPrefix > MaxPrefix[ ob ]) - { - MaxPrefix[ ob ] = fs.OutPrefix; - } - - l = fs.OutLen + fs.OutSuffix; - - if( l > MaxLen[ ob ]) - { - MaxLen[ ob ] = l; - } - } - else - { - if( fs.OutLen > MaxLen[ ob ]) - { - MaxLen[ ob ] = fs.OutLen; - } - } - } - - // Update OutElIncr values of all steps. - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - CFilterStep& fs = Steps[ i ]; - - if( fs.OutBuf == 2 ) - { - fs.OutElIncr = ResElIncr; - break; - } - - CFilterStep& fs2 = Steps[ i + 1 ]; - - if( fs.IsUpsample ) - { - fs.OutElIncr = fs.OutPrefix + fs.OutLen + fs.OutSuffix; - - if( fs.OutElIncr > fs2.InElIncr ) - { - fs2.InElIncr = fs.OutElIncr; - } - else - { - fs.OutElIncr = fs2.InElIncr; - } - } - else - { - fs.OutElIncr = fs2.InElIncr; - } - } - - // Update temporary buffer's length. - - for( i = 0; i < 2; i++ ) - { - Vars.BufLen[ i ] = MaxPrefix[ i ] + MaxLen[ i ]; - Vars.BufOffs[ i ] = MaxPrefix[ i ]; - - if( Vars.packmode == 0 ) - { - Vars.BufOffs[ i ] *= Vars.ElCount; - } - - Vars.BufLen[ i ] *= Vars.ElCount; - } - - // Update RPosBuf pointers and SrcOffs. - - CFilterStep& fs = Steps[ Vars.ResizeStep ]; - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; - const int em = ( fpclass :: packmode == 0 ? Vars.ElCount : 1 ); - const int fl = fs.FltBank -> getFilterLen(); - const int FilterLenD21 = fl / 2 - 1; - - if( Vars.IsResize2 ) - { - for( i = 0; i < fs.OutLen; i++ ) - { - const int p = rpos -> SrcPosInt - FilterLenD21; - const int fo = p & 1; - rpos -> SrcOffs = ( p + fo ) * em; - rpos -> ftp = fs.FltBank -> getFilter( rpos -> fti ) + fo; - rpos -> fl = fl - fo; - rpos++; - } - } - else - { - for( i = 0; i < fs.OutLen; i++ ) - { - rpos -> SrcOffs = ( rpos -> SrcPosInt - FilterLenD21 ) * em; - rpos -> ftp = fs.FltBank -> getFilter( rpos -> fti ); - rpos++; - } - } - } - - /** - * Function modifies the overall (DC) gain of the correction filter in the - * pre-built filtering steps array. - * - * @param Steps Filtering steps. - * @param m Multiplier to apply to the correction filter. - */ - - void modifyCorrFilterDCGain( CFilterSteps& Steps, const double m ) const - { - CBuffer< fptype >* Flt; - const int z = Steps.getItemCount() - 1; - - if( !Steps[ z ].IsUpsample && Steps[ z ].ResampleFactor == 1 ) - { - Flt = &Steps[ z ].Flt; - } - else - { - Flt = &Steps[ 0 ].Flt; - } - - int i; - - for( i = 0; i < Flt -> getCapacity(); i++ ) - { - (*Flt)[ i ] = (fptype) ( (double) (*Flt)[ i ] * m ); - } - } - - /** - * Function builds a map of used fractional delay filters based on the - * resizing positions buffer. - * - * @param fs Resizing step. - * @param[out] UsedFracMap Map of used fractional delay filters. - */ - - static void fillUsedFracMap( const CFilterStep& fs, - CBuffer< uint8_t >& UsedFracMap ) - { - const int FracCount = fs.FltBank -> getFracCount(); - UsedFracMap.increaseCapacity( FracCount, false ); - memset( &UsedFracMap[ 0 ], 0, FracCount * sizeof( UsedFracMap[ 0 ])); - - typename CFilterStep :: CResizePos* rpos = &(*fs.RPosBuf)[ 0 ]; - int i; - - for( i = 0; i < fs.OutLen; i++ ) - { - UsedFracMap[ rpos -> fti ] |= 1; - rpos++; - } - } - - /** - * Function calculates the overall filtering steps complexity per - * scanline. Each complexity unit corresponds to a single multiply-add - * operation. Data copy and pointer math operations are not included in - * this calculation, it is assumed that they correlate to the multiply-add - * operations. Calculation also does not include final rounding, dithering - * and clamping operations since they cannot be optimized out anyway. - * - * Calculation of the CRPosBuf buffer is not included since it cannot be - * avoided. - * - * This function should be called after the updateFilterStepBuffers() - * function. - * - * @param Steps Filtering steps array. - * @param Vars Variables object. - * @param UsedFracMap The map of used fractional delay filters. - * @param ScanlineCount Scanline count. - */ - - static int calcComplexity( const CFilterSteps& Steps, - const CImageResizerVars& Vars, const CBuffer< uint8_t >& UsedFracMap, - const int ScanlineCount ) - { - int fcnum; // Filter complexity multiplier numerator. - int fcdenom; // Filter complexity multiplier denominator. - - if( Vars.packmode != 0 ) - { - fcnum = 1; - fcdenom = 1; - } - else - { - // In interleaved processing mode, filters require 1 less - // multiplication per 2 multiply-add instructions. - - fcnum = 3; - fcdenom = 4; - } - - int s = 0; // Complexity per one scanline. - int s2 = 0; // Complexity per all scanlines. - int i; - - for( i = 0; i < Steps.getItemCount(); i++ ) - { - const CFilterStep& fs = Steps[ i ]; - - s2 += 65 * fs.Flt.getCapacity(); // Filter creation complexity. - - if( fs.IsUpsample ) - { - if( fs.FltOrig.getCapacity() > 0 ) - { - continue; - } - - s += ( fs.Flt.getCapacity() * - ( fs.InPrefix + fs.InLen + fs.InSuffix ) + - fs.SuffixDC.getCapacity() + fs.PrefixDC.getCapacity() ) * - Vars.ElCount; - } - else - if( fs.ResampleFactor == 0 ) - { - s += fs.FltBank -> getFilterLen() * - ( fs.FltBank -> getOrder() + Vars.ElCount ) * fs.OutLen; - - if( i == Vars.ResizeStep && Vars.IsResize2 ) - { - s >>= 1; - } - - s2 += fs.FltBank -> calcInitComplexity( UsedFracMap ); - } - else - { - s += fs.Flt.getCapacity() * Vars.ElCount * fs.OutLen * - fcnum / fcdenom; - } - } - - return( s + s2 / ScanlineCount ); - } - - /** - * @brief Thread-isolated data used for scanline processing. - * - * This structure holds data necessary for image's horizontal or vertical - * scanline processing, including scanline processing queue. - * - * @tparam Tin Source element data type. Intermediate buffers store data - * in floating point format. - * @tparam Tout Destination element data type. Intermediate buffers store - * data in floating point format. - */ - - template< class Tin, class Tout > - class CThreadData : public CImageResizerThreadPool :: CWorkload - { - public: - virtual void process() - { - processScanlineQueue(); - } - - /** - * This enumeration lists possible scanline operations. - */ - - enum EScanlineOperation - { - sopResizeH, ///< Resize horizontal scanline. - ///< - sopResizeV, ///< Resize vertical scanline. - ///< - sopDitherAndUnpackH, ///< Dither and unpack horizontal scanline. - ///< - sopUnpackH ///< Unpack horizontal scanline. - ///< - }; - - /** - * Function initializes *this thread data object and assigns certain - * variables provided by the higher level code. - * - * @param aThreadIndex Index of this thread data (0-based). - * @param aThreadCount Total number of threads used during processing. - * @param aSteps Filtering steps. - * @param aVars Image resizer variables. - */ - - void init( const int aThreadIndex, const int aThreadCount, - const CFilterSteps& aSteps, const CImageResizerVars& aVars ) - { - ThreadIndex = aThreadIndex; - ThreadCount = aThreadCount; - Steps = &aSteps; - Vars = &aVars; - } - - /** - * Function initializes scanline processing queue, and updates - * capacities of intermediate buffers. - * - * @param aOp Operation to perform over scanline. - * @param TotalLines The total number of scanlines that will be - * processed by all threads. - * @param aSrcLen Source scanline length in pixels. - * @param aSrcIncr Source scanline buffer increment. Ignored in - * horizontal scanline processing. - * @param aResIncr Resulting scanline buffer increment. Ignored in - * horizontal scanline processing. - */ - - void initScanlineQueue( const EScanlineOperation aOp, - const int TotalLines, const int aSrcLen, const int aSrcIncr = 0, - const int aResIncr = 0 ) - { - const int l = Vars -> BufLen[ 0 ] + Vars -> BufLen[ 1 ]; - - if( Bufs.getCapacity() < l ) - { - Bufs.alloc( l, fpclass :: fpalign ); - } - - BufPtrs[ 0 ] = Bufs + Vars -> BufOffs[ 0 ]; - BufPtrs[ 1 ] = Bufs + Vars -> BufLen[ 0 ] + Vars -> BufOffs[ 1 ]; - - int j; - int ml = 0; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - - if( fs.ResampleFactor == 0 && - ml < fs.FltBank -> getFilterLen() ) - { - ml = fs.FltBank -> getFilterLen(); - } - } - - TmpFltBuf.alloc( ml, fpclass :: fpalign ); - ScanlineOp = aOp; - SrcLen = aSrcLen; - SrcIncr = aSrcIncr; - ResIncr = aResIncr; - QueueLen = 0; - Queue.increaseCapacity(( TotalLines + ThreadCount - 1 ) / - ThreadCount, false ); - } - - /** - * Function adds a scanline to the queue buffer. The - * initScanlineQueue() function should be called before calling this - * function. The number of calls to this add function should not - * exceed the TotalLines spread over all threads. - * - * @param SrcBuf Source scanline buffer. - * @param ResBuf Resulting scanline buffer. - */ - - void addScanlineToQueue( void* const SrcBuf, void* const ResBuf ) - { - Queue[ QueueLen ].SrcBuf = SrcBuf; - Queue[ QueueLen ].ResBuf = ResBuf; - QueueLen++; - } - - /** - * Function processes all queued scanlines. - */ - - void processScanlineQueue() - { - int i; - - switch( ScanlineOp ) - { - case sopResizeH: - { - for( i = 0; i < QueueLen; i++ ) - { - resizeScanlineH( (Tin*) Queue[ i ].SrcBuf, - (fptype*) Queue[ i ].ResBuf ); - } - - break; - } - - case sopResizeV: - { - for( i = 0; i < QueueLen; i++ ) - { - resizeScanlineV( (fptype*) Queue[ i ].SrcBuf, - (fptype*) Queue[ i ].ResBuf ); - } - - break; - } - - case sopDitherAndUnpackH: - { - if( Vars -> UseSRGBGamma ) - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: applySRGBGamma( - (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); - - Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - else - { - for( i = 0; i < QueueLen; i++ ) - { - Ditherer.dither( (fptype*) Queue[ i ].SrcBuf ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - - break; - } - - case sopUnpackH: - { - if( Vars -> UseSRGBGamma ) - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: applySRGBGamma( - (fptype*) Queue[ i ].SrcBuf, SrcLen, *Vars ); - - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - else - { - for( i = 0; i < QueueLen; i++ ) - { - CFilterStep :: unpackScanline( - (fptype*) Queue[ i ].SrcBuf, - (Tout*) Queue[ i ].ResBuf, SrcLen, *Vars ); - } - } - - break; - } - } - } - - /** - * Function returns ditherer object associated with *this thread data - * object. - */ - - CDitherer& getDitherer() - { - return( Ditherer ); - } - - private: - int ThreadIndex; ///< Thread index. - ///< - int ThreadCount; ///< Thread count. - ///< - const CFilterSteps* Steps; ///< Filtering steps. - ///< - const CImageResizerVars* Vars; ///< Image resizer variables. - ///< - CBuffer< fptype > Bufs; ///< Flip-flop intermediate buffers. - ///< - fptype* BufPtrs[ 3 ]; ///< Flip-flop buffer pointers (referenced by - ///< filtering step's InBuf and OutBuf indices). - ///< - CBuffer< fptype > TmpFltBuf; ///< Temporary buffer used in the - ///< doResize() function, aligned by fpclass :: fpalign. - ///< - EScanlineOperation ScanlineOp; ///< Operation to perform over - ///< scanline. - ///< - int SrcLen; ///< Source scanline length in the last queue. - ///< - int SrcIncr; ///< Source scanline buffer increment in the last queue. - ///< - int ResIncr; ///< Resulting scanline buffer increment in the last - ///< queue. - ///< - CDitherer Ditherer; ///< Ditherer object to use. - ///< - - /** - * @brief Scanline processing queue item. - * - * Scanline processing queue item. - */ - - struct CQueueItem - { - void* SrcBuf; ///< Source scanline buffer, will by typecasted to - ///< Tin or fptype*. - ///< - void* ResBuf; ///< Resulting scanline buffer, will by typecasted - ///< to Tout or fptype*. - ///< - }; - - CBuffer< CQueueItem > Queue; ///< Scanline processing queue. - ///< - int QueueLen; ///< Queue length. - ///< - - /** - * Function resizes a single horizontal scanline. - * - * @param SrcBuf Source scanline buffer. Can be either horizontal or - * vertical. - * @param ResBuf Resulting scanline buffer. - */ - - void resizeScanlineH( const Tin* const SrcBuf, fptype* const ResBuf ) - { - const CFilterStep& fs0 = (*Steps)[ 0 ]; - - fs0.packScanline( SrcBuf, BufPtrs[ 0 ], SrcLen ); - BufPtrs[ 2 ] = ResBuf; - - fptype ElBiases[ 4 ]; - fs0.calcScanlineBias( BufPtrs[ 0 ], SrcLen, ElBiases ); - fs0.unbiasScanline( BufPtrs[ 0 ], SrcLen, ElBiases ); - - int j; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - fs.prepareInBuf( BufPtrs[ fs.InBuf ]); - const int DstIncr = - ( Vars -> packmode == 0 ? Vars -> ElCount : 1 ); - - if( fs.ResampleFactor != 0 ) - { - if( fs.IsUpsample ) - { - fs.doUpsample( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ]); - } - else - { - fs.doFilter( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr ); - } - } - else - { - if( Vars -> IsResize2 ) - { - fs.doResize2( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - else - { - fs.doResize( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - } - } - } - - /** - * Function resizes a single vertical scanline. - * - * @param SrcBuf Source scanline buffer. Can be either horizontal or - * vertical. - * @param ResBuf Resulting scanline buffer. - */ - - void resizeScanlineV( const fptype* const SrcBuf, - fptype* const ResBuf ) - { - const CFilterStep& fs0 = (*Steps)[ 0 ]; - - fs0.convertVtoH( SrcBuf, BufPtrs[ 0 ], SrcLen, SrcIncr ); - BufPtrs[ 2 ] = ResBuf; - - fptype ElBiases[ 4 ]; - fs0.calcScanlineBias( BufPtrs[ 0 ], SrcLen, ElBiases ); - fs0.unbiasScanline( BufPtrs[ 0 ], SrcLen, ElBiases ); - - int j; - - for( j = 0; j < Steps -> getItemCount(); j++ ) - { - const CFilterStep& fs = (*Steps)[ j ]; - fs.prepareInBuf( BufPtrs[ fs.InBuf ]); - const int DstIncr = ( fs.OutBuf == 2 ? ResIncr : - ( Vars -> packmode == 0 ? Vars -> ElCount : 1 )); - - if( fs.ResampleFactor != 0 ) - { - if( fs.IsUpsample ) - { - fs.doUpsample( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ]); - } - else - { - fs.doFilter( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr ); - } - } - else - { - if( Vars -> IsResize2 ) - { - fs.doResize2( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - else - { - fs.doResize( BufPtrs[ fs.InBuf ], - BufPtrs[ fs.OutBuf ], DstIncr, ElBiases, - TmpFltBuf ); - } - } - } - } - }; -}; - -#undef AVIR_PI -#undef AVIR_PId2 -#undef AVIR_NOCTOR - -} // namespace avir - -#endif // AVIR_CIMAGERESIZER_INCLUDED diff --git a/libraries/Camera/examples/GigaCameraDisplay/display.cpp b/libraries/Camera/examples/GigaCameraDisplay/display.cpp deleted file mode 100644 index 4d4b6d4e4..000000000 --- a/libraries/Camera/examples/GigaCameraDisplay/display.cpp +++ /dev/null @@ -1,351 +0,0 @@ -//#include "Types.h" -#include "Arduino.h" - - -/* Command2 BKx selection command */ -#define DSI_CMD2BKX_SEL 0xFF -#define DSI_CMD2BK1_SEL 0x11 -#define DSI_CMD2BK0_SEL 0x10 -#define DSI_CMD2BKX_SEL_NONE 0x00 - -/* Command2, BK0 commands */ -#define DSI_CMD2_BK0_PVGAMCTRL 0xB0 /* Positive Voltage Gamma Control */ -#define DSI_CMD2_BK0_NVGAMCTRL 0xB1 /* Negative Voltage Gamma Control */ -#define DSI_CMD2_BK0_LNESET 0xC0 /* Display Line setting */ -#define DSI_CMD2_BK0_PORCTRL 0xC1 /* Porch control */ -#define DSI_CMD2_BK0_INVSEL 0xC2 /* Inversion selection, Frame Rate Control */ - -/* Command2, BK1 commands */ -#define DSI_CMD2_BK1_VRHS 0xB0 /* Vop amplitude setting */ -#define DSI_CMD2_BK1_VCOM 0xB1 /* VCOM amplitude setting */ -#define DSI_CMD2_BK1_VGHSS 0xB2 /* VGH Voltage setting */ -#define DSI_CMD2_BK1_TESTCMD 0xB3 /* TEST Command Setting */ -#define DSI_CMD2_BK1_VGLS 0xB5 /* VGL Voltage setting */ -#define DSI_CMD2_BK1_PWCTLR1 0xB7 /* Power Control 1 */ -#define DSI_CMD2_BK1_PWCTLR2 0xB8 /* Power Control 2 */ -#define DSI_CMD2_BK1_SPD1 0xC1 /* Source pre_drive timing set1 */ -#define DSI_CMD2_BK1_SPD2 0xC2 /* Source EQ2 Setting */ -#define DSI_CMD2_BK1_MIPISET1 0xD0 /* MIPI Setting 1 */ - -#define MIPI_DCS_SOFT_RESET 0x01 -#define MIPI_DCS_EXIT_SLEEP_MODE 0x11 - -#ifndef U16 -#define U16 uint16_t -#endif - -#define SSD_MODE(a,b) -#define Set_POWER(a,b,c,d) -#define Set_STANDBY() -#define Set_BOOST(a,b,c,d) -#define Set_RESET(a,b) -#define SSD_LANE(a,b) - -extern DSI_HandleTypeDef dsi; -#define hdsi_eval dsi - -#define LCD_ST7701_ID 0x00 // VC (Virtual channel, for using muliple displays) - -#define Delay(x) delay(x) - -uint8_t BUFFER[8]; -//////////////////////////////////////////////////////// -// Procedure: DCS_Short_Write_NP -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void DCS_Short_Write_NP(uint8_t data0) -{ -// HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_SHORT_PKT_WRITE_P0, data0, 0x00); // DSI_DCS_SHORT_PKT_WRITE_P0 - Serial.print("before DCS_Short_Write_NP "); - Serial.println(millis()); - HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_SHORT_PKT_WRITE_P1, data0, 0x00); // DSI_DCS_SHORT_PKT_WRITE_P0 - Serial.print("after "); - Serial.println(millis()); -} - -//////////////////////////////////////////////////////// -// Procedure: -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void Generic_Short_Write_1P (uint8_t data0, uint8_t data1) -{ -Serial.print("before Generic_Short_Write_1P "); - Serial.println(millis()); - HAL_DSI_ShortWrite(&hdsi_eval, LCD_ST7701_ID, DSI_GEN_SHORT_PKT_WRITE_P1, data0, data1); -Serial.print("after "); - Serial.println(millis()); -} - - -//////////////////////////////////////////////////////// -// Procedure: -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void Generic_Long_Write(uint8_t* pdata, int length) -{ - uint8_t data_buf[19] = {0}; // data_buf size with command(*pdata) = 20 so data is alligned 4 - uint8_t data_length = length- 1; - - if (data_length > sizeof(data_buf)) - return; - - memcpy(data_buf, pdata+1, data_length); -// HAL_DSI_LongWrite(&hdsi_eval, LCD_ST7701_ID, DSI_GEN_LONG_PKT_WRITE, data_length, *pdata, data_buf); -Serial.print("before Generic_Long_Write "); - Serial.println(millis()); - HAL_DSI_LongWrite(&hdsi_eval, LCD_ST7701_ID, DSI_DCS_LONG_PKT_WRITE, data_length, *pdata, data_buf); -Serial.print("after "); - Serial.println(millis()); -} -//////////////////////////////////////////////////////// -// Procedure: DCS_Short_Read_NP -/// Description: -/// @param None -/// @retval None -/// @details -/// -//////////////////////////////////////////////////////// -void DCS_Short_Read_NP(uint8_t data0, int length, uint8_t* p_data) -{ - HAL_DSI_Read(&hdsi_eval, LCD_ST7701_ID, p_data, length, DSI_DCS_SHORT_PKT_READ, data0, NULL); -} - -//------------------------------------------------------------------------- -- -// Example: -// Model - HSD040B8W9 -// IC - ST7701 -// Width - 480 -// Height - 800 -// Author - Huangyu(Bitland) -// History: -// V01 2015/05/18 -// -// Disclaimer: -// This C source code is intended as a design reference -// which illustrates how these types of functions can be implemented. -// It is the user's responsibility to verify their design for -// consistency and functionality through the use of formal -// verification methods. LCD Studio provides no warranty regarding the use -// or functionality of this code. -//-------------------------------------------------------------------------------------- -const U16 _E5[17] = {0xE5,0x0E,0x2D,0xA0,0xa0,0x10,0x2D,0xA0,0xA0,0x0A,0x2D,0xA0,0xA0,0x0C,0x2D,0xA0,0xA0}; -const U16 _E8[17] = {0xE8,0x0D,0x2D,0xA0,0xA0,0x0F,0x2D,0xA0,0xA0,0x09,0x2D,0xA0,0xA0,0x0B,0x2D,0xA0,0xA0}; -const U16 _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA}; - - -/**************************************************/ -// I2C power module controller -/**************************************************/ - -void DisplayOn() -{ - Set_POWER(1,1,1,1);//1.8V ON, 2.8V ON, 5V ON, BL ON - -} - - -// -void PowerOffSequence() -{ - DCS_Short_Write_NP(0x28); - Delay(200); - DCS_Short_Write_NP(0x10); - Delay(100); - Set_STANDBY();//Video transfer stop - Delay(50); - - Set_RESET(1,0);//MIPI RESET 1, LCD RESET 0 - Delay(50); - Set_RESET(0,0);//MIPI RESET 0, LCD RESET 0 - Delay(50); - - Set_POWER(1,1,0,1);//1.8V ON, 2.8V ON, 5V OFF, BL ON - Delay(50); - - Set_BOOST(5.00, 5.00, 0x81, 50);//VDD, VEE, OFF:VDD->VEE, 10ms - Delay(50); - - Set_POWER(1,0,0,1);//1.8V ON, 2.8V OFF, 5V OFF, BL ON - Delay(100); - Set_POWER(0,0,0,0);//1.8V OFF, 2.8V OFF, 5V OFF, BL OFF - -} - -/**************************************************/ -// Read function (Option) -/**************************************************/ -// -void ReadOperation() -{ - //Clean memory: BUFFER - memset(BUFFER, 0, sizeof(BUFFER));//BUFFER size: 8 Bytes - - //Read value to BUFFER - DCS_Short_Read_NP(0xDA, 1, BUFFER+0); - DCS_Short_Read_NP(0xDB, 1, BUFFER+1); - DCS_Short_Read_NP(0xDC, 1,BUFFER+2); -} -volatile int LENGTH; -#define ST7701_DSI(mipi_dsi, seq...) \ -do { \ - const u8 d[] = { seq }; \ - LENGTH = ARRAY_SIZE(d); \ -}while(0) - - -void LCD_ST7701_Init(void) -{ - pinMode(PD_3, OUTPUT); - pinMode(PD_3, HIGH); - delay(200); - pinMode(PD_3, LOW); - delay(200); - pinMode(PD_3, HIGH); - - DCS_Short_Write_NP(MIPI_DCS_SOFT_RESET); - Delay(200); - - Serial.println("here"); - - //ST7701S+IVO5.0 - DCS_Short_Write_NP(MIPI_DCS_EXIT_SLEEP_MODE); - - // tesrt - - //------------------------------------------Bank0 Setting----------------------------------------------------// - //------------------------------------Display Control setting----------------------------------------------// - Delay(800); - - const uint8_t Display_Control_0[] = {0xFF,0x77,0x01,0x00,0x00,0x10}; //Generic_Long_Write_5P - const uint8_t Display_Control_1[] = {0xC0,0x63,0x00}; //Generic_Long_Write_2P - const uint8_t Display_Control_2[] = {0xC1,0x11,0x02}; - const uint8_t Display_Control_3[] = {0xC2,0x01,0x08}; - const uint8_t Display_Control_4[] = {0xCC,0x18}; - // const uint8_t Display_Control_5[] = {0x3a,0x50}; // color mode 565:50h 666:60h 888:70h - - Generic_Long_Write((uint8_t*)Display_Control_0, sizeof(Display_Control_0)); - Generic_Long_Write((uint8_t*)Display_Control_1, sizeof(Display_Control_1)); - Generic_Long_Write((uint8_t*)Display_Control_2, sizeof(Display_Control_2)); - Generic_Long_Write((uint8_t*)Display_Control_3, sizeof(Display_Control_3)); - Generic_Long_Write((uint8_t*)Display_Control_4, sizeof(Display_Control_4)); - - //-------------------------------------Gamma Cluster Setting-------------------------------------------// -// Ver1 const uint8_t _B0[17] = {0xB0,0x00, 0x0E, 0x15, 0x0F, 0x11, 0x08, 0x08, 0x08, 0x08, 0x23, 0x04, 0x13, 0x12,0x2B, 0x34, 0x1F}; - const uint8_t _B0[] = {0xB0,0x40, 0xc9, 0x91, 0x0d, - 0x12, 0x07, 0x02, 0x09, 0x09, 0x1f, 0x04, 0x50, 0x0f, - 0xe4, 0x29, 0xdf}; - -// Ver1 const uint8_t _B1[17] = {0xB1, 0x00, 0x0E, 0x95, 0x0F,0x13, 0x07, 0x09, 0x08, 0x08, 0x22, 0x04, 0x10, 0x0E,0x2C, 0x34, 0x1F}; - const uint8_t _B1[] = {0xB1, 0x40, 0xcb, 0xd0, 0x11, - 0x92, 0x07, 0x00, 0x08, 0x07, 0x1c, 0x06, 0x53, 0x12, - 0x63, 0xeb, 0xdf}; - - Generic_Long_Write((uint8_t*)_B0, sizeof(_B0)); - Generic_Long_Write((uint8_t*)_B1, sizeof(_B1)); - //---------------------------------------End Gamma Setting----------------------------------------------// - //------------------------------------End Display Control setting----------------------------------------// - //-----------------------------------------Bank0 Setting End---------------------------------------------// - //-------------------------------------------Bank1 Setting---------------------------------------------------// - //-------------------------------- Power Control Registers Initial --------------------------------------// - const uint8_t _FF1[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BK1_SEL}; - Generic_Long_Write ((uint8_t*)_FF1, sizeof(_FF1)); - - -// Generic_Short_Write_1P (DSI_CMD2_BK1_VRHS,0x50); - Generic_Short_Write_1P (DSI_CMD2_BK1_VRHS,0x65); - //-------------------------------------------Vcom Setting---------------------------------------------------// -// Generic_Short_Write_1P (DSI_CMD2_BK1_VCOM,0x68); - Generic_Short_Write_1P (DSI_CMD2_BK1_VCOM,0x34); - //-----------------------------------------End Vcom Setting-----------------------------------------------// -// Generic_Short_Write_1P (DSI_CMD2_BK1_VGHSS,0x07); - Generic_Short_Write_1P (DSI_CMD2_BK1_VGHSS,0x87); - - Generic_Short_Write_1P (DSI_CMD2_BK1_TESTCMD,0x80); -// Generic_Short_Write_1P (DSI_CMD2_BK1_VGLS,0x47); - Generic_Short_Write_1P (DSI_CMD2_BK1_VGLS,0x49); - Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR1,0x85); -// Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR2,0x21); - Generic_Short_Write_1P (DSI_CMD2_BK1_PWCTLR2,0x20); - Generic_Short_Write_1P (0xB9,0x10); - Generic_Short_Write_1P (DSI_CMD2_BK1_SPD1,0x78); - Generic_Short_Write_1P (DSI_CMD2_BK1_SPD2,0x78); - Generic_Short_Write_1P (DSI_CMD2_BK1_MIPISET1,0x88); - //---------------------------------End Power Control Registers Initial -------------------------------// - Delay(100); - //---------------------------------------------GIP Setting----------------------------------------------------// - const uint8_t _E0[] = {0xE0,0x00,0x00,0x02}; - Generic_Long_Write((uint8_t*)_E0, sizeof(_E0)); - //----------------------------------GIP---------------------------------------------------- - const uint8_t _E1[] = {0xE1,0x08,0x00,0x0A,0x00,0x07,0x00,0x09,0x00,0x00,0x33,0x33}; - const uint8_t _E2[] = {0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - Generic_Long_Write((uint8_t*)_E1, sizeof(_E1)); - Generic_Long_Write((uint8_t*)_E2, sizeof(_E2)); - - //-------------------------------------------------------------------------------------- - const uint8_t _E3[] = {0xE3,0x00,0x00,0x33,0x33}; - const uint8_t _E4[] = {0xE4,0x44,0x44}; - Generic_Long_Write((uint8_t*)_E3, sizeof(_E3)); - Generic_Long_Write((uint8_t*)_E4, sizeof(_E4)); - -// const uint8_t _E5[] = {0xE5,0x0E,0x2D,0xA0,0xa0,0x10,0x2D,0xA0,0xA0,0x0A,0x2D,0xA0,0xA0,0x0C,0x2D,0xA0,0xA0}; - const uint8_t _E5[] = {0xE5,0x0E,0x60,0xA0,0xa0,0x10,0x60,0xA0,0xA0,0x0A,0x60,0xA0,0xA0,0x0C,0x60,0xA0,0xA0}; - Generic_Long_Write((uint8_t*)_E5, sizeof(_E5)); - - const uint8_t _E6[] = {0xE6,0x00,0x00,0x33,0x33}; - const uint8_t _E7[] = {0xE7,0x44,0x44}; - Generic_Long_Write((uint8_t*)_E6, sizeof(_E6)); - Generic_Long_Write((uint8_t*)_E7, sizeof(_E7)); - -// const uint8_t _E8[] = {0xE8,0x0D,0x2D,0xA0,0xA0,0x0F,0x2D,0xA0,0xA0,0x09,0x2D,0xA0,0xA0,0x0B,0x2D,0xA0,0xA0}; - const uint8_t _E8[] = {0xE8,0x0D,0x60,0xA0,0xA0,0x0F,0x60,0xA0,0xA0,0x09,0x60,0xA0,0xA0,0x0B,0x60,0xA0,0xA0}; - Generic_Long_Write((uint8_t*)_E8, sizeof(_E8)); - - const uint8_t _EB[] = {0xEB,0x02,0x01,0xE4,0xE4,0x44,0x00,0x40}; - const uint8_t _EC[] = {0xEC,0x02,0x01}; - Generic_Long_Write((uint8_t*)_EB, sizeof(_EB)); - Generic_Long_Write((uint8_t*)_EC, sizeof(_EC)); - - const uint8_t _ED[17] = {0xED,0xAB,0x89,0x76,0x54,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0x45,0x67,0x98,0xBA}; - Generic_Long_Write((uint8_t*)_ED, sizeof(_ED)); - - //--------------------------------------------End GIP Setting-----------------------------------------------// - //------------------------------ Power Control Registers Initial End-----------------------------------// - //------------------------------------------Bank1 Setting----------------------------------------------------// - const uint8_t _FF2[] = {DSI_CMD2BKX_SEL,0x77,0x01,0x00,0x00,DSI_CMD2BKX_SEL_NONE}; - Generic_Long_Write ((uint8_t*)_FF2, sizeof(_FF2)); - - Delay(10); - DCS_Short_Write_NP(0x29); - Delay(200); - - - SSD_MODE(0,1); - -// ReadOperation(); - /* - Read_ADC(2.80,1,0.2);//��ȡӲ��ID ��ѹ��Χ0V - 3.3V - - if(!memcmp("0x01")) //�жϵ�ѹ���ڵķ�Χ�� - { - Set_TEXT(0, 1, 0x22);//��Ļ��ʾ��ɫ������������ - } - else - { - Set_TEXT(0, 0, 0x01);//Draw Text: "PASS" - - } - - */ -} diff --git a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md new file mode 100644 index 000000000..ca6928207 --- /dev/null +++ b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/Readme.md @@ -0,0 +1,35 @@ +# Managing CA Certs for TLS connections + +## Generating `certificates.h` from PEM file: + +> [!NOTE] +> Pre-requisites: `xxd` from `vim` packages or standalone +``` +xxd -i cacert.pem -n cacert_pem | sed 's/^unsigned/const unsigned/g' > certificates.h +``` + +## Getting PEM file from `certificates.h` + +> [!NOTE] +> Pre-requisites: `xxd`, GNU Tools (Use g-tools on MacOS: e.g., `gtail`, `ghead`) +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p > cacert.pem +``` +## Listing certifcates in `certificates.h` + +> [!NOTE] +> Pre-requisites: `openssl` + +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p > cacert.pem +openssl crl2pkcs7 -nocrl -certfile cacert.pem | openssl pkcs7 -print_certs | grep '^subject' +``` + +## Adding a new root certificate to `certificates.h` + +> [!Note] +> The PEM file for the root CA to add, e.g., `new_root.pem` + +``` +cat certificates.h | tail -n +2 | head -n -2 | xxd -r -p | cat - new_root.pem | xxd -n cacert_pem -i | sed 's/^unsigned/const unsigned/g' > certificates.h +``` diff --git a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h index 44fdeb168..768aa670c 100644 --- a/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h +++ b/libraries/STM32H747_System/examples/WiFiFirmwareUpdater/certificates.h @@ -5267,6 +5267,167 @@ const unsigned char cacert_pem[] = { 0x56, 0x39, 0x70, 0x41, 0x35, 0x47, 0x59, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x0a, 0x00 + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, + 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x46, 0x61, 0x7a, 0x43, + 0x43, 0x41, 0x31, 0x4f, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, + 0x52, 0x41, 0x49, 0x49, 0x51, 0x7a, 0x37, 0x44, 0x53, 0x51, 0x4f, 0x4e, + 0x5a, 0x52, 0x47, 0x50, 0x67, 0x75, 0x32, 0x4f, 0x43, 0x69, 0x77, 0x41, + 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, + 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41, 0x77, 0x0a, 0x54, 0x7a, + 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, + 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x4b, 0x54, 0x41, 0x6e, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x49, 0x45, 0x6c, 0x75, 0x64, 0x47, + 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x4e, 0x6c, 0x59, 0x33, + 0x56, 0x79, 0x61, 0x58, 0x52, 0x35, 0x49, 0x46, 0x4a, 0x6c, 0x63, 0x32, + 0x56, 0x68, 0x0a, 0x63, 0x6d, 0x4e, 0x6f, 0x49, 0x45, 0x64, 0x79, 0x62, + 0x33, 0x56, 0x77, 0x4d, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x44, 0x45, 0x77, 0x78, 0x4a, 0x55, 0x31, 0x4a, 0x48, 0x49, + 0x46, 0x4a, 0x76, 0x62, 0x33, 0x51, 0x67, 0x57, 0x44, 0x45, 0x77, 0x48, + 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x55, 0x77, 0x4e, 0x6a, 0x41, 0x30, 0x4d, + 0x54, 0x45, 0x77, 0x4e, 0x44, 0x4d, 0x34, 0x0a, 0x57, 0x68, 0x63, 0x4e, + 0x4d, 0x7a, 0x55, 0x77, 0x4e, 0x6a, 0x41, 0x30, 0x4d, 0x54, 0x45, 0x77, + 0x4e, 0x44, 0x4d, 0x34, 0x57, 0x6a, 0x42, 0x50, 0x4d, 0x51, 0x73, 0x77, + 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, + 0x55, 0x7a, 0x45, 0x70, 0x4d, 0x43, 0x63, 0x47, 0x41, 0x31, 0x55, 0x45, + 0x43, 0x68, 0x4d, 0x67, 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x75, + 0x0a, 0x5a, 0x58, 0x51, 0x67, 0x55, 0x32, 0x56, 0x6a, 0x64, 0x58, 0x4a, + 0x70, 0x64, 0x48, 0x6b, 0x67, 0x55, 0x6d, 0x56, 0x7a, 0x5a, 0x57, 0x46, + 0x79, 0x59, 0x32, 0x67, 0x67, 0x52, 0x33, 0x4a, 0x76, 0x64, 0x58, 0x41, + 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, + 0x54, 0x44, 0x45, 0x6c, 0x54, 0x55, 0x6b, 0x63, 0x67, 0x55, 0x6d, 0x39, + 0x76, 0x64, 0x43, 0x42, 0x59, 0x0a, 0x4d, 0x54, 0x43, 0x43, 0x41, 0x69, + 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, + 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x67, + 0x49, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x67, 0x6f, 0x43, 0x67, 0x67, + 0x49, 0x42, 0x41, 0x4b, 0x33, 0x6f, 0x4a, 0x48, 0x50, 0x30, 0x46, 0x44, + 0x66, 0x7a, 0x6d, 0x35, 0x34, 0x72, 0x56, 0x79, 0x67, 0x63, 0x0a, 0x68, + 0x37, 0x37, 0x63, 0x74, 0x39, 0x38, 0x34, 0x6b, 0x49, 0x78, 0x75, 0x50, + 0x4f, 0x5a, 0x58, 0x6f, 0x48, 0x6a, 0x33, 0x64, 0x63, 0x4b, 0x69, 0x2f, + 0x76, 0x56, 0x71, 0x62, 0x76, 0x59, 0x41, 0x54, 0x79, 0x6a, 0x62, 0x33, + 0x6d, 0x69, 0x47, 0x62, 0x45, 0x53, 0x54, 0x74, 0x72, 0x46, 0x6a, 0x2f, + 0x52, 0x51, 0x53, 0x61, 0x37, 0x38, 0x66, 0x30, 0x75, 0x6f, 0x78, 0x6d, + 0x79, 0x46, 0x2b, 0x0a, 0x30, 0x54, 0x4d, 0x38, 0x75, 0x6b, 0x6a, 0x31, + 0x33, 0x58, 0x6e, 0x66, 0x73, 0x37, 0x6a, 0x2f, 0x45, 0x76, 0x45, 0x68, + 0x6d, 0x6b, 0x76, 0x42, 0x69, 0x6f, 0x5a, 0x78, 0x61, 0x55, 0x70, 0x6d, + 0x5a, 0x6d, 0x79, 0x50, 0x66, 0x6a, 0x78, 0x77, 0x76, 0x36, 0x30, 0x70, + 0x49, 0x67, 0x62, 0x7a, 0x35, 0x4d, 0x44, 0x6d, 0x67, 0x4b, 0x37, 0x69, + 0x53, 0x34, 0x2b, 0x33, 0x6d, 0x58, 0x36, 0x55, 0x0a, 0x41, 0x35, 0x2f, + 0x54, 0x52, 0x35, 0x64, 0x38, 0x6d, 0x55, 0x67, 0x6a, 0x55, 0x2b, 0x67, + 0x34, 0x72, 0x6b, 0x38, 0x4b, 0x62, 0x34, 0x4d, 0x75, 0x30, 0x55, 0x6c, + 0x58, 0x6a, 0x49, 0x42, 0x30, 0x74, 0x74, 0x6f, 0x76, 0x30, 0x44, 0x69, + 0x4e, 0x65, 0x77, 0x4e, 0x77, 0x49, 0x52, 0x74, 0x31, 0x38, 0x6a, 0x41, + 0x38, 0x2b, 0x6f, 0x2b, 0x75, 0x33, 0x64, 0x70, 0x6a, 0x71, 0x2b, 0x73, + 0x57, 0x0a, 0x54, 0x38, 0x4b, 0x4f, 0x45, 0x55, 0x74, 0x2b, 0x7a, 0x77, + 0x76, 0x6f, 0x2f, 0x37, 0x56, 0x33, 0x4c, 0x76, 0x53, 0x79, 0x65, 0x30, + 0x72, 0x67, 0x54, 0x42, 0x49, 0x6c, 0x44, 0x48, 0x43, 0x4e, 0x41, 0x79, + 0x6d, 0x67, 0x34, 0x56, 0x4d, 0x6b, 0x37, 0x42, 0x50, 0x5a, 0x37, 0x68, + 0x6d, 0x2f, 0x45, 0x4c, 0x4e, 0x4b, 0x6a, 0x44, 0x2b, 0x4a, 0x6f, 0x32, + 0x46, 0x52, 0x33, 0x71, 0x79, 0x48, 0x0a, 0x42, 0x35, 0x54, 0x30, 0x59, + 0x33, 0x48, 0x73, 0x4c, 0x75, 0x4a, 0x76, 0x57, 0x35, 0x69, 0x42, 0x34, + 0x59, 0x6c, 0x63, 0x4e, 0x48, 0x6c, 0x73, 0x64, 0x75, 0x38, 0x37, 0x6b, + 0x47, 0x4a, 0x35, 0x35, 0x74, 0x75, 0x6b, 0x6d, 0x69, 0x38, 0x6d, 0x78, + 0x64, 0x41, 0x51, 0x34, 0x51, 0x37, 0x65, 0x32, 0x52, 0x43, 0x4f, 0x46, + 0x76, 0x75, 0x33, 0x39, 0x36, 0x6a, 0x33, 0x78, 0x2b, 0x55, 0x43, 0x0a, + 0x42, 0x35, 0x69, 0x50, 0x4e, 0x67, 0x69, 0x56, 0x35, 0x2b, 0x49, 0x33, + 0x6c, 0x67, 0x30, 0x32, 0x64, 0x5a, 0x37, 0x37, 0x44, 0x6e, 0x4b, 0x78, + 0x48, 0x5a, 0x75, 0x38, 0x41, 0x2f, 0x6c, 0x4a, 0x42, 0x64, 0x69, 0x42, + 0x33, 0x51, 0x57, 0x30, 0x4b, 0x74, 0x5a, 0x42, 0x36, 0x61, 0x77, 0x42, + 0x64, 0x70, 0x55, 0x4b, 0x44, 0x39, 0x6a, 0x66, 0x31, 0x62, 0x30, 0x53, + 0x48, 0x7a, 0x55, 0x76, 0x0a, 0x4b, 0x42, 0x64, 0x73, 0x30, 0x70, 0x6a, + 0x42, 0x71, 0x41, 0x6c, 0x6b, 0x64, 0x32, 0x35, 0x48, 0x4e, 0x37, 0x72, + 0x4f, 0x72, 0x46, 0x6c, 0x65, 0x61, 0x4a, 0x31, 0x2f, 0x63, 0x74, 0x61, + 0x4a, 0x78, 0x51, 0x5a, 0x42, 0x4b, 0x54, 0x35, 0x5a, 0x50, 0x74, 0x30, + 0x6d, 0x39, 0x53, 0x54, 0x4a, 0x45, 0x61, 0x64, 0x61, 0x6f, 0x30, 0x78, + 0x41, 0x48, 0x30, 0x61, 0x68, 0x6d, 0x62, 0x57, 0x6e, 0x0a, 0x4f, 0x6c, + 0x46, 0x75, 0x68, 0x6a, 0x75, 0x65, 0x66, 0x58, 0x4b, 0x6e, 0x45, 0x67, + 0x56, 0x34, 0x57, 0x65, 0x30, 0x2b, 0x55, 0x58, 0x67, 0x56, 0x43, 0x77, + 0x4f, 0x50, 0x6a, 0x64, 0x41, 0x76, 0x42, 0x62, 0x49, 0x2b, 0x65, 0x30, + 0x6f, 0x63, 0x53, 0x33, 0x4d, 0x46, 0x45, 0x76, 0x7a, 0x47, 0x36, 0x75, + 0x42, 0x51, 0x45, 0x33, 0x78, 0x44, 0x6b, 0x33, 0x53, 0x7a, 0x79, 0x6e, + 0x54, 0x6e, 0x0a, 0x6a, 0x68, 0x38, 0x42, 0x43, 0x4e, 0x41, 0x77, 0x31, + 0x46, 0x74, 0x78, 0x4e, 0x72, 0x51, 0x48, 0x75, 0x73, 0x45, 0x77, 0x4d, + 0x46, 0x78, 0x49, 0x74, 0x34, 0x49, 0x37, 0x6d, 0x4b, 0x5a, 0x39, 0x59, + 0x49, 0x71, 0x69, 0x6f, 0x79, 0x6d, 0x43, 0x7a, 0x4c, 0x71, 0x39, 0x67, + 0x77, 0x51, 0x62, 0x6f, 0x6f, 0x4d, 0x44, 0x51, 0x61, 0x48, 0x57, 0x42, + 0x66, 0x45, 0x62, 0x77, 0x72, 0x62, 0x77, 0x0a, 0x71, 0x48, 0x79, 0x47, + 0x4f, 0x30, 0x61, 0x6f, 0x53, 0x43, 0x71, 0x49, 0x33, 0x48, 0x61, 0x61, + 0x64, 0x72, 0x38, 0x66, 0x61, 0x71, 0x55, 0x39, 0x47, 0x59, 0x2f, 0x72, + 0x4f, 0x50, 0x4e, 0x6b, 0x33, 0x73, 0x67, 0x72, 0x44, 0x51, 0x6f, 0x6f, + 0x2f, 0x2f, 0x66, 0x62, 0x34, 0x68, 0x56, 0x43, 0x31, 0x43, 0x4c, 0x51, + 0x4a, 0x31, 0x33, 0x68, 0x65, 0x66, 0x34, 0x59, 0x35, 0x33, 0x43, 0x49, + 0x0a, 0x72, 0x55, 0x37, 0x6d, 0x32, 0x59, 0x73, 0x36, 0x78, 0x74, 0x30, + 0x6e, 0x55, 0x57, 0x37, 0x2f, 0x76, 0x47, 0x54, 0x31, 0x4d, 0x30, 0x4e, + 0x50, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x51, 0x6a, 0x42, + 0x41, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x45, + 0x42, 0x2f, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49, 0x42, 0x42, 0x6a, 0x41, + 0x50, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, + 0x38, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x42, + 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, + 0x52, 0x35, 0x74, 0x46, 0x6e, 0x6d, 0x65, 0x37, 0x62, 0x6c, 0x35, 0x41, + 0x46, 0x7a, 0x67, 0x41, 0x69, 0x49, 0x79, 0x42, 0x70, 0x59, 0x39, 0x75, + 0x6d, 0x62, 0x62, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x0a, 0x68, + 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, + 0x41, 0x4f, 0x43, 0x41, 0x67, 0x45, 0x41, 0x56, 0x52, 0x39, 0x59, 0x71, + 0x62, 0x79, 0x79, 0x71, 0x46, 0x44, 0x51, 0x44, 0x4c, 0x48, 0x59, 0x47, + 0x6d, 0x6b, 0x67, 0x4a, 0x79, 0x6b, 0x49, 0x72, 0x47, 0x46, 0x31, 0x58, + 0x49, 0x70, 0x75, 0x2b, 0x49, 0x4c, 0x6c, 0x61, 0x53, 0x2f, 0x56, 0x39, + 0x6c, 0x5a, 0x4c, 0x0a, 0x75, 0x62, 0x68, 0x7a, 0x45, 0x46, 0x6e, 0x54, + 0x49, 0x5a, 0x64, 0x2b, 0x35, 0x30, 0x78, 0x78, 0x2b, 0x37, 0x4c, 0x53, + 0x59, 0x4b, 0x30, 0x35, 0x71, 0x41, 0x76, 0x71, 0x46, 0x79, 0x46, 0x57, + 0x68, 0x66, 0x46, 0x51, 0x44, 0x6c, 0x6e, 0x72, 0x7a, 0x75, 0x42, 0x5a, + 0x36, 0x62, 0x72, 0x4a, 0x46, 0x65, 0x2b, 0x47, 0x6e, 0x59, 0x2b, 0x45, + 0x67, 0x50, 0x62, 0x6b, 0x36, 0x5a, 0x47, 0x51, 0x0a, 0x33, 0x42, 0x65, + 0x62, 0x59, 0x68, 0x74, 0x46, 0x38, 0x47, 0x61, 0x56, 0x30, 0x6e, 0x78, + 0x76, 0x77, 0x75, 0x6f, 0x37, 0x37, 0x78, 0x2f, 0x50, 0x79, 0x39, 0x61, + 0x75, 0x4a, 0x2f, 0x47, 0x70, 0x73, 0x4d, 0x69, 0x75, 0x2f, 0x58, 0x31, + 0x2b, 0x6d, 0x76, 0x6f, 0x69, 0x42, 0x4f, 0x76, 0x2f, 0x32, 0x58, 0x2f, + 0x71, 0x6b, 0x53, 0x73, 0x69, 0x73, 0x52, 0x63, 0x4f, 0x6a, 0x2f, 0x4b, + 0x4b, 0x0a, 0x4e, 0x46, 0x74, 0x59, 0x32, 0x50, 0x77, 0x42, 0x79, 0x56, + 0x53, 0x35, 0x75, 0x43, 0x62, 0x4d, 0x69, 0x6f, 0x67, 0x7a, 0x69, 0x55, + 0x77, 0x74, 0x68, 0x44, 0x79, 0x43, 0x33, 0x2b, 0x36, 0x57, 0x56, 0x77, + 0x57, 0x36, 0x4c, 0x4c, 0x76, 0x33, 0x78, 0x4c, 0x66, 0x48, 0x54, 0x6a, + 0x75, 0x43, 0x76, 0x6a, 0x48, 0x49, 0x49, 0x6e, 0x4e, 0x7a, 0x6b, 0x74, + 0x48, 0x43, 0x67, 0x4b, 0x51, 0x35, 0x0a, 0x4f, 0x52, 0x41, 0x7a, 0x49, + 0x34, 0x4a, 0x4d, 0x50, 0x4a, 0x2b, 0x47, 0x73, 0x6c, 0x57, 0x59, 0x48, + 0x62, 0x34, 0x70, 0x68, 0x6f, 0x77, 0x69, 0x6d, 0x35, 0x37, 0x69, 0x61, + 0x7a, 0x74, 0x58, 0x4f, 0x6f, 0x4a, 0x77, 0x54, 0x64, 0x77, 0x4a, 0x78, + 0x34, 0x6e, 0x4c, 0x43, 0x67, 0x64, 0x4e, 0x62, 0x4f, 0x68, 0x64, 0x6a, + 0x73, 0x6e, 0x76, 0x7a, 0x71, 0x76, 0x48, 0x75, 0x37, 0x55, 0x72, 0x0a, + 0x54, 0x6b, 0x58, 0x57, 0x53, 0x74, 0x41, 0x6d, 0x7a, 0x4f, 0x56, 0x79, + 0x79, 0x67, 0x68, 0x71, 0x70, 0x5a, 0x58, 0x6a, 0x46, 0x61, 0x48, 0x33, + 0x70, 0x4f, 0x33, 0x4a, 0x4c, 0x46, 0x2b, 0x6c, 0x2b, 0x2f, 0x2b, 0x73, + 0x4b, 0x41, 0x49, 0x75, 0x76, 0x74, 0x64, 0x37, 0x75, 0x2b, 0x4e, 0x78, + 0x65, 0x35, 0x41, 0x57, 0x30, 0x77, 0x64, 0x65, 0x52, 0x6c, 0x4e, 0x38, + 0x4e, 0x77, 0x64, 0x43, 0x0a, 0x6a, 0x4e, 0x50, 0x45, 0x6c, 0x70, 0x7a, + 0x56, 0x6d, 0x62, 0x55, 0x71, 0x34, 0x4a, 0x55, 0x61, 0x67, 0x45, 0x69, + 0x75, 0x54, 0x44, 0x6b, 0x48, 0x7a, 0x73, 0x78, 0x48, 0x70, 0x46, 0x4b, + 0x56, 0x4b, 0x37, 0x71, 0x34, 0x2b, 0x36, 0x33, 0x53, 0x4d, 0x31, 0x4e, + 0x39, 0x35, 0x52, 0x31, 0x4e, 0x62, 0x64, 0x57, 0x68, 0x73, 0x63, 0x64, + 0x43, 0x62, 0x2b, 0x5a, 0x41, 0x4a, 0x7a, 0x56, 0x63, 0x0a, 0x6f, 0x79, + 0x69, 0x33, 0x42, 0x34, 0x33, 0x6e, 0x6a, 0x54, 0x4f, 0x51, 0x35, 0x79, + 0x4f, 0x66, 0x2b, 0x31, 0x43, 0x63, 0x65, 0x57, 0x78, 0x47, 0x31, 0x62, + 0x51, 0x56, 0x73, 0x35, 0x5a, 0x75, 0x66, 0x70, 0x73, 0x4d, 0x6c, 0x6a, + 0x71, 0x34, 0x55, 0x69, 0x30, 0x2f, 0x31, 0x6c, 0x76, 0x68, 0x2b, 0x77, + 0x6a, 0x43, 0x68, 0x50, 0x34, 0x6b, 0x71, 0x4b, 0x4f, 0x4a, 0x32, 0x71, + 0x78, 0x71, 0x0a, 0x34, 0x52, 0x67, 0x71, 0x73, 0x61, 0x68, 0x44, 0x59, + 0x56, 0x76, 0x54, 0x48, 0x39, 0x77, 0x37, 0x6a, 0x58, 0x62, 0x79, 0x4c, + 0x65, 0x69, 0x4e, 0x64, 0x64, 0x38, 0x58, 0x4d, 0x32, 0x77, 0x39, 0x55, + 0x2f, 0x74, 0x37, 0x79, 0x30, 0x46, 0x66, 0x2f, 0x39, 0x79, 0x69, 0x30, + 0x47, 0x45, 0x34, 0x34, 0x5a, 0x61, 0x34, 0x72, 0x46, 0x32, 0x4c, 0x4e, + 0x39, 0x64, 0x31, 0x31, 0x54, 0x50, 0x41, 0x0a, 0x6d, 0x52, 0x47, 0x75, + 0x6e, 0x55, 0x48, 0x42, 0x63, 0x6e, 0x57, 0x45, 0x76, 0x67, 0x4a, 0x42, + 0x51, 0x6c, 0x39, 0x6e, 0x4a, 0x45, 0x69, 0x55, 0x30, 0x5a, 0x73, 0x6e, + 0x76, 0x67, 0x63, 0x2f, 0x75, 0x62, 0x68, 0x50, 0x67, 0x58, 0x52, 0x52, + 0x34, 0x58, 0x71, 0x33, 0x37, 0x5a, 0x30, 0x6a, 0x34, 0x72, 0x37, 0x67, + 0x31, 0x53, 0x67, 0x45, 0x45, 0x7a, 0x77, 0x78, 0x41, 0x35, 0x37, 0x64, + 0x0a, 0x65, 0x6d, 0x79, 0x50, 0x78, 0x67, 0x63, 0x59, 0x78, 0x6e, 0x2f, + 0x65, 0x52, 0x34, 0x34, 0x2f, 0x4b, 0x4a, 0x34, 0x45, 0x42, 0x73, 0x2b, + 0x6c, 0x56, 0x44, 0x52, 0x33, 0x76, 0x65, 0x79, 0x4a, 0x6d, 0x2b, 0x6b, + 0x58, 0x51, 0x39, 0x39, 0x62, 0x32, 0x31, 0x2f, 0x2b, 0x6a, 0x68, 0x35, + 0x58, 0x6f, 0x73, 0x31, 0x41, 0x6e, 0x58, 0x35, 0x69, 0x49, 0x74, 0x72, + 0x65, 0x47, 0x43, 0x63, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, + 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, + 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a }; -unsigned int cacert_pem_len = 63218; +const unsigned int cacert_pem_len = 65156; diff --git a/nano.variables b/nano.variables index 1cba7139a..20602833e 100644 --- a/nano.variables +++ b/nano.variables @@ -1,5 +1,5 @@ export FLAVOUR="nano" export VARIANTS=("NANO_RP2040_CONNECT ARDUINO_NANO33BLE") export FQBNS=("nanorp2040connect nano33ble") -export LIBRARIES=("PDM SPI Wire MRI USBHID USBMSD ThreadDebug Scheduler SFU Nano33BLE_System SocketWrapper MLC") +export LIBRARIES=("PDM SPI Wire MRI USBHID USBMIDI USBMSD ThreadDebug Scheduler SFU Nano33BLE_System SocketWrapper MLC") export BOOTLOADERS=("nano33ble") diff --git a/package_full.sh b/package_full.sh index fa84dcd0d..66c09d963 100755 --- a/package_full.sh +++ b/package_full.sh @@ -1,5 +1,5 @@ #Get version from git(hub) tag -export VERSION="4.0.4" +export VERSION="4.0.6" FLAVOURS=`ls *.variables` diff --git a/platform.txt b/platform.txt index a8cae2a71..4ab18ab42 100644 --- a/platform.txt +++ b/platform.txt @@ -4,8 +4,8 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification -name=Arduino Mbed OS Boards -version=9.9.9 +name=Arduino Mbed OS Boards +version= # Compile variables # ------------------------ diff --git a/portenta.variables b/portenta.variables index ed2e0973f..8ae4b3f2b 100644 --- a/portenta.variables +++ b/portenta.variables @@ -1,5 +1,5 @@ export FLAVOUR="portenta" export VARIANTS=("PORTENTA_H7_M7 PORTENTA_H7_M4 PORTENTA_X8") export FQBNS=("envie_m7 portenta_x8") -export LIBRARIES=("doom Ethernet MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 Himax_HM0360 PDM Portenta_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib USBHOST mbed-memory-status Portenta_SDCARD Scheduler USBMSD SocketWrapper GSM GPS MCUboot") +export LIBRARIES=("doom Ethernet MRI Portenta_SDRAM SPI WiFi ea_malloc openamp_arduino STM32H747_System ThreadDebug Himax_HM01B0 Himax_HM0360 PDM Arduino_H7_Video USBAudio KernelDebug Portenta_Audio RPC USBHID Wire Portenta_lvgl Camera rpclib USBHOST mbed-memory-status Portenta_SDCARD Scheduler USBMSD USBMIDI SocketWrapper GSM GPS MCUboot Arduino_CAN") export BOOTLOADERS=("PORTENTA_H7") diff --git a/variants/ARDUINO_NANO33BLE/defines.txt b/variants/ARDUINO_NANO33BLE/defines.txt index 0123b4077..0a9037a60 100644 --- a/variants/ARDUINO_NANO33BLE/defines.txt +++ b/variants/ARDUINO_NANO33BLE/defines.txt @@ -1,15 +1,17 @@ -DARM_MATH_CM4 -DBOARD_PCA10056 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 -DCONFIG_GPIO_AS_PINRESET +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -30,10 +32,13 @@ -DFEATURE_BLE=1 -DFEATURE_CRYPTOCELL310=1 -DFEATURE_STORAGE=1 --DMBEDTLS_CONFIG_HW_SUPPORT --DMBED_BUILD_TIMESTAMP=1670863539.4329445 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690446991.0429106 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_CONFIG_HW_SUPPORT -DNRF52840_XXAA -DNRF52_PAN_20 -DSWI_DISABLE0 @@ -59,11 +64,6 @@ -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -DWSF_MAX_HANDLERS=10 --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/ARDUINO_NANO33BLE/includes.txt b/variants/ARDUINO_NANO33BLE/includes.txt index d2a028010..63c35643d 100644 --- a/variants/ARDUINO_NANO33BLE/includes.txt +++ b/variants/ARDUINO_NANO33BLE/includes.txt @@ -128,23 +128,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/ARDUINO_NANO33BLE/libs/libmbed.a b/variants/ARDUINO_NANO33BLE/libs/libmbed.a index 62703cbde..915858f44 100644 Binary files a/variants/ARDUINO_NANO33BLE/libs/libmbed.a and b/variants/ARDUINO_NANO33BLE/libs/libmbed.a differ diff --git a/variants/ARDUINO_NANO33BLE/mbed_config.h b/variants/ARDUINO_NANO33BLE/mbed_config.h index 5cf0ce054..7af2c4570 100644 --- a/variants/ARDUINO_NANO33BLE/mbed_config.h +++ b/variants/ARDUINO_NANO33BLE/mbed_config.h @@ -202,6 +202,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/EDGE_CONTROL/defines.txt b/variants/EDGE_CONTROL/defines.txt index d8ee365dc..0198e4a12 100644 --- a/variants/EDGE_CONTROL/defines.txt +++ b/variants/EDGE_CONTROL/defines.txt @@ -1,6 +1,7 @@ -DARM_MATH_CM4 -DBOARD_PCA10056 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 @@ -8,11 +9,12 @@ -DCOMPONENT_SD=1 -DCOMPONENT_SPIF=1 -DCONFIG_GPIO_AS_PINRESET +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -34,10 +36,13 @@ -DFEATURE_BLE=1 -DFEATURE_CRYPTOCELL310=1 -DFEATURE_STORAGE=1 --DMBEDTLS_CONFIG_HW_SUPPORT --DMBED_BUILD_TIMESTAMP=1670864083.6341271 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447154.5646534 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_CONFIG_HW_SUPPORT -DNRF52840_XXAA -DNRF52_PAN_20 -DSWI_DISABLE0 @@ -63,11 +68,6 @@ -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM -DWSF_MAX_HANDLERS=10 --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/EDGE_CONTROL/includes.txt b/variants/EDGE_CONTROL/includes.txt index 2c648b90e..238ddb925 100644 --- a/variants/EDGE_CONTROL/includes.txt +++ b/variants/EDGE_CONTROL/includes.txt @@ -128,23 +128,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/EDGE_CONTROL/libs/libmbed.a b/variants/EDGE_CONTROL/libs/libmbed.a index 0a63a3481..69085f107 100644 Binary files a/variants/EDGE_CONTROL/libs/libmbed.a and b/variants/EDGE_CONTROL/libs/libmbed.a differ diff --git a/variants/EDGE_CONTROL/mbed_config.h b/variants/EDGE_CONTROL/mbed_config.h index bbaf8eed7..83a45d8be 100644 --- a/variants/EDGE_CONTROL/mbed_config.h +++ b/variants/EDGE_CONTROL/mbed_config.h @@ -201,6 +201,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/GIGA/defines.txt b/variants/GIGA/defines.txt index dccae1a77..53a08c42f 100644 --- a/variants/GIGA/defines.txt +++ b/variants/GIGA/defines.txt @@ -44,7 +44,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1675161895.788852 +-DMBED_BUILD_TIMESTAMP=1690447383.8050008 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/GIGA/libs/libmbed.a b/variants/GIGA/libs/libmbed.a index 0aa148275..7b1e6bb8f 100644 Binary files a/variants/GIGA/libs/libmbed.a and b/variants/GIGA/libs/libmbed.a differ diff --git a/variants/GIGA/mbed_config.h b/variants/GIGA/mbed_config.h index 31bfc723c..460ac941c 100644 --- a/variants/GIGA/mbed_config.h +++ b/variants/GIGA/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/NANO_RP2040_CONNECT/defines.txt b/variants/NANO_RP2040_CONNECT/defines.txt index 369919919..85f8bdb41 100644 --- a/variants/NANO_RP2040_CONNECT/defines.txt +++ b/variants/NANO_RP2040_CONNECT/defines.txt @@ -1,6 +1,8 @@ -DARM_MATH_CM0PLUS +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 +-D__CORTEX_M0PLUS -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 @@ -17,9 +19,11 @@ -DDEVICE_USBDEVICE=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 --DMBEDTLS_ENTROPY_NV_SEED --DMBED_BUILD_TIMESTAMP=1670863511.0757143 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690446969.4415529 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM +-DMBEDTLS_ENTROPY_NV_SEED -DPICO_FLASH_SIZE_BYTES=16*1024*1024 -DPICO_NO_BINARY_INFO=1 -DPICO_ON_DEVICE=1 @@ -31,18 +35,14 @@ -DTARGET_LIKE_CORTEX_M0 -DTARGET_LIKE_MBED -DTARGET_M0P +-DTARGET_memmap_default -DTARGET_NAME=NANO_RP2040_CONNECT -DTARGET_NANO_RP2040_CONNECT -DTARGET_RASPBERRYPI -DTARGET_RELEASE -DTARGET_RP2040 --DTARGET_memmap_default -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M0PLUS --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/NANO_RP2040_CONNECT/includes.txt b/variants/NANO_RP2040_CONNECT/includes.txt index f42afe795..d84e91a12 100644 --- a/variants/NANO_RP2040_CONNECT/includes.txt +++ b/variants/NANO_RP2040_CONNECT/includes.txt @@ -65,23 +65,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NANO_RP2040_CONNECT/libs/libmbed.a b/variants/NANO_RP2040_CONNECT/libs/libmbed.a index 83d5e58de..276e5d120 100644 Binary files a/variants/NANO_RP2040_CONNECT/libs/libmbed.a and b/variants/NANO_RP2040_CONNECT/libs/libmbed.a differ diff --git a/variants/NANO_RP2040_CONNECT/mbed_config.h b/variants/NANO_RP2040_CONNECT/mbed_config.h index 08a14dc14..62a29941f 100644 --- a/variants/NANO_RP2040_CONNECT/mbed_config.h +++ b/variants/NANO_RP2040_CONNECT/mbed_config.h @@ -141,6 +141,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/NICLA/defines.txt b/variants/NICLA/defines.txt index a68b2f253..954f8bbbe 100644 --- a/variants/NICLA/defines.txt +++ b/variants/NICLA/defines.txt @@ -1,16 +1,18 @@ -DARM_MATH_CM4 -DBOARD_PCA10040 +-D__CMSIS_RTOS -DCMSIS_VECTAB_VIRTUAL -DCMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\" -DCOMPONENT_FLASHIAP=1 -DCOMPONENT_SPIF=1 -DCONFIG_NFCT_PINS_AS_GPIOS +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_ITM=1 -DDEVICE_LPTICKER=1 @@ -29,7 +31,10 @@ -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 -DFEATURE_BLE=1 --DMBED_BUILD_TIMESTAMP=1670864134.7724268 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447190.2057042 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS -DNRF52 @@ -69,11 +74,6 @@ -DTARGET_SOFTDEVICE_NONE -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/NICLA/includes.txt b/variants/NICLA/includes.txt index 4cc4b394b..e05af8b4e 100644 --- a/variants/NICLA/includes.txt +++ b/variants/NICLA/includes.txt @@ -123,23 +123,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NICLA/libs/libmbed.a b/variants/NICLA/libs/libmbed.a index e6c56cfe7..3033bd740 100644 Binary files a/variants/NICLA/libs/libmbed.a and b/variants/NICLA/libs/libmbed.a differ diff --git a/variants/NICLA/mbed_config.h b/variants/NICLA/mbed_config.h index 0f7a8772d..02cc24c06 100644 --- a/variants/NICLA/mbed_config.h +++ b/variants/NICLA/mbed_config.h @@ -31,7 +31,7 @@ #define BLE_FEATURE_PHY_MANAGEMENT 1 // set by library:ble #define BLE_FEATURE_PRIVACY 0 // set by application[*] #define BLE_FEATURE_SECURE_CONNECTIONS 0 // set by application[*] -#define BLE_FEATURE_SECURITY 0 // set by application[*] +#define BLE_FEATURE_SECURITY 1 // set by application[*] #define BLE_FEATURE_SIGNING 0 // set by application[*] #define BLE_FEATURE_WHITELIST 0 // set by application[*] #define BLE_GAP_HOST_BASED_PRIVATE_ADDRESS_RESOLUTION 0 // set by application[*] @@ -199,6 +199,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora @@ -305,7 +306,7 @@ #define MBED_CONF_RTOS_PRESENT 1 // set by library:rtos #define MBED_CONF_RTOS_SEMAPHORE_NUM 0 // set by library:rtos #define MBED_CONF_RTOS_THREAD_NUM 0 // set by library:rtos -#define MBED_CONF_RTOS_THREAD_STACK_SIZE 1024 // set by application[*] +#define MBED_CONF_RTOS_THREAD_STACK_SIZE 768 // set by application[*] #define MBED_CONF_RTOS_THREAD_USER_STACK_SIZE 0 // set by library:rtos #define MBED_CONF_RTOS_TIMER_NUM 0 // set by library:rtos #define MBED_CONF_RTOS_TIMER_THREAD_STACK_SIZE 768 // set by library:rtos @@ -385,9 +386,7 @@ #define LHCI_ENABLE_VS 0 // defined by library:cordio-nordic-ll #define LL_MAX_PER_SCAN 3 // defined by library:cordio-nordic-ll #define MBEDTLS_CIPHER_MODE_CTR // defined by library:SecureStore -#define MBED_HEAP_STATS_ENABLED 1 // defined by application #define MBED_MEM_TRACING_ENABLED 1 // defined by application -#define MBED_STACK_STATS_ENABLED 1 // defined by application #define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 8 // defined by application #define NRFX_WDT_ENABLED 1 // defined by application #define NSAPI_PPP_AVAILABLE (MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED) // defined by library:ppp diff --git a/variants/NICLA_VISION/cflags.txt b/variants/NICLA_VISION/cflags.txt index ac9f710b6..8c5eb01b0 100644 --- a/variants/NICLA_VISION/cflags.txt +++ b/variants/NICLA_VISION/cflags.txt @@ -19,7 +19,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/NICLA_VISION/cxxflags.txt b/variants/NICLA_VISION/cxxflags.txt index 2dec88933..24d860cfa 100644 --- a/variants/NICLA_VISION/cxxflags.txt +++ b/variants/NICLA_VISION/cxxflags.txt @@ -21,7 +21,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/NICLA_VISION/defines.txt b/variants/NICLA_VISION/defines.txt index 6fa69c4e3..8e73def76 100644 --- a/variants/NICLA_VISION/defines.txt +++ b/variants/NICLA_VISION/defines.txt @@ -45,7 +45,7 @@ -DFLOW_SILENT -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1673362829.88069 +-DMBED_BUILD_TIMESTAMP=1690447224.0712476 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/NICLA_VISION/includes.txt b/variants/NICLA_VISION/includes.txt index b44ead3f0..4bef4f58c 100644 --- a/variants/NICLA_VISION/includes.txt +++ b/variants/NICLA_VISION/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/NICLA_VISION/libs/libmbed.a b/variants/NICLA_VISION/libs/libmbed.a index e4888bdaf..66947671c 100644 Binary files a/variants/NICLA_VISION/libs/libmbed.a and b/variants/NICLA_VISION/libs/libmbed.a differ diff --git a/variants/NICLA_VISION/linker_script.ld b/variants/NICLA_VISION/linker_script.ld index f634db472..0b00d41d9 100644 --- a/variants/NICLA_VISION/linker_script.ld +++ b/variants/NICLA_VISION/linker_script.ld @@ -1,12 +1,14 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 0x1c0000 + FLASH (rx) : ORIGIN = 0x8040000, LENGTH = CM4_BINARY_START - 0x8040000 DTCMRAM (rwx) : ORIGIN = 0x20000000 + (((166 * 4) + 7) & 0xFFFFFFF8), LENGTH = 128K - (((166 * 4) + 7) & 0xFFFFFFF8) RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 0x80000 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +__OPENAMP_region_start__ = 0x38000400; +__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K; ENTRY(Reset_Handler) SECTIONS { @@ -92,6 +94,15 @@ SECTIONS __bss_end__ = .; _ebss = .; } > RAM + .openamp_section (NOLOAD) : { + . = ABSOLUTE(0x38000000); + *(.resource_table) + } >RAM_D3 AT > FLASH + .pdm_section (NOLOAD) : { + . = ABSOLUTE(0x3800FC00); + *(.pdm_buffer) + } > RAM_D3 + .heap (COPY): { __end__ = .; diff --git a/variants/NICLA_VISION/mbed_config.h b/variants/NICLA_VISION/mbed_config.h index 3cb8deaa9..ed8376f00 100644 --- a/variants/NICLA_VISION/mbed_config.h +++ b/variants/NICLA_VISION/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/OPTA/cflags.txt b/variants/OPTA/cflags.txt index ac9f710b6..8c5eb01b0 100644 --- a/variants/OPTA/cflags.txt +++ b/variants/OPTA/cflags.txt @@ -19,7 +19,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/OPTA/cxxflags.txt b/variants/OPTA/cxxflags.txt index 2dec88933..24d860cfa 100644 --- a/variants/OPTA/cxxflags.txt +++ b/variants/OPTA/cxxflags.txt @@ -21,7 +21,6 @@ -fdata-sections -ffunction-sections -fmessage-length=0 --fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m7 diff --git a/variants/OPTA/defines.txt b/variants/OPTA/defines.txt index 9232d9eb8..970b3bc5d 100644 --- a/variants/OPTA/defines.txt +++ b/variants/OPTA/defines.txt @@ -44,7 +44,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1673362585.5704832 +-DMBED_BUILD_TIMESTAMP=1690447327.7181125 -D__MBED_CMSIS_RTOS_CM -DMBED_TICKLESS -DMBEDTLS_FS_IO diff --git a/variants/OPTA/includes.txt b/variants/OPTA/includes.txt index 83aacc793..413e84b71 100644 --- a/variants/OPTA/includes.txt +++ b/variants/OPTA/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/OPTA/libs/libmbed.a b/variants/OPTA/libs/libmbed.a index ddd7de3fc..aec91ccba 100644 Binary files a/variants/OPTA/libs/libmbed.a and b/variants/OPTA/libs/libmbed.a differ diff --git a/variants/OPTA/linker_script.ld b/variants/OPTA/linker_script.ld index f634db472..8941b72a6 100644 --- a/variants/OPTA/linker_script.ld +++ b/variants/OPTA/linker_script.ld @@ -1,12 +1,14 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 0x1c0000 + FLASH (rx) : ORIGIN = 0x8040000, LENGTH = CM4_BINARY_START - 0x8040000 DTCMRAM (rwx) : ORIGIN = 0x20000000 + (((166 * 4) + 7) & 0xFFFFFFF8), LENGTH = 128K - (((166 * 4) + 7) & 0xFFFFFFF8) RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 0x80000 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K } +__OPENAMP_region_start__ = 0x38000400; +__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K; ENTRY(Reset_Handler) SECTIONS { @@ -92,6 +94,20 @@ SECTIONS __bss_end__ = .; _ebss = .; } > RAM + .openamp_section (NOLOAD) : { + . = ABSOLUTE(0x38000000); + *(.resource_table) + } >RAM_D3 AT > FLASH + .pdm_section (NOLOAD) : { + . = ABSOLUTE(0x3800FC00); + *(.pdm_buffer) + } > RAM_D3 + _dtcm_lma = __etext + SIZEOF(.data); + .dtcm : AT(_dtcm_lma) { + _sdtcm = .; + *(.dtcm*) + _edtcm = .; + } > DTCMRAM .heap (COPY): { __end__ = .; diff --git a/variants/OPTA/mbed_config.h b/variants/OPTA/mbed_config.h index cade4b32b..c0485cbf8 100644 --- a/variants/OPTA/mbed_config.h +++ b/variants/OPTA/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/OPTA/pins_arduino.h b/variants/OPTA/pins_arduino.h index 62bbc478f..25d6e8c06 100644 --- a/variants/OPTA/pins_arduino.h +++ b/variants/OPTA/pins_arduino.h @@ -130,13 +130,18 @@ static const uint8_t SCK = PIN_SPI_SCK; #define PIN_WIRE_SDA (11u) #define PIN_WIRE_SCL (12u) -#define SERIAL_HOWMANY 2 +#define SERIAL_HOWMANY 3 #define SERIAL1_TX (digitalPinToPinName(PIN_SERIAL_TX)) #define SERIAL1_RX (digitalPinToPinName(PIN_SERIAL_RX)) #define SERIAL2_TX PB_10 #define SERIAL2_RX PB_11 +#define SERIAL3_TX PB_9 +#define SERIAL3_RX PH_14 +#define SERIAL3_RTS PA_15 +#define SERIAL3_CTS PB_15 + #define SERIAL_CDC 1 #define HAS_UNIQUE_ISERIAL_DESCRIPTOR @@ -184,11 +189,6 @@ void _ontouch1200bps_(); #define RS485_DEFAULT_DE_PIN PB_14 #define RS485_DEFAULT_RE_PIN PB_13 -#define SerialLoRa Serial3 -#define LORA_BOOT0 (PG_7) -#define LORA_RESET (PC_7) -#define LORA_IRQ_DUMB (PJ_11) - #define CRYPTO_WIRE Wire1 #define USB_MAX_POWER (500) diff --git a/variants/PORTENTA_H7_M4/defines.txt b/variants/PORTENTA_H7_M4/defines.txt index abd13279b..90277e8fe 100644 --- a/variants/PORTENTA_H7_M4/defines.txt +++ b/variants/PORTENTA_H7_M4/defines.txt @@ -42,7 +42,7 @@ -DFEATURE_BLE=1 -D__FPU_PRESENT=1 -D__MBED__=1 --DMBED_BUILD_TIMESTAMP=1674127650.1797109 +-DMBED_BUILD_TIMESTAMP=1690447099.1347957 -D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS diff --git a/variants/PORTENTA_H7_M4/libs/libmbed.a b/variants/PORTENTA_H7_M4/libs/libmbed.a index a1c9c8e12..297d3dfdd 100644 Binary files a/variants/PORTENTA_H7_M4/libs/libmbed.a and b/variants/PORTENTA_H7_M4/libs/libmbed.a differ diff --git a/variants/PORTENTA_H7_M4/mbed_config.h b/variants/PORTENTA_H7_M4/mbed_config.h index 936622de4..20f47ae62 100644 --- a/variants/PORTENTA_H7_M4/mbed_config.h +++ b/variants/PORTENTA_H7_M4/mbed_config.h @@ -195,6 +195,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/PORTENTA_H7_M7/defines.txt b/variants/PORTENTA_H7_M7/defines.txt index 5162a4fad..d4eec2164 100644 --- a/variants/PORTENTA_H7_M7/defines.txt +++ b/variants/PORTENTA_H7_M7/defines.txt @@ -2,12 +2,14 @@ -DARM_MATH_CM7 -DBT_UART_NO_3M_SUPPORT -DCM4_BOOT_BY_APPLICATION +-D__CMSIS_RTOS -DCOMPONENT_4343W_FS=1 -DCOMPONENT_CYW43XXX=1 -DCOMPONENT_FLASHIAP=1 -DCOMPONENT_QSPIF=1 -DCOMPONENT_WHD=1 -DCORE_CM7 +-D__CORTEX_M7 -DCYW43XXX_UNBUFFERED_UART -DDEVICE_ANALOGIN=1 -DDEVICE_ANALOGOUT=1 @@ -16,8 +18,8 @@ -DDEVICE_EMAC=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_MPU=1 @@ -32,8 +34,8 @@ -DDEVICE_SERIAL_FC=1 -DDEVICE_SLEEP=1 -DDEVICE_SPI=1 --DDEVICE_SPISLAVE=1 -DDEVICE_SPI_ASYNCH=1 +-DDEVICE_SPISLAVE=1 -DDEVICE_STDIO_MESSAGES=1 -DDEVICE_TRNG=1 -DDEVICE_USBDEVICE=1 @@ -41,11 +43,14 @@ -DDEVICE_WATCHDOG=1 -DEXTRA_IDLE_STACK_REQUIRED -DFEATURE_BLE=1 +-D__FPU_PRESENT=1 -DLSE_STARTUP_TIMEOUT=200 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447044.864524 +-D__MBED_CMSIS_RTOS_CM +-DMBED_TICKLESS -DMBEDTLS_FS_IO -DMBEDTLS_SHA1_C --DMBED_BUILD_TIMESTAMP=1670863887.7329667 --DMBED_TICKLESS -DMETAL_INTERNAL -DMETAL_MAX_DEVICE_REGIONS=2 -DNO_ATOMIC_64_SUPPORT @@ -77,11 +82,6 @@ -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -DVIRTIO_MASTER_ONLY --D__CMSIS_RTOS --D__CORTEX_M7 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/PORTENTA_H7_M7/includes.txt b/variants/PORTENTA_H7_M7/includes.txt index 1aef9dc4e..abddc6f96 100644 --- a/variants/PORTENTA_H7_M7/includes.txt +++ b/variants/PORTENTA_H7_M7/includes.txt @@ -148,23 +148,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/PORTENTA_H7_M7/libs/libmbed.a b/variants/PORTENTA_H7_M7/libs/libmbed.a index e2fec309b..d262766d7 100644 Binary files a/variants/PORTENTA_H7_M7/libs/libmbed.a and b/variants/PORTENTA_H7_M7/libs/libmbed.a differ diff --git a/variants/PORTENTA_H7_M7/linker_script.ld b/variants/PORTENTA_H7_M7/linker_script.ld index 17d5ac032..8941b72a6 100644 --- a/variants/PORTENTA_H7_M7/linker_script.ld +++ b/variants/PORTENTA_H7_M7/linker_script.ld @@ -30,6 +30,12 @@ SECTIONS *(.dtors) *(.rodata*) KEEP(*(.eh_frame*)) + *ltrans0*.o(.rodata*) + *ltrans1*.o(.rodata*) + *ltrans2*.o(.rodata*) + *ltrans3*.o(.rodata*) + *ltrans4*.o(.rodata*) + *lib*.o(.rodata*) } > FLASH .ARM.extab : { diff --git a/variants/PORTENTA_H7_M7/mbed_config.h b/variants/PORTENTA_H7_M7/mbed_config.h index 5eb2392ed..a6f5ffd53 100644 --- a/variants/PORTENTA_H7_M7/mbed_config.h +++ b/variants/PORTENTA_H7_M7/mbed_config.h @@ -196,6 +196,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/PORTENTA_X8/defines.txt b/variants/PORTENTA_X8/defines.txt index 6b5ab9bb7..7541674f7 100644 --- a/variants/PORTENTA_X8/defines.txt +++ b/variants/PORTENTA_X8/defines.txt @@ -1,16 +1,18 @@ -DARM_MATH_CM4 -DCM4_BOOT_BY_APPLICATION +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 -DCORE_CM4 +-D__CORTEX_M4 -DDEVICE_ANALOGIN=1 -DDEVICE_ANALOGOUT=1 -DDEVICE_CAN=1 -DDEVICE_CRC=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 --DDEVICE_I2CSLAVE=1 -DDEVICE_I2C_ASYNCH=1 +-DDEVICE_I2CSLAVE=1 -DDEVICE_INTERRUPTIN=1 -DDEVICE_LPTICKER=1 -DDEVICE_PORTIN=1 @@ -23,18 +25,21 @@ -DDEVICE_SERIAL_FC=1 -DDEVICE_SLEEP=1 -DDEVICE_SPI=1 --DDEVICE_SPISLAVE=1 -DDEVICE_SPI_ASYNCH=1 +-DDEVICE_SPISLAVE=1 -DDEVICE_STDIO_MESSAGES=1 -DDEVICE_TRNG=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 -DEXTRA_IDLE_STACK_REQUIRED --DMBEDTLS_FS_IO --DMBEDTLS_SHA1_C --DMBED_BUILD_TIMESTAMP=1670864288.6141653 +-D__FPU_PRESENT=1 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447283.7087135 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM -DMBED_TICKLESS +-DMBEDTLS_FS_IO +-DMBEDTLS_SHA1_C -DMETAL_INTERNAL -DMETAL_MAX_DEVICE_REGIONS=2 -DNO_ATOMIC_64_SUPPORT @@ -64,11 +69,6 @@ -DUSE_FULL_LL_DRIVER -DUSE_HAL_DRIVER -DVIRTIO_SLAVE_ONLY --D__CMSIS_RTOS --D__CORTEX_M4 --D__FPU_PRESENT=1 --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/PORTENTA_X8/includes.txt b/variants/PORTENTA_X8/includes.txt index 2d996d085..e071ee154 100644 --- a/variants/PORTENTA_X8/includes.txt +++ b/variants/PORTENTA_X8/includes.txt @@ -96,23 +96,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/PORTENTA_X8/libs/libmbed.a b/variants/PORTENTA_X8/libs/libmbed.a index 20a65cddb..7d9dd3a47 100644 Binary files a/variants/PORTENTA_X8/libs/libmbed.a and b/variants/PORTENTA_X8/libs/libmbed.a differ diff --git a/variants/PORTENTA_X8/mbed_config.h b/variants/PORTENTA_X8/mbed_config.h index 07c548a8b..3a0e9f454 100644 --- a/variants/PORTENTA_X8/mbed_config.h +++ b/variants/PORTENTA_X8/mbed_config.h @@ -150,6 +150,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora diff --git a/variants/RASPBERRY_PI_PICO/defines.txt b/variants/RASPBERRY_PI_PICO/defines.txt index 64f7cd8fa..15fb053eb 100644 --- a/variants/RASPBERRY_PI_PICO/defines.txt +++ b/variants/RASPBERRY_PI_PICO/defines.txt @@ -1,6 +1,8 @@ -DARM_MATH_CM0PLUS +-D__CMSIS_RTOS -DCOMPONENT_FLASHIAP=1 +-D__CORTEX_M0PLUS -DDEVICE_ANALOGIN=1 -DDEVICE_FLASH=1 -DDEVICE_I2C=1 @@ -17,9 +19,11 @@ -DDEVICE_USBDEVICE=1 -DDEVICE_USTICKER=1 -DDEVICE_WATCHDOG=1 --DMBEDTLS_ENTROPY_NV_SEED --DMBED_BUILD_TIMESTAMP=1670863580.9430058 +-D__MBED__=1 +-DMBED_BUILD_TIMESTAMP=1690447021.82633 +-D__MBED_CMSIS_RTOS_CM -DMBED_MPU_CUSTOM +-DMBEDTLS_ENTROPY_NV_SEED -DPICO_NO_BINARY_INFO=1 -DPICO_ON_DEVICE=1 -DPICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 @@ -30,18 +34,14 @@ -DTARGET_LIKE_CORTEX_M0 -DTARGET_LIKE_MBED -DTARGET_M0P +-DTARGET_memmap_default -DTARGET_NAME=RASPBERRY_PI_PICO -DTARGET_RASPBERRYPI -DTARGET_RASPBERRY_PI_PICO -DTARGET_RELEASE -DTARGET_RP2040 --DTARGET_memmap_default -DTOOLCHAIN_GCC -DTOOLCHAIN_GCC_ARM --D__CMSIS_RTOS --D__CORTEX_M0PLUS --D__MBED_CMSIS_RTOS_CM --D__MBED__=1 -DMBED_NO_GLOBAL_USING_DIRECTIVE=1 -DCORE_MAJOR= -DCORE_MINOR= diff --git a/variants/RASPBERRY_PI_PICO/includes.txt b/variants/RASPBERRY_PI_PICO/includes.txt index d538e6c6d..ec0bfda37 100644 --- a/variants/RASPBERRY_PI_PICO/includes.txt +++ b/variants/RASPBERRY_PI_PICO/includes.txt @@ -65,23 +65,6 @@ -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/mac -iwithprefixbefore/mbed/connectivity/lorawan/lorastack/phy -iwithprefixbefore/mbed/connectivity/lorawan/system --iwithprefixbefore/mbed/connectivity/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/include --iwithprefixbefore/mbed/connectivity/lwipstack/include/lwipstack --iwithprefixbefore/mbed/connectivity/lwipstack/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip-sys/arch --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/arpa --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/net --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/compat/posix/sys --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/priv --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/lwip/prot --iwithprefixbefore/mbed/connectivity/lwipstack/lwip/src/include/netif -iwithprefixbefore/mbed/connectivity/mbedtls -iwithprefixbefore/mbed/connectivity/mbedtls/include -iwithprefixbefore/mbed/connectivity/mbedtls/include/mbedtls diff --git a/variants/RASPBERRY_PI_PICO/libs/libmbed.a b/variants/RASPBERRY_PI_PICO/libs/libmbed.a index d7e1de69c..78edaa82d 100644 Binary files a/variants/RASPBERRY_PI_PICO/libs/libmbed.a and b/variants/RASPBERRY_PI_PICO/libs/libmbed.a differ diff --git a/variants/RASPBERRY_PI_PICO/mbed_config.h b/variants/RASPBERRY_PI_PICO/mbed_config.h index 08a14dc14..62a29941f 100644 --- a/variants/RASPBERRY_PI_PICO/mbed_config.h +++ b/variants/RASPBERRY_PI_PICO/mbed_config.h @@ -141,6 +141,7 @@ #define MBED_CONF_LORA_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // set by library:lora #define MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION 1 // set by library:lora #define MBED_CONF_LORA_PHY EU868 // set by library:lora +#define MBED_CONF_LORA_PHY_AS923_SUB_REGION AS1 // set by library:lora #define MBED_CONF_LORA_PUBLIC_NETWORK 1 // set by library:lora #define MBED_CONF_LORA_TX_MAX_SIZE 64 // set by library:lora #define MBED_CONF_LORA_UPLINK_PREAMBLE_LENGTH 8 // set by library:lora